I fed the previous post to the Deep Dive team so it would produce a podcast. They did a great job.
Tag: gaming
LudoForge #1
Two nights ago I was rolling around in bed trying to sleep when a notion came into my head, one that has returned from time to time: some of the most flow-like fun I’ve ever had was playing tabletop games. I’m a systems builder by nature, and I love to solve problems with a variety of tools. Tabletop games are complex problems to solve with specific series of tools. My favorite tabletop game is Arkham Horror LCG, although I’ve loved many more like Terraforming Mars, Ark Nova, Baseball Highlights: 2045, Core Worlds, Imperium, Labyrinth, Renegade… But none of them fully captured me. Like some potential game exists that has exactly every feature my brain yearns for, but that game doesn’t exist. I’ve cyclically thought that I should create that game, but I never know where to start. I don’t even know what exactly I want, other than knowing that what I’ve experienced isn’t enough.
These past few weeks I’ve been implementing extremely-complex analytics reports generators for my repository Living Narrative Engine. I was surprised to find out that it’s feasible to mathematically find gaps in extremely complex spaces (dozens of dimensions) as long as they’re mathematically defined. I guess Alicia was justified to be obsessed with math. So I started wondering: what makes a tabletop game good? Surely, the fun you have with it. Can “fun” be mathematically defined? Is it the agency you have? The strategic depth? The variety? If any of such metrics could be mathematically defined, then “fun” is a fitness score that combines them.
And what if you didn’t need to design the game yourself? If you can map a simulated game’s activity to metrics such as the agency per player, the strategic depth, the variety… Then you can evolve a population of game definitions in a way that, generation after generation, the “fun” score improves. If you can turn all game mechanics into primitives, the primitives will mutate in and prove their worth throughout the generations, composing coherent mechanics or even inventing new ones. Initially, a human may need to score game definition variants according to how “fun” the playthrough of those games were, but in the end that could be automated as well.
Because this is the era of Claude Code and Codex, I’ve already implemented the first version of the app. I’ve fed ChatGPT the architectural docs and told it to write a report. You can read it down below.
LudoForge: evolving tabletop games with a deterministic “taste loop”
I’m building LudoForge, a system that tries to answer a pretty blunt question:
What if we treated tabletop game design like search—simulate thousands of candidates, kill the broken ones fast, and let a human “taste model” steer evolution toward what’s actually fun?
Under the hood, it’s a seeded-population evolution loop: you start with a set of game definitions (genomes), run simulations, extract metrics, filter degeneracy, blend in learned human preferences, and then evolve the population using MAP-Elites and genetic operators. Then you repeat.
The big picture: the loop
LudoForge is structured as a pipeline with clean seams so each layer can be tested and swapped without turning the whole thing into spaghetti. The stages look like this: seed → evaluate → simulate → analytics → (optional) human feedback → fitness → MAP-Elites → (optional) mutate/crossover/repair → next generation. pipeline-overview
A key design choice: the core expects a seeded population. There’s no “magic generator” hidden inside that invents games from scratch. If you want a generator, you build it outside and feed it in. That keeps the engine honest and debuggable. Note by me after rereading this part of the report: this will change soon enough.
Games as genomes: a DSL that can be validated and repaired
Each candidate game is a genome: { id, definition }, where definition is a DSL game definition. Before any evaluation happens, the definition goes through schema + semantic validation—and optionally a repair pass if you enable repair operators. Invalid DSL gets rejected before it can contaminate simulation or preference learning.
Repair is deliberately conservative: it’s mostly “DSL safety” (e.g., clamp invalid variable initial values to bounds). Anything that’s “this game is technically valid but dumb/unplayable” is handled by simulation + degeneracy detection, not by sweeping edits that hide the real problem.
The simulation engine: deterministic playthroughs with real termination reasons
The simulation layer runs a single playthrough via runSimulation(config) (or wrapped via createSimulationEngine). It builds initial state from the definition, picks the active agent, lists legal actions, applies costs/effects/triggers, advances turns/phases, and records a trajectory of step snapshots and events.
It’s also built to fail safely:
- No legal actions → terminates as a draw with
terminationReason = "stalemate". - Max turns exceeded →
terminationReason = "max-turns"with an outcome computed in that cutoff mode. - Loop detection (optional hashing + repetition threshold) →
terminationReason = "loop-detected".
Most importantly: runs are reproducible. The RNG is a seeded 32-bit LCG, so identical seeds give identical behavior.
Metrics: cheap proxies first, expensive rollouts only when you ask
After simulation, LudoForge summarizes trajectories into analytics: step/turn counts, action frequencies, unique state counts, termination reasons, and sampled “key steps” that include legalActionCount.
From there it computes core metrics like:
- Agency (fraction of steps with >1 legal action)
- Strategic depth (average legal actions per step)
- Variety (action entropy proxy)
- Pacing tension (steps per turn)
- Interaction rate (turn-taking proxy)
Extended metrics exist too, and some are intentionally opt-in because they’re expensive:
- Meaningful choice spread via per-action rollouts at sampled decision points
- Comeback potential via correlation between early advantage and final outcome
Here’s the honest stance: these metrics are not “fun”. They’re proxies. They become powerful when you combine them with learned human preference.
Degeneracy detection: kill the boring and the broken early
This is one of the parts I’m most stubborn about. Evolution will happily optimize garbage if you let it.
So LudoForge explicitly detects degeneracy patterns like:
- loops / non-termination
- stalemates
- forced-move and no-choice games
- dominant-action spam
- trivial wins metrics-and-fitness
By default, those flags can reject candidates outright, and degeneracy flags also become part of the feature vector so the system can learn to avoid them even when they slip through.
Human feedback: turning taste into a model
Metrics get you a feature vector. Humans supply the missing ingredient: taste.
LudoForge supports two feedback modes:
- Ratings (1–5) with optional tags and rationale
- Pairwise comparisons (A/B/Tie) with optional tags and rationale
Pairwise comparisons are the main signal: they’re cleaner than ratings and train a preference model using a logistic/Bradley–Terry style update. Ratings still matter, but they’re weighted lower by default.
There’s also active learning: it selects comparison pairs where the model is most uncertain (predicted preference closest to 0.5), while reserving slots to ensure underrepresented MAP-Elites niches get surfaced. That keeps your feedback from collapsing into “I only ever see one genre of game.”
Fitness: blending objective proxies, diversity pressure, and learned preference
Fitness isn’t a single magic number pulled from the void. It’s a blend:
- Base composite score from metrics (weighted sum/objectives)
- Diversity contribution (pressure toward exploring niches)
- Preference contribution from the learned preference model (centered/capped, with bootstrap limits early on)
Feature vectors are keyed by metric id (not positional arrays), which matters a lot: adding a new metric doesn’t silently scramble your model weights. Renaming metrics, though, becomes a migration event (and that’s correct—you should feel that pain explicitly).
Evolution: MAP-Elites + mutation/crossover that respect DSL validity
Instead of selecting “top N” and converging into a monoculture, LudoForge uses MAP-Elites: it bins candidates into descriptor niches and keeps the best elite per niche.
Descriptor binning is explicit and deterministic (normalize → floor into bin count; clamp to range), and niche ids serialize coordinates like descriptorId:bin|....
Then you can evolve elites with genetic operators:
- Mutations like numeric tweaks, boolean toggles, enum cycling, duplicating/removing actions, nudging effect magnitudes, adding/removing phases, rewriting token/zone references safely, etc.
- Crossover via subtree swaps of
state.variablesoractions, followed by DSL re-validation.
Optional “shortlisting” exists too: it picks a diversified subset of elites for human review using a max-min distance heuristic over descriptor coordinates.
What’s already proven (and what isn’t yet)
This isn’t vaporware; the end-to-end tests already prove key behaviors like:
- the ordered phases of the pipeline
- invalid DSL rejection before evaluation
- safety cutoffs (
max-turns) and deterministic seeded outputs - human prompt loops and legality enforcement
- deterministic state transitions
- MAP-Elites producing stable ids
- active learning selection behavior
- mutation + repair at scale, including crossover
And there are explicitly documented gaps—like extended metrics aggregation and worker-thread batch simulations.
The point of LudoForge
I’m not trying to build a “game designer replacement.” I’m building a design pressure cooker:
- Simulate hard
- Reject degeneracy ruthlessly
- Measure what you can
- Ask humans the right questions
- Let evolution explore breadth, not just a single hill
If you’re into procedural design, evolutionary search, or just enjoy the idea of treating “fun” as something you can iteratively approximate with a human-in-the-loop model, that’s what this project is for.
Post-mortem for Custody of the Rot
If you’re reading these words without having read the story mentioned in the title, don’t be a fucking moronski; read it first.
I assume you’ve read some of my previous posts on my ongoing fantasy cycle, so you may remember that I’m producing these stories in tandem with improvements to my app, named Living Narrative Engine. It’s a browser-based system for playing scenarios like immersive sims, RPGs, etc. I’m compelled by the mutual pulls of adding more features to my engine and experiencing new scenarios; sometimes I come up with the scenario first, sometimes with the mechanics. That has my brain on a constant “solve this puzzle” mode, which is the ideal way to live for me.
Anyway, the following scenarios involving a brave bunch of dredgers in a fantasy world, tasked with extracting a dangerous arcane artifact from some gods-forsaken hole, will require me to develop the following new mechanics:
- Lighting mechanics. Currently, every location is considered constantly lit. Given that we’re going underground and that the narrative itself requires using lanterns, I have to implement mechanics for recognizing when a location is naturally dark, and whether there are light sources active. There are other mechanics providing information about the location and actors in it, so from now on, when a location is naturally dark and nobody has switched on a flashlight, we have to block offering descriptions of the location and other actors in it, and instead display text like “You can’t see shit.”
- Once lighting mechanics exist, we need actions for lighting up and snuffing out lanterns and lantern-like entities. By far the easiest part.
- Currently, when an actor speaks in a location, the speech is only received by actors in that location. At the same time, I consider an entity a location when it has defined exits. Now we find ourselves in a situation in which we have a thirty-feet-long underground corridor separated by grates. That would make each segment between grates a location (which would be correct, given the boundary), but an actor could step from a boundary into the next and suddenly not hear a character on the other side of a grate’s bars. Obviously idiotic. So I need to implement a mechanical system for declaring “if an actor speaks here, the voice will be heard in these other places too.” That will need to extent to actions too: if you have eyes, you can see someone scratching his ass on the other side of bars.
- No other scenario has featured water sources that could play a part. And by play a part I mean that actors could get in or fall in, exit them, struggle in the water, and drown. I really don’t want to see my characters drowning, but that’s part of the stakes, so the mechanics need to exist. Given that water sources tend to be connected to other locations and not through the regular exits, I will need some way of allowing “I’m in the water, so I want to swim upstream or downstream to a connected stretch of this water source.” This whole water system will be arduous.
- Line-tending mechanics. Until I started researching matters for this story, I doubt that the notion of line-tending had ever entered my mind. Now we need mechanics for: 1) making an owned rope available to others. 2) Clipping and unclipping oneself from the available rope. 3) pulling on the rope to draw back someone clipped that’s wandering away. 4) possibly other cool line-tending-related mechanics. I can see line-tending reappearing in future scenarios such as traditional dungeon delves (for example, to avoid falling in Moria-like environments). Admittedly, though, this whole thing is quite niche.
- Blocker-breaking mechanics. Basically: this door is bar-based, so this allows a hacksaw to hack through the bars. I don’t want to make it a single action, but a progressive one (e.g. if you succeed once, it only progresses a step toward completion).
- Mechanics related to mind control. To even use those actions, I will need to create a new type of actor for the scenarios: a dungeon master of sorts. Basically a human player that’s not accessible to others, as if it were invisible, but that can act on present actors. I would give that dungeon master for this run the can_mind_control component, then allow actions such as putting people into trances, making them walk off, dive into water, etc. This means that there would need to be opposite actions, with the victims fighting to snap out of the trance. It will be fun to find out what happens when the scenario plays out. In the future, this dungeon master could be controlled by a large language model without excessive difficulty: for example, feeding it what’s happened in the story so far, what are the general notions about what should happen, and giving it actions such as “spawn a hundred murder dragons.”
That’s all that comes to mind now regarding the mechanics to add.
About the story: so far, it seems I want magic to be treated in this fantasy world as if it were toxic material. That’s not a decision I’ve made about worldbuilding, but a natural consequence of the stories I’ve felt like telling. I actually don’t believe in the kind of worldbuilding in which you come up with imaginary words for the warts on an invented race’s ass. I’m all about use and tools. My mind always goes for “what can I build with this.” I’m very rarely interested in a subject if I can’t see myself creating a system out of it. It also doesn’t help that due to autism, abstractions tend to slip through my fingers, so I need to feel like I’m sensing something to understand it.
In a way, I wanted to create a story about specialists working through a problem that needs to be solved. Jorren Weir, Kestrel Brune, Saffi Two-Tides, Pitch… these people don’t have superpowers. Most of them are glad they can keep a job. There is no grand evil here, just people’s self-interest. I want them to do well so that they can return home at the end of the ordeal. But given that we’re dealing with chance-based tests, that’s not a guarantee. And that tension alone makes it exciting for me to experience these scenarios.
As usual, if you’re enjoying these stories, then great. Otherwise, fuck off.
Post-mortem for That Feathered Bastard
Read first the short story this post-mortem is about: That Feathered Bastard.

Through this cycle of fantasy stories, I’m exercising in tandem my two main passions in life: building systems and creating narratives. Every upcoming scenario, which turns into a short story, requires me to program new systems into my Living Narrative Engine, which is a browser-based platform for playing through immersive sims, RPGs and the likes. Long gone are the scenarios that solely required me to figure out how to move an actor from a location to another, or to pick up an item, or to read a book. Programming the systems so I could play through the chicken coop ambush involved about five days of constant work on the codebase. I’ve forgotten all that was necessary to add, but off the top of my head:
- A completely new system for non-deterministic actions. Previously, all actions succeeded, given that the code has a very robust system for action discoverability: unless the context for the action is right, no actor can execute them to begin with. I needed a way for an actor to see “I can hit this bird, but my chances are 55%. I may not want to do this.” Once you have non-deterministic actions in a scenario, it becomes unpredictable, with the actors constantly having to maneuver a changing state, which reveals their character more.
- I implemented numerous non-deterministic actions:
- Striking targets with blunt weapons, swinging at targets with slashing weapons, thrusting piercing weapons at targets. None of those ended up taking part of this scenario, because the actors considered that keeping the birds alive was a priority, as Aldous intended.
- Warding-related non-deterministic actions: drawing salt boundaries around corrupted targets (which Aldous said originally he was going to do, but the situation turned chaotic way too fast), and extracting spiritual corruption through an anchor, which Aldous did twice in the short.
- Beak attacks, only available to entities whose body graphs have beak parts (so not only chickens, but griffins, krakens, etc.). This got plenty of use.
- Throwing items at targets. Bertram relied on this one in a fury. I got clever with the code; the damage caused by a thrown weapon, when the damage type is not specified, is logarithmically determined by the item’s weight. So a pipe produces 1 unit of blunt damage, and throwing Vespera’s instrument case at birds (which I did plenty during testing) would cause significant damage. Fun fact: throwing an item could have produced a fumble (96-100 result on a 1-100 throw), and that would have hit a bystander. Humorous when throwing a pipe, not so much an axe.
- Restraining targets, as well as the chance for restrained targets to free themselves. Both of these got plenty of use.
- A corrupting gaze. It was attempted thrice, if I remember correctly, once by the main vector of corruption and the other by that creepy one with the crooked neck. If it had succeeded, it would have corrupted the human target, and Aldous would have had to extract it out of them as well. That could have been interesting, but I doubt it would have happened in the middle of chickens flying all over.
- Implementing actions that cause damage meant that I needed to implement two new systems: health and damage. Both would rely on the extensive anatomy system, which produces anatomy graphs out of recipes. What I mean about that is that we have recipes for roosters, hens, cat-girls, men, women. You specify in the recipe if you want strong legs, long hair, firm ass cheeks, and you end up with a literal graph of connected body parts. Noses, hands, vaginas exist as their own entities in this system. They can individually suffer damage. I could have gone insane with this, as Dwarf Fortress does, simulating even individual finger segments and non-vital internal organs. I may do something similar some day if I don’t have anything better to do.
- Health system: individual body parts have their own health levels. They can suffer different tiers of damage. They can bleed, be fractured, poisoned, burned, etc. At an overall health level of 10%, actors enter a dying state. Suffering critical damage on a vital organ can kill creatures outright. During testing there were situations in which a head was destroyed, but the brain was still functioning well enough, so no death.
- Damage system: weapons declare their own damage types and the status effects that could be applied. Vespera’s theatrical rapier can pierce but also slash, with specific amounts of damage. Rill’s practice stick only does low blunt damage, but can fracture.
Having a proper health and damage system, their initial versions anyway, revealed something troubling: simple non-armored combat with slashing weapons can slice off limbs and random body parts with realistic ease. Whenever I get to scenes involving more serious stakes than a bunch of chickens, stories are going to be terrifyingly unpredictable. Oh, and when body parts are dismembered, a corresponding body part entity gets spawned at the location. That means that any actor can pick up a detached limb and throw it at someone.
Why go through all this trouble, other than the fact that I enjoy doing it and that it distracts me from the ocean of despair that surrounds me and that I can only ignore when I’m absorbed in a passion of mine? Well, over the many years of producing stories, what ended up boring me was that I went into a scene knowing all that was going to happen. Of course, I didn’t know the specifics of every paragraph, and most of the joy went into the execution of those sentences. But often I found myself looking up at the sequences of scenes to come, and it was like erecting a building that you already knew how it was going to end up looking. You start to wonder why even bother, when you can see it clearly in your mind.
And I’m not talking about that “plotter vs. pantser” dichotomy. Pantsing means you don’t know where you’re going, and all pantser stories, as far as I recall, devolve into messes that can’t be tied down neatly by the end. And of course they’re not going to go back and revise them to the necessary extent of making something coherent out of them. As much as I respect Cormac McCarthy, one of his best if not the best written novel of his, Suttree, is that kind of mess, which turns the whole thing into an episodic affair. An extremely vivid one that left many compelling, some harrowing, images in my brain, but still.
I needed the structure, with chance for deviation, but I also needed to be constantly surprised by the execution of a scene. I wanted to go into it with a plan, only for the plan to fail to survive the contact with the enemy. That’s where my Living Narrative Engine comes in. Now, when I experience a scene, I don’t know what the conversations are going to entail. I didn’t even come up with Aldous myself: Copperplate brought him up in the first scene when making up the details of the chicken contract. It was like that whole “Lalo didn’t send you” from Breaking Bad, which ended up producing a whole series. From that mention of Aldous, after an iterative process of making the guy interesting for myself, he ended up becoming a potter-exorcist I can respect.
I went into that chicken coop not knowing anything about what was going to happen other than the plan the characters themselves had. Would they overpower the chickens and extract the corruption out of them methodically with little resistance? Would any of the extraction attempts succeed? Would any actor fly into a rage, wield their weapons and start chopping off chicken limbs while Aldous complained? Would any of the characters suffer a nasty wound like, let’s say, a beak to the eye? I didn’t know, and that made the process of producing this scene thrilling.
Also, Vespera constantly failing at everything she tried, including two rare fumbles that sent her to the straw, was pure chance. It made for a more compelling scene from her POV; at one point I considered making Aldous the POV, as he had very intriguing internal processes.
Well, the scene wasn’t all thrilling. You see, after the natural ending when that feathered bastard pecked Vespera’s ass, the scene originally extended for damn near three-fourths of the original length. People constantly losing chickens, the rooster pecking at anyone in sight, Melissa getting frustrated with others failing to hold down the chickens, Rill doing her best to re-capture the chickens that kept wrenching free from her hold. Aldous even failed bad at two extractions and had to pick up the vessel again. It was a battle of attrition, which realistically would have been in real life. I ended up quitting, because I got the point: after a long, grueling, undignified struggle, the chickens are saved, the entity is contained in the vessel, and the actors exit back to the warm morning with their heads down, not willing to speak for a good while about what they endured.
Did the scene work? I’m not sure. It turned out chaotic, with its biggest flaw maybe the repetition of attempting to catch chickens only for them to evade capture. There were more instances of this in the original draft, which I cut out. I could say that the scene was meant to feel chaotic and frustrating, and while that’s true, that’s also the excuse of those that say “You thought my story was bad? Ah, but it was meant to be bad, so I succeeded!” Through producing that scene, editing it, and rereading it, I did get the feeling of being there in that chaotic situation, trying to realistically accomplish a difficult task when the targets of the task didn’t want it completed, so if any reader has felt like that, I guess that’s a success.
I have no idea what anyone reading this short story must have felt or thought about it, but it’s there now, and I’ll soon move out to envision the next scenario.
Anyway, here are some portraits for the characters involved:
Aldous, the potter-exorcist

Kink-necked black pullet

Slate-blue bantam

White-faced buff hen

Large speckled hen

Copper-backed rooster

Review: Dispatch
Back in late 2000s and early 2010s, we had this thing we affectionately called Telltale-style games: heavily narrative-driven games that relied on letting the player make more or less compelling decisions that would affect the narrative. They didn’t have the complexity of early adventure games, but they couldn’t be called simple visual novels either. They were tremendously successful, until corporate greed swallowed them, spread them thin, and eventually dissolved them into nothing. The company shut down.
A new studio made of former Telltale devs decided to try their hand a new Telltale-style game that removed the dragging parts of former Telltale games (mainly walking around and interacting with objects) to focus on a good story, a stellar presentation, and compelling minigames. Their first product was the game Dispatch, released about a month ago in an episodic format (two episodes a week, but all of them are out already). The game has become a runaway success.
The story focuses on Robert Robertson, a powerless Iron Man in a society where many, many people have superpowers. He carries the family legacy of battling villains with a mecha. As an adult, he pursued the supervillain who murdered Robert’s father, and who now led one of the most dangerous criminal groups. However, during an assault on the villain’s base, Robert’s mecha gets destroyed, which puts him out of a job.
However, he’s approached by one of the most notorious superheroes, a gorgeous, strong woman who goes by the name Blonde Blazer. She offers him a job at the company she works for, SDN (Superhero Dispatch Network). Their engineers will work on repairing Robert’s mecha, while he offers his expertise on fighting crime as the one in charge of dispatching other heroes to the appropriate calls.

Robert finds out that the team of heroes he’s supposed to handle are a bunch of villains who either have approached the company to reform themselves, or were sent by the criminal system for rehabilitation. They’re a diverse bunch of rowdy, at times nasty superpowered people who aren’t all too keen on having a non-superpowered nobody in charge of them. The narrative explores how the team grows to work together better.

The execution of this story could have gone wrong in so many ways: wrong aesthetic, time-wasting, atrocious writing, and above all, marxist infiltration; like most entertainment products released on the West these days, the whole thing could have been a vehicle for rotten politics. But to my surprise, that’s not the case here. A male protagonist, white male no less, who is an intelligent, hard-working, self-respecting role model? Attractive characters, fit as they would be in their circumstances? A woman in charge (Blonde Blazer) who is nice, understanding, competent, caring, and good? Villains with believable redemption arcs? Romance routes that flow naturally? Where the hell did this game come from in 2025?

Entertainment consumers have been deliberately deprived of all of this by ideologues who despise everything beautiful and good, who, as Tolkien put it, “cannot create anything new, they can only corrupt and ruin what good forces have invented or made.” Franchise after franchise taken over by marxists who dismantle it, shit on the remains, and then insult you if you don’t like it. Dispatch is none of it. For that reason alone, I recommend the hell out of it. I’m sure that given its sudden popularity, the forces-that-be will infiltrate it and ruin it in its second season as they do with everything else, but the first season is already done.
It’s not perfect, of course. Its pros: an astonishing visual style that makes it look like a high-quality comic book in movement. No idea how they pulled it off. Clever writing. Endearing characters. Interesting set pieces. The voice acting is extraordinary, led by Aaron Paul of Breaking Bad fame. He deserves an award for his acting as Robert Robertson. It’s a good story told well, and you’re in the middle of it making important decisions (and also plenty of flavorful ones).
The cons: some whedonesque dialogue that didn’t land for me. Too much cursing even for my tastes, to the extent that often feels edgy for edge’s sake. Some narrative decisions taken during the third act, particularly regarding the fate of one of the main characters, didn’t sit well for me, as it deflated the pathos of the whole thing. But despite the pros, this was a ride well worth the price.
Oh, I forgot: they should have let us romance the demon mommy. My goodness.

Check out this nice music video some fan created about Dispatch, using one of the songs of its soundtrack.
VR game review: Ghost Town
I’ve been playing a lot of VR recently, so I may as well review the only long-form game that I’ve finished in this couple of weeks. Ghost Town is a puzzle-based adventure game set in Great Britain back in the eighties. You’re a spirit medium (a witch) named Edith, whose shitty younger brother disappeared under shady circumstances, and your goal is to find him. Trailer is below:
There are many more pros than cons as far as I’m concerned. The setting, mainly London in the 80s, is quite unique, and provides a gritty touch that I appreciated. The character animations and models are generally exceptional for the Meta Quest 3, maybe the best I’ve seen so far. I don’t like puzzle games, yet this one made me appreciate the puzzles. I was never entirely stuck, as the progressive hint system helped me eventually realize at least where I should focus on. I loved the tactile feel of exorcising ghosts, although it’s a minor part of the experience. Plenty of great moments come to mind: interacting with ghosts behind glass (great-looking in VR), using eighties ghost-bustery technology to investigate artifacts, a very creative museum of haunted artifacts, sleepwalking through your eerie apartment tower in 80s London, a great sequence in which you wander through a maze-like version of your apartment while malevolent presences whisper from the shadows (very P.T. like), clever use of light in puzzles, etc.
Horror stories are never more terrifying than in VR. Play Phasmophobia if you dare, for example. I try to avoid horror games because of my damaged heart. However, the ghosts in this one are more spooky than scary.
Now, the cons: personally, I wish the game were more like a regular adventure game instead of a puzzle game with a narrative thread woven throughout it. That’s just a personal preference, though; I wish we got the equivalents of the Monkey Island series in VR. Anyway, the least interesting sequence of puzzles for me was the lighthouse, which comes right after the introductory flashback. I actually dropped the game for like a couple of months after I first played it, because I didn’t feel like returning, but I’m glad I picked it back up and continued.
However, my biggest gripe with the story is that you’re supposed to search for your brother, whom you meet in the first scene, when you’re investigating a haunting in an abandoned theatre, but in every damn scene he’s in, the brother comes off as envious, narcissistic, entitled, and overall a complete dickhead. I didn’t want to interact with him. Did the creators believe we would be invested in finding this guy just because he was related to the protagonist? I think it’s a given that they should have made the brother sympathetic, but he annoyed me in every scene he appeared.
All in all, fantastic experience. Perhaps a bit short, but I felt like I got my money’s worth. If you have a Quest 3 and you enjoy these sorts of games, check it out.
Living Narrative Engine #9
Behold the anatomy visualizer: a visual representation of a graph of body parts for any given entity, with the parts represented as nodes connected by Bézier curves. Ain’t it beautiful?

This visualizer has been invaluable to detect subtle bugs and design issues when creating the recipes and blueprints of anatomy graphs. Now, everything is ready to adapt existing action definitions to take into account the entity’s anatomy. For example: a “go {direction}” target could have the prerequisite that the acting character has “core:movement” unlocked anywhere in his body parts. Normally, the legs would have individual “core:movement” components. If any of the legs are disabled or removed, suddenly the “go {direction}” action wouldn’t become an available action. No code changes.
The current schemas for blueprints, recipes, and sockets, make it trivial to add things like internal organs, for a future combat system. Imagine using a “strike {target} with {weapon}” action, and some rule determining the probabilities of damaging what parts of any given body part, with the possibility of destroying internal organs.
From now on I’ll always provide the Discord invite for the community I created for this project (Living Narrative Engine):
Living Narrative Engine #8
Perhaps some of you fine folks would like to follow the development of this app of mine, see the regular blog posts about the matter in an orderly manner, or just chat about its development or whatever, so I’ve created a discord community. Perhaps in the future I’ll have randos cloning the repository and offering feedback.
Discord invite below:
Living Narrative Engine #7
I’m developing a browser-based, chat-like platform for playing adventure games, RPGs, immersive sims and the likes. It’s “modding-first,” meaning that all game content comes in mods. That includes actions, events, components, rules, entities, etc. My goal is that eventually, you could define in mod files the characters, locations, actions, rules, etc. for any existing RPG campaign and you would be able to play through it, with other characters being large language models or GOAP-based artificial intelligences.
From early on, it became clear that the platform was going to be able to support thousands of actions for its actors (which may be human or controlled by a large language model). The code shouldn’t be aware of the specifics of any action, which wasn’t easy to do; I had to extract all the logic for going from place to place from the engine, to the extent that I had to create a domain-specific language for determining target scopes.
When the turn of any actor starts, the system looks at all the actions registered, and determines which are available. I registered some actions like waiting, moving from place to place, following other people, dismissing followers, to some more niche ones (in an “intimacy” mod) like getting close to others and fondling them. Yes, I’m gearing toward erotica in the future. But as I was implementing the actions, it became clear that the availability of some actions wouldn’t be easily discerned for the impossible-to-predict breath of possible entities. For example, if you wanted to implement an “slap {target}” action, you can write a scope that includes actors in the location, but what determines that the actor actually has a head that could be slapped? In addition, what ensures that the acting actor has a hand to slap with?
So I had to create an anatomy system. Fully moddable. The following is a report that I had Claude Code prepare on the first version of the anatomy system.
The Anatomy System: A Deep Dive into Dynamic Entity Body Generation
Executive Summary
The anatomy system is a sophisticated framework for dynamically generating and managing complex anatomical structures for entities in the Living Narrative Engine. It transforms simple blueprint definitions and recipes into fully-realized, interconnected body part graphs with rich descriptions, validation, and runtime management capabilities.
At its core, the system addresses a fundamental challenge in narrative gaming: how to create diverse, detailed, and consistent physical descriptions for entities without manual authoring of every possible combination. The solution is an elegant blend of data-driven design, graph theory, and natural language generation.
System Architecture
The anatomy system follows a modular, service-oriented architecture with clear separation of concerns. The design emphasizes:
- Orchestration Pattern: A central orchestrator coordinates multiple specialized workflows
- Unit of Work Pattern: Ensures transactional consistency during anatomy generation
- Chain of Responsibility: Validation rules are processed in a configurable chain
- Strategy Pattern: Description formatting uses pluggable strategies for different part configurations
- Factory Pattern: Blueprint factory creates anatomy graphs from data definitions
Core Service Layers
- Orchestration Layer (
AnatomyOrchestrator)
- Coordinates the entire generation process
- Manages transactional boundaries
- Handles error recovery and rollback
- Workflow Layer
AnatomyGenerationWorkflow: Creates the entity graph structureDescriptionGenerationWorkflow: Generates natural language descriptionsGraphBuildingWorkflow: Builds efficient traversal caches
- Service Layer
BodyBlueprintFactory: Transforms blueprints + recipes into entity graphsAnatomyDescriptionService: Manages description generationBodyGraphService: Provides graph operations and traversal
- Infrastructure Layer
EntityGraphBuilder: Low-level entity creationSocketManager: Manages connection points between partsRecipeProcessor: Processes and expands recipe patterns
Information Flow
The anatomy generation process follows a carefully orchestrated flow:
1. Initialization Phase
When an entity with an anatomy:body component is created, the AnatomyInitializationService detects it and triggers generation if the entity has a recipeId.
2. Blueprint Selection
The system loads two key data structures:
- Blueprint: Defines the structural skeleton (slots, sockets, parent-child relationships)
- Recipe: Provides specific customizations, constraints, and part selections
3. Graph Construction
The BodyBlueprintFactory orchestrates the complex process of building the anatomy:
Blueprint + Recipe → Graph Construction → Entity Creation → Validation → Description Generation
Each step involves:
- Slot Resolution: Blueprint slots are processed in dependency order
- Part Selection: The system selects appropriate parts based on requirements
- Socket Management: Parts are connected via sockets with occupancy tracking
- Constraint Validation: Recipe constraints are continuously checked
4. Description Generation
Once the physical structure exists, the description system creates human-readable text:
- Individual part descriptions are generated using context-aware builders
- Descriptions are composed into a complete body description
- Formatting strategies handle single parts, paired parts, and multiple parts differently
5. Runtime Management
The generated anatomy becomes a living system:
- Parts can be detached (with cascade options)
- The graph can be traversed efficiently via cached adjacency lists
- Events are dispatched for anatomy changes
Core Capabilities
1. Dynamic Entity Generation
- Creates complete anatomical structures from data definitions
- Supports unlimited variety through recipe combinations
- Generates unique entities while maintaining consistency
2. Hierarchical Part Management
- Parts are organized in a parent-child graph structure
- Each part can have multiple sockets for child attachments
- Supports complex anatomies (e.g., creatures with multiple limbs, wings, tails)
3. Intelligent Part Selection
- Matches parts based on multiple criteria (type, tags, properties)
- Supports preferences and fallbacks
- Handles optional vs. required parts gracefully
4. Natural Language Descriptions
- Generates contextual descriptions for individual parts
- Composes full-body descriptions with proper formatting
- Handles pluralization, grouping, and special cases
5. Constraint System
- Enforces recipe-defined constraints (requires/excludes)
- Validates socket compatibility
- Ensures graph integrity (no cycles, orphans, or invalid connections)
6. Runtime Operations
- Part detachment with cascade support
- Efficient graph traversal via cached adjacency lists
- Path finding between parts
- Event-driven notifications for changes
Key Components Deep Dive
AnatomyOrchestrator
The maestro of the system, ensuring all workflows execute in the correct order with proper error handling and rollback capabilities. It implements a Unit of Work pattern to maintain consistency.
BodyBlueprintFactory
The factory transforms static data (blueprints and recipes) into living entity graphs. It handles:
- Dependency resolution for slots
- Socket availability validation
- Part selection and creation
- Name generation from templates
Validation System
A sophisticated chain of validation rules ensures anatomical correctness:
- CycleDetectionRule: Prevents circular parent-child relationships
- OrphanDetectionRule: Ensures all parts are connected
- SocketLimitRule: Validates socket occupancy
- RecipeConstraintRule: Enforces recipe-specific rules
- JointConsistencyRule: Ensures joint data integrity
Description Generation Pipeline
The description system is remarkably sophisticated:
- BodyPartDescriptionBuilder: Creates individual part descriptions
- DescriptionTemplate: Applies formatting strategies
- PartGroupingStrategies: Handles different grouping scenarios
- TextFormatter: Provides consistent text formatting
- BodyDescriptionComposer: Orchestrates the complete description
Strengths of the System
1. Modularity and Extensibility
Each component has a single, well-defined responsibility. New features can be added without modifying existing code.
2. Data-Driven Design
Anatomies are defined entirely in data, making it easy to add new creature types without code changes.
3. Robustness
Comprehensive validation, error handling, and rollback mechanisms ensure system reliability.
4. Performance Optimization
- Cached adjacency lists for efficient traversal
- Lazy description generation
- Batched entity operations
5. Developer Experience
- Clear service boundaries
- Extensive logging and debugging support
- Consistent error handling patterns
Expansion Opportunities
1. Dynamic Modification System
- Runtime part growth/shrinkage: Allow parts to change size dynamically
- Transformation support: Enable parts to transform into different types
- Damage modeling: Track part health and visual damage states
2. Advanced Constraints
- Symmetry requirements: Ensure paired parts match when needed
- Resource-based constraints: Limit total mass, magical capacity, etc.
- Environmental adaptations: Parts that change based on environment
3. Procedural Enhancement
- Mutation system: Random variations within constraints
- Evolutionary algorithms: Breed new anatomies from existing ones
- Machine learning integration: Learn optimal configurations
4. Visual Integration
- 3D model mapping: Connect anatomy graph to visual representations
- Animation constraints: Define movement limitations based on anatomy
- Procedural texturing: Generate textures based on part properties
5. Gameplay Systems
- Ability derivation: Generate abilities from anatomy (wings = flight)
- Weakness detection: Identify vulnerable points in anatomy
- Part-specific interactions: Different interactions per body part
6. Description Enhancement
- Contextual descriptions: Change based on observer perspective
- Emotional coloring: Descriptions that reflect entity state
- Cultural variations: Different description styles for different cultures
7. Performance Scaling
- Anatomy LOD (Level of Detail): Simplified anatomies for distant entities
- Streaming support: Load/unload anatomy data dynamically
- Parallel generation: Generate multiple anatomies concurrently
8. Tool Support
- Visual anatomy editor: GUI for creating blueprints and recipes
- Validation sandbox: Test recipes before deployment
- Analytics dashboard: Track anatomy generation patterns
Technical Implementation Details
Design Patterns in Action
The codebase demonstrates excellent use of software design patterns:
- Service Locator: Services are injected via constructor dependencies
- Facade:
AnatomyGenerationServiceprovides a simple interface to complex subsystems - Template Method: Validation rules follow a consistent pattern
- Composite: The anatomy graph itself is a composite structure
- Observer: Event system notifies interested parties of anatomy changes
Error Handling Philosophy
The system follows a “fail-fast” approach with comprehensive error information:
- Validation errors prevent invalid states
- Detailed error messages aid debugging
- Rollback mechanisms prevent partial states
- Event dispatching for error tracking
Extensibility Points
Key extension points for customization:
- Custom validation rules via the
ValidationRulebase class - New part grouping strategies via
PartGroupingStrategy - Custom formatters via the formatting service interface
- Additional graph algorithms via the graph service
Conclusion
The anatomy system represents a significant achievement in dynamic content generation. It successfully balances flexibility with consistency, performance with functionality, and simplicity with power. The modular architecture ensures the system can grow and adapt to new requirements while maintaining its core elegance.
The combination of graph-based structural representation, constraint-driven generation, and sophisticated natural language processing creates a system capable of generating virtually unlimited variety while maintaining narrative coherence and technical correctness.
As the Living Narrative Engine evolves, the anatomy system provides a solid foundation for increasingly complex and engaging entity interactions, opening doors to emergent gameplay and storytelling possibilities limited only by imagination.
Living Narrative Engine #6
How the process of developing a modular, data-driven anatomy system in my app is going:
Me: We’ve recently created a complex anatomy system that builds a graph of body parts from a recipe and a corresponding blueprint, as well as a myriad of entity definitions for body parts. The code is in @src/anatomy/ , while most of the data is in @data/mods/anatomy/ . As I was looking over the sockets for the human_female_torso.entity.json and the human_male_torso.entity.json , I noticed that while most sockets require concrete “allowedTypes” (e.g. “breast” for “left_chest” in a woman), the sockets for “penis”, “left_testicle”, “right_testicle”, “asshole”, and “vagina” require a “genital” “allowedTypes”. That is too broad; the system that matches fitting entities could slot a penis entity in the socket of a vagina, or a testicle entity in the socket for a penis. That’s obviously undesired behavior. I want you to change the allowed types to more specific subTypes (likely, a subType “penis” for the “penis” socket, and so on).
You will need to modify the entity definitions of human_penis.entity.json, human_testicle.entity.json, human_vagina.entity.json to change their subtype in “anatomy:part” appropriately.
Claude Code: I can see the issue clearly now. Looking at line 433-437, the validation checks if a part’s subType is included in the socket’s allowedTypes. Currently all genital parts have subType: “genital”, which matches the allowedTypes: [“genital”] on all genital sockets, allowing incorrect matches.
Plan to Fix Genital Socket Type Specificity
I’ve identified the issue: all genital parts (penis, testicle, vagina) have the same subType: “genital”, and all genital sockets accept allowedTypes: [“genital”]. This allows incorrect matches like a penis in a vagina socket.
Here’s what I’ll do:
1. Update torso entity files to use specific allowed types:
– human_female_torso.entity.json:
– vagina socket: allowedTypes: [“vagina”]
– asshole socket: allowedTypes: [“asshole”]
– human_male_torso.entity.json:
– penis socket: allowedTypes: [“penis”]
– left_testicle socket: allowedTypes: [“testicle”]
– right_testicle socket: allowedTypes: [“testicle”]
– asshole socket: allowedTypes: [“asshole”]
2. Update genital entity files to use specific subTypes:
– human_penis.entity.json: subType: “penis”
– human_testicle.entity.json: subType: “testicle”
– human_vagina.entity.json: subType: “vagina”
3. Note: There’s no separate entity for “asshole” – it’s integrated into the torso. If needed in the future, an asshole entity could be created with subType: “asshole”.
Me: I agree with your plan, except that I’m not sure what you mean that “there’s no separate entity for ‘asshole’ – it’s integrated into the torso”. Does the code or schemas allow for “integrated” body parts? I think the issue is that simply we need to create an entity definition for the subtype “asshole”.
Claude Code: I was mistaken. The anatomy system requires separate entities for all attachable parts. There’s no asshole entity definition. Both torsos have an “asshole” socket but no corresponding entity to attach to it.
You must be logged in to post a comment.