Skip to content

System Simulation Patterns

Purpose

This document describes the shared technical approach that keeps all major game systems authoritative, scalable, and cheap enough to run on Cloudflare.

Core Pattern

The game should be command-driven and timer-driven.

  • the client sends intent
  • the server validates prerequisites
  • the server stores authoritative state
  • time passes
  • the server settles the outcome when a timer completes or the player checks in

Command Model

Every mutating action should be represented as a command such as:

  • start expedition
  • place market order
  • plant crop
  • deliver resources to town
  • bid on auction
  • post player contract

Commands should validate actor state, permissions, resource costs, and location rules before any write is committed.

Safe Retry Rule

Every command should carry a unique request key so that retries do not duplicate rewards, purchases, shipments, or contract payouts.

State Ownership

Use a clear ownership boundary for mutable state:

  • one expedition coordinator per active expedition or group mission
  • one market coordinator per exchange
  • one town coordinator per settlement
  • one guild coordinator per guild treasury and permissions

This keeps race conditions local and debuggable.

Storage Split

D1

Use for relational persistence, historical records, and reporting-friendly data.

Durable Objects

Use for serialized coordination and short-lived in-memory active state.

KV

Use for read-heavy cached projections like public town status, codex summaries, and map board views.

R2

Use for static SVG assets, sound, and large immutable content bundles.

Timer Model

All long actions should be stored as job records with:

  • actor
  • action type
  • start time
  • next wake time
  • expected end time
  • seed
  • current phase

This model works for expeditions, crop growth, shipments, town projects, and contract expiration.

The same model should be used for dynamic event instances and their resolution windows.

Event Director Pattern

Dynamic world events should be evaluated locally, not by one giant world scan.

Recommended approach:

  • each town or area coordinator maintains compact local condition scores
  • an evaluation pass runs on a fixed cadence
  • eligible event templates are weighted by local state
  • a small number of events are spawned or advanced
  • results feed back into town, route, resource, and market state

This preserves dynamism without breaking the cost model.

Event Log Pattern

For important systems, write append-only event rows instead of only overwriting final totals.

This is especially valuable for:

  • currency movement
  • item transfers
  • expedition outcomes
  • town reserve changes
  • tax application
  • auction settlement

Read Model Pattern

Player interfaces should read from summarized projections where possible.

Examples:

  • town status panel reads a town summary
  • market overview reads regional price snapshots
  • codex reads player and guild knowledge summaries
  • event board reads active local and regional event summaries

This keeps the UI fast without compromising authoritative writes.

Failure Recovery

Every timer-driven system needs replay-safe settlement. If a Worker retries or a coordinator wakes twice, the system should detect that settlement already happened and return the same result instead of duplicating state changes.

Why This Matters

The same technical pattern should drive combat, farming, market settlement, town demand, and logistics. Reusing one clear backend model is what keeps the game maintainable.