amogus/docs/design_main_game.md
Antigravity 071906df59 feat: Complete LLM agent framework with fog-of-war, meeting flow, and prompt assembly
- Core engine: simulator, game mechanics, triggers (138 tests)
- Fog-of-war per-player state tracking
- Meeting flow: interrupt, discussion, voting, consolidation
- Prompt assembler with strategy injection tiers
- LLM client with fallbacks for models without JSON/system support
- Prompt templates: action, discussion, voting, reflection
- Full integration in main.py orchestrator
- Verified working with free OpenRouter models (Gemma)
2026-02-01 00:00:34 -05:00

5.7 KiB

The Glass Box League — Main Game Design

Agent Architecture

Identity & Persona

  • Format: "You are {model}. {PERSONA}. {context}"
  • Persona is optional and toggleable
  • Same model can have multiple personas
  • Goal: emergent behavior first, spice second

Memory System

Scratchpad Persistence Purpose
plan.json Per-game Current intentions, agent-controlled
events.json Per-game Curated game events worth remembering
suspicions.json Per-game Player reads, agent-maintained
learned.json Cross-game Core memory, enforced JSON schema
meeting_scratch.json Per-meeting Temp, erased after consolidation

JSON is god. Enforced schema for structure, freeform for agent thoughts. JSON improves attention.


Prompt Structure

System Prompt (Core Memory)

  1. Model identity
  2. Persona (if set)
  3. Game rules + current map + settings
  4. Role briefing (crewmate/impostor)
  5. Strategy tips (toggleable injection levels)
  6. Meta-awareness (toggleable: subtle → direct → 4th wall)
  7. Output format instructions
  8. Learned lessons from learned.json

User Prompt (Working Memory)

Order matters:

  1. You — role, location, status, cooldowns
  2. Recent history — accumulated vision from skipped ticks
  3. Vision — current snapshot
  4. Available actions — dynamic tool list

Tool System

Core Tools (Always Available)

  • MOVE(room_id | player_id) — walk or follow
  • WAIT()
  • INTERACT(object_id) — tasks, panels, buttons, bodies, vents, cams

Impostor Only

  • KILL(player_id)
  • SABOTAGE(system_id)
  • FAKE_TASK(task_id)

Trigger Management (Optional)

  • CONFIGURE_TRIGGERS(config) — only if changing defaults

Dynamic Available Actions

{
  "available_interactions": ["task_wires_cafe", "body_blue", "admin_table"],
  "available_kills": ["green", "yellow"],
  "available_sabotages": ["lights", "o2", "reactor", "comms"]
}
  • Context-filtered by engine based on role + location
  • Agent told "these are your actions this turn"
  • Object IDs validated against engine to prevent glitches

Trigger System

Mandatory (Cannot Mute)

  • GAME_START
  • DISCUSSION_START
  • VOTE_START
  • GAME_END
  • SABOTAGE_CRITICAL

Standard (Mutable)

  • PLAYER_ENTERS_FOV
  • PLAYER_EXITS_FOV
  • BODY_IN_FOV
  • OBJECT_IN_RANGE (every interactable)
  • VENT_WITNESSED
  • KILL_WITNESSED
  • DESTINATION_REACHED
  • TASK_COMPLETE
  • SABOTAGE_START / SABOTAGE_END
  • LIGHTS_OUT (panic tick)
  • COOLDOWN_READY (kill, emergency)
  • DEATH (special message, transition to ghost)

Optional (Opt-in)

  • EVERY_N_SECONDS (configurable)
  • RANDOM_N_SECONDS (RNG toggleable)
  • INTERSECTION (hallway/room boundaries)
  • HALLWAY_WAYPOINT

Trigger Frequency

  • Impostors: Every tick (more decision points)
  • Crewmates: Event-driven + opt-in periodic
  • Ghosts: Reduced frequency, longer intervals

Trigger Message Schema

{
  "trigger_type": "VENT_WITNESSED",
  "trigger_data": {
    "player": "red",
    "vent_location": "electrical",
    "action": "entered",
    "timestamp": 47.3
  }
}

Game State Schema

Per-Tick Context

{
  "time": 47.3,
  "phase": "PLAYING",
  "you": {
    "role": "impostor",
    "location": "electrical",
    "kill_cooldown": 0,
    "tasks": [],
    "emergencies_remaining": 1
  },
  "recent_history": [
    {"t": 12.3, "vision": {"players": ["blue"], "location": "hallway_1"}}
  ],
  "vision": {
    "players_visible": [
      {"id": "blue", "location": "electrical", "doing": "task"}
    ],
    "objects_visible": ["vent_elec", "task_wires", "body_yellow"],
    "exits": ["security", "cafeteria"]
  },
  "available_actions": {...}
}

Fog of War

Critical: Each agent only knows what they've observed.

  • Engine tracks per-player knowledge
  • known_deaths: bodies seen or announced
  • known_locations: last seen positions + timestamps
  • witnessed_events: vents, kills, sus behavior

Response Format

Action Phase

{
  "internal_thought": "Blue just left, perfect time to kill Green",
  "action": {"type": "KILL", "target": "green"},
  "scratchpad_updates": {
    "plan": "...",
    "events": "...",
    "suspicions": "..."
  },
  "trigger_config": {
    "mute": [{"type": "INTERSECTION", "until": "REACHED_DESTINATION"}]
  }
}
  • trigger_config only if changing defaults
  • internal_thought separate from action (for thinking models)

Meeting Interrupt Flow

When report/emergency called:

  1. Interrupt note: Agent leaves context ("this was what I was doing")
  2. Pre-meeting prep: Agent reviews & prepares thoughts
  3. Meeting scratchpad: Temporary, discussion-only
  4. Post-meeting consolidation: Agent saves important info to main scratchpads

Ghost Mode

  • Omniscient view of entire game
  • No access to other agents' thoughts
  • Can do ghost tasks
  • Reduced tick frequency (save tokens)
  • Write to scratchpad, observe strategies
  • No game state modifications

Special Mechanics

Lights Out

  • Vision radius shrinks (0.25x multiplier)
  • Triggers panic tick for all players
  • Engine recalculates trajectories
  • Fix triggers restoration tick

Near-Death Edge Case

  • Impostor queues kill, victim queues report same tick
  • Report fires first (higher priority)
  • Impostor gets: "Your kill was interrupted"
  • Victim has no direct knowledge (must deduce from proximity)

Configuration Philosophy

Everything toggleable:

  • Persona injection
  • Strategy tip levels
  • Meta-awareness levels (subtle/direct/4th wall)
  • Periodic tick frequency
  • Random tick RNG
  • Tool availability based on context

Goal: Replicate human experience. LLM should have same information and options as human player.