Contract Tables

Source for Primodium Tables

Building Contracts from JSON

In MUD-compliant projects, tables are defined in a file named mud.config.ts and generated before compilation (opens in a new tab) into Solidity contracts for each individual table. To represent contract state, each table has a key schema and a value schema.

For example, the following JSON string in mud.config.ts encodes a table that stores the number of asteroids named AsteroidCount. Because there is no specified key schema, the key schema defaults to { "key": "bytes32" }. The value schema is a single uint256 type.

@primodiumxyz/contracts/mud.config.ts
{
  // ...
  AsteroidCount: {
    key: [],
    schema: { value: "uint256" },
  },
  // ...
}

After compilation, the AsteroidCount table is represented by a Solidity contract that conforms to the StoreCore (opens in a new tab) specifications. Therefore, the generated contract for the AsteroidCount table below has getter function that takes in the default bytes32 key schema:

@primodiumxyz/contracts/src/codegen/tables/AsteroidCount.sol
library AsteroidCount {
  // ...
  function getValue() internal view returns (uint256 value) {
    bytes32[] memory _keyTuple = new bytes32[](0);
 
    bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout);
    return (uint256(bytes32(_blob)));
  }
  // ...
}

Primodium Tables in World Extensions

When developing a world extension as a MUD-compliant project that modifies Primodium tables, the templates of such tables must be included in the extension's mud.config.ts.

For example, in the mud-config.ts of the building-upgrade-bounty world extension, the core Position and OwnedBy tables are referenced (opens in a new tab) as follows:

/examples/building-upgrade-bounty/packages/contracts/mud.config.ts#L21-L35
{
  // ...
  Position: {
    key: ["entity"],
    schema: { 
      entity: "bytes32", 
      x: "int32", 
      y: "int32", 
      parentEntity: "bytes32" 
    },
  },
 
  OwnedBy: {
    key: ["entity"],
    schema: { 
      entity: "bytes32", 
      value: "bytes32"
    },
  },
  // ...
}

After running pnpm run build, the Position and OwnedBy tables are generated as Solidity contracts in the codegen/tables directory. For instance, PositionData, which is generated from the Position table key schema, can be referenced in the world extension as follows.

/examples/building-upgrade-bounty/packages/contracts/src/libraries/LibHelpers.sol
import { PositionData } from "../codegen/index.sol";
 
library LibHelpers {
  function getHash(bytes32 key, PositionData memory position) internal pure returns (bytes32) {
    return keccak256(abi.encode(key, position.x, position.y, position.parent));
  }
  // ...
}

To read directly from the OwnedBy table, you can directly reference the OwnedBy table in the world extension as follows.

/examples/building-upgrade-bounty/packages/contracts/src/libraries/LibHelpers.sol
import { OwnedBy } from "../codegen/index.sol";
 
library LibHelpers {
  // ...
    function getBuildingFromCoord(PositionData memory coord) internal view returns (bytes32) {
    bytes32 buildingTile = getHash(BuildingTileKey, coord);
    return OwnedBy.get(buildingTile);
  }
  // ...
}