TUI now owns the full game loop with embedded LLM engine

The game is now self-contained: run.sh starts the TUI, which calls the
LLM directly via engine.py. No external agent (OpenCode) needed.

- tools/engine.py: Game engine with prompt builder, litellm client,
  response parser (JSON block extraction), and state persistence
- tools/run.py: Refactored TUI with PLAY/CHAR/LOG/BOOK tabs. PLAY tab
  has streaming narrative pane, dynamic choice buttons, and text input.
  Game loop: scene -> input -> resolve -> archive -> apply -> scene
- session/config.json: LLM provider configuration (model, api_key, etc.)
- AGENTS.md: Updated to document the new architecture
- tools/__init__.py: Package marker for clean imports
- session/turn_description.md, turn_reaction.md: Deprecated - no longer
  needed now that the TUI drives the game loop internally
This commit is contained in:
Dejvino
2026-06-25 12:12:04 +02:00
parent 9f8db6e64c
commit 4b9078d41f
10 changed files with 1014 additions and 181 deletions
+1 -1
View File
@@ -1 +1 @@
dungeon
wilds
+77
View File
@@ -158,3 +158,80 @@ Rina whispers: *"That's blood magick. I've seen the signs before. He's not just
She looks at you, waiting.
Waits and deliberates, weighing the risk of waiting for the ritual to finish against the danger of interrupting a blood-weaver mid-chant.
## Turn — 2026-06-25
The weaver's voice rises to a shout — a single word, sharp and resonant. The candle flames all gutter at once, then flare back a deep, pulsing red. A low thrum vibrates through the stone under your boots.
Through the gap in the curtain, you see the dagger in the circle begin to glow — a dull, hungry orange, like iron pulled from a forge. The weaver's hands tremble as he holds them over the blade, chanting faster now, sweat gleaming on his face.
Rina's fingers brush your arm. She points — past the curtain, where the corridor curves right. A heavy wooden door, banded in iron. The same crest: a fist gripping a gear.
The weaver's chant is building toward its final note. The dagger pulses brighter. Whatever he's summoning is almost here.
You have seconds.
Decides to hide and wait. Slipping into the weaver's study behind shelves and furniture, Dillion and Rina watch as the ritual reaches its peak and something begins to take shape in the chalk circle.
## Turn — 2026-06-25
The light in the chalk circle collapses inward, then explodes outward in a wave of heat and pressure. The weaver stumbles back, arms shielding his face.
Where the dagger lay, a figure now stands.
It is man-shaped, but wrong — tall and gaunt, skin the colour of old ash. A jagged blade protrudes from its own chest, driven in at an angle, crusted with dried black blood. Deep wounds crater its torso and arms — some fresh, some scarred. Its eyes open. They have no pupil, only a dull orange glow, like embers guttering in a dead fire.
The temperature in the room drops. Frost spiderwebs across the stone floor from the demon's feet. The candles gutter blue again, then die. Only the orange glow of the demon's eyes lights the room.
The weaver stares, breathless, a grin spreading across his face. *"It worked... it actually worked..."*
The demon's head turns — slowly — toward the weaver. Then toward the shelf where Rina hides. Then toward the table.
*A damned thing. Summoned. Wounded. Looking for something to defend — or destroy.*
Rina's fingers tighten on her crossbow. She's frozen, waiting for your signal.
Signals Rina to hold steady. They watch as the weaver tries to command the summoned demon — it resists, kills him, and now stands in the dark, aware it is not alone.
## Turn — 2026-06-25
Silence. Just the drip of moisture somewhere in the tunnel, and the slow, wet breathing of the demon.
It takes a step toward the shelves — toward Rina. Its bare foot leaves a frozen print on the stone. The blade in its chest grinds with every movement. Its orange eyes sweep the jars, the scrolls, the shadows.
It stops. Tilts its head.
*A low, guttural voice, like stones grinding together:* **"I smell you."**
Rina's hand drifts to her crossbow.
The demon turns — slowly — toward the table where Dillion crouches. Its cracked lips peel back from teeth that are too long, too many. The cold intensifies. Your breath fogs.
**"Fresh meat. Wrapped in leather and fear."**
It takes another step. Then another. The frost crawls up the table legs.
## Turn — 2026-06-25
The demon stands over you, frost crackling across its scarred hide. The blade in its chest glints in the dim orange light of its eyes. It's close — too close — but it's wounded, slow, and you still have your mace.
Rina yanks the string of her crossbow, slotting a fresh bolt with trembling fingers. *"Buy me three seconds!"*
The demon's lips peel back. **"The warm one first. Then the other."** It raises a hand — the same hand that froze your chest — and the temperature in the room plummets again.
You have a split second. The mace is heavy in your grip — freshly sharpened, never used since Weber's stone. It wants to bite.
## Turn — 2026-06-25
The demon plants its feet, frost spiderwebbing across the floor. Its eyes fix on you — then dart to Rina, crossbow raised. It's weighing which of you to strike first.
Rina's voice, low and steady: *"Say the word. I'll put one through its eye."*
The demon's lips curl. **"The crossbow won't save you, little thing. I've been killed before. It didn't stick."** It takes a step toward Rina, testing.
You're between them. Mace in hand. Blood still cold where it touched you.
+1 -1
View File
@@ -14,7 +14,7 @@
## Vitals
- **Max Health:** 10
- **Current Health:** 10
- **Current Health:** 6
- **Armour:** Leather (-1 reduction)
- **Weapon:** Mace (1d6+1, freshly sharpened — 1d6+2 for one job)
- **Cash:** 52 silver
+8
View File
@@ -0,0 +1,8 @@
{
"llm": {
"model": "ollama/llama3.1",
"api_key": null,
"api_base": null,
"temperature": 0.8
}
}
+6
View File
@@ -14,3 +14,9 @@
- **Late Afternoon** — Bodies hidden. Dillion searches the guards (19 silver, key ring, handbill). Rina finds delivery manifests and a note mentioning "The Weeper" and "H." Dillion takes the loot and moves to the iron-reinforced door. Listens. Opens it safely with a rope from behind crates. Beyond: a dark tunnel sloping downward, humid air, slow rhythmic breathing sound.
- **Late Afternoon** — Dillion and Rina descend into the tunnel. It opens into a chamber with a pit at the centre — chains descending into darkness, slow wet breathing from below. A second iron door on the far side. Dillion and Rina skirt the pit silently (DEX 7). Beyond the door: a hallway with a velvet curtain, warm light and a chanting voice beyond. Dillion peeks: a weaver's study, chalk circle with a dagger at the centre. He pulls back to consult Rina.
- **Late Afternoon** — Dillion weighs the options — wait for the ritual to finish and snatch the artifact, or strike now. Rina warns it's blood magick. The weaver's chant climbs toward its peak. Decision hangs in the air.
- **Late Afternoon** — Dillion decides to hide and wait. DEX check (11, success). Dillion and Rina slip into the weaver's study undetected, taking cover behind shelves and the table as the ritual reaches its climax.
- **Late Afternoon** — The ritual completes. A wounded demon emerges from the chalk circle — scarred, a blade in its chest, frost radiating from its feet. Dillion signals Rina to hold. The weaver tries to command the demon — it kills him instead. Now it stands in the dark, searching the room.
- **Late Afternoon** — Combat opens. Dillion wins initiative. He hurls a jar to distract — Rina fires but misses. The demon strikes Dillion with a freezing blast (−4 HP, now 6/10). Dillion is on his feet, mace ready. Rina reloads.
- **Late Afternoon** — Dillion lands a solid blow on the demon's ribs (5+2=7 hits, 1+2-1=2 damage). The demon shrugs it off, wound icing over. Rina finishes reloading.
- **Late Afternoon** — Dillion shouts "Shoot!" Rina fires but misses (3). Dillion swings hard (5) — 6 damage. The demon staggers. Dillion and Rina flee through the hallway into the pit chamber. The demon gives chase.
- **Late Afternoon** — Ambush at the pit. Rina hits (5, 2 damage -1 = 1). Stones miss (1). Dillion tries again (4) — knocks the demon into the pit. Escape clean (5). Dillion and Rina flee the underground, back through the tunnel, and emerge at the mill at dusk.
-9
View File
@@ -1,9 +0,0 @@
The weaver's voice rises to a shout — a single word, sharp and resonant. The candle flames all gutter at once, then flare back a deep, pulsing red. A low thrum vibrates through the stone under your boots.
Through the gap in the curtain, you see the dagger in the circle begin to glow — a dull, hungry orange, like iron pulled from a forge. The weaver's hands tremble as he holds them over the blade, chanting faster now, sweat gleaming on his face.
Rina's fingers brush your arm. She points — past the curtain, where the corridor curves right. A heavy wooden door, banded in iron. The same crest: a fist gripping a gear.
The weaver's chant is building toward its final note. The dagger pulses brighter. Whatever he's summoning is almost here.
You have seconds.