Upgrading worlds
The System
s can be upgraded without changing the underlying World
code.
However, if the World
was deployed behind a proxy it is also possible to upgrade the World
itself.
This allows you to upgrade to a future version of MUD, but adds some gas overhead for all calls (due to one more level of indirection).
Are upgrades possible?
As per ERC-1967 (opens in a new tab), the storage slot 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
stores the address of the World
implementation in a proxy.
So to identify if a World
is deployed behind a proxy run these commands:
WORLD_ADDRESS=0xbe6b85dc88f969e45d8d8ae128c5a9c9744d6464
cast implementation $WORLD_ADDRESS
If the answer is anything other than zero, the World
is behind a proxy and can be upgraded.
Performing an upgrade
To upgrade the World
use these steps in a package/contracts
directory:
-
Edit
.env
to addWORLD_ADDRESS
with the address displayed by MUD Dev Tools. For example, you might want to use this file:.env# This .env file is for demonstration purposes only. # # This should usually be excluded via .gitignore and the env vars attached to # your deployment environment, but we're including this here for ease of local # development. Please do not commit changes to this file! # # Enable debug logs for MUD CLI DEBUG=mud:* # # Anvil default private key: PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 WORLD_ADDRESS=0xbe6b85dc88f969e45d8d8ae128c5a9c9744d6464
-
Create this script in
scripts/UpgradeWorld.s.sol
.UpgradeWorld.s.sol// SPDX-License-Identifier: MIT pragma solidity >=0.8.24; import { Script } from "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; import { World } from "@latticexyz/world/src/World.sol"; import { WorldProxy } from "@latticexyz/world/src/WorldProxy.sol"; contract SetImplementation is Script { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); vm.startBroadcast(deployerPrivateKey); address proxyAddress = vm.envAddress("WORLD_ADDRESS"); // Deploy new world implementation World newWorld = new World(); console.log("proxy:", proxyAddress); console.log("new World:", address(newWorld)); WorldProxy(payable(proxyAddress)).setImplementation(address(newWorld)); vm.stopBroadcast(); } }
-
Run the script.
forge script script/UpgradeWorld.s.sol --rpc-url http://localhost:8545 --broadcast
-
See the new address.
source .env cast implementation $WORLD_ADDRESS