Skip to content

World lifecycle, ticks, and updates

WorldManager coordinates access to world data and the runtime lifecycle. Its responsibilities include routing reads and writes to chunk data, coordinating block entities, scheduling work, relaying neighbor and signal queries, and connecting world state to the scene. Keep independent algorithms in focused managers or services.

Use the manager as a boundary: gameplay asks for a world capability, and the manager routes it to storage or a focused subsystem. This centralizes chunk lookup and update ordering without moving each block’s decision logic into one class.

The IBlockGetter, ILevelReader, ILevelWriter, IScheduledTickAccess, ISignalGetter, ILevelAccessor, and ILevel interfaces separate capabilities. Their names follow Minecraft’s level API boundaries and let blocks, features, and other systems depend on the operations they require. docs/design/WP-1.1_LEVEL_INTERFACES.md records the migration rationale and remaining cleanup.

Scheduled ticks let blocks and fluids request a future update without owning a timer node. A scheduled action should retain its position, type, delay/order information, and be executed by the level’s ticking owner. Check current implementation and the porting plan for timing and priority limitations before relying on exact vanilla cadence.

Distinguish scheduled block/fluid ticks from frame callbacks and entity ticks: they have different clocks and owners. If pending work must survive unload or save, inspect whether the queue is persisted; a runtime scheduler alone does not guarantee it resumes after load.

Block writes can notify neighboring blocks, whose behavior may produce additional writes or signals. Order and recursion depth matter for redstone and observers. Keep notification policy in the world/update coordinator, and keep each block’s response in its class. The fidelity ledger tracks known update-order differences.

For a write, trace the API call from a block or gameplay action through the level interface into the world manager. Then check its side effects: block entity lifecycle, mesh invalidation, lighting, neighbor notification, and scheduled tick bookkeeping. Avoid direct storage mutation that skips these effects.

  1. Confirm the active world and target position.
  2. Check which level capability the caller uses and which implementation handles it.
  3. Verify stored state separately from notifications and scheduled work.
  4. Check derived lighting and mesh refresh after mutation.
  5. Trace save/load if state changes after reopening the world.

Related: blocks, voxel storage, and the persistence map.