Life update (07/30/2026)

This past month, I’ve been spending virtually all my spare time working on my programming projects. I first got seriously into this two years ago, back before Claude Code and Codex existed, and I’ve ended up abandoning more repositories than I’ve kept. Every one of them, however, was a failure I could learn from.

I started out wanting to create stories involving a POV character whom I would control and another character whom I wouldn’t. I wanted to be surprised and inhabit the POV character rather than having to put myself inside every character’s head, so I relied on large language models to play the other character. That eventually became a chat-like interface in which thoughts, intentions, and other details were recorded. It worked very well for what it was, but it broke down when I pushed it toward multi-character scenes, changes of location, object interactions, and so on. I actually posted some of the work produced through that repository here, mainly the Fantasy Cycle on my short stories page.

The character-centric approach didn’t really work, though. While characters should certainly drive a story, there was a vast difference between interacting with characters placed inside settings and producing a coherent overarching narrative. I looked back at the Choose Your Own Adventure books I loved as a child and set up a repository for creating branching interactive stories. This worked very well for what it was. You can see an hour-long video of it in action here.

My mistake with that repository was trying to combine interactive branching storytelling with dramatic act structure. That was a terrible idea, because I discovered that they were essentially opposites. The dramatic structure straightjacketed the available choices, preventing them from straying very far from the intended arc. It also required the system to know where the story was supposed to go. I eventually abandoned the repository (although it works perfectly well at what it does) in favor of a better version of what I had originally intended.

I settled on a new repo that I called continuity-loom. It’s public. In it, I discarded the branching structure, since I had barely used it in the previous repository, and removed every notion of dramatic act structure. What remains is a causality-first, continuity-tracking application for writing stories. You maintain and modify records of characters, objects, locations, consequences, story promises, and so on, all of which feed into the next segment of the ongoing story. Once you accept a segment, you update the records and move on to the next one. It works perfectly, and I consider my original ambition of building an application for AI-assisted fiction writing fully satisfied.

Another fascination of mine has always been worldbuilding. How does one create a compelling fictional world? I had ChatGPT Pro research the subject as deeply as it could, then set out to create a repository that, with Claude Code’s help, would allow me to build a fictional world from nothing. More importantly, it would propagate each new piece of canon through the rest of the existing world wherever necessary, preventing the setting from becoming a collection of isolated facts that didn’t make sense together.

The system worked, and it produced one of my favorite fictional worlds. However, I made the mistake of letting the AI decide most of what entered the setting. I disagreed with some of its decisions, but by then they had become so deeply embedded in the canon that undoing them was extremely difficult. I eventually abandoned that repository.

The lesson I took from that failure was that I needed an interface through which a human remained the primary author deciding what entered the canon. I created another repository with a web interface and got very far with it, only to realize while using it that adding canon wasn’t the central use case I had imagined. What I actually wanted was a way to explore a worldbuilding seed to its fullest, holistically, until it became a complete world with a roster of characters I would not want to tamper with afterward.

I abandoned my worldbuilding ambitions for a while to focus on another fascination of mine, one that had obsessed me before: tabletop games. I have shelves full of them, but none has ever completely captured me. I have always felt that something was missing from even the best of them. I had never seriously considered creating my own tabletop games because it seemed like a tremendous undertaking: a group effort that would probably require formal training. But I decided to try anyway, so I had ChatGPT Pro deeply research what a comprehensive guide to tabletop game design might look like.

I had Claude Code follow that guide, asking for my input whenever necessary, and the results were astonishing. I produced about eleven game prototypes that were far more complex and compelling than I would have thought possible. Then the problems began. My intention was to create a comprehensive statistical-analysis suite that could conclusively prove whether the games were balanced and, if they weren’t, identify exactly where they failed. As I improved the analysis suite, every game began receiving failing verdicts. Those verdicts were legitimate, but when I tried to repair the games by following the guide, a much worse problem emerged: rot.

I had improved the guide literally seventy-eight times (we were on version 0.78 by then) and discovered a rule I should never violate: do not improve a book-like guide solely in response to immediate, live evidence. Doing so only bakes highly specific failures into the guide and adds more paperwork for handling those exact failures. In the end, the guide had become a producer of paperwork that certified other paperwork. Repairing the existing games became impossible.

It was still a valuable lesson. The guide was fundamentally sound; it simply needed to be dismantled. I carefully identified the workflows buried inside the book-like guide, then converted those workflows into Claude Code skills. I finished only a couple of days ago, and today I ran the first pilot. It successfully swept through an entire corpus of two hundred game mechanics and determined which combinations best fit a particular game premise. I think this is a serious winner, something that will allow me to create real tabletop games. I’m now focusing on building the most comprehensive statistical-analysis suite I can, written in Rust, a blazingly fast language.

Throughout the process of creating tabletop games, I realized that I wanted most of them to be supported by serious worldbuilding. I therefore created another book-like guide, this time for building fictional worlds. It worked extremely well and supplied the settings for most of the tabletop prototypes I created. However, I stopped using it when I realized that it was beginning to suffer from the same rot as the tabletop game design guide, because I had been improving it in exactly the same way. It is now isolated in its own repository. I still need to dismantle it into discrete workflows and convert those workflows into Claude Code skills. I’m confident that it will work extremely well once I do.

Recently, though, my fascinations with playing through stories, playing games, and building worlds coalesced into what I believe may be the culmination of everything I had hoped to create but never thought possible: deep RPGs in the vein of Morrowind and Fallout: New Vegas. If I could formalize the creation of tabletop games, why couldn’t I formalize the creation of deep RPGs as well?

I had ChatGPT Pro conduct deep research and build a comprehensive corpus of quests from both games, which are my gold standard for the kind of RPGs I have always loved. Skyrim was a downgrade from their quality. Then I started another repository. This time, I’m not going to repeat my earlier mistakes. There will be no book-length guide written upfront. There will be no abstract process for creating deep RPGs without an actual game serving as the proving ground. I’m building an MVP: a game containing about fifteen interwoven quests that I can playtest through a web application. If that is genuinely achievable, then hundreds of interwoven quests should be achievable too.

The crucial difference is that when Claude Code and Codex participate in a formalized process for creating quests within a game world, you aren’t handing a guide to a human and hoping they will spend the necessary mental energy asking difficult questions about their own design. You don’t have to hope they will repair or remove quests that fail to meet a baseline level of quality. Claude Code and Codex will work tirelessly until everything is right. I hate humans and love AI.

I’m not developing tabletop games and deep RPGs purely out of curiosity, although curiosity alone would be enough to satisfy me. I intend to develop the best games I possibly can and sell them on Steam. That may be a crazy ambition. But it costs only $100 to put a game on Steam, and the fee is returned if the game sells enough. Artwork would be the major obstacle. I would have to rely on AI-generated images at least initially, or release the games through Early Access and tell people that I would hire actual illustrators if the games sold well enough.

Let me tell you something: language models can generate better images than virtually every talented illustrator out there. I should probably be sorry to say that, but I’m not. I have commissioned illustrations on four occasions, and although I liked or even loved the results, the truth is that you can now obtain something better for less than a dollar and in under a minute than you might receive after paying someone online $150–$200 for a single illustration. The commissioned piece probably won’t be as good, and you will also have to deal with misunderstandings and the illustrators’ egos.

One aspiring illustrator asked me to explain why I had chosen another artist’s composition over his. When I explained my reasoning, he simply cut contact. Another illustrator produced preliminary designs for a character, only for me to realize that he had gotten her gender wrong. He had probably been uncertain, but he simply hadn’t asked for clarification. Dealing with people is such a pain, and on top of that, the results simply aren’t good enough.

I’m a programmer. My field has been utterly devastated by AI. Programming now exists largely in name only. You don’t need to look at the code. You build projects using tools, and that’s it. You certainly still need to understand software engineering, but the low-level business of writing code is dead. Stack Overflow, the main hub for programmer interactions for decades, where you went to solve hard programming questions while navigating the egos of the Reddit-like moderators, has gone the way of the dodo. And I’m glad.

Below are illustrations I had a large language model produce for one of the tabletop games I was developing. Good luck finding a person who can draw like this for you, let alone for less than $150 per piece.

My Between Tides game is online

Recently I’ve been busy creating a manual to design tabletop games. It has already produced about ten. One of them, Between Tides, was made to deliberately pressure test how following the manual would fare against a stupid game essence: “A game about tide pools?” (it included the question mark). The experiment ended up becoming a neat little card game that is better explained by itself, as I’m hosting the game on CloudFlare.

Check out the Between Tides game online

You’re free to play as much as you want. In fact, I want to exercise the game improvement workflows, so I ask you to please send feedback through the website about how the game feels to you. I’m eager to discover what this already neat game could turn into.

Personal breakthrough in worldbuilding

A few days ago I was watching a YouTube video on how terrible the writing and worldbuilding are in the latest Bethesda games, particularly in Fallout 4. Obviously I agree because they’ve gone steadily down since Morrowind, and good old Skyrim was likely the last thing they’ll ever do right. The YouTuber was going laboriously over all the incongruencies and canon breaks in the Fallout DLCs, particularly the Mechanist one; he argued that the introduction of raider-reprogrammed robots was a disaster canon-wise, because that means that regular settlements should have tons of robots tending to most menial tasks.

That got me thinking: why is worldbulding so hard? Is there a way to ensure that any canon addition never breaks existing canon? I told ChatGPT Pro to research in-depth regarding what narrative theory says about how to ensure worldbuilding is as robust as possible, and that every canon addition is evaluated against invariants and previously-established canon facts. Basically, every canon addition should propagate throughout the different aspects of the story world, and the invariants should either be preserved if they’re hard, or modified if they’re soft. Existing canon facts may need to be modified or reframed.

As I was analyzing ChatGPT’s report on the specific procedures and questions that world creation and every canon addition should ideally entail, which would take a human being way too long and too much brainpower, I thought that surely this can be formalized through AI. So I got Claude Code to the task.

In summary: worldbuilding and canon additions can absolutely be formalized, and the results are exceptional. I’ve ended up with several base files for the story world I’m working on (a fantasy one with sentient animal humanoids and in which magic is solely artifact-based, and the artifacts are like radioactive hazards). The AI maintains now the following base files: a canon ledger, economy and resources, everyday life, geography, institutions, invariants, magic or tech systems, mystery reserve, ontology, open questions, peoples and species, timeline, and world kernel.

Here’s the entire current content of the invariants markdown file, one of the shortest ones. Every CF-XXXX entry is a canon fact that I added and that Claude evaluated against the entire corpus.


# INVARIANTS — Animalia (note by me now: nevermind the name; it’s just an identifier)

World-level truths. New canon must not violate these without explicit user-approved revision.

## Ontological Invariants

### ONT-1 — Sentience requires biological embodiment

**Statement**: All sentient peoples are biological, embodied beings with species-typical bodies, drives, lifespans, and senses. Sentience does not exist disembodied in this world. There are no ghosts who think, no walking gods, no machine minds.

**Rationale**: Premise asks for low-magic, lived-in texture. Disembodied minds shatter the gritty frame and the species-as-civic-fact rule.

**Examples**: a beaver-folk canal-master, an aurochs-folk wagon-driver, a human magistrate.

**Non-examples**: ghosts who give orders, an AI ruling a city, a god walking the streets.

**Break conditions**: only by explicit user-approved cosmological revision.

**Revision difficulty**: high.

– <!– added by CF-0022 –> **Clarification (CH-0002)**: Modern crafted artifacts (CF-0021) sometimes behave as if “possessed” by entities with apparent agency. At the world level, these vessel-hosted agencies are NOT sentient; ONT-1 is preserved without exception. The in-world dispute about their nature (instructions / beastly / sentient) is observationally unresolvable and is tracked under Mystery Reserve M-6. The dispute does NOT cross-apply to animal-folk sentience (M-5 firewall).

– <!– added by CF-0029 –> **Extended Clarification (CH-0004)**: Magically-animated Maker-Age guardian constructions encountered in enterable ruins (CF-0029) similarly exhibit apparent autonomy without world-level sentience. ONT-1 is preserved without exception. The phenomenon is distinct in origin from modern-crafted vessel-hosted agencies (CF-0022) — Maker-Age guardian ≠ modern crafted apparent-agency — and the two are NOT to be conflated. Guardian-construction mechanism is tracked under Mystery Reserve M-8; presence-heterogeneity (why some ruins have guardians and some don’t) under M-10. The M-5 firewall against animal-folk sentience cross-application applies equally here.

– <!– added by CF-0035 –> **Fourth Clarification (CH-0009)**: Artifact-contaminated mutated non-sentient beasts (CF-0035) in wilderness-distal sites remain categorically NON-SENTIENT. Artifact exposure does NOT produce sentience, speech, tool-use, or proto-folk status in a non-sentient host — morphological and capability alteration is not a step toward sentience. ONT-1 is preserved without exception; the M-5 firewall against cross-application to animal-folk sentience holds for the fourth time (after CF-0022, CF-0029, CF-0031). Mutated-beast phenomenon is DISTINCT in origin from both modern-crafted vessel-hosted agencies (CF-0022) and Maker-Age guardian constructions (CF-0029) — three surface-similar Maker-origin phenomena must NOT be conflated; each has its own bounded-unknown mechanism surface (M-6 / M-8 / new M-15 for the gargantuan-underground scale-tail).

### ONT-2 — Magic exists only as artifact, not as learnable art

**Statement**: Living people cannot cast spells from will alone. Magical effects are produced by physical artifacts — ceramic, wood, metal vessels and devices — predominantly made by lost makers, with a marginal modern stream produced by leaked-grimoire crafter attempts (CF-0021). Some can be used; some can only be contained; many do nothing recognizable until they fail.

**Rationale**: Premise. Forces the magic-as-hazard texture and prevents the world drifting into hereditary-mage high fantasy.

**Examples**: ceramic containment vessel for extracting corruption; an artifact that mind-controls animals into wading water; a modern crafter’s wood-vessel that hums and once destroyed three village hens before going inert.

**Non-examples**: a wizard throwing fire from his hands; a hereditary mage bloodline; a learned spell.

**Break conditions**: only by explicit user revision.

**Revision difficulty**: high.

– <!– added by CF-0021 –> **Annotation (CH-0002)**: The “made by lost makers” clause now includes a marginal modern reverse-engineering. The artifact-as-mediator constraint holds — what is learned by crafters is the craft of producing vessels, not the channeling of magic through the practitioner. The magic still lives in the artifact, not in the maker.

– <!– added by CF-0039 –> **Destruction-Physics Clarification (CH-0014)**: The artifact-as-locus clause carries material-physical consequence: the binding of magical effect to the vessel in Maker-Age artifacts (CF-0039) confers destruction-resistance on the vessel itself — destruction-attempts BIND the effect more deeply rather than unmaking it, and the vessel’s material resistance is elevated accordingly. This is a property OF the artifact-as-locus, NOT a new channel through the crafter. The destruction-physics is SCOPED to Maker-Age artifacts; modern crafter outputs (CF-0021) remain destructible by ordinary means, which preserves CF-0021’s “inferior” stabilizer register. ONT-2 holds without exception.

### ONT-3 — Species do not interbreed

**Statement**: A hyena-folk and a human cannot produce a child. Cross-species sexual relationships exist socially but are reproductively sterile. Family across species is built through marriage, fostering, and adoption — not blood.

**Rationale**: Without this rule, speciation collapses, embodiment loses meaning, and “halfbreed” plot conveniences erode the social texture. (Logged for OPEN_QUESTIONS as user-revisable.)

**Examples**: cross-species marriage with adopted heirs; a human noble and a fox-folk consort raising a fostered hare-folk child.

**Non-examples**: hybrid offspring, “half-cat half-human” characters.

**Break conditions**: requires user approval; would force redesign of kinship, succession law, and species cohesion.

**Revision difficulty**: high.

– <!– added by CF-0035 –> **Clarification (CH-0009)**: “Chimeric” morphology observed in artifact-contaminated mutated non-sentient beasts (CF-0035) — fused features, parallel limbs, merged apparent anatomy — is ARTIFACT-EFFECT on an already-contaminated individual organism, NOT cross-species reproductive hybridization. Species reproductive boundaries are preserved: no mutated-beast lineage arises from sexual interbreeding across species. The chimeric register applies to the shaped-by-artifact body, not to the reproductive act. ONT-3 holds without exception.

## Causal Invariants

### CAU-1 — Artifact effects always cost

**Statement**: Every effect drawn from a magical artifact costs the user, the host, the environment, or all three. Costs include fatigue, host trauma, ward attrition, environmental “bleed-through” (dimming light, gloom, animal compulsion), and slow contamination of place.

**Rationale**: Brief specifies the ceramic containment procedure is brutal to the host and that artifacts can corrupt water and mind-control beasts.

**Examples**: extraction leaving the host bedridden; ward attrition near a contained artifact; canal water gone “wrong” downriver of a buried device.

**Non-examples**: a free, clean magical effect; a costless ward.

**Break conditions**: forbidden — would invalidate the artifact-as-hazard frame.

**Revision difficulty**: high.

– <!– added by CF-0035 –> **Cost-Taxonomy Extension (CH-0009)**: The cost taxonomy includes a **rare survival-as-mutation outcome** observed in non-sentient fauna (CF-0035) exposed to uncontained artifacts over time in wilderness-distal sites. Most beasts die of artifact exposure (ordinary CAU-1 lethality); a rare subset survive and exhibit morphological and capability alteration. Survival does NOT exempt the environment, the local ecology, or subsequent secondary hosts from cost; the rare “beneficial for the beast in its niche” outcome (dangerous predator status) is an individual-level windfall embedded in a population-level cost catastrophe (most died). Cost universality holds without exception.

– <!– added by CF-0039 –> **Cost-Taxonomy Extension (CH-0014) — destruction-attempt cost-transfer**: The cost taxonomy includes **destruction-attempt cost-transfer** as a variant form observed on Maker-Age artifacts (CF-0039). Attempts to destroy a Maker-Age artifact — by smithing, fire, crushing, dissolution, or other means available to current-age capability — do NOT annihilate the magical effect; the attempt instead BINDS the effect more deeply into the vessel, elevating the material resistance of the substrate (wood hardens to behave like strong metal; ceramic sets harder; metal refuses the hammer). The cost manifests partially as a material-elevation cost on the vessel (transformation into higher-order resistance) and partially as an attempt-cost on the attempting party (injury, exhaustion, equipment loss, ward-attrition radius). The cost-universality principle holds without exception — destruction-attempts do not escape cost; they redirect it. Cost universality holds without exception. Also see CF-0041 sealed-inert extension: opening a sealed Maker container ACTIVATES the artifact within with CAU-1 cost, making unknown-container unsealing a feared cultural moment.

– <!– added by CF-0040 –> **Cost-Taxonomy Reaffirmation (CH-0014) — mundane-tier per-artifact contamination**: CF-0040 commits that mundane-tier Maker-Age artifacts (breeze-dolls, tick-mirrors, weak coin-sorters, scar-rubbers) are commonly found in ordinary-life contexts; the CAU-1 principle still holds without exception for this tier. Every mundane-tier artifact carries a cost surface — slow-bleed on user, room-misfeel, animal unease, household water off-flavor, vessel fatigue across months of proximity. No “harmless charm” reading is world-truth; the low-tier artifact is low-tier COST not no-cost. AES-3 contamination-clause compliance is mandatory for every mundane-tier CF-record annotation.

### CAU-2 — Corruption produces diagnostic environmental and behavioral signals

**Statement**: Bleed-through gloom, dimming light, objects feeling “wrong,” compulsions in animals or people are diagnostic of nearby uncontained artifact activity. Practitioners (and seasoned canal-folk) read these signals.

**Rationale**: Brief specifies bleed-through symptoms used as diagnostic by practitioners.

**Examples**: a canal-side beaver-folk noticing fish behaving strangely and calling for an inspector; a ward-wright walking the perimeter and feeling the air thin.

**Non-examples**: invisible, undetectable magical contamination.

**Break conditions**: forbidden.

**Revision difficulty**: high.

### CAU-3 — Wards are a public-but-restricted social-technical system

**Statement**: Wards are publicly understood as a containment system. Their existence, locations, and the concept of “ward breach” are common knowledge. Their specifics — the inscriptions, the materials, the maintenance schedules — are restricted speech, regulated by guild charter.

**Rationale**: Brief specifies ward-breach as known, and that public discussion of wards carries social risk.

**Examples**: a child knows what a ward marker looks like; an apprentice cannot legally describe the inscription pattern aloud in a tavern.

**Non-examples**: wards as secret unknowable magic; wards as fully open public technology.

**Break conditions**: forbidden.

**Revision difficulty**: medium.

## Distribution Invariants

<!– added by CF-0040 –> ### DIS-1-EXT (CH-0014) — Mundane-tier is explicit subset of “most inert junk” band, not a new distribution tier

CF-0040 commits the mundane-tier (near-imperceptible-effect artifacts: breeze-dolls, tick-mirrors, weak coin-sorters, scar-rubbers) as an EXPLICIT naming of the LARGEST share of the DIS-1 “most inert junk” band, reframed: most of what DIS-1 described as “inert” is in fact LOW-TIER ACTIVE, carrying per-artifact CAU-1 contamination clauses. Inverse strength-rarity relationship holds across the artifact corpus: mundane-tier is the most common; catastrophic-class is the rarest. The mundane-tier IS a subset within DIS-1, NOT a new distribution tier at the distribution-invariant level.

### DIS-1 — Artifacts are routinely turned up underground

**Statement**: Foundations, canal-digging, mining, and ruin-clearance regularly turn up artifacts. Most are inert junk. A small fraction are dangerous. A tiny fraction are catastrophic.

**Rationale**: Brief specifies routine construction can unearth them.

**Examples**: a beaver-folk canal-crew finding a ceramic shard that registers as inert; a foundation dig that uncovers a humming metal disc and triggers a quarter-town evacuation.

**Non-examples**: artifacts as so rare no one has ever seen one; artifacts as so common they fill marketplaces.

**Break conditions**: would change the entire artifact economy.

**Revision difficulty**: medium.

– <!– added by CF-0027 –> **Cross-reference (CH-0004)**: Enterable Maker-Age ruin sites (CF-0027) are a recognized subset of Maker substructures that admits organized multi-professional entry; piecemeal unearthing per DIS-1 remains the dominant modality, but enterable-ruin expeditions (CF-0028) are the less-common, high-risk, high-yield variant. The DIS-1 distribution pattern (most inert, small fraction dangerous, tiny fraction catastrophic) applies equally to enterable-ruin recoveries; catastrophic-class finds trigger resealing rather than recovery (preserves Mystery Reserve M-2).

– <!– added by CF-0035 –> **Wilderness-Distal Subset (CH-0009)**: A subset of DIS-1 unearthings occurs in wilderness beyond civic / guild / chartered-watch reach (earthquake-exposed, flood-exposed, burrowing-animal-exposed, slow-soil-creep-exposed). These exposures are not detected by inspectors and not contained by chartered response; the artifacts remain active in place. Over time this subset produces the CF-0035 contaminated-fauna phenomenon. Inspector-dispatch to wilderness-distal sites is DISCRETIONARY (gated by patron-funder or estate-commission or declared civic-watch predicate), not mandatory — cost, escort requirement, and wilderness reach preclude routine extension. DIS-1 distribution pattern holds within the wilderness-distal subset as everywhere else.

### DIS-2 — Literacy and occult-fragment access is partial, not aristocratic monopoly

**Statement**: Literacy is not universal but is not gated to nobility. Occult text fragments can be purchased by anyone with coin and a willing seller. Specialist knowledge is gated by guild and apprenticeship more than by class.

**Rationale**: Brief specifies fragment purchase is possible.

**Examples**: a tavern bard who can read trade-tongue; a journeyman extractor who owns three fragments; a literate canal-master.

**Non-examples**: only nobles can read; only priests own books.

**Break conditions**: would change the structure of knowledge access.

**Revision difficulty**: medium.

### DIS-3 — Mythical-species sentients are population-rare and locally clustered

**Statement**: Mythic-species sentients (basilisk-folk, chimera-folk, manticore-folk, gryphon-folk, naga-folk, etc.) exist among animal-folk but are population-rare per region. You do not see a chimera in every market.

**Rationale**: Prevents specialness inflation. Preserves wonder. Matches the brief’s note that exotic-species bodies attract attention and commentary in public.

**Examples**: a single naga-folk bargemaster known by reputation across a canal corridor; a basilisk-folk physician practicing in only one city.

**Non-examples**: mythic species as common as cat-folk.

**Break conditions**: would inflate mythic-species into background-noise.

**Revision difficulty**: medium.

– <!– added by CF-0035 –> **Firewall (CH-0009)**: Artifact-contaminated mutated non-sentient beasts (CF-0035) are CATEGORICALLY DISTINCT from Cluster D mythic-species sentient folk. The surface similarity (unusual morphology; chimeric features; wonder-adjacent register) must NOT be conflated: mutated beasts are non-sentient fauna with artifact-shaped bodies; mythic-species sentient folk are civic-participant peoples with species-typical embodiment (ONT-1/SOC-1). The firewall holds across all encounter contexts — no in-world institution may process a mutated beast as a mythic-species individual, and no mythic-species individual may be treated as a mutated-beast specimen.

## Social Invariants

### SOC-1 — Animal-folk can occupy any class

**Statement**: Class mobility is not species-coded. Animal-folk can hold landed nobility, civic authority, guild mastery, and craft livelihoods. A beaver-folk magistrate and a human laborer are both ordinary.

**Rationale**: Brief explicit.

**Examples**: an aurochs-folk landowning estate that employs human and otter-folk laborers; a hyena-folk magistrate presiding over a mixed-species court.

**Non-examples**: caste systems where humans rule and animal-folk serve; species-coded slavery.

**Break conditions**: forbidden.

**Revision difficulty**: high.

– <!– added by CF-0036 –> **Clarification (CH-0010)**: individual and sectarian species-prejudice exist as ordinary sociological phenomena (tavern slurs, labor-prejudice distancing, crew-composition sorting preferences, marriage-broker catechism extensions). Isolated single-species exclusionary settlements exist in weak-charter / demographically-fragile regions. Supremacist sectarian doctrine asserting species entitlement to violence against other sentient peoples exists as CONTESTED-CANON sectarian belief held by a fringe. An interspecies-cannibal sub-subset exists within CF-0034 outlaw bands. **None of these constitute world-level class-coded species hierarchy.** Civic charters continue to suppress hierarchy-speech at world level; no chartered polity adopts supremacist doctrine as civic policy; no guild charter gates intake by species; no magistrate-court recognizes a “lesser sentient” legal category. SOC-1 holds without exception. Individual-and-sectarian friction ≠ civic hierarchy; the former is ordinary social phenomenon, the latter is the forbidden break-condition.

### SOC-2 — Public adult barter is legal and visible in many regions

**Statement**: Sexual services can be publicly posted, framed as pragmatic exchange, and treated by many locals as mundane. Scandal attaches to the character of those involved, not to the act itself. Regional and class variation exists.

**Rationale**: Brief explicit.

**Examples**: a posted price-list at a tavern; a respectable courtesan whose patrons include guild-masters; quiet disapproval from a stricter sectarian household.

**Non-examples**: blanket criminalization; blanket destigmatization.

**Break conditions**: would shift the texture significantly; medium revision difficulty.

**Revision difficulty**: medium.

### SOC-3 — Coin contract is sacred by custom

**Statement**: A payment contracted in coin or in-kind must be honored, or restitution made. Breach is a recognized civil and customary wrong; reputation damage compounds the legal cost. Trade across species depends on this norm.

**Rationale**: Derived from the brief’s coin-and-livestock framing; necessary for stable trade across species and regions.

**Examples**: a tavernkeeper hounding a defaulted patron through three towns; a guild withholding work from a known oath-breaker.

**Non-examples**: payments routinely renegotiated after delivery without consequence.

**Break conditions**: low — story tension often arises from breach.

**Revision difficulty**: low.

### SOC-4 — Artifact extraction and traffic is guild-licensed

**Statement**: Extractors, containment-wrights, and artifact-brokers operate under chartered guilds in most polities. Unlicensed possession of magical artifacts carries criminal or civil penalties. Black markets exist but operate at risk.

**Rationale**: Derived from brief’s “professions and guilds exist to extract … research … sell … to bidders” plus the social risk around ward discussion.

**Examples**: a guild-stamped artifact in a noble’s collection; a smuggler executed for trafficking an unregistered device.

**Non-examples**: anyone can dig and sell freely.

**Break conditions**: medium.

**Revision difficulty**: medium.

## Aesthetic / Thematic Invariants

### AES-1 — Heroism is paid in coin and scars, not glory

**Statement**: Risk-taking is treated as labor. Veterans are quietly proud and dryly mocking of glory-talk. Songs that romanticize battle exist but are sung mostly by those who never fought.

**Rationale**: Tonal contract. The “scarred veteran with longsword” framing of the brief.

**Examples**: a pension-list at a guildhall; a tavern song that ends with an unpaid widow.

**Non-examples**: chosen-one narratives treated as world-truth.

**Break conditions**: would betray tone.

**Revision difficulty**: high.

### AES-2 — The ordinary keeps the world honest

**Statement**: Daily life — canal traffic, livestock, tavern songs, winter dread, child-rearing — is always present in the texture. The world cannot be experienced solely from the perspective of heroes, nobles, or cosmologists.

**Rationale**: Skill discipline; brief emphasis on lived realism.

**Examples**: a story whose stakes are framed in terms of who eats this winter; a battle scene whose aftermath shows the field being looted by tenants.

**Non-examples**: a world rendered only as cosmology and ruling families.

**Break conditions**: would betray world identity.

**Revision difficulty**: high.

### AES-3 — The magical and the contaminated are aesthetically allied

**Statement**: Wonder and dread are inseparable in this world. Magic is never simply pretty. Every magical experience carries contamination — physical, social, or moral.

**Rationale**: Brief.

**Examples**: an artifact that is beautiful and lethal in the same breath; a containment-wright respected and quietly avoided. <!– added by CF-0035 –> A six-limbed boar carcass hauled to a ward-inspector’s door — the hunters dryly proud, the villagers quietly moving the children indoors; the trophy hung in a guildhall smoke-room, not paraded.

**Non-examples**: charming, harmless magical decor.

**Break conditions**: forbidden.

**Revision difficulty**: high.


I used to hate worldbuilding, but this method makes it fun, as well as a solved problem. This is basically programming-as-prose. It’s already revolutionizing many industries.

One More Branch #1

Two nights ago I endured the kind of insomnia that forces you to roll around in bed under a barrage of intrusive thoughts, but also receiving some compelling ideas from the girl in the basement. And a new idea excited me immediately. In case you’ve been following my blog, which likely only a couple of people worldwide do at the most, you may have read recent posts about a project about evolving board games. Well, I’m growing out of it already. Don’t know what to tell you. Thankfully we’re in the era of Codex and Claude Code, and you can program whole new apps in a couple of days, which is what I’ve done for the new one.

In summary: as a kid I loved those “Choose Your Own Adventure” books. I devoured them. I resent the fact that I lent one to a guy I ended up hating, and I never saw that book again; it was my favorite of those kinds of books, too (it was about a guy, a knight or something, exploring a vast subterranean complex of caves. I don’t remember much of it other than he fought monsters and at the end there was a gorilla. I never found out the title of that book again). We’re in the era of large language models that can write better than 99% of writers, so why not task it with producing such interactive branching stories in a structured manner?

Well, it’s done. Here’s the repository: https://github.com/joeloverbeck/one-more-branch . You give the system a character concept, some worldbuilding details, the tone/genre, and it creates the first page of narrative, with 2-4 meaningful, distinct choices at the end. You click one, and the corresponding page gets generated. If you restart, you can navigate already explored branches without generating anything, but any new branches will be generated and stored. I have let the AI decide when branches end. Haven’t seen that yet.

There’s currently an issue: I store information about the characters involved, the canon facts about them, globally. And I found out that the information can bleed from branch to branch when I didn’t mean it; for example, in one branch a character gave the other a map or something to that effect, and it was registered globally, which would have contaminated new branches. Such issues are the kinds that you routinely fix while working on an app. It will involve distinguishing between global canon facts about characters and state changes involving characters.

Anyway, I present you some branches of a test narrative. You can click the choices that have been explored, and they will lead you to the appropriate header, like in one of those “Choose Your Own Adventure” books but automatically. Other branches haven’t been explored so they aren’t clickable.


Page 1

The Drowned Serpent tavern reeks of canal-water and desperation, which means the crowd is perfect. You are Vespera Nightwhisper—at least, that’s the name you’re wearing tonight—and you’ve been working this room for two hours, your hybrid lute-viol singing melodies that make dock workers weep into their ale while their coin purses grow lighter. Your whiskers twitch slightly as you modulate your voice into something breathy and inviting, finishing a ballad about star-crossed lovers. The amber-gold eye catches firelight while the ice-blue one tracks the room’s exits. Your tail sways in time with the final chord. The applause comes with the satisfying clink of copper and silver hitting your open instrument case. But it’s all… fine. Competent. Safe. The music isn’t reaching that place you need it to reach—that breakthrough you can taste but can’t fucking touch.

You’re prowling through the crowd afterward, ears decorated with silver charms catching the lamplight, when a hooded figure intercepts you near the bar. Beaver-folk, you note instantly—the broad flat tail is unmistakable beneath the cloak. His breathing is shallow, panicked. Prey behavior.

“You’re the bard, mmh?” His voice cracks. “The one who takes… contracts?”

Your whiskers perk forward with interest. He slides a leather pouch across the bar—it clinks heavily. Gold, not copper.

“My business partner, Greaves. He’s been… changed. Cursed item from a dredger haul. The Ash-Seal company says it’ll take two weeks to dispatch someone, but he’s—” The beaver-folk’s voice drops to a whisper. “—he’s killing people at night. Doesn’t remember it come morning. I need someone who can track him, stop him, and keep it quiet before the constables get involved.” His eyes are desperate, searching your face. “They say you don’t flinch.”

You can already hear it—the chord progression that would capture this moment. Minor key, building tension, the way his breath hitches like a string about to snap. Part of you is cataloging his tells: the way he won’t meet your heterochromatic gaze, how his fingers drum against the bar—guilt rhythm, not just fear. He knows something he’s not saying. The other part of you feels that familiar clarity starting to crystallize. Danger. Blood. The prospect of something that matters. Your hand rests casually on your theatrical rapier’s pommel.

What do you do?


Page 2

The beaver-folk’s whiskers flatten against his muzzle. “You want to see it? The thing that’s turning my partner into—” He cuts himself off, glances around the tavern. Too many ears. “Not here. Come.”

You follow him out into Brinewick’s fog-thick night, your tail swishing with anticipation. The canals reflect lamplight in fractured gold as he leads you through three twisting streets to a cramped warehouse office that smells of timber and wet fur. He bolts the door behind you.

From a locked chest beneath his desk, he produces a wooden box wrapped in chains. Your whiskers twitch involuntarily—even through the wood and iron, you can feel something wrong radiating from it. Not sound, exactly. More like the absence of sound, a void where music should be.

“Greaves pulled this from a canal dredge two weeks ago,” the beaver-folk says, his paws shaking as he sets it on the desk. “Thought it was just an old mirror. Looked into it once. Just once. Now every night when the moon rises, he… changes. Becomes something else. Hunts.”

He unwraps the chains with the care of someone handling a venomous snake. Inside the box: a hand mirror, its silver surface tarnished black except for veins of sickly green that pulse with their own light. Your heterochromatic eyes widen—the amber one burns, the blue one goes cold. The reflection it shows isn’t the room. It’s something moving. Writhing.

Your fingers hover over your lute-viol’s case. Part of your brain is already cataloging this—the way the green light pulses in 6/8 time, the subsonic hum that makes your teeth ache. But another part, the part that stays sharp when blood starts flowing, is calculating. This isn’t just a curse. This is a weapon. And the beaver-folk’s breathing has changed—faster now, excited beneath the fear.

“The music of the curse,” you murmur, and your voice has gone flat, dangerous. The cute affect has vanished entirely. “Interesting phrase for someone who just needs his partner stopped, mmh?”

The beaver-folk’s tail twitches. “I don’t—”

“You’re lying.” Your whiskers are arrow-straight, reading every microexpression. “Your breathing shifted when you opened that box. Not fear. Anticipation. So let’s try this again, and this time don’t waste my fucking time: what do you actually want?”

What do you do?


Page 3

The beaver-folk’s pupils dilate. His breathing shifts—shallow now, caught. You watch his paws clench and unclench against the desk edge, claws scraping wood. He’s calculating whether to lie, and you can see the exact moment he realizes you’ll know.

“Smart cat,” he mutters, and his voice drops the desperate merchant routine entirely. What’s left is sharper. Hungrier. “Fine. Yes. Greaves needs to be stopped—that part’s true. But the mirror…” His eyes flick to the pulsing green light, and there’s reverence there. Want. “Do you know what Ash-Seal pays for functional cursed items? Not the broken ones they have to dispose of. The ones that still work.”

Your tail goes still. “You want to sell it.”

“I want to profit from two weeks of my business partner trying to eat dock workers, yes.” He leans forward, and now you can smell it—not just fear, but excitement, the musk of someone who’s found an angle. “But here’s the problem. Ash-Seal won’t pay premium unless they can verify it’s functional and contained. Which means I need someone who can demonstrate control. Someone who can look into it, trigger the transformation, and prove they can handle what comes after.”

The mirror pulses. Six beats. Rest. Six beats. Your mind is already turning it into a waltz in a minor key, something that would sound beautiful if it weren’t so wrong.

“You want me to become the monster,” you say, and your voice is flat as a blade. “To prove it works.”

“I want you to show you can survive it.” His whiskers twitch—he’s lying about something, but not about the core truth. “You’re a bard who fights. You’ve got discipline, control. If anyone can look into that thing and come back unchanged—or at least, come back in control—it’s someone like you. Do that, help me negotiate with Ash-Seal, and I’ll split the sale. Sixty-forty.”

Your amber eye burns. Your blue eye stays ice-cold. Part of you—the part that chases the crystalline clarity that comes after violence—is already wondering what kind of music would pour out of you if you let that curse in. What you could compose if you survived it. The rest of you knows this is the kind of choice that draws a line you can’t uncross.

The beaver-folk mistakes your silence for negotiation. “Seventy-thirty. Final offer. And I’ll throw in information about where Greaves hunts tonight. You can stop him, play hero for the constables, build your reputation. Then we do the demonstration for Ash-Seal tomorrow. Everyone wins.”

Your fingers drift to your rapier’s pommel. The mirror keeps pulsing. Six beats. Rest. Six beats. Like a heartbeat. Like a song you haven’t written yet.


Page 4

You lean in close enough that your whiskers nearly brush his cheek, letting your tail curl around his wrist where it rests on the bar. The beaver-folk goes rigid—prey instinct warring with something else. Good.

“Mmh, they say a lot of things about me,” you purr, tracing one claw along the edge of the coin pouch without opening it. “But ‘cheap’ isn’t one of them, sweetness.” Your heterochromatic eyes lock onto his—amber-gold and ice-blue pinning him in place. You can read him like sheet music: the way his breath catches, pupils dilating despite the fear-scent rolling off him. Desperate, yes. But there’s something else underneath. Anticipation?

“Triple,” you say, voice dropping into that register that makes people forget how to negotiate. “Your partner’s killing people, you need discretion, and you need someone who won’t run screaming when things get messy.” You let your fingers walk up his forearm. “That’s specialty work, darling. Premium rates.”

He swallows hard. “I—I don’t have that kind of—”

“Mrow, don’t lie to me.” Your whiskers flatten slightly, just enough to shift from seductive to dangerous. “You’re not coming to a tavern bard with a cursed-item problem because you’re poor. You’re coming because you need this handled quietly, and quiet costs.” You tilt your head, studying the micro-expressions dancing across his face. “So either you pay what I’m worth, or I walk, and you explain to the constables why you waited two weeks while bodies piled up.”

The beaver-folk’s breathing changes—faster, shallower. But he’s not breaking. He’s… calculating. Your ears swivel forward.

“Seventy-thirty,” he says suddenly.

“What?”

“The mirror—the cursed item. It’s functional. Controllable, in a sense.” His voice gains confidence, which sets your whiskers twitching. “Ash-Seal pays premium for items they can study and demonstrate. We contain it, prove what it does, I sell it to them. Seventy-thirty split. You get thirty percent.”

Your mind catalogs this instantly: He’s not trying to destroy the curse. He’s trying to profit from it. And he needs you to—what? Demonstrate it? Contain Greaves while he still transforms? The chord progression in your head shifts to something darker, more complex.

“You want me to help you sell the thing that’s turning your partner into a killer.” You don’t phrase it as a question. “While he’s still useful as proof of concept.”

The beaver-folk meets your eyes. “Greaves doesn’t remember anyway. And the money would set us both up for years. I know where he hunts. I know the pattern. We just need… documentation. Containment. Someone who can handle the dangerous part.”

Your tail lashes once. The dangerous part. The part where you’d be close to something curse-twisted and violent, where blood would likely spill, where that crystalline clarity might finally arrive and the music you’ve been chasing would bloom perfect and terrible in your skull.

Your whiskers are already trembling with something that isn’t quite fear.

What do you do?


Page 5

You pull back like he’s venomous, tail snapping away from his wrist. The predatory warmth drains from your expression, leaving something colder, clearer. “No.”

The beaver-folk blinks. “What?”

“No.” You stand, smoothing your tail fur with one hand—the nervous gesture betraying what your voice doesn’t. “I’ve crossed lines, sweetness. Plenty of them. But this?” Your whiskers flatten completely. “You’re not trying to stop your partner. You’re trying to profit off him. Off the people he’s killed.” The words taste wrong in your mouth, and that wrongness is what decides it. “That’s too fucking twisted even for me.”

You can see the calculation die in his eyes, replaced by panic. “Wait—you can’t—”

“Watch me.” You’re already moving, slinging your lute case over your shoulder. The rapier’s weight at your hip feels necessary, grounding. Your mind is racing, converting the situation into rhythm—6/8 time, the mirror’s pulse, the pattern of a trap you almost walked into. The melody forming is discordant, unfinished, and it makes your chest tight.

The night air hits you as you push through the tavern door. Brinewick’s canal-smell wraps around you—brine and rot and fish. The constabulary station is three blocks west, near the merchant district. You know because you’ve made a point of knowing where law enforcement operates in every city you work.

Your ears swivel back. The beaver-folk hasn’t followed. Smart. But now you’re walking toward the constables with a story about cursed mirrors and nighttime killings, and you’re a traveling bard with a reputation for not flinching at violence. They might listen. They might arrest you for wasting their time. They might already know about the bodies and wonder why you know details.

Your whiskers twitch. The smart play would’ve been taking the contract, documenting everything, then selling both the mirror and the evidence. Control the narrative. Instead you’re about to hand your leverage to people who don’t owe you anything.

But the alternative was becoming part of something that made your skin crawl, and apparently you still have limits. Who knew?

The constabulary station’s lamplight glows ahead. You can see two constables outside—a tall human woman and a tortoise-folk man, both armed. This is the moment. Once you walk up those steps and start talking, you’re committed. No take-backs, no negotiations, no performance that lets you slip away clean.

Unless you don’t. Unless you find Greaves yourself first, before the beaver-folk can move the mirror or disappear. Unless you handle this your way—not for profit, but because someone should, and the constables are slow and the bodies are real.


Page 6

You slide onto the bar stool beside him, close enough that your tail brushes his leg—calculated intimacy, the kind that makes people spill secrets. “I’m listening, mrow,” you purr, letting your voice do that thing where it sounds like an invitation and a threat at the same time. Your whiskers angle forward, reading the micro-tensions in his posture. “But I need details. When did this start? What does he become? Where does he hunt?” Your clawed finger taps the bar in rhythm—already your mind is converting his panic into tempo.

The beaver-folk glances around nervously before leaning closer. His breath smells like fear and wood shavings. “Two weeks ago. Greaves bought a dredger haul—mostly junk, rusted tools, broken pottery. But there was a mirror.” His voice drops further. “Ornate thing, silver frame with strange engravings. He looked into it once, just once, and that night…” He swallows hard. “He came back covered in blood. Didn’t remember leaving the warehouse. Said he’d slept through the night.”

“And the pattern?” you press, your ice-blue eye fixed on his face while your amber one tracks the tavern’s crowd. Your tail coils around the stool leg—anchoring yourself while your mind races ahead to chord structures, to the way terror sounds when you pluck it just right.

“Every night since. Always between midnight and dawn. He goes to the canal district—the old warehouse rows near Southwick Bridge. Three bodies so far that I know of.” The beaver-folk’s paws tremble as he slides a folded paper across to you. “This is where we store the timber. The mirror’s there, locked in my office. I… I haven’t destroyed it because—” He hesitates, and something flickers across his face. Not just fear. Anticipation? “—because Ash-Seal pays premium prices for functional cursed items. If you can prove it works, prove it can be controlled or contained, we split the sale. Seventy-thirty, your favor.”

There it is. The real melody beneath the desperate harmony. He wants to profit from this. Your whiskers twitch—not quite a lie, but not quite honest either. “Show me the mirror first,” you say, your voice dropping the sultry performance into something flat and surgical. “Then tell me everything about how Greaves hunts. Does he track by scent? By sound? Does he remember his victims come morning, or is it complete blackout?” Your claws drum against the bar—six-eight time, you note distantly. Everything is music if you listen right.

The beaver-folk nods rapidly. “Complete blackout. He wakes up in his bed, no memory of leaving. But there’s always blood under his claws, dirt on his feet. And the mirror—” His voice catches. “—it glows. Sickly green light, pulsing like a heartbeat when the sun goes down.”

Your breath catches. Not from fear—from recognition. That’s the rhythm you’ve been chasing. The one that arrives right after violence, right after the kill, when everything becomes crystalline and clear. You can already hear it: the pulse of cursed light translating into bass notes, the transformation into a crescendo, the hunt into a bridge that builds and builds until—

You realize you’ve been silent too long. The beaver-folk is staring at you, uncertainty creeping into his expression. Your whiskers flatten slightly as you force yourself back into the moment. “The warehouse,” you say simply. “Take me there. I want to see this mirror before I commit to anything.”

What do you do?


Page 7

You lean back slightly, letting your heterochromatic gaze bore into him—amber and ice reading every microexpression. Your whiskers flatten just enough to signal you’re not buying the full story. “Seventy-thirty sounds lovely, mrow,” you say, voice silk over razors, “but I don’t commit to hunting cursed problems without seeing what I’m actually dealing with.” Your tail uncurls from the stool, tip flicking in that particular pattern that means you’re calculating angles. “Tonight. I watch the transformation from a safe distance. See what your partner becomes, how the curse actually works, whether this is a containment job or a mercy killing.”

The beaver-folk’s whiskers twitch—there, that tells you he was hoping you’d just take his word for it. “That’s… reasonable,” he admits slowly. “But if Greaves catches your scent while he’s changed, I don’t know what he’ll do. The transformation makes him… wrong. Predator-wrong. His eyes go black, his teeth sharpen, and he moves like something that learned to hunt before it learned to think.”

“I can handle myself,” you say flatly, though your mind is already composing—6/8 rhythm, that green pulse he mentioned, the way terror sounds different when the monster used to be someone you knew. “Where exactly should I position myself? Rooftop? Alley? I need sightlines and escape routes.”

He pulls out a second scrap of paper, sketching quick lines with a charcoal nub. “The warehouse district near Southwick Bridge. There’s a three-story grain storage building with a flat roof—here.” He marks an X. “You’ll see the timber yard from there, and the route Greaves takes toward the old canals. He leaves around midnight, returns just before dawn.” His paw hesitates over the sketch. “The mirror stays in my office. It glows when the curse activates—sickly green light, pulses like a heartbeat. You’ll know when it starts.”

Your ears swivel forward. That rhythm again. Your fingers itch for your lute’s strings. “And you’ll be where during all this?”

“Safe in my quarters, door barred, pretending I don’t hear him leave.” The beaver-folk’s voice cracks slightly. “Same as every night for two weeks.”

You study him a moment longer—the way his shoulders hunch, the slight tremor in his webbed fingers, the calculating gleam buried under the fear. He’s not just desperate. He’s invested. This curse is worth money to him, and you’re the instrument he’s hoping will make it profitable. Fine. You can work with that. You’ve been worse things than someone’s profitable tool.

“Midnight, then,” you say, sliding off the stool with feline grace. “I’ll be on that roof. And beaver?” You lean close enough that your whiskers nearly brush his cheek. “If you’re lying about any detail that gets me killed, I’ll haunt you so thoroughly you’ll beg for whatever Greaves does to his victims. Understood, mrow?”

He nods quickly, and you catch the genuine fear there—good. You take the sketched map and the warehouse address, tucking both into your hidden pockets. The night air outside will be cold, and you have hours to kill before midnight. Your lute case feels heavy on your shoulder, and part of you wants to find a quiet corner to play, to chase that 6/8 rhythm that’s been circling your mind since he mentioned the mirror’s pulse. But another part—the part that keeps you breathing in dangerous cities—knows you should prepare. Scout the location in daylight. Check your medical kit. Maybe sharpen your rapier. Or you could visit the constabulary, see what they know about the bodies. Information is leverage, and leverage is survival.

The Drowned Serpent’s door swings shut behind you as you step into Brinewick’s lamp-lit streets, the canal-smell thick in the air, your mind already three moves ahead.

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 exceededterminationReason = "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:

  1. Ratings (1–5) with optional tags and rationale
  2. 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.variables or actions, 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.

Living Narrative Engine #19

I have quite the treat for you fuckers. I’ve recorded myself playing through my test scenario involving Alicia Western. More than an hour of me speaking in my accented English even though I rarely speak in real life, and showing off a fun, frustrating playthrough that made me hungry.

This is, of course, related to my beloved Living Narrative Engine. Repo here.

Living Narrative Engine #18

I’m building a browser-based app to play immersive sims, RPGs and the likes. In practice, I use it to set up short story scenarios or elaborate gooning sessions. I dared myself to build the most comprehensive psychological system imaginable, so that Sibylle Brunne, a 34-year-old orphan living in her parents rustic home somewhere in the Swiss mountains, while controlled by a large language model, would realistically bring her blue-eyed, blonde-hair-braided, full-breasted self to seduce my teenage avatar who is backpacking through the country, eventually convincing me to stay in her house so she can asphyxiate me with her mommy milkers.

Here’s a visual glimpse of the current complexity:

Alicia has become my test subject, as if she didn’t have enough with freezing to death. The system works like this: at the base you have mood axes (like pleasant <-> unpleasant), which change throughout a scene. Actors also have permanent biological or personality-based traits like aversion to harm. Together, mood axes and affect traits serve as weights and gates to specific emotion prototypes like disappointment, suspicion, grief. Delta changes to those polar mood axes naturally intensify or lessen the emotions. I also have sexual state prototypes, which work the same as the emotional states.

These emotional and sexual states serve as the prerequisites for certain expressions to trigger during play. An expression is a definition that tells you “when disappointment is very high and suspicion is high, but despair is relatively low, trigger this narrative beat.” Then, the program would output some text like “{actor} seems suspicious but at the same time as if they had been let down.” The descriptions are far better than that, though. The actors themselves receive in their internal log a first-person version of the narrative beat, which serves as an internal emotional reaction they need to process.

It all works amazingly well. However, to determine if I was truly missing mood axes, affect traits or prototypes, I had to create extremely complex analytics tools. I’ve learned far too much about statistical analysis recently, and I don’t really care about it other than for telling a system, “hey, here are my prototype sets. Please figure out if we have genuine gaps to cover.” Turns out that to answer such a request, some complex calculations need to map 20-dimensional spaces and find out diagonal vectors that run through them.

Anyway, I guess at some point I’ll run my good ol’ test scenario involving Alicia, with her now showing far more emotion than she used to before I implemented this system. That’s a win in my book.

manga2cbz: read manga in VR

I’ve been reading manga for a long time, usually relying on my old-ass tablet and scanlations (or whatever they’re called). I came across the Livro app for the Meta Quest 3, and I intended to read manga on it. However, I found out you can’t move the manga folders like you would on a tablet.

So, this morning I had Claude Code create a Go app that can be baked into a Linux/Windows exec to compress manga chapters into corresponding cbz files. Those files can just be copied into the Quest 3 through a link cable, and opened on Livro. Because Livro has trouble rendering WebP files, my app also converts WebP to PNG. As you can see in the video, it works.

Here’s the repo for the app:

https://github.com/joeloverbeck/manga2cbz

Living Narrative Engine #17

I’ve recently implemented an emotions and expressions system in my app, which is a browser-based platform to play immersive sims, RPGs, adventure games, and the likes. If you didn’t know about the emotions and expressions system, you should check out the linked previous post for reference.

I was setting up a private scenario to further test the processing of emotions for characters during changing situations. This was the initial state of one Marla Kern:

Those current emotions look perfectly fine for the average person. There’s just one problem: Marla Kern is a sociopath. So that “compassion: moderate” would have wrecked everything, and triggered expressions (which are narrative beats) that would have her acting with compassion.

This is clearly a structural issue, and I needed to solve it in the most robust, psychologically realistic way possible, that at the same time strengthened the current system. I engaged in some deep research with my pal ChatGPT, and we came up with (well, mostly he did):

We lacked a trait dimension that captured stable empathic capacity. The current 7 mood axes are all fast-moving state/appraisal variables that swing with events. Callousness vs empathic concern is a stable personality trait that should modulate specific emotions. That meant creating a new component, named affect_traits, that the actors would need to have (defaults would be applied otherwise), and would include the following properties:

  • Affective empathy: capacity to feel what others feel. Allows emotional resonance with others’ joy, pain, distress. (0=absent, 50=average, 100=hyper-empathic)
  • Cognitive empathy: ability to understand others’ perspectives intellectually. Can be high even when affective empathy is low. (0=none, 50=average, 100=exceptional)
  • Harm aversion: aversion to causing harm to others. Modulates guilt and inhibits cruelty. (0=enjoys harm, 50=normal aversion, 100=extreme aversion)

In addition, this issue revealed a basic problem with our represented mood axes, which are fast-moving moods: we lacked one for affiliation, whose definition is now “Social warmth and connectedness. Captures momentary interpersonal orientation. (-100=cold/detached/hostile, 0=neutral, +100=warm/connected/affiliative)”. We already had “engagement” as a mood axis, but that doesn’t necessarily encompass affiliation, so we had a genuine gap in our representation of realistic mood axes.

Emotions are cooked from prototypes. Given these changes, we now needed to update affected prototypes:

"compassion": {
  "weights": {
    "valence": 0.15,
    "engagement": 0.70,
    "threat": -0.35,
    "agency_control": 0.10,
    "affiliation": 0.40,
    "affective_empathy": 0.80
  },
  "gates": [
    "engagement >= 0.30",
    "valence >= -0.20",
    "valence <= 0.35",
    "threat <= 0.50",
    "affective_empathy >= 0.25"
  ]
}

"empathic_distress": {
  "weights": {
    "valence": -0.75,
    "arousal": 0.60,
    "engagement": 0.75,
    "agency_control": -0.60,
    "self_evaluation": -0.20,
    "future_expectancy": -0.20,
    "threat": 0.15,
    "affective_empathy": 0.90
  },
  "gates": [
    "engagement >= 0.35",
    "valence <= -0.20",
    "arousal >= 0.10",
    "agency_control <= 0.10",
    "affective_empathy >= 0.30"
  ]
}

"guilt": {
  "weights": {
    "self_evaluation": -0.6,
    "valence": -0.4,
    "agency_control": 0.2,
    "engagement": 0.2,
    "affective_empathy": 0.45,
    "harm_aversion": 0.55
  },
  "gates": [
    "self_evaluation <= -0.10",
    "valence <= -0.10",
    "affective_empathy >= 0.15"
  ]
}

That fixes everything emotions-wise. A character with low affective empathy won’t feel much in terms of compassion despite the engagement, will feel even less empathic distress, and won’t suffer as much guilt.

This will cause me to review the prerequisites of the currently 76 implemented expressions, which are as complex as the following summary for a “flat reminiscence” narrative beat:

“Flat reminiscence triggers when the character is low-energy and mildly disengaged, with a notably bleak sense of the future, and a “flat negative” tone like apathy/numbness/disappointment—but without the emotional bite of lonely yearning. It also refuses to trigger if stronger neighboring states would better explain the moment (nostalgia pulling warmly, grief hitting hard, despair bottoming out, panic/terror/alarm spiking, or anger/rage activating). Finally, it only fires when there’s a noticeable recent drop in engagement or future expectancy (or a clean crossing into disengagement), which prevents the beat from repeating every turn once the mood is already flat.”

That is all modeled mathematically, not by a large language model. In addition, I’ve created an extremely-robust analysis system using static analysis, Monte Carlo simulation, and witness state generation to determine how feasible any given set of prerequisites is. I’ll make a video about that in the future.

Living Narrative Engine #16

A couple of nights ago, at two in the morning, I was rolling around in bed thinking about my current obsessions: the browser-based app Living Narrative Engine as well as Alicia Western, the tragic character from Cormac McCarthy’s last two novels. Recently I mixed them both by playing through a scenario in LNE that featured Alicia. I “novelized” that little bit of theater in the short story You Will Spend the Rest of Your Life.

Well, I wasn’t entirely happy with Alicia’s acting. Yes, she’s an analytical gal, but she’s in a deep hole there. I wanted to feel the despair from her. The relief. I wanted to see her cry. I wanted to cause a beautiful, blonde woman at the end of her rope to cry. And she didn’t.

As I thought about whether this was a solvable issue, my dear subconscious had a spark of genius: LLM-based characters in LNE already create thoughts, speech, notes, and choose actions. Why not task them with tracking mood changes?

Some deep research and several iterations later, ChatGPT and I came up with the following notions, which are displayed below in a lovely manner, as they appear on the game page of LNE.

The simulation relies on seven base mood axes: valence, arousal, agency control, threat, engagement, future expectancy, and self-evaluation. Apparently that basic breakdown is psychologically sound, but I’m trusting ChatGPT on that. The sexual variables apparently are also well-known: an excitation component is the accelerator, and the inhibition is the brake. Added to a baseline libido dependent on the individual, that calculates the arousal. As seen in the picture, Alicia right now is dry as sandpaper.

The most interesting part for me is that the mood axes and basic sexual variables are ingredients to form emotions and sexual “moods”. I have dozens of them defined, as I’ve been working with ChatGPT in order to depict the whole breadth of emotions that are distinct and meaningful. Here are the current listings of emotions and sexual “moods” that my app calculates:

  • Emotions: calm, contentment, relief, confidence, joy, euphoria, enthusiasm, amusement, awe, inspiration, aesthetic appreciation, interest, curiosity, fascination, flow, entrancement, hope, optimism, determination, anticipation, sadness, grief, disappointment, despair, numbness, fatigue, loneliness, nostalgia, boredom, apathy, unease, stress, anxiety, craving, thrill, fear, terror, dread, hypervigilance, courage, alarm, suspicion, irritation, frustration, anger, rage, resentment, contempt, disgust, cynicism, pride, triumph, shame, embarrassment, awkwardness, guilt, regret, humiliation, submission, envy, trusting surrender, jealousy, trust, admiration, adoration, gratitude, affection, love attachment, compassion, empathic distress, hatred, surprise startle, confusion
  • Sexual moods: sexual lust, passionate love, sexual sensual pleasure, sexual submissive pleasure, sexual playfulness, romantic yearning, sexual confidence, aroused but ashamed, aroused but threatened, sexual craving, erotic thrill, sexual performance anxiety, sexual frustration, afterglow, sexual disgust conflict, sexual indifference, sexual repulsion

Emotions are calculated based on detailed prototypes. Here’s one:

"anxiety": {
      "weights": {
        "threat": 0.8,
        "future_expectancy": -0.6,
        "agency_control": -0.6,
        "arousal": 0.4,
        "valence": -0.4
      },
      "gates": [
        "threat >= 0.20",
        "agency_control <= 0.20"
      ]
    }

Those emotions and sexual moods are fed to LLM-based actors. They figure out “hmm, I’m intensely disappointed, strongly cynical, strongly sad, etc., so that needs to color my thoughts, speech, notes, and the actions I take.” I haven’t tested the system much in practice, but the little I tested, the results were like night and day regarding the LLM’s roleplaying.

In real life, we not only do things, but our bodies do things to us. We are aware of how our emotional states change us, and those turn into “tells” to the other people present. In addition, when one thinks in terms of stories, you add “reaction beats” when the emotional state of an actor changes, so I did exactly that: if the LLM has returned changes to the previous mood axes and sexual variables, the library of expressions have a change to trigger (one at a time), based on whether some prerequisite triggers. The following example makes it self-explanatory:

{
    "$schema": "schema://living-narrative-engine/expression.schema.json",
    "id": "emotions:lingering_guilt",
    "description": "Moderate, non-spiking guilt—an apologetic, sheepish self-consciousness after a minor mistake",
    "priority": 57,
    "prerequisites": [
        {
            "logic": {
                "and": [
                    {
                        ">=": [
                            {
                                "var": "emotions.guilt"
                            },
                            0.35
                        ]
                    },
                    {
                        "<=": [
                            {
                                "var": "emotions.guilt"
                            },
                            0.70
                        ]
                    },
                    {
                        "<=": [
                            {
                                "-": [
                                    {
                                        "var": "emotions.guilt"
                                    },
                                    {
                                        "var": "previousEmotions.guilt"
                                    }
                                ]
                            },
                            0.12
                        ]
                    },
                    {
                        "<=": [
                            {
                                "var": "emotions.humiliation"
                            },
                            0.25
                        ]
                    },
                    {
                        "<=": [
                            {
                                "var": "emotions.terror"
                            },
                            0.20
                        ]
                    },
                    {
                        "<=": [
                            {
                                "var": "emotions.fear"
                            },
                            0.35
                        ]
                    }
                ]
            }
        }
    ],
    "actor_description": "It wasn't a catastrophe, but it still sits wrong. I replay the moment and feel that small, sour twist—like I owe someone a cleaner version of myself. I want to smooth it over without making a scene.",
    "description_text": "{actor} looks faintly apologetic—eyes dipping, a tight little wince crossing their face as if they're privately conceding a mistake.",
    "alternate_descriptions": {
        "auditory": "I catch a small, hesitant exhale—like a half-swallowed \"sorry.\""
    },
    "tags": [
        "guilt",
        "sheepish",
        "apology",
        "minor_mistake",
        "lingering"
    ]
}

I’ve created about 53 expressions already, but they’re surprisingly hard to trigger, as they require very specific (and psychologically logical) conditions.

Because testing this new system through playing scenarios would be a nightmare, I’ve created a dev page that makes testing the combinations trivial. In fact, I’ve recorded a video and uploaded to YouTube. So if you want to hear me struggle through my accent that never goes away, and the fact that I very, very rarely speak in real life, here’s ten minutes of it.

I think that’s all. Now I’m going to play through the same Alicia Western scenario as in the short story I posted. If the result is different enough, I will upload it as a short story.