Tiny Civilization โ The Tinywick Hollow Gazette
Persistent woodland civilisation sim. 1.5B model.
Every morning in Tinywick Hollow, four animals do something absurd.
๐ฆ Reginald Fox forges a certificate of uncertain provenance. ๐ฆก Beatrice Badger issues a decree nobody asked for, on fourteen constitutional grounds. ๐ฟ๏ธ Cornelius Squirrel invents something that almost works โ and announces it twice. ๐ Millicent Mole surfaces briefly to observe that something is already happening underground, then descends.
Then The Tinywick Hollow Gazette covers it all with the utmost journalistic gravity.
Try it โ huggingface.co/spaces/build-small-hackathon/tiny-civilization
Tiny Civilization is a persistent multi-agent simulation that runs entirely on Qwen2.5-1.5B-Instruct โ 1.5 billion parameters, no external AI APIs, fully local on ZeroGPU. Each time you click Advance Day, five AI agents generate one complete newspaper edition:
You can nudge the story by spreading a rumour, donating a suspicious mushroom, or proposing a new law. The newspaper changes. The creatures remember. The history accumulates.
Most multi-agent simulations show you numbers. Prices, wealth distributions, Gini coefficients. These are impressive engineering, but they're not immediately fun in the way you'd want to screenshot and send to a friend.
A newspaper is different. It takes ordinary events and treats them as stories. The formal journalistic register โ "In a development that surprised absolutely no one who knows these four..." โ makes even the most trivial woodland dispute feel significant. When the AI is writing the journalism, even a mediocre output reads like a slow news day rather than a broken simulation.
This also solved a practical small-model problem. A 1.5B model is excellent at short-form imitation and terrible at open-ended reasoning. "Write two sentences in a pompous journalist's voice" โ it handles this beautifully. "Reason about which creature is most strategically affected by this policy change" โ it falls apart. The newspaper format plays entirely to the model's strengths.
Each agent has exactly one job: speak in their voice.
Reginald Fox is charming, dishonest, and obsessed with official-looking certificates. Everything with him involves a secret deal. He speaks formally and hints at arrangements that may or may not exist.
Beatrice Badger is the gruff self-appointed keeper of rules. She is deeply suspicious of everyone (especially the fox) and always right. She is secretly a poet but will never admit it.
Cornelius Squirrel is an anxious inventor who speaks fast and repeats himself! He invents things that almost-but-not-quite work! He is obsessed with efficiency even when spectacularly inefficient!
Millicent Mole rarely surfaces. She speaks in incomplete thoughts and gentle riddles. She knows everyone's secrets but shares them only obliquely. "Something is already connected underground."
Four sentences of system prompt each. That's it. At 1.5B, character consistency is surprisingly robust โ as long as the format instruction is explicit: "Reply in EXACTLY 2 sentences. No stage directions. Speak only as yourself."
Each day makes exactly four LLM calls:
advance_day()
โโ call_agent("fox", situation_prompt) โ ~80 tokens
โโ call_agent("badger", situation_prompt) โ ~80 tokens
โโ call_agent("squirrel", situation_prompt) โ ~80 tokens
โโ generate_newspaper(events_summary) โ ~280 tokens
Total per day: roughly 520 tokens across 4 calls. On a T4 GPU at ~50 tokens/second, an entire day of civilisation history generates in under 15 seconds.
The newspaper call uses a rigid structured output format, and crucially โ a concrete worked example:
NARRATOR PROMPT (simplified):
...
EXAMPLE OF CORRECT OUTPUT:
FOX PROPOSES REPLACING ACORNS WITH FORGED CERTIFICATES
Reginald Fox has formally proposed that the hollow's economy be restructured
around certificates of authenticity...
WEATHER: Partly suspicious, with a seventy percent chance of decrees.
FOX: Forged three certificates before the morning dew had lifted.
BADGER: Filed eleven formal objections before elevenses.
SQUIRREL: Invented a certificate-counting machine that counts to seven then resets.
MOLE: Something certificated is already circulating underground.
Without this example, the 1.5B model would echo the format instruction names literally โ "HEADLINE IN ALL CAPS:" โ instead of writing real headlines. With the example, format compliance jumps from ~60% to ~90%. Few-shot prompting beats abstract instructions at 1.5B, every time.
This is submitted to the Thousand Token Wood track, which is partly judged on the polish of the Gradio app. So I went all in.
The masthead uses UnifrakturMaguntia, a Gothic blackletter font loaded from Google Fonts. It makes even "Fox Disagrees With Everything" feel like it belongs in a 1920s broadsheet.
The layout uses CSS column-count: 2 for a two-column article with a ruled divider, plus an "In Brief" sidebar for the creature one-liners, a weather strip, classifieds footer, and a live civilisation stats bar.
Every time a new edition is published, a sequence of CSS animations plays automatically โ because Gradio replaces the HTML element on each update, re-triggering animations on fresh DOM nodes. No JavaScript required to restart them:
paperDrop keyframe)inkFade)headlineType clip-path reveal)The Read Aloud button uses the browser's built-in window.speechSynthesis โ no server calls, no API keys, works in every modern browser. The full TTS logic lives inline in the onclick attribute so it works regardless of script execution order in Gradio's SSR proxy. Click once to start; click again to stop.
Paper sound effects are synthesised via Web Audio API โ a short oscillator click followed by a noise burst โ generated programmatically, no audio files needed.
The loading state is a generator pattern: clicking Advance Day immediately shows a loading newspaper with a spinning ornament โ, animated dots, and rotating funny messages from a list of 10:
"Squirrel invented a faster printing press! It prints sideways!"
"Badger has declared the comma unconstitutional..."
"Fox has pre-forged three copies of the headline..."
The simulation stores everything in SQLite: every day's full newspaper text, every agent action, every creature's relationship scores and inventory, every nudge. The civilisation picks up exactly where it left off.
More importantly, history influences future content. The newspaper prompt includes the last two published headlines, so the model can naturally write "In a development reminiscent of last Tuesday's acorn scandal..." without any extra engineering. Past nudges persist and are injected as context for the next three days, creating a real chain of cause and effect.
Creature relationship scores drift based on event type:
| Event | Relationship delta |
|---|---|
| Trade | +5 |
| Invention | +7 |
| Gossip | โ4 |
| Feud | โ10 |
These scores feed back into agent prompts. A Fox at 18 with Badger (Sworn Enemies โ๏ธ) gets a different situation framing than a Fox at 83 with Squirrel (Close Companions ๐ฟ). The creatures develop actual histories with each other over time.
Format adherence is everything. The difference between "write a pompous newspaper article" and specifying the exact structure with a worked example is the difference between 60% usable output and 90% usable output. The model isn't reasoning about journalism โ it's pattern matching. Give it the pattern explicitly and concretely.
Personas survive at 1.5B. Cornelius Squirrel reliably uses exclamation points and repeats himself across dozens of interactions. Beatrice Badger is reliably gruff and declarative. Character consistency emerged from a few sentences of description โ no fine-tuning required.
Short outputs beat long ones. Every agent call is capped at 100 new tokens, every newspaper call at 300. Longer generations at 1.5B tend to drift, loop, or produce markdown formatting. Short, focused outputs are consistently better.
Design around the model's weaknesses. I originally asked the model to choose which creature would be most strategically affected by a nudge. The outputs were random. I moved that logic into Python and just asked the model to react to a given situation. Much better results. Push reasoning into your code; ask the model for language.
Strip the markdown. A 1.5B model trained on internet text will produce **bold text** and ### headers constantly. Build a _strip_markdown() function and run every model output through it before displaying or speaking it.
Type the Konami Code while the app is focused: โ โ โ โ โ โ โ โ B A
A modal appears with all five raw system prompts โ the Gazette editor's, and each creature agent's. A behind-the-scenes look at what's actually driving the simulation. Only the woodland elite know this. ๐ฎ
The Tinywick Hollow Gazette โ
Advance a few days. Spread a rumour that Fox owns the moon (allegedly). Propose that mushrooms are sacred. Donate a half-eaten poem to whoever receives it. Watch the Gazette cover it all with complete journalistic seriousness.
The civilisation has been running for a while now. Badger and Fox are Sworn Enemies (score: 18). Squirrel recently received a "map to somewhere that may not exist" and it has appeared in three subsequent headlines. A law declaring that "buttons = currency" passed on Day 4 and the Gazette continues to report on its economic implications.
Small model. Big headlines. One acorn per copy.
"All things are connected underground." โ Millicent Mole, Day 1
Technical stack: Qwen2.5-1.5B-Instruct ยท Gradio 6 ยท ZeroGPU ยท SQLite ยท Pillow ยท Web Speech API ยท Web Audio API ยท CSS animations ยท UnifrakturMaguntia ยท Libre Baskerville ยท Playfair Display
Persistent woodland civilisation sim. 1.5B model.
More from this author