create-mud 2.2.17-5aa8a3ad00aa591f9c3a60526b045257dc8a0bb5 → 2.2.17-78e9ed1294db2e924bd295734f3738bdd2786242

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +1 -1
  4. package/templates/react/mprocs.yaml +1 -9
  5. package/templates/react/packages/client/index.html +2 -2
  6. package/templates/react/packages/client/package.json +9 -17
  7. package/templates/react/packages/client/src/App.tsx +100 -41
  8. package/templates/react/packages/client/src/MUDContext.tsx +21 -0
  9. package/templates/react/packages/client/src/index.tsx +32 -17
  10. package/templates/react/packages/client/src/mud/createSystemCalls.ts +56 -0
  11. package/templates/react/packages/client/src/mud/getNetworkConfig.ts +76 -0
  12. package/templates/react/packages/client/src/mud/setup.ts +18 -0
  13. package/templates/react/packages/client/src/mud/setupNetwork.ts +101 -0
  14. package/templates/react/packages/client/src/mud/supportedChains.ts +20 -0
  15. package/templates/react/packages/client/tsconfig.json +1 -1
  16. package/templates/react/packages/client/vite.config.ts +7 -2
  17. package/templates/react/packages/contracts/.env +1 -1
  18. package/templates/react/packages/contracts/mud.config.ts +8 -6
  19. package/templates/react/packages/contracts/package.json +0 -1
  20. package/templates/react/packages/contracts/script/PostDeploy.s.sol +9 -1
  21. package/templates/react/packages/contracts/src/codegen/index.sol +1 -1
  22. package/templates/react/packages/contracts/src/codegen/tables/Tasks.sol +522 -0
  23. package/templates/{react-ecs/packages/contracts/src/codegen/world/IMoveSystem.sol → react/packages/contracts/src/codegen/world/ITasksSystem.sol} +9 -6
  24. package/templates/react/packages/contracts/src/codegen/world/IWorld.sol +2 -2
  25. package/templates/react/packages/contracts/src/systems/TasksSystem.sol +24 -0
  26. package/templates/react/packages/contracts/test/TasksTest.t.sol +30 -0
  27. package/templates/react/packages/contracts/worlds.json +1 -1
  28. package/templates/react-ecs/mprocs.yaml +1 -9
  29. package/templates/react-ecs/package.json +2 -1
  30. package/templates/react-ecs/packages/client/index.html +2 -2
  31. package/templates/react-ecs/packages/client/package.json +9 -16
  32. package/templates/react-ecs/packages/client/src/App.tsx +21 -66
  33. package/templates/react-ecs/packages/client/src/MUDContext.tsx +21 -0
  34. package/templates/react-ecs/packages/client/src/index.tsx +32 -17
  35. package/templates/react-ecs/packages/client/src/mud/createClientComponents.ts +21 -0
  36. package/templates/react-ecs/packages/client/src/mud/createSystemCalls.ts +51 -0
  37. package/templates/react-ecs/packages/client/src/mud/getNetworkConfig.ts +77 -0
  38. package/templates/react-ecs/packages/client/src/mud/setup.ts +21 -0
  39. package/templates/react-ecs/packages/client/src/mud/setupNetwork.ts +106 -0
  40. package/templates/react-ecs/packages/client/src/mud/supportedChains.ts +20 -0
  41. package/templates/react-ecs/packages/client/src/mud/world.ts +3 -0
  42. package/templates/react-ecs/packages/client/tsconfig.json +1 -1
  43. package/templates/react-ecs/packages/client/vite.config.ts +7 -2
  44. package/templates/react-ecs/packages/contracts/.env +1 -1
  45. package/templates/react-ecs/packages/contracts/mud.config.ts +6 -11
  46. package/templates/react-ecs/packages/contracts/package.json +0 -1
  47. package/templates/react-ecs/packages/contracts/script/PostDeploy.s.sol +5 -1
  48. package/templates/react-ecs/packages/contracts/src/codegen/index.sol +1 -3
  49. package/templates/react-ecs/packages/contracts/src/codegen/tables/{EntityCount.sol → Counter.sol} +35 -35
  50. package/templates/{react/packages/contracts/src/codegen/world/IMoveSystem.sol → react-ecs/packages/contracts/src/codegen/world/IIncrementSystem.sol} +3 -5
  51. package/templates/react-ecs/packages/contracts/src/codegen/world/IWorld.sol +2 -3
  52. package/templates/react-ecs/packages/contracts/src/systems/IncrementSystem.sol +14 -0
  53. package/templates/react-ecs/packages/contracts/test/CounterTest.t.sol +31 -0
  54. package/templates/react-ecs/packages/contracts/worlds.json +1 -1
  55. package/templates/phaser/.gitignore_ +0 -7
  56. package/templates/phaser/packages/art/.gitignore_ +0 -0
  57. package/templates/phaser/packages/client/.gitignore_ +0 -3
  58. package/templates/phaser/packages/contracts/.gitignore_ +0 -9
  59. package/templates/react/.gitignore_ +0 -16
  60. package/templates/react/packages/client/.gitignore_ +0 -1
  61. package/templates/react/packages/client/postcss.config.cjs +0 -6
  62. package/templates/react/packages/client/src/Providers.tsx +0 -35
  63. package/templates/react/packages/client/src/common.ts +0 -26
  64. package/templates/react/packages/client/src/game/GameMap.tsx +0 -102
  65. package/templates/react/packages/client/src/game/useKeyboardMovement.ts +0 -26
  66. package/templates/react/packages/client/src/mud/Explorer.tsx +0 -32
  67. package/templates/react/packages/client/src/mud/Synced.tsx +0 -14
  68. package/templates/react/packages/client/src/mud/stash.ts +0 -4
  69. package/templates/react/packages/client/src/mud/useSyncStatus.ts +0 -21
  70. package/templates/react/packages/client/src/mud/useWorldContract.ts +0 -44
  71. package/templates/react/packages/client/src/ui/AsyncButton.tsx +0 -41
  72. package/templates/react/packages/client/src/ui/ErrorFallback.tsx +0 -58
  73. package/templates/react/packages/client/src/ui/icons/ArrowDownIcon.tsx +0 -22
  74. package/templates/react/packages/client/src/ui/icons/MUDIcon.tsx +0 -25
  75. package/templates/react/packages/client/src/wagmiConfig.ts +0 -49
  76. package/templates/react/packages/client/tailwind.config.ts +0 -10
  77. package/templates/react/packages/contracts/.gitignore_ +0 -13
  78. package/templates/react/packages/contracts/out/IWorld.sol/IWorld.abi.json +0 -2021
  79. package/templates/react/packages/contracts/src/MoveSystem.sol +0 -26
  80. package/templates/react/packages/contracts/src/codegen/common.sol +0 -11
  81. package/templates/react/packages/contracts/src/codegen/tables/Position.sol +0 -318
  82. package/templates/react/packages/contracts/test/MoveTest.t.sol +0 -25
  83. package/templates/react/packages/contracts/test/WorldTest.t.sol +0 -16
  84. package/templates/react-ecs/.gitignore_ +0 -16
  85. package/templates/react-ecs/packages/client/.gitignore_ +0 -1
  86. package/templates/react-ecs/packages/client/postcss.config.cjs +0 -6
  87. package/templates/react-ecs/packages/client/src/Providers.tsx +0 -29
  88. package/templates/react-ecs/packages/client/src/common.ts +0 -27
  89. package/templates/react-ecs/packages/client/src/game/GameMap.tsx +0 -112
  90. package/templates/react-ecs/packages/client/src/game/useKeyboardMovement.ts +0 -26
  91. package/templates/react-ecs/packages/client/src/mud/Explorer.tsx +0 -32
  92. package/templates/react-ecs/packages/client/src/mud/Synced.tsx +0 -14
  93. package/templates/react-ecs/packages/client/src/mud/recs.ts +0 -6
  94. package/templates/react-ecs/packages/client/src/mud/useSyncStatus.ts +0 -17
  95. package/templates/react-ecs/packages/client/src/mud/useWorldContract.ts +0 -44
  96. package/templates/react-ecs/packages/client/src/ui/AsyncButton.tsx +0 -41
  97. package/templates/react-ecs/packages/client/src/ui/ErrorFallback.tsx +0 -58
  98. package/templates/react-ecs/packages/client/src/ui/icons/ArrowDownIcon.tsx +0 -22
  99. package/templates/react-ecs/packages/client/src/ui/icons/MUDIcon.tsx +0 -25
  100. package/templates/react-ecs/packages/client/src/wagmiConfig.ts +0 -49
  101. package/templates/react-ecs/packages/client/tailwind.config.ts +0 -10
  102. package/templates/react-ecs/packages/contracts/.gitignore_ +0 -13
  103. package/templates/react-ecs/packages/contracts/out/IWorld.sol/IWorld.abi.json +0 -2039
  104. package/templates/react-ecs/packages/contracts/src/Entity.sol +0 -20
  105. package/templates/react-ecs/packages/contracts/src/MoveSystem.sol +0 -30
  106. package/templates/react-ecs/packages/contracts/src/SpawnSystem.sol +0 -18
  107. package/templates/react-ecs/packages/contracts/src/codegen/common.sol +0 -11
  108. package/templates/react-ecs/packages/contracts/src/codegen/tables/Owner.sol +0 -202
  109. package/templates/react-ecs/packages/contracts/src/codegen/tables/Position.sol +0 -321
  110. package/templates/react-ecs/packages/contracts/src/codegen/world/ISpawnSystem.sol +0 -15
  111. package/templates/react-ecs/packages/contracts/src/createEntity.sol +0 -11
  112. package/templates/react-ecs/packages/contracts/test/MoveTest.t.sol +0 -39
  113. package/templates/react-ecs/packages/contracts/test/WorldTest.t.sol +0 -16
  114. package/templates/threejs/.gitignore_ +0 -7
  115. package/templates/threejs/packages/client/.gitignore_ +0 -3
  116. package/templates/threejs/packages/contracts/.gitignore_ +0 -9
  117. package/templates/vanilla/.gitignore_ +0 -7
  118. package/templates/vanilla/packages/client/.gitignore_ +0 -3
  119. package/templates/vanilla/packages/contracts/.gitignore_ +0 -9
@@ -1,26 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity >=0.8.24;
3
-
4
- import { System } from "@latticexyz/world/src/System.sol";
5
-
6
- import { Direction } from "./codegen/common.sol";
7
- import { Position, PositionData } from "./codegen/tables/Position.sol";
8
-
9
- contract MoveSystem is System {
10
- function move(Direction direction) public {
11
- address player = _msgSender();
12
- PositionData memory position = Position.get(player);
13
-
14
- if (direction == Direction.North) {
15
- position.y += 1;
16
- } else if (direction == Direction.East) {
17
- position.x += 1;
18
- } else if (direction == Direction.South) {
19
- position.y -= 1;
20
- } else if (direction == Direction.West) {
21
- position.x -= 1;
22
- }
23
-
24
- Position.set(player, position);
25
- }
26
- }
@@ -1,11 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity >=0.8.24;
3
-
4
- /* Autogenerated file. Do not edit manually. */
5
-
6
- enum Direction {
7
- North,
8
- East,
9
- South,
10
- West
11
- }
@@ -1,318 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity >=0.8.24;
3
-
4
- /* Autogenerated file. Do not edit manually. */
5
-
6
- // Import store internals
7
- import { IStore } from "@latticexyz/store/src/IStore.sol";
8
- import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol";
9
- import { StoreCore } from "@latticexyz/store/src/StoreCore.sol";
10
- import { Bytes } from "@latticexyz/store/src/Bytes.sol";
11
- import { Memory } from "@latticexyz/store/src/Memory.sol";
12
- import { SliceLib } from "@latticexyz/store/src/Slice.sol";
13
- import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol";
14
- import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol";
15
- import { Schema } from "@latticexyz/store/src/Schema.sol";
16
- import { EncodedLengths, EncodedLengthsLib } from "@latticexyz/store/src/EncodedLengths.sol";
17
- import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
18
-
19
- struct PositionData {
20
- int32 x;
21
- int32 y;
22
- }
23
-
24
- library Position {
25
- // Hex below is the result of `WorldResourceIdLib.encode({ namespace: "app", name: "Position", typeId: RESOURCE_TABLE });`
26
- ResourceId constant _tableId = ResourceId.wrap(0x74626170700000000000000000000000506f736974696f6e0000000000000000);
27
-
28
- FieldLayout constant _fieldLayout =
29
- FieldLayout.wrap(0x0008020004040000000000000000000000000000000000000000000000000000);
30
-
31
- // Hex-encoded key schema of (address)
32
- Schema constant _keySchema = Schema.wrap(0x0014010061000000000000000000000000000000000000000000000000000000);
33
- // Hex-encoded value schema of (int32, int32)
34
- Schema constant _valueSchema = Schema.wrap(0x0008020023230000000000000000000000000000000000000000000000000000);
35
-
36
- /**
37
- * @notice Get the table's key field names.
38
- * @return keyNames An array of strings with the names of key fields.
39
- */
40
- function getKeyNames() internal pure returns (string[] memory keyNames) {
41
- keyNames = new string[](1);
42
- keyNames[0] = "player";
43
- }
44
-
45
- /**
46
- * @notice Get the table's value field names.
47
- * @return fieldNames An array of strings with the names of value fields.
48
- */
49
- function getFieldNames() internal pure returns (string[] memory fieldNames) {
50
- fieldNames = new string[](2);
51
- fieldNames[0] = "x";
52
- fieldNames[1] = "y";
53
- }
54
-
55
- /**
56
- * @notice Register the table with its config.
57
- */
58
- function register() internal {
59
- StoreSwitch.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames());
60
- }
61
-
62
- /**
63
- * @notice Register the table with its config.
64
- */
65
- function _register() internal {
66
- StoreCore.registerTable(_tableId, _fieldLayout, _keySchema, _valueSchema, getKeyNames(), getFieldNames());
67
- }
68
-
69
- /**
70
- * @notice Get x.
71
- */
72
- function getX(address player) internal view returns (int32 x) {
73
- bytes32[] memory _keyTuple = new bytes32[](1);
74
- _keyTuple[0] = bytes32(uint256(uint160(player)));
75
-
76
- bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout);
77
- return (int32(uint32(bytes4(_blob))));
78
- }
79
-
80
- /**
81
- * @notice Get x.
82
- */
83
- function _getX(address player) internal view returns (int32 x) {
84
- bytes32[] memory _keyTuple = new bytes32[](1);
85
- _keyTuple[0] = bytes32(uint256(uint160(player)));
86
-
87
- bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout);
88
- return (int32(uint32(bytes4(_blob))));
89
- }
90
-
91
- /**
92
- * @notice Set x.
93
- */
94
- function setX(address player, int32 x) internal {
95
- bytes32[] memory _keyTuple = new bytes32[](1);
96
- _keyTuple[0] = bytes32(uint256(uint160(player)));
97
-
98
- StoreSwitch.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((x)), _fieldLayout);
99
- }
100
-
101
- /**
102
- * @notice Set x.
103
- */
104
- function _setX(address player, int32 x) internal {
105
- bytes32[] memory _keyTuple = new bytes32[](1);
106
- _keyTuple[0] = bytes32(uint256(uint160(player)));
107
-
108
- StoreCore.setStaticField(_tableId, _keyTuple, 0, abi.encodePacked((x)), _fieldLayout);
109
- }
110
-
111
- /**
112
- * @notice Get y.
113
- */
114
- function getY(address player) internal view returns (int32 y) {
115
- bytes32[] memory _keyTuple = new bytes32[](1);
116
- _keyTuple[0] = bytes32(uint256(uint160(player)));
117
-
118
- bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 1, _fieldLayout);
119
- return (int32(uint32(bytes4(_blob))));
120
- }
121
-
122
- /**
123
- * @notice Get y.
124
- */
125
- function _getY(address player) internal view returns (int32 y) {
126
- bytes32[] memory _keyTuple = new bytes32[](1);
127
- _keyTuple[0] = bytes32(uint256(uint160(player)));
128
-
129
- bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 1, _fieldLayout);
130
- return (int32(uint32(bytes4(_blob))));
131
- }
132
-
133
- /**
134
- * @notice Set y.
135
- */
136
- function setY(address player, int32 y) internal {
137
- bytes32[] memory _keyTuple = new bytes32[](1);
138
- _keyTuple[0] = bytes32(uint256(uint160(player)));
139
-
140
- StoreSwitch.setStaticField(_tableId, _keyTuple, 1, abi.encodePacked((y)), _fieldLayout);
141
- }
142
-
143
- /**
144
- * @notice Set y.
145
- */
146
- function _setY(address player, int32 y) internal {
147
- bytes32[] memory _keyTuple = new bytes32[](1);
148
- _keyTuple[0] = bytes32(uint256(uint160(player)));
149
-
150
- StoreCore.setStaticField(_tableId, _keyTuple, 1, abi.encodePacked((y)), _fieldLayout);
151
- }
152
-
153
- /**
154
- * @notice Get the full data.
155
- */
156
- function get(address player) internal view returns (PositionData memory _table) {
157
- bytes32[] memory _keyTuple = new bytes32[](1);
158
- _keyTuple[0] = bytes32(uint256(uint160(player)));
159
-
160
- (bytes memory _staticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = StoreSwitch.getRecord(
161
- _tableId,
162
- _keyTuple,
163
- _fieldLayout
164
- );
165
- return decode(_staticData, _encodedLengths, _dynamicData);
166
- }
167
-
168
- /**
169
- * @notice Get the full data.
170
- */
171
- function _get(address player) internal view returns (PositionData memory _table) {
172
- bytes32[] memory _keyTuple = new bytes32[](1);
173
- _keyTuple[0] = bytes32(uint256(uint160(player)));
174
-
175
- (bytes memory _staticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = StoreCore.getRecord(
176
- _tableId,
177
- _keyTuple,
178
- _fieldLayout
179
- );
180
- return decode(_staticData, _encodedLengths, _dynamicData);
181
- }
182
-
183
- /**
184
- * @notice Set the full data using individual values.
185
- */
186
- function set(address player, int32 x, int32 y) internal {
187
- bytes memory _staticData = encodeStatic(x, y);
188
-
189
- EncodedLengths _encodedLengths;
190
- bytes memory _dynamicData;
191
-
192
- bytes32[] memory _keyTuple = new bytes32[](1);
193
- _keyTuple[0] = bytes32(uint256(uint160(player)));
194
-
195
- StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData);
196
- }
197
-
198
- /**
199
- * @notice Set the full data using individual values.
200
- */
201
- function _set(address player, int32 x, int32 y) internal {
202
- bytes memory _staticData = encodeStatic(x, y);
203
-
204
- EncodedLengths _encodedLengths;
205
- bytes memory _dynamicData;
206
-
207
- bytes32[] memory _keyTuple = new bytes32[](1);
208
- _keyTuple[0] = bytes32(uint256(uint160(player)));
209
-
210
- StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout);
211
- }
212
-
213
- /**
214
- * @notice Set the full data using the data struct.
215
- */
216
- function set(address player, PositionData memory _table) internal {
217
- bytes memory _staticData = encodeStatic(_table.x, _table.y);
218
-
219
- EncodedLengths _encodedLengths;
220
- bytes memory _dynamicData;
221
-
222
- bytes32[] memory _keyTuple = new bytes32[](1);
223
- _keyTuple[0] = bytes32(uint256(uint160(player)));
224
-
225
- StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData);
226
- }
227
-
228
- /**
229
- * @notice Set the full data using the data struct.
230
- */
231
- function _set(address player, PositionData memory _table) internal {
232
- bytes memory _staticData = encodeStatic(_table.x, _table.y);
233
-
234
- EncodedLengths _encodedLengths;
235
- bytes memory _dynamicData;
236
-
237
- bytes32[] memory _keyTuple = new bytes32[](1);
238
- _keyTuple[0] = bytes32(uint256(uint160(player)));
239
-
240
- StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout);
241
- }
242
-
243
- /**
244
- * @notice Decode the tightly packed blob of static data using this table's field layout.
245
- */
246
- function decodeStatic(bytes memory _blob) internal pure returns (int32 x, int32 y) {
247
- x = (int32(uint32(Bytes.getBytes4(_blob, 0))));
248
-
249
- y = (int32(uint32(Bytes.getBytes4(_blob, 4))));
250
- }
251
-
252
- /**
253
- * @notice Decode the tightly packed blobs using this table's field layout.
254
- * @param _staticData Tightly packed static fields.
255
- *
256
- *
257
- */
258
- function decode(
259
- bytes memory _staticData,
260
- EncodedLengths,
261
- bytes memory
262
- ) internal pure returns (PositionData memory _table) {
263
- (_table.x, _table.y) = decodeStatic(_staticData);
264
- }
265
-
266
- /**
267
- * @notice Delete all data for given keys.
268
- */
269
- function deleteRecord(address player) internal {
270
- bytes32[] memory _keyTuple = new bytes32[](1);
271
- _keyTuple[0] = bytes32(uint256(uint160(player)));
272
-
273
- StoreSwitch.deleteRecord(_tableId, _keyTuple);
274
- }
275
-
276
- /**
277
- * @notice Delete all data for given keys.
278
- */
279
- function _deleteRecord(address player) internal {
280
- bytes32[] memory _keyTuple = new bytes32[](1);
281
- _keyTuple[0] = bytes32(uint256(uint160(player)));
282
-
283
- StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout);
284
- }
285
-
286
- /**
287
- * @notice Tightly pack static (fixed length) data using this table's schema.
288
- * @return The static data, encoded into a sequence of bytes.
289
- */
290
- function encodeStatic(int32 x, int32 y) internal pure returns (bytes memory) {
291
- return abi.encodePacked(x, y);
292
- }
293
-
294
- /**
295
- * @notice Encode all of a record's fields.
296
- * @return The static (fixed length) data, encoded into a sequence of bytes.
297
- * @return The lengths of the dynamic fields (packed into a single bytes32 value).
298
- * @return The dynamic (variable length) data, encoded into a sequence of bytes.
299
- */
300
- function encode(int32 x, int32 y) internal pure returns (bytes memory, EncodedLengths, bytes memory) {
301
- bytes memory _staticData = encodeStatic(x, y);
302
-
303
- EncodedLengths _encodedLengths;
304
- bytes memory _dynamicData;
305
-
306
- return (_staticData, _encodedLengths, _dynamicData);
307
- }
308
-
309
- /**
310
- * @notice Encode keys as a bytes32 array using this table's field layout.
311
- */
312
- function encodeKeyTuple(address player) internal pure returns (bytes32[] memory) {
313
- bytes32[] memory _keyTuple = new bytes32[](1);
314
- _keyTuple[0] = bytes32(uint256(uint160(player)));
315
-
316
- return _keyTuple;
317
- }
318
- }
@@ -1,25 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity >=0.8.24;
3
-
4
- import "forge-std/Test.sol";
5
- import { MudTest } from "@latticexyz/world/test/MudTest.t.sol";
6
-
7
- import { IWorld } from "../src/codegen/world/IWorld.sol";
8
- import { Position, PositionData } from "../src/codegen/tables/Position.sol";
9
- import { Direction } from "../src/codegen/common.sol";
10
-
11
- contract MoveTest is MudTest {
12
- function testMove() public {
13
- address alice = vm.addr(uint256(keccak256("alice")));
14
- vm.startPrank(alice);
15
-
16
- PositionData memory position = Position.get(alice);
17
- assertEq(position.x, 0);
18
- assertEq(position.y, 0);
19
-
20
- IWorld(worldAddress).app__move(Direction.North);
21
- position = Position.get(alice);
22
- assertEq(position.x, 0);
23
- assertEq(position.y, 1);
24
- }
25
- }
@@ -1,16 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity >=0.8.24;
3
-
4
- import "forge-std/Test.sol";
5
- import { MudTest } from "@latticexyz/world/test/MudTest.t.sol";
6
-
7
- contract WorldTest is MudTest {
8
- function testWorldDeployed() public {
9
- uint256 codeSize;
10
- address addr = worldAddress;
11
- assembly {
12
- codeSize := extcodesize(addr)
13
- }
14
- assertTrue(codeSize > 0);
15
- }
16
- }
@@ -1,16 +0,0 @@
1
- .DS_Store
2
- logs
3
- *.log
4
-
5
- node_modules
6
-
7
- .env.*
8
-
9
- # foundry
10
- cache
11
- broadcast
12
- out/*
13
- !out/IWorld.sol
14
- out/IWorld.sol/*
15
- !out/IWorld.sol/IWorld.abi.json
16
- !out/IWorld.sol/IWorld.abi.d.json.ts
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- plugins: {
3
- tailwindcss: {},
4
- autoprefixer: {},
5
- },
6
- };
@@ -1,29 +0,0 @@
1
- import { WagmiProvider } from "wagmi";
2
- import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
3
- import { ReactNode } from "react";
4
- import { SyncProvider } from "@latticexyz/store-sync/react";
5
- import { defineConfig, EntryKitProvider } from "@latticexyz/entrykit/internal";
6
- import { wagmiConfig } from "./wagmiConfig";
7
- import { chainId, getWorldAddress, startBlock } from "./common";
8
- import { syncAdapter } from "./mud/recs";
9
-
10
- const queryClient = new QueryClient();
11
-
12
- export type Props = {
13
- children: ReactNode;
14
- };
15
-
16
- export function Providers({ children }: Props) {
17
- const worldAddress = getWorldAddress();
18
- return (
19
- <WagmiProvider config={wagmiConfig}>
20
- <QueryClientProvider client={queryClient}>
21
- <EntryKitProvider config={defineConfig({ chainId, worldAddress })}>
22
- <SyncProvider chainId={chainId} address={worldAddress} startBlock={startBlock} adapter={syncAdapter}>
23
- {children}
24
- </SyncProvider>
25
- </EntryKitProvider>
26
- </QueryClientProvider>
27
- </WagmiProvider>
28
- );
29
- }
@@ -1,27 +0,0 @@
1
- import mudConfig from "contracts/mud.config";
2
- import { chains } from "./wagmiConfig";
3
- import { Chain, Hex } from "viem";
4
-
5
- export const chainId = import.meta.env.CHAIN_ID;
6
- export const worldAddress = import.meta.env.WORLD_ADDRESS;
7
- export const startBlock = import.meta.env.START_BLOCK;
8
-
9
- export const url = new URL(window.location.href);
10
-
11
- export type Entity = Hex;
12
- export type Direction = (typeof mudConfig.enums.Direction)[number];
13
-
14
- export function getWorldAddress() {
15
- if (!worldAddress) {
16
- throw new Error("No world address configured. Is the world still deploying?");
17
- }
18
- return worldAddress;
19
- }
20
-
21
- export function getChain(): Chain {
22
- const chain = chains.find((c) => c.id === chainId);
23
- if (!chain) {
24
- throw new Error(`No chain configured for chain ID ${chainId}.`);
25
- }
26
- return chain;
27
- }
@@ -1,112 +0,0 @@
1
- import { serialize, useAccount } from "wagmi";
2
- import { useKeyboardMovement } from "./useKeyboardMovement";
3
- import { Address, Hex, hexToBigInt, keccak256 } from "viem";
4
- import { ArrowDownIcon } from "../ui/icons/ArrowDownIcon";
5
- import { twMerge } from "tailwind-merge";
6
- import { Direction, Entity } from "../common";
7
- import mudConfig from "contracts/mud.config";
8
- import { AsyncButton } from "../ui/AsyncButton";
9
- import { useAccountModal } from "@latticexyz/entrykit/internal";
10
- import { useMemo } from "react";
11
-
12
- export type Props = {
13
- readonly players?: {
14
- readonly entity: Entity;
15
- readonly owner: Address;
16
- readonly x: number;
17
- readonly y: number;
18
- }[];
19
- readonly onMove?: (entity: Entity, direction: Direction) => Promise<void>;
20
- readonly onSpawn?: () => Promise<void>;
21
- };
22
-
23
- const size = 40;
24
- const scale = 100 / size;
25
-
26
- function getColorAngle(seed: Hex) {
27
- return Number(hexToBigInt(keccak256(seed)) % 360n);
28
- }
29
-
30
- const rotateClassName = {
31
- North: "rotate-0",
32
- East: "rotate-90",
33
- South: "rotate-180",
34
- West: "-rotate-90",
35
- } as const satisfies Record<Direction, `${"" | "-"}rotate-${number}`>;
36
-
37
- export function GameMap({ players = [], onMove, onSpawn }: Props) {
38
- const { openAccountModal } = useAccountModal();
39
- const { address: userAddress } = useAccount();
40
-
41
- const currentPlayer = players.find((player) => player.owner.toLowerCase() === userAddress?.toLowerCase());
42
-
43
- useKeyboardMovement(
44
- useMemo(
45
- () => (onMove && currentPlayer ? (direction: Direction) => onMove(currentPlayer.entity, direction) : undefined),
46
- [currentPlayer, onMove],
47
- ),
48
- );
49
-
50
- return (
51
- <div className="aspect-square w-full max-w-[40rem]">
52
- <div className="relative w-full h-full border-8 border-black/10">
53
- {currentPlayer && onMove
54
- ? mudConfig.enums.Direction.map((direction) => (
55
- <button
56
- key={direction}
57
- title={`Move ${direction.toLowerCase()}`}
58
- className={twMerge(
59
- "outline-0 absolute inset-0 cursor-pointer grid p-4",
60
- rotateClassName[direction],
61
- "transition bg-gradient-to-t from-transparent via-transparent to-blue-50 text-blue-400 opacity-0 hover:opacity-40 active:opacity-100",
62
- )}
63
- style={{ clipPath: "polygon(0% 0%, 100% 0%, 50% 50%)" }}
64
- onClick={() => onMove(currentPlayer.entity, direction)}
65
- >
66
- <ArrowDownIcon className="rotate-180 text-4xl self-start justify-self-center" />
67
- </button>
68
- ))
69
- : null}
70
-
71
- {players.map((player) => (
72
- <div
73
- key={player.entity}
74
- className="absolute bg-current"
75
- style={{
76
- color: `hwb(${getColorAngle(player.owner)} 40% 20%)`,
77
- width: `${scale}%`,
78
- height: `${scale}%`,
79
- left: `${((((player.x + size / 2) % size) + size) % size) * scale}%`,
80
- top: `${((size - ((player.y + size / 2) % size)) % size) * scale}%`,
81
- }}
82
- title={serialize(player, null, 2)}
83
- >
84
- {player === currentPlayer ? <div className="w-full h-full bg-current animate-ping opacity-50" /> : null}
85
- </div>
86
- ))}
87
-
88
- {!currentPlayer ? (
89
- onSpawn ? (
90
- <div className="absolute inset-0 grid place-items-center">
91
- <AsyncButton
92
- className="group outline-0 p-4 border-4 border-green-400 transition ring-green-300 hover:ring-4 active:scale-95 rounded-lg text-lg font-medium aria-busy:pointer-events-none aria-busy:animate-pulse"
93
- onClick={() => onSpawn()}
94
- >
95
- Spawn<span className="hidden group-aria-busy:inline">ing…</span>
96
- </AsyncButton>
97
- </div>
98
- ) : (
99
- <div className="absolute inset-0 grid place-items-center">
100
- <button
101
- className="group outline-0 p-4 border-4 border-green-400 transition ring-green-300 hover:ring-4 active:scale-95 rounded-lg text-lg font-medium aria-busy:pointer-events-none aria-busy:animate-pulse"
102
- onClick={openAccountModal}
103
- >
104
- Sign in to play
105
- </button>
106
- </div>
107
- )
108
- ) : null}
109
- </div>
110
- </div>
111
- );
112
- }
@@ -1,26 +0,0 @@
1
- import { useEffect } from "react";
2
- import { Direction } from "../common";
3
-
4
- const keys = new Map<KeyboardEvent["key"], Direction>([
5
- ["ArrowUp", "North"],
6
- ["ArrowRight", "East"],
7
- ["ArrowDown", "South"],
8
- ["ArrowLeft", "West"],
9
- ]);
10
-
11
- export const useKeyboardMovement = (move: undefined | ((direction: Direction) => void)) => {
12
- useEffect(() => {
13
- if (!move) return;
14
-
15
- const listener = (event: KeyboardEvent) => {
16
- const direction = keys.get(event.key);
17
- if (direction == null) return;
18
-
19
- event.preventDefault();
20
- move(direction);
21
- };
22
-
23
- window.addEventListener("keydown", listener);
24
- return () => window.removeEventListener("keydown", listener);
25
- }, [move]);
26
- };
@@ -1,32 +0,0 @@
1
- import { useState } from "react";
2
- import { getChain, getWorldAddress } from "../common";
3
- import { MUDIcon } from "../ui/icons/MUDIcon";
4
-
5
- export function Explorer() {
6
- const [open, setOpen] = useState(false);
7
-
8
- const chain = getChain();
9
- const worldAddress = getWorldAddress();
10
-
11
- const explorerUrl = chain.blockExplorers?.worldsExplorer?.url;
12
- if (!explorerUrl) return null;
13
-
14
- return (
15
- <div className="fixed bottom-0 inset-x-0 flex flex-col opacity-80 transition hover:opacity-100">
16
- <button
17
- type="button"
18
- onClick={() => setOpen(!open)}
19
- className="outline-none flex justify-end gap-2 p-2 font-medium leading-none text-black"
20
- >
21
- {open ? (
22
- <>Close</>
23
- ) : (
24
- <>
25
- Explore <MUDIcon className="text-orange-500" />
26
- </>
27
- )}
28
- </button>
29
- {open ? <iframe src={`${explorerUrl}/${worldAddress}`} className="bg-black h-[50vh]" /> : null}
30
- </div>
31
- );
32
- }
@@ -1,14 +0,0 @@
1
- import { ReactNode } from "react";
2
- import { useSyncStatus } from "./useSyncStatus";
3
- import { ComponentValue } from "@latticexyz/recs";
4
- import { components } from "./recs";
5
-
6
- export type Props = {
7
- children: ReactNode;
8
- fallback?: (props: ComponentValue<(typeof components)["SyncProgress"]["schema"]>) => ReactNode;
9
- };
10
-
11
- export function Synced({ children, fallback }: Props) {
12
- const status = useSyncStatus();
13
- return status.isLive ? children : fallback?.(status);
14
- }
@@ -1,6 +0,0 @@
1
- import { createWorld } from "@latticexyz/recs";
2
- import { createSyncAdapter } from "@latticexyz/store-sync/recs";
3
- import config from "contracts/mud.config";
4
-
5
- export const world = createWorld();
6
- export const { syncAdapter, components } = createSyncAdapter({ world, config });