I DM a weekly steampunk campaign, so I built the table we play on. A live combat engine, an AI story co-writer, a map builder, and a player companion everyone opens on their own phone, all synced over websockets. One Express server, one SQLite file, zero subscriptions.
Combat is where most VTTs fall apart, so CogForge treats it as one unified screen: initiative order, a token-based battle grid with fog of war, the active combatant's full action economy (action / bonus / reaction), spell-effect zones, hazards, conditions, and a combat log. All of it live at once. Damage buttons, custom attacks, advantage/disadvantage rolls, and concentration tracking are one click from the active turn panel.
Every character gets a private join link (/player/<token>) that opens a full companion app on the player's phone or laptop. It's not a mirror of the DM screen, it's the player's own surface: their sheet, their actions, their inventory, and a live scene view of the battle map where they drag their token to move. Every HP change, condition, and turn advance the DM makes is pushed instantly over Socket.IO. Both apps share the same appearance settings, so the table and the phones all run the same brass-and-ember theme.




The same app reshapes itself for the phone in your hand at the table: bottom tabs, a thumb-sized action bar, and the same live scene.
This is the part I show people first. The clip below is one continuous sequence: the DM applies damage to the wizard, the engine demands a concentration save on the spot, and then we cut to the player's phone — where the next hit lands live. HP drops, and the concentration check shows up on the player's screen with their own roll button. Nobody refreshes anything. The server validates each action over REST, then broadcasts converged state to every connected view.
And here are both ends of the websocket in the same frame. The DM clicks once on the left; the player's HP bar and concentration prompt land on the right in the same instant.
Spells are first-class data, not text fields. A 106-spell library carries casting time, range, components, duration, school, save ability, damage type, and concentration, ritual, and upcast flags. Casting from the player companion walks slots by level, logs every cast to a cast_log table, and places persistent area effects: a Cloud of Daggers occupies real cells on the battle grid in a spell_zones table until it ends.
Concentration is enforced, not suggested. Casting a second concentration spell drops the first. Taking damage while concentrating triggers a save at DC 10 or half the damage, whichever is higher — and the prompt goes to whoever needs to roll it, on their own screen. Dropping to 0 HP clears concentration automatically, and every success and failure lands in the combat log.


The story engine models a campaign as a graph of beats: taken paths, planned branches, and skipped forks. Not a linear outline. When players inevitably go off script, the Improvise button branches an improvised beat off the current one in two clicks, and the AI quick-moves ("next beat", "fork the path") generate where it leads. The AI Arc Builder goes further: describe the story you want, pick a length (3 to 10 beats) and detail depth, and it generates the full arc with linked NPCs and enemies for every beat.


The map library holds grid-based battle maps with per-map fog of war, sizes up to 40×30, and a tile editor for building new ones. The same AI pipeline that writes story beats also creates game content on demand: describe "a massive owlbear matriarch protecting her nest" and the generator returns a complete stat block with abilities, attacks, tactics, and loot, straight into the campaign database. Characters, NPCs, enemies, items, and spells can all be created this way mid-session.


Here's the editor doing real work: a new 50×40 map from the creation wizard, floor filled, walls and a water channel laid down, then brass pipework, gearworks, and iron grates painted in. Tools have single-key shortcuts, every stroke autosaves, and the same map is immediately playable in an encounter — fog of war, lighting, and token movement included.
After the feature set grew, the UI had sprawled to 21 tabs. Rather than guess at fixes, I ran three structured audits scoring the product on profitability, feature completeness, and ease of use, then built a ranked roadmap where issues flagged by multiple audits got priority. The result: 21 tabs collapsed into 5 task-based modes with browser-style split tabs, four combat panels merged into one screen, and a guided character creation wizard.
Measured result: the combined audit score rose from a 151 baseline to ~274/300, with feature completeness reaching 93/100. Every change is logged against the roadmap with before/after scores.