Simulating World Extension Deployment
The commented code can be found in
packages/contracts/script/RegisterReadDemoSystem.s.sol
(opens in a new tab).
Code
examples/ReadDemo/packages/contracts/script/RegisterReadDemoSystem.s.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.24;
import { Script } from "forge-std/Script.sol";
import { console2 } from "forge-std/Test.sol";
import { WorldRegistrationSystem } from "@latticexyz/world/src/modules/init/implementations/WorldRegistrationSystem.sol";
import { System } from "@latticexyz/world/src/System.sol";
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
import { WorldResourceIdLib } from "@latticexyz/world/src/WorldResourceId.sol";
import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol";
import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol";
import { ReadDemoSystem } from "../src/systems/ReadDemoSystem.sol";
contract RegisterReadDemoSystem is Script {
address worldAddress = vm.envAddress("WORLD_ADDRESS");
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY_ALICE");
address playerAddress = vm.envAddress("ADDRESS_PLAYER");
bytes14 namespace = bytes14("PluginExamples");
bytes16 system = bytes16("ReadDemoSystem");
function run() external {
StoreSwitch.setStoreAddress(worldAddress);
WorldRegistrationSystem world = WorldRegistrationSystem(worldAddress);
ResourceId namespaceResource = WorldResourceIdLib.encodeNamespace(bytes14(namespace));
ResourceId systemResource = WorldResourceIdLib.encode(RESOURCE_SYSTEM, namespace, system);
vm.startBroadcast(deployerPrivateKey);
// check if the namespace already exists
// if you own the namespace, you can change/deregister it via other code
// if you do not own the namespace but it is already registered, you will need to change your namespace
bool existingNamespaceCheck = ResourceIds.getExists(namespaceResource);
require(!existingNamespaceCheck, "Namespace already exists.");
world.registerNamespace(namespaceResource);
ReadDemoSystem readDemoSystem = new ReadDemoSystem();
world.registerSystem(systemResource, readDemoSystem, true);
world.registerFunctionSelector(systemResource, "readMainBaseLevel()");
vm.stopBroadcast();
}
}
This should look incredibly familiar. Most of the code is identical to the
setUp()
function of our tests.
Deploying your extension looks much like testing your extension, but occurs in a script. Most of the code is identical to the test, which is kind of the point. Test thoroughly before deploying; deployments are permanent.
Key differences are:
- This is a
Script
, not aMudTest
.- Tests (and MudTests) use vm cheatcodes like startPrank to execute a local simulation. Nothing is impacted on the live chain
- Scripts can read from and broadcast to the live chain, causing permanent changes.
- We must declare and specify the
WORLD_ADDRESS
variable; it is not inherited fromMudTest
. - When deploying, you must use a
PRIVATE_KEY
in.env
, since this action will cost gas. - Writing to the chain requires startBroadcast() instead of startPrank()
- You can do a simulation of a deployment with the following command:
forge script script/RegisterReadDemoSystem.s.sol --fork-url https://primodium-sepolia.rpc.caldera.xyz/http