ADR-008: WASM Component Model for Future Plugins

Status: Proposed (Roadmap) Date: 2026-01-15

Context

As SiliconGhetto matures, we want to support third-party plugins and mods — custom components, systems, and behaviors that extend a game without modifying its core code. The WASM Component Model provides a standardized way to compose independently-built WASM modules with well-defined interfaces.

Options Considered

1. WASM Component Model (chosen for future)

  • W3C standard for composable WASM modules
  • WIT (WebAssembly Interface Types) defines typed interfaces between components
  • Strong sandboxing — components cannot access each other’s memory
  • Language-agnostic — plugins can be written in any language that compiles to WASM

2. Dynamic linking (WASM shared modules)

  • Share memory between modules
  • No standardized interface types
  • Security concerns — shared memory allows data leaks between modules
  • Limited browser support

3. Scripting language (Lua, JavaScript)

  • Familiar to game modders
  • Performance overhead from interpretation
  • Adds a language runtime to the WASM binary
  • Type safety depends on the scripting language

4. Static plugin compilation

  • Plugins compiled into the main binary
  • No runtime overhead
  • Requires recompilation for any plugin change
  • Not suitable for user-generated content

Decision

Plan for the WASM Component Model as the plugin/mod system, targeting implementation in v0.5+. Current engine design should avoid patterns that would prevent future component model adoption (e.g., don’t rely on shared linear memory between modules).

Consequences

Positive

  • Plugins are fully sandboxed — a buggy plugin cannot crash the engine
  • WIT interfaces provide type-safe boundaries
  • Plugins can be written in Rust, C, AssemblyScript, or any language with WASM Component Model support
  • Hot-reloading plugins becomes possible (swap one component, keep others)
  • Security model aligns with platform goals (untrusted game code)

Negative

  • WASM Component Model is not yet fully supported in browsers
  • Performance overhead from component boundaries (copying data across interfaces)
  • WIT interface design requires careful upfront planning
  • Toolchain is still maturing (wit-bindgen, wasm-tools)

Mitigations

  • This is a future feature — browser support will improve by the time we implement
  • Design WIT interfaces to minimize cross-boundary data transfer
  • Start with a small plugin surface (custom systems, component definitions)
  • Follow the specification’s progress and prototype when browser support lands

Proposed Plugin Interface (Sketch)

// plugin.wit
interface sg-plugin {
    record vec2 { x: f32, y: f32 }
    record entity-id { index: u32, generation: u32 }

    // Called once when the plugin loads
    init: func()

    // Called each fixed update tick
    update: func(dt: f32)

    // Query entity positions (engine provides data)
    get-position: func(entity: entity-id) -> option<vec2>
    set-position: func(entity: entity-id, pos: vec2)
}

References