Lattice Workshop - Step 3.2

First contract system: Spawn

Next step

Systems on the contracts are not reactive like on the client, but rather methods that are actively called. But just like client systems, they act on components and entities.

In this step, we'll add a very simple contract system: a spawn method. For now, calling it just sets values of the position and appearance component.

On the client we can use the txExecutor we get from the @latticexyz/eth-middleware contract setup. The txExecutor takes care of submitting transactions synchronously to avoid nonce issues and handles chain specific transaction options.

We can test the spawn function by calling it directly from the developer console in the Lattice Launcher. If successful, we should see an entity popping up at the specified coordinate on the map.

Files changed (2) hide show
  1. client/src/Game.ts +4 -3
  2. contracts/src/Game.sol +6 -3
client/src/Game.ts CHANGED
@@ -18,6 +18,7 @@ import {
18
18
  import { createPositionSystem } from "./systems/PositionSystem";
19
19
  import { createTextureSystem } from "./systems/TextureSystem";
20
20
  import { createAppearanceSystem } from "./systems/AppearanceSystem";
21
+ import { Coord } from "./types";
21
22
 
22
23
  export async function createGame(contractAddress: string, privateKey: string, chainId: number, personaId: number) {
23
24
  const world = createWorld();
@@ -82,8 +83,8 @@ export async function createGame(contractAddress: string, privateKey: string, ch
82
83
  /*****************************************
83
84
  * Methods and context for consumers
84
85
  *****************************************/
85
- function ping() {
86
- return "pong";
86
+ function spawn(coord: Coord) {
87
+ txExecutor.sendTx((c) => c.spawn(coord));
87
88
  }
88
89
 
89
90
  const context = {
@@ -94,7 +95,7 @@ export async function createGame(contractAddress: string, privateKey: string, ch
94
95
  signer,
95
96
  txExecutor,
96
97
  personaId,
97
- api: { ping },
98
+ api: { spawn },
98
99
  };
99
100
 
100
101
  /*****************************************
contracts/src/Game.sol CHANGED
@@ -48,12 +48,9 @@ contract Game {
48
48
  function registerComponents(Components memory _components, address[] memory _componentList) public onlyContractOwner {
49
49
  c = _components;
50
50
  componentList = _componentList;
51
- c.position.set(1, Coord(0, 0));
52
51
 
53
52
  string memory imp = 'https://imagedelivery.net/kiVB3FlOmd8gwoTJWblSOA/ef4adf50-0e0d-4959-9917-439de7ed9500/public';
54
53
  c.texture.set(uint256(Texture.Imp), imp);
55
-
56
- c.appearance.set(1, uint256(Texture.Imp));
57
54
  }
58
55
 
59
56
  /**
@@ -64,4 +61,10 @@ contract Game {
64
61
  Component(componentList[i]).remove(entity);
65
62
  }
66
63
  }
64
+
65
+ function spawn(Coord memory coord) public {
66
+ uint256 entity = World(world).getNumEntities();
67
+ c.position.set(entity, coord);
68
+ c.appearance.set(entity, uint256(Texture.Imp));
69
+ }
67
70
  }