| --- |
| title: World Simulator |
| colorFrom: green |
| colorTo: blue |
| sdk: gradio |
| sdk_version: 6.17.3 |
| python_version: 3.11 |
| app_file: app.py |
| header: mini |
| fullWidth: true |
| startup_duration_timeout: 1h |
| pinned: true |
| tags: |
| - thousand-token-wood |
| - judges-wildcard |
| - best-demo |
| - best-agent |
| - track:wood |
| - sponsor:nvidia |
| - sponsor:modal |
| - achievement:offbrand |
| --- |
| |
| # World Simulator |
|
|
| An AI civilization sandbox: LLM-driven NPCs live, move, talk, and fight on a 80Γ20 |
| grid, rendered in a Three.js/R3F 3D client. The Python simulation owns all meaning; |
| the renderer only displays it β so planners, memory, factions, and world events can |
| be added without touching the UI. |
|
|
| > **Build Small Hackathon** β Track: **Thousand Token Wood** Β· Badges: **Judges' |
| > Wildcard**, **Best Demo**, **Best Agent** |
| > |
| > - πΉ [Demo video](https://youtu.be/cAIkA-WHoFM) |
| > - π£ [Social post](https://www.linkedin.com/posts/georgii-savin_world-simulator-a-hugging-face-space-by-share-7472524387615793152-gGJq/?utm_source=share&utm_medium=member_desktop&rcm=ACoAAEE12gYBC0YnknRVylJQUfuMiqfJVP8jKao) |
| > |
| > **Models (all < 32B):** NPC decisions run on `Nemotron-3-Nano-30B-A3B-FP8` (30B), |
| > the God Console on `Qwen3.6-27B-FP8` (27B) β small models combined under the cap. |
|
|
| ## Quick Start |
|
|
| ```powershell |
| # Backend (deterministic, no model calls) |
| $env:WORLD_SIMULATOR_FORCE_DETERMINISTIC="1" |
| uv run python -m world_simulator run # serves /health, /state, /scene/state, POST /tick |
| |
| # 3D UI |
| npm install |
| npm run dev # http://127.0.0.1:5173 |
| ``` |
|
|
| Controls: drag to orbit, scroll to zoom, `WASD`/arrows to pan. |
|
|
| Autoplay is on by default: the manual tick controls are hidden and the world |
| advances ticks automatically. Set `VITE_WORLD_SIMULATOR_AUTOPLAY=0` (build/dev |
| env) to show the manual step / play-pause controls instead. |
|
|
| ## Hugging Face Space |
|
|
| `app.py` wraps the same game runtime in `gradio.Server` and serves the built React/Three |
| UI from `dist/frontend`. Build it first, then run: |
|
|
| ```powershell |
| npm install |
| npm run gradio |
| ``` |
|
|
| `requirements.txt` installs the local project from `pyproject.toml`. Set |
| `WORLD_SIMULATOR_CONFIG` to override the default `config/game.modal.local.json`. |
|
|
| ## How NPCs Think |
|
|
| Each tick, every living NPC gets its own model request containing its health, attack, |
| personality, god directive, recent memories, and visible NPCs within 5 blocks. The model |
| picks exactly one action β `walk`, `talk`, or `attack` β and all decisions are collected |
| then applied together, so turn order grants no advantage. The server records outcome |
| memories afterward and compacts older ones into a rolling summary. |
|
|
| A **God Console** (when an OpenAI-compatible connector is active) takes freeform commands |
| like _"Ada wants to kill everyone"_ and applies the model's tool calls to world state |
| (health, attack, personality, directive, memory, position). |
|
|
| Connector is binary: `connector.type` is `deterministic` (every tick deterministic) or |
| `openai_compatible` (model every tick). `WORLD_SIMULATOR_FORCE_DETERMINISTIC=1` forces |
| deterministic ticks and disables model-backed features. |
|
|
| ## Model Configs |
|
|
| - `config/game.modal.local.json` (default) β NPCs on a Modal vLLM Nemotron Nano H100 |
| endpoint, God Console on a Modal vLLM Qwen3.6 H100 endpoint. Override with |
| `OPENAI_BASE_URL` / `OPENAI_API_KEY` / `OPENAI_MODEL`. |
| - `config/game.local.json` β fully offline/deterministic. |
|
|
| Deploy the Modal endpoints with `modal deploy deployments/modal_nemotron_nano.py` and |
| `deployments/modal_qwen36_27b_h100.py`; smoke-test with `deployments/smoke_modal_endpoint.py`. |
|
|
| ## Development |
|
|
| ```powershell |
| npm run gradio |
| ``` |
|
|
| Runtime deps live in `pyproject.toml`; dev tools are in the `dev` group. |
|
|