The game is formed by a system of contracts in a design, here called 'aggregated architecture'
The essence is to have:
- An authority (controlled ideally by community members)
- A mapping of modules
- Modules
The modules have two main types, those that a user might interact with, and those that maintain game state variables. Each module is backward compatible and may be upgraded as needed. Additional modules may be added. This is achieved by the authority updating the deployment addresses stored in the module mappings.
Imagine a network of partially connected modules. Each module may read different game variables from the system (e.g., player stats, item quantities, location statistics, other games states). Modules, after being vetted, may also update some variables selectively.
The system will initially consist of the simplest module set. Players will interact with a contract that then utilises the other modules for game operation. Then, additional modules can be connected. A player may then play by interacting in two separate transactions asynchronously. The game variables may be shared, allowing for complex interplay.
- Deploy a new application contract
- Point the application to read variables from modules, by
- Querying the
ModuleControllerfor the deployment address of themodule_idof interest. - Reading the state from that address.
- Querying the
- If write access is desired, the process is:
- Community review of deployed application code
approve_module_to_module_write_access()executed by the Arbiter contract, which updates permissions in theModuleController.
Module requirements:
- All modules that maintain state that is intended for open-ended use
must point to the
ModuleControllerfor write-access permissions.has_write_access()is called by the variable contract to ensure that the calling contract has the power to authorize updates that may affect other modules (which share the same variables).
- A module updgrade MUST NOT remove functions. New functions MAY be added, but backward compatibility with other modules is required.
Example module upgrade:
- Weapon overhaul: A module contains a record of who owns which weapon. A new module is written that keeps a record of how often a weapon is used. It adds a new function that exposes how worn out each weapon is. Another module may use this new variable.
- Drug upgrade: A module contains the record of who owns which drug. A new module is written that represents the drugs as a deposited token with limited scopes. The drugs may be deposited and made available for gameplay, or used in another module (E.g,. Where they may be consumed permanently).
- Bug fixes: Modules can be upgraded for the purpose of redesigning mechanisms or parameters for better play.
A contract that wants to write to a state variable must:
- Off-chain determine the appropriate
module_idfor the variable. - Fetch the
controller_addressfrom internal storage. - Call
get_module_address()in theModuleController. - Call the module with the appropriate function (e.g.,
update_var_x()). - The module receives the request and reads the calling address with
get_caller_address()from the common library. - The module fetches the
controller_addressfrom internal storage. - The module calls the
has_write_access()function in theModuleController, passing the caller's address (reverts if disallowed.) - The module then updates internal storage with the requested value.
Thus, every module has an only_approved() internal method that performs
steps 5-7.