Inside Machi Engine

Sprited DevSprited Dev
2 min read

Here is a little bit about the performance conscious decisions made to make Machi engine responsive and able to handle large scale simulations.

How the Machi Engine Actually Works

At the heart of Machi, there are two core components dancing together: the main thread UI and the Web Worker running our Rust-based simulation. Here's how that split-brain setup plays out:

┌────────────────────┐            ┌────────────────────┐  
│      Machi UI      │    Actions │     Web Worker     │  
│┌──────────────────┐├────────────▶┌──────────────────┐│  
││      Canvas      ││            ││  simulator.wasm  ││  
││    (Pixi.js)     ││    State   ││      (Rust)      ││  
│└──────────────────┘◀────────────┤└──────────────────┘│  
└────────────────────┘            └────────────────────┘  
Rendering happens in the          Simulation happens here.
main thread here.                 All the core simulation 
It receives a copy of the         logic runs inside Rust  
current state of the game,        code compiled into web  
and renders it in the HTML        assembly code.          
canvas using Pixi.js.

The Separation of Concerns

  • Machi UI (Main Thread)
    This is the part users see and interact with—rendered using Pixi.js for lightning-fast WebGL-based drawing. It’s responsible for drawing the world (tiles, agents, effects) based on the game state it receives. But here’s the twist: it doesn't simulate anything. It’s just the window into the world.

  • Web Worker (Off-Main-Thread)
    This is where the actual "brains" of the operation live. The simulation logic—written in Rust and compiled to WebAssembly (Wasm)—runs independently inside a Web Worker. It handles physics, water flow, plant growth, agent AI, etc., ticking away like a tiny world clock.

How They Communicate

Every frame or tick:

  1. User Input or Time triggers an Action.

  2. The UI thread sends that action (like “agent moves” or “dig tile”) to the Web Worker.

  3. The Web Worker simulates a new state.

  4. Once it’s done, it sends a copy of the updated world state back to the UI thread.

  5. The main thread then renders this state on the canvas.

Since all the heavy lifting (like pathfinding or water simulation) happens off the main thread, the UI stays snappy and responsive—even on slower devices. This architecture also mirrors how multiplayer or authoritative servers might work later, making the transition to online play seamless.

0
Subscribe to my newsletter

Read articles from Sprited Dev directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sprited Dev
Sprited Dev