0

I am developing a game which currently uses a GameFactory contract to create instances of a Game contract. The Factory pattern would allow any number of players to play their own single player game and the game data stored in separate Game instances.

However, ideally I need the Game contracts to interact with the GameFactory contracts to update global high scores and statistics about all games being currently played.

What would be a good way to achieve this? Are there any existing examples of patterns for decentralised games like this?

  • Have you considered storing all your data in one smart contract? Object-oriented patterns often don't translate well into Solidity contracts. You usually should not think of contracts as you would think of e.g. Java's classes. – Jesse Busman Nov 30 '18 at 18:28
  • I have around 20 variables including arrays and mappings that I need to keep track of for each game 'instance'. Instead, I should create a big struct of all those variables and create a mapping to the player address and game data struct? Then access that mapping every time i need to call a function to update? – koukotsu Nov 30 '18 at 19:00
  • To contradict @JesseBusman, from the standpoint of a security auditor, I tend to prefer factories and single contract instances. In my experience, that model is easier to get right than one where every function call takes an ID and has to do a more complex permissions check. – smarx Nov 30 '18 at 19:38
  • As for the original question, I don't understand the issue. Just have the Game call into the GameFactory. The GameFactory should keep a mapping of Games so it knows that the data it receives is valid (comes from a contract it deployed). – smarx Nov 30 '18 at 19:38
1

A hub and Spoke arrangement has advantages, as does a monolithic contract.

Hub and Spoke

  • Simpler internal structure, possibly more readable
  • Can accommodate a "rolling upgrade" path if that is desirable.

Monolithic

  • It costs considerably less to initialize a few variables than to deploy a new contract for each game.

Working on a Hub and Spoke basis leads naturally to some generic concerns. As you mentioned, probably the Spokes need to update globals in the Hub, the Hub needs to limit access to certain functions so only a Spoke is authorized to do so, etc.

My explorations led me to create generalized contracts, roughly:

contract Hub is Deployer { ...

contract Spoke is Deployed { ...

Consider that Deployer keeps track of deployed Spokes and does things like:

modifier onlyDeployed { // only trust contracts made by this Hub

... and Deployed does things like remembering the Hub that spawned it.

If you want to be able to upgrade the game logic, then you can consider further separation of Hub data and Factory logic. That is, you want to be able to hold the global data in a contract that is not expected to change, while periodically replacing the contract that deploys new games.

The lowest gas cost and simplest approach is a monolithic contract with game data rolled up into structs and no possibility of an upgrade.

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.