Skip to main content
Glama

World Games

v1.8.0 · English · 简体中文 · Architecture · What it is for · Gameplay · Prior art · Changelog · Live site

The AI narrates. The engine decides.

Your agent writes the prose. A deterministic engine resolves every hit, price, relationship and faction shift, then persists it to one auditable state file.

205 rule functions · 67 MCP tools · 4 MCP resources · 4 playable worlds · 8 templates · 0 runtime dependencies


Why this exists

Three problems kill long AI-run games. Each one is solved in code, not in prompt wording.

Problem

What usually happens

What World Games does

Numbers drift

The model invents damage, prices, HP

Rule functions resolve them; same state + seed + actions replay byte-identically

The AI forgets

Context window overflows, old facts vanish

Context ledger persists clues, promises and facts; retrieval scored like Generative Agents

Saves become chaos

One JSON file, hand-managed

Save library: multiple runs, snapshots, trash, all through session_*

Everything is replayable. Every mutating call is logged with its arguments (hashed), the RNG counters on both sides, and before/after state fingerprints. Same seed plus the same action log reproduces the same world — and verify_replay.py proves it instead of claiming it.

Two things most frameworks skip:

  • The world moves on its own. Every tick advances factions (logistic growth + Lotka–Volterra), rumors (SIR), culture (Deffuant), roaming NPCs and a Panarchy r → K → Ω → α cycle driven by real stock. Do not call tick and the world stands still — intentional, not a bug.

  • The panel is read-only, and bilingual. English by default, one click to Chinese. It renders the real state and never writes. Players queue actions to a sidecar; the host drains them with pending_actions. One writer, one truth.


Related MCP server: mcp-server-if

Install

pip install -e ".[mcp]"      # core is standard library only; the mcp extra is for MCP mode

No Python? Download world-games.exe — one file, ~30 MB, runs standalone. Same program, same data.

wg init my-game.json      # create a starter save
wg play --state my-game.json

wg is the single front door: init, play, serve, mcp, run, doctor, version. Run wg --help for the full list.

Hook it to an agent

{ "mcpServers": { "world-games": { "command": "world-games-mcp" } } }

Works with Claude Code, Codex, Cursor, opencode, or any MCP client. world-walker-mcp is a compatibility alias.

Then:

load_setting(path="settings/玄枢界.setting.json")
trade(location="临川城", item="ningyuan_dan", direction="buy", quantity=1)

That is a complete game: world, protagonist, NPCs, market, relations, tiers, lorebook, questline, subsystems. The host calls tools only when a number is needed.


Screens

Every image is a real render of a real save, asserted element-by-element in Edge by scripts/shots.py. Source saves live in docs/demo/.

Xuanshu · Eastern fantasy

Zhejian · Wuxia

Neon Abyss · Cyberpunk

Fogport · Investigation

Xuanshu

Zhejian

Neon

Fogport

Skins are the surface. What actually changes per world is vocabulary, tiers, currency and place descriptions: a bundle declares terms: { level: "身手", gold: "银两" } and the panel never shows "境界 / 灵石" again.

World pulse

Character card

Command palette

Action queue

World pulse

Character card

Palette

Queue

Codex

Market

Milestones

Help

Codex

Market

Milestones

Help

768 px

320 px

Share mode

Tablet

Narrow

Share


Architecture

        your agent (Claude Code / Codex / Cursor / custom)
                          │  MCP over stdio
                          ▼
    ┌─────────────────────────────────────────────┐
    │  World Games MCP server                     │
    │  67 tools · 4 resources · 1 prompt          │
    │  tool annotations: read-only / destructive  │
    └───────────────┬─────────────────────────────┘
                    │  every mutation goes through
                    ▼  one transactional writer
    ┌─────────────────────────────────────────────┐
    │  rules/*  deterministic settlement          │
    │  checks · combat · economy · social · karma │
    │  questline · lorebook · systems · models    │
    └───────────────┬─────────────────────────────┘
                    ▼
            state.json  ◄── read-only ──  live stage (HTTP + SSE)
                    │                   + /admin console
                    └── generational archive (.log.jsonl)

Invariants (all asserted by the gate):

  1. One writer. The panel serves GET only; actions queue to <state>.inbox.jsonl.

  2. Determinism. sha256(seed, tick, counter) reseeds every settlement; rng_counter persists.

  3. Everything is bounded. Event log, karma ledger, sidecar and inbox all have caps and merge rather than truncate.


What the engine gives you

Settlement

Layer

What it resolves

checks

d20 / 2d6 / d100 / 4dF / dice pools, roll-under, opposed rolls, success bands

combat · economy · social · karma

hits and damage, prices, relationships, structured debt

cognition · narrative_engine · progression

flow channel, Panarchy phase, tier progression

world_evolution

factions, rumors, culture, roaming NPCs, world flags

rulebook + loopguard

world-specific exceptions declared by the bundle; circling detection

action_log

command-level replay with per-step state fingerprints

Seven pluggable subsystems

Mechanics are data, not code. Add or remove at runtime.

Kind

Manages

Actions

time

day/hour, season, weather

advance(minutes), status

loot

weighted tables, quantity ranges

roll(table, times, grant), list

craft

recipes, material checks, skill roll

craft(recipe), list

reputation

faction standing −100..100 with tiers

adjust(faction, delta), status

achievement

questline predicates + rewards

check, list

progression

XP curve, levels, attribute growth

grant(amount), status

custom

restricted effect list

<action>, list

Four play loops, one rule set

freeform (free input) · choice (options) · mud (location commands) · ttrpg (declare → resolve → consequence). The loops guide the host; the engine does not enforce them.

The four bundles are the four loops: Xuanshu freeform, Zhejian ttrpg, Neon Abyss mud, Fogport choice.

Eight playable templates

jrpg · mystery · management · survival · narrative · cozy · tabletop · immersive

template_start(template="mystery", name="my case",
               overrides={"world": {"name": "Rain Harbor"}})

The 67 tools

Group

Tools

Setup and saves

session_new session_list session_switch session_snapshot session_manage session_import load_setting world_init world_open

Per-turn core

pending_actions context_pack narration_context publish_prose tick

Checks and numbers

roll combat combat_preview trade social karma advance use_item game_profile game_adjust game_tag game_sheet

World and place

travel world_state narrative status playbook_info quest_status quest_advance lore_lookup failure_tick

Memory and recall

context_remember context_known context_tell context_search context_forget recall write_summary recap read_state

Systems and templates

templates_list template_info template_apply template_start system_define system_remove system_run system_status system_schema

Ecosystem and tooling

character_card_read add_character import_lorebook spawn_npc model model_list merit narrative_weight snapshot restore configure open_panel close_panel world_schema

Plus four MCP resources a host can pin into context without a tool round-trip: world://state/current, world://summary/current, world://settings/index, world://docs/protocol.

Full parameters: GAME_MASTER_PROTOCOL.md.


One turn, end to end

Real return values from the Fogport investigation bundle.

Player: I go to the docks and ask the gatekeeper whether the lighthouse has been lit.

1. context_pack(scene_text="码头 灯塔 门房")
   → playbook (choice · clues 0/24), open clues, recent events

2. roll(attribute="per", difficulty=9, dice="2d6")
   → {"rolls":[1,1], "total":2, "difficulty":9, "margin":-7, "level":"failure"}

3. context_remember("The gatekeeper says the lighthouse burned for three minutes",
                     kind="clue", keys=["lighthouse"], source="gatekeeper")
   → {"fact":{"id":"f0001", ...}, "created":true}

4. game_adjust("clue", delta=1)    → {"after":1, "at_max":false}
   game_adjust("sanity", delta=-1) → {"after":7, "at_min":false}

5. publish_prose("The rain did not stop...")
6. tick()  → one turn of world evolution

Everything lands in one state file: checks under checks, facts under context.facts, resources under game, prose under prose, world under panarchy/factions/....


Scope

In scope: rule resolution, setting bundles, saves, context ledger, host narration guidance, SillyTavern character cards (PNG/JSON, V1–V3) and world info.

Out of scope, deliberately: image generation, multiplayer, cloud accounts, plugin marketplace. Reasons in ROADMAP.md.


Quality

No pytest suite, by design. Verification is scripts/verify_*.py plus behaviour regressions plus mutation testing: an assertion must be killable, not merely covered.

Suite

Assertions

What it locks

verify_formulas.py

122

recompute 77 functions from their docstring math

verify_branches.py

192

exception paths and state branches of low-coverage modules

verify_cli.py

21

read-only invariants, write effects, cross-channel determinism

verify_panel.py

93

view-model contract, legacy saves, static whitelist, inbox guards

verify_mcp_stdio.py

64

real stdio e2e, tavern ecosystem, read-only zero side effects

verify_world.py

54

self-evolution, phase, flow, morality, terms, prose, ledger

verify_settings.py

17

all four bundles load and evolve (zero-dependency path)

verify_docs.py

—

version single source, tool count, assertion counts, asset references

verify_i18n.py

12

panel dictionary: unique keys, unambiguous templates, bilingual wiring

verify_mechanics.py

25

rulebook priority/stop, loop detection, NPC knowledge boundary, combat preview, quest DAG

verify_replay.py

15

action log chain, seq persistence, canonical hashing, deterministic fingerprint

verify_gameplay.py

65

playbook loops, questline DAG, lorebook semantics

verify_generic.py

104

generic checks, game profile, context ledger, save library, brand

verify_systems.py

161

seven subsystem kinds, eight templates, counters, panel contract

verify_injection.py

23

injection signatures and untrusted marking

verify_near_death.py

7

near-death protection

verify_audit_fix.py

22

snapshot restore, concurrent RMW, finite JSON, input boundaries

verify_memory.py

7

leak check and three bounded structures

user_playtest.py

47

player-perspective abuse cases and error readability

smoke_ui.py

20

real Edge render, cards and drawers, responsive, zero JS errors

verify_tests.py

—

AST-level rejection of tautological assertions

verify_mutation.py

50 mutants

break the code, require tests to go red; survival must be 0%

bash scripts/pre_push_gate.sh     # 32 steps; missing required dependencies fail the gate

Coverage gate: core domain ≥70% (measured 86%, including the generic layer); pyflakes 0.


Project layout

world-walker/                  # repo root IS the game_engine package
├── cli.py                     # `wg` — the single front door
├── engine.py                  # CLI rule actions
├── mcp_server.py              # MCP server, 67 tools + 4 resources
├── mcp_primitives.py          # resources and tool annotations
├── state_schema.py            # state model / atomic write / transaction lock / archive
├── panel.py                   # read-only view model + HTTP/SSE + /admin console
├── panel.html / .css / .js    # the stage: native trio, no build chain
├── panel.i18n.js              # EN/ZH translation layer
├── sessions.py                # save library: multi-run / snapshot / trash
├── rules/                     # 205 public rule functions
│   ├── checks.py gamesystem.py context.py
│   ├── combat.py economy.py social.py karma.py
│   ├── cognition.py narrative_engine.py progression.py
│   ├── world_dynamics.py world_evolution.py
│   └── models.py              # 16 named closed-form models
├── settings/                  # 4 ready-to-play bundles
├── scripts/                   # 21 self-checks + build_exe + screenshot pipeline
└── assets/echarts.min.js      # offline chart library (Apache-2.0)

FAQ

Does it need network access? No. Zero runtime dependencies; the chart library ships locally. Only MCP mode installs the mcp SDK.

Does it need an API key? No. It never calls a model. Your agent supplies the model.

Can I use it commercially? MIT. Every name, faction and place in the demo bundles is original.

Why no pytest? Assertions must survive "break the code, watch the test go red". verify_tests.py statically rejects tautological assertions; verify_mutation.py injects 50 real defects and requires every one to be killed.

Why can't the panel submit actions directly? It can queue them, not settle them. That keeps a single writer, which is what makes determinism and snapshot rollback trustworthy.

Is power-loss safety guaranteed? No, and we do not claim it. Saves use atomic replacement with .bak fallback and a re-entrant Windows/POSIX lock, and crash tests cover several interruption windows. If <state>.archive-pending or .ww-session-transaction-pending exists, protected reads and writes are refused and there is no automatic recovery — stop writing, preserve the evidence and review it manually. Restoring the caller's in-memory state after a failed save is not an archive rollback. See the archive recovery guide.


Regenerate the demo assets

python scripts/make_demo.py          # 4 real demo saves → docs/demo/
python scripts/shots.py --lang en    # assert, screenshot, record → docs/screenshots/
python scripts/build_exe.py          # standalone executable → dist/

License

MIT. Charts by ECharts 5.5.1 (Apache-2.0). Tavern-ecosystem compatibility follows the publicly documented character-card and world-info conventions; no names or settings from existing works are reused.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables creation and management of structured game worlds for text adventures and RPGs with character creation, world generation, and natural language interaction through AI integration.
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to play interactive fiction games (Glulx and Z-machine) through the Model Context Protocol, with automatic save/restore and optional journaling mode.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI narrators to maintain persistent world state for interactive fiction and tabletop play by managing entities, relationships, dice rolls, threads, clocks, and continuity checks.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to play, test and QA Twine / interactive-fiction HTML games by reading passages as Markdown, clicking numbered choices, inspecting story variables, screenshotting, and saving or restoring state to explore branches. It provides a small, token-friendly semantic tool surface with format detection for SugarCube, Harlowe, Snowman and Chapbook games, plus live viewing, console error capture and journal tracking for clean playtesting.
    22
    34 npm
    MIT