<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Blaqcaptain</title>
    <description>The latest articles on DEV Community by Blaqcaptain (@captainebru84sudo).</description>
    <link>https://dev.to/captainebru84sudo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4016118%2F9c0eb051-253c-48d2-8625-b278d3e3ef44.png</url>
      <title>DEV Community: Blaqcaptain</title>
      <link>https://dev.to/captainebru84sudo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/captainebru84sudo"/>
    <language>en</language>
    <item>
      <title>How I built an AI Dungeon Master that actually remembers what you did three sessions ago</title>
      <dc:creator>Blaqcaptain</dc:creator>
      <pubDate>Sun, 05 Jul 2026 12:18:29 +0000</pubDate>
      <link>https://dev.to/captainebru84sudo/how-i-built-an-ai-dungeon-master-that-actually-remembers-what-you-did-three-sessions-ago-1kec</link>
      <guid>https://dev.to/captainebru84sudo/how-i-built-an-ai-dungeon-master-that-actually-remembers-what-you-did-three-sessions-ago-1kec</guid>
      <description>&lt;p&gt;% embed &lt;a href="https://youtu.be/emnUvx4V8as" rel="noopener noreferrer"&gt;https://youtu.be/emnUvx4V8as&lt;/a&gt; %&lt;br&gt;
&lt;strong&gt;## The demo moment&lt;/strong&gt;&lt;br&gt;
Player types: &lt;em&gt;"I push open the door of The Salt Lantern and step inside, shaking the rain off my cloak. I scan the room for Bren."&lt;/em&gt;&lt;br&gt;
The AI Dungeon Master narrates back a paragraph in which the barkeep Bren shoots them a wary look — because in Session 3, the party sold his brother Aldric out to Captain Vell. In the corner, Mirek the Hawk silently watches — because in Session 2, the party quietly paid Joren's 80-gold gambling debt to him. On the wall, a wanted poster shows a scar shaped like the one on Kara's cheek — the rogue who stole the Amulet of Vohr in Session 1.&lt;br&gt;
Three canon threads. One player action. Zero canon written into the narration prompt.&lt;br&gt;
The tagline the whole build ships behind: &lt;strong&gt;The world remembers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## What I built&lt;/strong&gt;&lt;br&gt;
An AI Dungeon Master with persistent world memory, powered by &lt;a href="https://cognee.ai" rel="noopener noreferrer"&gt;Cognee&lt;/a&gt;. Every player action gets written to a Cognee graph via &lt;code&gt;remember()&lt;/code&gt;. Every subsequent turn queries that graph via &lt;code&gt;recall()&lt;/code&gt; before narrating. The graph accumulates canon organically as the campaign runs — NPCs, factions, debts, betrayals, stolen amulets — and future narration pulls whatever's contextually relevant.&lt;br&gt;
Solo build. Seven-day sprint. Public repo: &lt;a href="https://github.com/captainebru84-sudo/cognee-ai-dm" rel="noopener noreferrer"&gt;captainebru84-sudo/cognee-ai-dm&lt;/a&gt; (MIT).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;## The one problem I did not see coming&lt;/strong&gt;&lt;br&gt;
Day 1 smoke test. Chat loop wired end-to-end. Player pushes open the tavern door. Cognee's &lt;code&gt;recall()&lt;/code&gt; returns: &lt;br&gt;
text: 'Got it.'&lt;br&gt;
Not the canon. Not the barkeep's name. Just: &lt;em&gt;"Got it."&lt;/em&gt;&lt;br&gt;
Turns out Cognee's &lt;code&gt;GRAPH_COMPLETION&lt;/code&gt; search type reads first-person player declarations as &lt;strong&gt;instructions&lt;/strong&gt;, not queries. When you feed it &lt;em&gt;"I push open the door"&lt;/em&gt; it dutifully replies as an assistant would to an instruction. Which is: nothing.&lt;br&gt;
The fix that took Day 2:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
python
WORLD_CAST_FOR_QUERY = "Salt Lantern, Bren, Mirek, Joren, Aldric, Vell, Vohr, Kara..."
def _rewrite_for_recall(player_action: str) -&amp;gt; str:
      return f"What canon exists about: {WORLD_CAST_FOR_QUERY}?"
A deterministic Python rewriter that turns every player declaration into an explicit canon lookup. Not an LLM rewriter — llama-3.1-8b couldn't hold the whole cast in its context under Groq's TPM ceiling. Just a string template.
Canon-hit rate on a 12-keyword smoke: 1/12 → 12/12 on the same session. Same graph, same LLM, same seeds. Just a better question.
That's the moment the project actually became a thing.
How I used Cognee (the honest read)
I leaned hard on two of the four lifecycle APIs:
- remember() — fires on every player turn (write-back), plus one-shot seeding of Sessions 1-3 from a canon file. The graph grows organically.
- recall() — fires before every narration, via the rewriter above. Local backend hits 12/12 canon on the pinned smoke; Cognee Cloud hits 9/12 (their extraction weights differently, still demo-quality).
I did not wire improve() / memify() or forget(). That was a deliberate scoping call, not an oversight. "The world remembers" is fundamentally an accumulate-and-recall pitch — forget() fights the tagline, and improve() fits a "session recap consolidates canon" beat that belongs in v2. Adding lifecycle calls just to broaden the API surface would have been cargo-culting a rubric.
The Cloud swap that actually worked
Wednesday, I swapped in Cognee Cloud behind an env var:
MEMORY_BACKEND=cloud
CLOUD_DATASET=ravenhollow
dm.py picks up CloudClient.recall() and CloudClient.remember() on the cloud path, routing to the same tenant dataset. Zero code duplication between local and cloud modes.

**Two things worth knowing if you try this:**
1. Always pass dataset_name to remember(). Writing to main_dataset threw a 409 hash-mismatch after multiple prior writes. Routing everything through a named dataset (ravenhollow) fixed it clean.
2. Cognee Cloud content-hash-dedupes writes. Re-running my seed script against the same dataset was a ~1s no-op instead of the ~70s it took the first time. Nice for repeatable demos.
What broke on D6
I burned Groq's daily token budget (100K TPD on llama-3.3-70b-versatile) three times across the shoot. The rolling window means you get capacity back ~24h from peak burn — I did the final take at 3 AM Lagos.
I also probed 23 OpenRouter :free models mid-crisis. Every Venice-backed one was upstream-throttled. Nvidia's Nemotron responded but was reasoning-style and dumped its planning trace instead of narrating.
Groq at 3 AM won.

**Try it**
git clone https://github.com/captainebru84-sudo/cognee-ai-dm
cd cognee-ai-dm
cp .env.example .env  # add your Groq key
./.venv/Scripts/python.exe seed_world.py  # ~30s
./.venv/Scripts/python.exe -m uvicorn api.main:app --port 8000
npm --prefix web run dev  # chat UI on :3000
Push open the door of the Salt Lantern.

**AI disclosure**
Built with Claude Code (Anthropic) as a coding assistant. All design decisions, Cognee integration architecture, the Ravenhollow campaign canon, and the recall rewriter concept are original. No AI-generated PRs were submitted to the Cognee repository.

Built for The Hangover Part AI: Where's My Context?  (https://www.wemakedevs.org/hackathons/cognee) by WeMakeDevs, powered by Cognee (https://cognee.ai). The world remembers.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>cognee</category>
      <category>ai</category>
      <category>hackathon</category>
      <category>python</category>
    </item>
  </channel>
</rss>
