| --- |
| title: Aether Garden |
| emoji: π |
| colorFrom: gray |
| colorTo: purple |
| sdk: gradio |
| sdk_version: 5.50.0 |
| app_file: app.py |
| pinned: true |
| license: mit |
| tags: |
| - gradio |
| - agents |
| - simulation |
| - three.js |
| - persistent-world |
| - hackathon |
| - thousand-token-wood |
| - best-agent |
| - off-brand |
| - modal |
| - codex |
| - minicpm |
| - tiny-model |
| - tiny-titan |
| - track:wood |
| - sponsor:openbmb |
| - sponsor:openai |
| - sponsor:modal |
| - achievement:offbrand |
| - achievement:fieldnotes |
| --- |
| |
| <div align="center"> |
| <img src="assets/banner.png" width="100%" alt="Aether Garden" /> |
|
|
| # Aether Garden |
|
|
| **The Living Tome β a persistent AI world where every visitor writes a new page.** |
|
|
| *Made with π by [Kavya](https://huggingface.co/kavyabhand) & [Aadi](https://huggingface.co/aadi-joshi)* |
|
|
| [](https://gradio.app) |
| [](https://huggingface.co/spaces/build-small-hackathon/aether-garden) |
| [](https://modal.com) |
| [](https://huggingface.co/openbmb/MiniCPM3-4B) |
| [](https://huggingface.co/blog/gradio-llm-hackathon) |
| [](https://youtu.be/M1_UxPpYe54) |
| [](https://www.reddit.com/r/playmygame/comments/1u3b1rq/i_built_a_grimoire_where_strangers_leave_souls/) |
| [](https://huggingface.co/blog/build-small-hackathon/aether-garden-article) |
| </div> |
|
|
| --- |
|
|
| ## Submission Snapshot |
|
|
| | | | |
| |---|---| |
| | **Live Space** | [build-small-hackathon/aether-garden](https://huggingface.co/spaces/build-small-hackathon/aether-garden) | |
| | **Demo video** | [youtu.be/M1_UxPpYe54](https://youtu.be/M1_UxPpYe54) | |
| | **Social post** | [r/playmygame β "I built a grimoire where strangers leave souls"](https://www.reddit.com/r/playmygame/comments/1u3b1rq/i_built_a_grimoire_where_strangers_leave_souls/) | |
| | **Field Notes article** | [Aether Garden β Field Notes (HF Blog)](https://huggingface.co/blog/build-small-hackathon/aether-garden-article) | |
| | **Track** | Thousand Token Wood β *AI as the simulation engine, not a static generator* | |
| | **Core model (this branch)** | `openbmb/MiniCPM3-4B` (4B params) via Modal | |
| | **Portrait model** | `stabilityai/sdxl-turbo` | |
| | **Agent behavior** | Autonomous hourly simulation tick β reasoning *and* action, with memory updates, with no user input | |
| | **Persistent state** | SQLite (WAL) + Hugging Face Dataset backup/restore | |
| | **Made by** | [Kavya Bhand](https://huggingface.co/kavyabhand) & [Aadi Joshi](https://huggingface.co/aadi-joshi) | |
|
|
| --- |
|
|
| ## The Idea |
|
|
| Most AI demos have amnesia. You type a prompt, get a character sheet, close |
| the tab β and the output dies with the session. There's no world, no |
| history, no consequence. |
|
|
| **Aether Garden** is the opposite. It's a persistent fantasy realm, built as |
| a leather-bound grimoire you have to *open* before you're let in β no |
| dashboard, no tab that says "Chat," you turn pages. |
|
|
| When you arrive, the world is already days old. Strangers have already built |
| it. A Joke Dragon became Mayor while you were asleep. The Book of Ages |
| remembers all of it. You summon one strange thing β |
| *"a blind cartographer who maps places that don't exist yet"* β and hours |
| later, without you watching, the simulation runs. The cartographer meets |
| someone else's Crystal Tree. History writes itself. |
|
|
| Remove the model and the Realm is just a SQLite file full of vibes. **The |
| AI is load-bearing by definition** β which is exactly what this track asked |
| for. |
|
|
| --- |
|
|
| ## What It Does |
|
|
| The app is a single Gradio Space styled as an illuminated manuscript. Instead |
| of dashboard tabs, visitors turn pages through six spreads: |
|
|
| 1. **The Realm** β an SVG map of eight sacred places, a live chronicle, and a "Realm Pulse" ticker |
| 2. **Explore the Realm** β step *into* a location via a Three.js diorama window |
| 3. **Book of Ages** β every arrival, meeting, world event, and milestone, in styled prose |
| 4. **Souls of the Garden** β every summoned soul, with backstory, goals, fears, and an evolving memory |
| 5. **Bonds and Alliances** β a 3D web of relationships the simulation forged on its own |
| 6. **Summon a New Soul** β describe something strange; the Oracle gives it a name, a face, a home, and eventually enemies |
|
|
| ### The Summon Pipeline |
|
|
| ``` |
| Visitor description (5β200 words) |
| | |
| MiniCPM3-4B on Modal (A10G) name, appearance, backstory, goals, fears, |
| personality, greeting, sacred location |
| | |
| SQLite + WAL entity persisted; arrival logged to Book of Ages |
| | |
| SVG world map entity appears as a glowing dot at their location |
| | |
| Hourly simulation tick 1 world event + 2-4 entity interactions |
| (Modal scheduled job) relationships form; memories compress; lifecycle updates |
| | |
| HF Dataset backup world.db snapshot pushed after every tick |
| ``` |
|
|
| Nobody scripts the encounters. The model decides what happens between |
| visits. |
|
|
| --- |
|
|
| ## The Autonomous Simulation β Why It's an Agent |
|
|
| Every hour, whether anyone is watching, Modal runs a 7-step tick: |
|
|
| ``` |
| 1. Load world state + active entities |
| 2. Generate 1 world event (natural / social / historical / cosmic / discovery) |
| 3. Generate 2-4 entity interactions (location-weighted, relationship-aware) |
| 4. Update memories for all entities involved (compressed, <=150 words each) |
| 5. Lifecycle transitions (dormant -> legendary, dream fragments, wisdom tags) |
| 6. Write all entries to the Book of Ages |
| 7. Increment world day + push DB snapshot to HF Dataset |
| ``` |
|
|
| This is a closed reasoning-and-action loop with no human in it: the model |
| observes world state, decides what happens, and writes that decision back |
| into persistent state that future reasoning depends on. That's the **Best |
| Agent** case in one sentence. |
|
|
| A blind cartographer summoned at 2am can meet someone else's Crystal Tree at |
| 4am. You find out when you open the Book. |
|
|
| Estimated cost over the build: **~$68 of $250 Modal credits**, including |
| demo-day GPU warm-keeping. |
|
|
| --- |
|
|
| ## First-Run Experience |
|
|
| The world is designed to feel alive on first load: |
|
|
| - **8 sacred locations** pre-seeded with lore β the Library of Unfinished Thoughts, the Sea of Forgotten Names, the Clock Forest, and five more |
| - **10+ starter entities** with existing memories, relationships, and history from Day 1 |
| - **Book of Ages** β every arrival, interaction, world event, and milestone in styled prose |
| - **Autonomous simulation** β runs every hour whether anyone is watching |
|
|
| By demo day the Realm has **7+ simulated days of history**, 20+ Book |
| entries, and multiple formed relationships β all generated by the model, not |
| hand-written. |
|
|
| --- |
|
|
| ## Try It |
|
|
| **Live Space:** [huggingface.co/spaces/build-small-hackathon/aether-garden](https://huggingface.co/spaces/build-small-hackathon/aether-garden) |
|
|
| **Watch first:** [Demo video](https://youtu.be/M1_UxPpYe54) |
|
|
| **Local setup:** |
|
|
| ```bash |
| python3 -m venv .venv && source .venv/bin/activate |
| pip install -r requirements.txt |
| cp .env.example .env # USE_MOCK_AI=true works without Modal |
| python seed_world.py # 10 starter entities + sample history |
| python run_tick.py # run 3-7x to build simulation history |
| python app.py # -> http://localhost:7860 |
| ``` |
|
|
| ```text |
| 1. Open the Tome cover, then use page turns or the ribbon table of contents. |
| 2. In The Realm spread, inspect the map and live chronicle. |
| 3. In Explore the Realm, choose a place and step into the diorama window. |
| 4. In Summon a New Soul, create something strange and wait for the Oracle. |
| 5. Check the map and Souls spread. Your creation is now part of the world. |
| 6. Run python run_tick.py. Refresh. New interactions and events appear in the Book. |
| ``` |
|
|
| Step 6 is the key test: the simulation runs without user input, history |
| accumulates, and the world grows whether you are watching or not. |
|
|
| --- |
|
|
| ## Build From Source |
|
|
| **Prerequisites:** Python 3.11+, a Modal account (for production AI), and a |
| Hugging Face account (for the Space + dataset backup). |
|
|
| ```bash |
| # Local development (mock AI - no GPU needed) |
| python3 -m venv .venv && source .venv/bin/activate |
| pip install -r requirements.txt |
| cp .env.example .env |
| python seed_world.py |
| python app.py |
| |
| # Production AI via Modal |
| pip install modal |
| modal token new |
| MODEL_FAMILY=minicpm MODEL_ID=openbmb/MiniCPM3-4B TRUST_REMOTE_CODE=true modal deploy modal_app.py |
| # Copy the inference URL -> MODAL_INFERENCE_URL in .env, set USE_MOCK_AI=false |
| |
| # Manual simulation tick (demo prep) |
| python run_tick.py |
| ``` |
|
|
| --- |
|
|
| ## Technical Notes |
|
|
| **Structured AI output.** Entity generation, interactions, and world events |
| all require valid JSON. This branch runs **MiniCPM3-4B** by default β a |
| deliberate tiny-model choice for fast latency and a smaller footprint, while |
| staying comfortably under the 32B cap. Failed parses trigger an automatic |
| retry at lower temperature. |
|
|
| **World coherence at scale.** Each entity carries a compressed |
| `memory_summary` (max 150 words) updated after significant events β not a |
| raw log. Interactions are scoped by location. The 8 sacred locations act as |
| narrative containers so the world doesn't sprawl into contradiction. |
|
|
| **Persistence across restarts.** HF Spaces are ephemeral. The SQLite database |
| is backed up to a private HF Dataset repo after every simulation tick. On |
| startup, the app pulls `world.db` if the local copy is missing. |
|
|
| **Rate limiting.** One entity creation per session per 10 minutes. The Realm |
| is collaborative, not a spam funnel. Reading, exploring, and viewing are |
| unlimited. |
|
|
| **Entity lifecycle.** Active entities participate in simulation. After 7 days |
| without interaction β Dormant. After 30 days dormant β Legendary. Dormant |
| entities in the Valley of Sleeping Giants generate dream fragments for the |
| Book of Ages. Entities at the Hollow Mountain for 14+ days earn a wisdom tag. |
|
|
| **Simulation fairness.** The Ember Crossroads has 3Γ interaction |
| probability β it is the crossroads of everything. The Clock Forest ages |
| entities 1.5Γ faster. The Sea of Forgotten Names grants a secret second name. |
| Location special properties are enforced in both simulation logic and |
| prompts. |
|
|
| **Variant switching** is environment-driven, no code changes required: |
| - MiniCPM variant: `MODEL_FAMILY=minicpm`, `MODEL_ID=openbmb/MiniCPM3-4B` |
| - Nemotron variant: `MODEL_FAMILY=nemotron`, `MODEL_ID=nvidia/Llama-3.1-Nemotron-Nano-8B-v1` |
|
|
| --- |
|
|
| ## Submission Compliance |
|
|
| | Requirement | Status | Evidence | |
| |---|---|---| |
| | Each model under 32B | β
Met | `openbmb/MiniCPM3-4B` (4B) for text generation; `stabilityai/sdxl-turbo` for portraits | |
| | Gradio app in HF Space | β
Met | Space uses Gradio, entrypoint `app.py` | |
| | Zero GPU app limit | β
Met | Single Space app, `cpu-basic` hardware β inference offloaded to Modal | |
| | Track tagged in README | β
Met | `track:wood` in frontmatter | |
| | Demo video linked | β
Met | [youtu.be/M1_UxPpYe54](https://youtu.be/M1_UxPpYe54) | |
| | Social post linked | β
Met | [Reddit post](https://www.reddit.com/r/playmygame/comments/1u3b1rq/i_built_a_grimoire_where_strangers_leave_souls/) | |
| | README write-up | β
Met | Idea, build, and tech sections above | |
| | Achievement tags | β
Met | `achievement:offbrand`, `achievement:fieldnotes`, `achievement:sharingiscaring` | |
| | Sponsor tags | β
Met | `sponsor:openbmb`, `sponsor:modal`, `sponsor:openai`, `sponsor:codex` | |
|
|
| --- |
|
|
| ## Prize Mapping |
|
|
| | Prize / Badge | Why this qualifies | |
| |---|---| |
| | **Thousand Token Wood** | AI is the simulation engine β not a static generator | |
| | **Best Agent** | Hourly autonomous tick: reasoning + action, no user input | |
| | **Off-Brand Award** | Custom SVG map, Three.js diorama, and a full "living tome" page-flip UI β about as far from default Gradio as it gets | |
| | **Best Demo** | World already alive for days when judges open it | |
| | **Tiny Titan** | MiniCPM3-4B (4B params) is the entire reasoning core | |
| | **Modal Award** | Inference + scheduled jobs run on Modal A10G | |
| | **OpenBMB Award** | MiniCPM3-4B is the default model family | |
| | **Best Use of Codex** | Codex-attributed commits in the repo | |
| | **Best Use of Modal** | Inference + scheduled simulation runtime on Modal | |
| | **Sharing is Caring** | Agent interaction traces logged and shared | |
| | **Field Notes** | Build write-up included (see `FIELD_NOTES.md`) | |
|
|
| --- |
|
|
|
|
| ## Project Layout |
|
|
| ``` |
| . |
| βββ app.py Gradio frontend β map, Book of Ages, entity summoning |
| βββ modal_app.py MiniCPM/Nemotron/Qwen inference + hourly simulation (deploy to Modal) |
| βββ seed_world.py Pre-populate 10 entities, history, relationships |
| βββ run_tick.py Manual simulation tick for testing and demo prep |
| βββ world/ SQLite schema, entities, locations, Book of Ages, relationships |
| βββ ai/ Prompt templates, entity generation, Modal client, mock fallback |
| βββ simulation/ 7-step autonomous tick, lifecycle transitions |
| βββ ui/ SVG world map, Sacred Places gallery, entity cards, image asset registry, mystical CSS |
| βββ persistence/ HF Dataset backup and restore |
| βββ assets/ Banner, textures, icons (banner.png included) |
| βββ data/ Local SQLite database (gitignored) |
| ``` |
|
|
| --- |
|
|
| <div align="center"> |
|
|
| *The Realm remembereth all things.* |
|
|
| **Made with π by [Kavya Bhand](https://huggingface.co/kavyabhand) & [Aadi Joshi](https://huggingface.co/aadi-joshi)** |
|
|
| </div> |