Audamir

part 30

How Audamir Is Put Together: Layers, Registration, One Move and Seats

A map of the whole game: a realm uses its games and a game uses the core. How one move travels, who answers for a seat, what holds it together, and what is still debt, with today's numbers.

· updated 6 November 2026 · 23 min read

Audamir started as one game with dice and territories. Today it has four games in two realms: dice and territories, with the campaign built on them, in Kastgard, and Colony with Lines in Rokgard; besides these there are two more realms in which there is no game yet. Each building has its own article: on the contract between a realm and a game, see From one game, more games; on moving Kastgard into its own folder, A move that must change nothing; on the building kit for boards, Two Games on One Board; and on texts and file names, Texts as trees (forthcoming article no. 38). This article is a map of the whole: how the pieces hold together today, where they meet and, above all, what holds them, so that a change which breaks the rules trips the check and not the player.

It answers a question that can be asked of any foreign project: how is such a game put together, so that modes and worlds can be added without rewriting, and how is that guarded (and not only drawn)? The pictures are not illustrations. They are drawn from measuring the game's tree (version 0.122.0, state of 6 November 2026) and from code that was read; where a picture is only a scheme, the caption under it says so. The basis was the architecture scheme of 29 October. It is a week older than the game, so every claim below is checked against today's code; where the scheme differs from today, the text says so.

This is my decision of 27 and 28 October 2026 on the direction of the rules. For this article today's code was read, the tools of the game were run, and it was tried what breaks them.

Three layers and one rule of direction

Four words recur below. A package is a folder of code with a list of its files (today nine packages and 338 files in js/). A realm is what the player sees: a card on the home screen, a hub with tiles, its own level and its own coins. A game is a set of rules with its own board, AI and record (in the code, a "ruleset"): stacks, campaign, colony, chains. The core (core) is what everyone uses: the random generator, the grid, the profile, the realm manager and the app's shell.

The rule of direction fits into one sentence: a realm uses its games, a game uses the core, and the core uses nobody. A game does not use its own realm, and realms do not use each other. The one exceptional relation is a game that builds on another game of its realm (campaign builds on stacks).

Layers of the Audamir game by the dependency graphScheme of the nine packages of code. Four realms are at the top: Kastgard (17 files), Rokgard (21), Vitgard (12) and Telgard (12). Below them are the games: in Kastgard stacks (81) and campaign (41), in Rokgard colony (19) and lines (20); Vitgard and Telgard do not have a game yet. At the bottom is the core with its 115 files. The black arrows show the direction in which a package may be used: a realm its games, a game the core. The red arrows go against the direction: files of the core that the packages above them use. Of 1,370 edges, 95 are in 21 files, most of them 59 into stacks and 24 into campaign.realmsgamecoreKastgard17Rokgard21Vitgard12Telgard12stacks81campaign41colony19lines20nogamenogamecoreshared core and application shell · 115 fileslibrary 35 · screens 44 · data 23 · texts 1359242111may use: realm its games, game the coreagainst the direction; the number = edges from the corerealm where there is no game yetIn all 95 of 1 370 edges in 21 files.88 drawn, 7 more: core → Kastgard 2, → Rokgard 1, stacks → campaign 4.
Nine packages and the edges between them, from the analysis of the tool tools/packages.js of the game (version 0.122.0, 6 Nov 2026). The number in the frame is the count of the files of the package. The red arrows are edges that go against the direction; the number is their count from the core into the package.

In Kastgard there are two games (stacks has 81 files, campaign 41), and in Rokgard two (colony with 19 and chains with 20; in the game they are called Colony and Lines). Vitgard and Telgard have 12 files each, three of code and nine of texts. They have no game, so the player does not see them: the home screen and the hubs are drawn only for realms that have at least one game (DESIGN §104.3).

The second thing in the picture is red, and the rule "the core does not know the game" does not hold entirely today. The tool tools/packages.js counts an edge when a file uses a global value that a file of another package defines. It looks for names in the code without comments and texts, names in the module list, and files named through require or importScripts. There are 1,370 edges, and 95 of them go against the direction, in 21 files: 59 from the core into stacks, 24 into campaign, 8 into the other packages and 4 from stacks into campaign. The reason lies in what the core is today. It is not only a library (35 files in js/core/) but also the app's shell (44 files in js/ui/): js/ui/app.js alone has 3,124 lines and 40 of those edges, and all of js/ui/ has 64. In js/data/ there are 9 more edges and in the library itself 18, in six files. A typical case is modetable.js: the table of modes loads before the realm manager, so it has to know which mode tables exist.

So the guard of the direction is not one hard "nothing" but two rules. Seven of the nine packages (both Rokgard games, its realm, Vitgard, Telgard, the realm Kastgard and campaign) are clean: any edge against the direction makes the check fail. Two (core and stacks) have a ratchet: the table in the file tools/packages-table.json writes, for each file, how many edges against the direction it may have. More is not allowed; fewer can be written (--lower-ratchet), and then the number does not rise again. Both rules were tried on a copy of the game's tree (git archive; the game itself was not changed). A line that reaches into Rules from stacks was added to game.js in Colony:

$ node tools/packages.js --check
direction: 1371 edges between the files of js/,
  96 break the rule (…)
  FAIL rokgard/colony -> kastgard/stacks:
    js/realms/rokgard/games/colony/core/game.js
    -> js/realms/kastgard/games/stacks/core/rules.js
    (Rules)
rokgard/colony: does NOT pass (…)
packages:check found a problem in 1 place.
(exit code 1; the lines are broken and shortened)

A name from the dice engine was added into a core file that already has one edge (js/core/phase.js). A clean package would fail at once; here the ratchet failed:

ratchet: 1 problem
  - ratchet: js/core/phase.js has 2 edges that
    break the direction, the table allows 1
    (…/stacks/core/ai.js, …/stacks/core/engine.js)
packages:check found a problem in 1 place.
(exit code 1; the lines are broken and shortened)

Why this is not mere decoration is shown by the next picture: what happened to the ratchet while the code grew.

Ratchet of the direction: edges against the direction and the number of files over timeTwo charts from 29 October to 5 November 2026. Top: the number of edges that go against the direction in which the packages may be used; it fell from 120 to 95 (on 31 Oct the campaign left the application shell, to 105; on 1 Nov the statistics to 94; on 4 Nov the challenge of the page added one). Bottom: the number of code files in the table of packages grew from 187 to 338.edges against the direction05010012031 Oct 120 → 1051 Nov 105 → 944 Nov 94 → 95code files in the table of packages010020030018733830 Oct1 Nov3 Nov5 Nov95 edges in 21 files. Files grew 1.8 times; edges not above 120 since 29 Oct.
The sum of ratchet and the number of files in the table of packages at every commit that changed tools/packages-table.json (29 Oct to 5 Nov 2026), read from the git history of the game. The first entry of the ratchet was on 29 Oct at 23:30.

The first entry was 120 edges (29 October). While the number of files grew from 187 to 338, the edges fell to 105 (31 October, when the campaign left the app's shell), to 94 (1 November, when the statistics moved from the core into the package of Kastgard), and on 4 November rose by one, when the challenge of the page was merged (js/ui/app.js 39 → 40). The increase is written in the table, so it is in the history. The rule can be relaxed, but only visibly.

Registration at start: clean data and one manager

When the page loads, each package writes clean data and functions; nothing is run yet. This is the manifest of the realm (its name, games, modes, tiles, level and coin), the game adapter (one frozen object that points to the code of the game: how it starts, what its cycle is, its record, AI and the facts of a finished game), a section (a game that builds on another) and the content that the game adds to shared lists: minigames, puzzles, lessons and tips. The picture shows who writes what; it is a search for the calls Realms.register( and others in the files of the packages.

What each package writes when it loadsA table of eight packages and what they write into the registers when the scripts load: the manifest of a realm (Kastgard, Rokgard, Vitgard, Telgard), the adapter of a game (stacks, colony, lines), the section (campaign), the level and the currency of a realm (four realms) and the content (campaign adds 5 minigames, 23 puzzles, 1 lesson and 15 tips). Below the table is the realm manager with five steps: assembly, requires, sections, extends, start(ctx). The home screen, the hubs of tiles, the games in progress (from the slots of the modes) and the windows of the pages, such as statistics and rules, are then drawn from the registers.manifestrealmadaptergamesectionleveland coincontentKastgardstackscampaign5 minigames23 puzzles1 lesson, 15 tipsRokgardcolonylinesVitgardTelgardso far only data, functionsrealm managerjs/core/realms.js: knows no gameassemblyrequiressectionsextendsstart(ctx)if one realm fails, only it does not start, the others runscreens drawn from registershomescreen:realm cardhubs:tilesof modesin progress:slotsof modeswindows:statistics,rulesA new game mode is a row in the table of modes of its realm.A new game and a new realm still touch the shared places (text).
What each package writes when it loads: a search for the calls Realms.register(, Rulesets.register(, Realms.registerSection( and Economy.register( in the files of the packages (game 0.122.0, 6 Nov 2026); the content of the campaign is counted from its modules. The manager and the screens are a scheme drawn from the code.

A real example is Rokgard. Its manifest names the games the realm plays, the adapter of each game registers itself at the end of its file ruleset.js, and a mode is one entry of the table in modes.js. The excerpts are shortened and broken:

// js/realms/rokgard/data/realm.js (shortened)
const manifest = {
  id: 'rokgard', name: 'Rokgard',
  rulesets: ['colony', 'chains'],
  // …
};
Realms.register(manifest, api);

// js/realms/rokgard/games/colony/core/ruleset.js
return Rulesets.register(adapter);

// js/realms/rokgard/data/modes.js: Colony (shortened)
{
  id: 'colony', ruleset: 'colony', tile: 'colony',
  slot: 'colony', counts: ['history', 'realms'],
  end: { branch: 'colony', card: 'colony' },
  again: 'colony-again', back: 'colony-setup',
  restart: { how: 'confirm', start: 'same-setup' },
  hud: { tips: false, narrator: false, quips: false },
},

The realm manager (js/core/realms.js, 998 lines) then reads the assembly (Build.realms; the assembly may, for example, leave out the campaign section), checks the manifests and what the realms attach to one another (requires, extends), sorts them by their dependencies and calls start(ctx). A realm sees only its ctx (its own part of the profile, the generator, the texts, the sound), never another realm. If an exception happens in one realm or its time runs out, only that realm fails and the others keep running. And, above all, it knows no game: a test reads its code without comments and fails any change that would name a realm, a game or a module of a game in it.

The screens are then drawn from the registers: the home screen makes a card from each realm that has a game, the hub draws its tiles from the table of its modes, the list of games in progress is the list of mode slots (Principalities[1], Tribes, free play, the daily challenge and others), and the windows of statistics, rules or settings are assembled from what the realm registers (pages).

The promise "a new mode needs no line in the wrapper" holds only halfway. A mode is a line of the table (slot, end card, the "again" and "back" buttons, what the HUD may show), and the screens read the table, so a mode that plays the same game as the others is only data. But the line of the mode Colony names handler functions (colony-again, colony-setup), and those are defined by the wrapper (for example 'chains-again': () => ChainsView.again() in js/ui/app.js). A new game always touches the wrapper. The table in DESIGN §104.5 of 31 October lists 20 registration places, and 13 of them are in files that every game edits (for example index.html, sw.js, the realm's line in modetable.js, lines in js/ui/app.js). Even a rough count shows it today: Lines stand in index.html on 13 lines (the screen and ten scripts), in sw.js on 5, in tools/compat.html on 4 and in style.css on 8. When Lines were built it was 91 lines in 14 files of the wrapper (DESIGN §80.6). Registration therefore shrank them, but did not remove them.

One move from a tap to the picture

The way of one move in the dice game, from one tap on a square. On the left the input goes down, on the right the picture goes up.

One move from a tap to the pictureScheme of two columns. On the left the input goes from top to bottom: BoardInput turns a touch into a tap event, the controller of the game Interaction.tap chooses the attacker and the target, Flow.humanAttack lets the rules check the move, writes it into the record and makes it; the rules and the engine evaluate the roll from the state of the game and a new state arises. On the right the picture goes from bottom to top: the hooks of Flow announce the change, StacksBoard.view makes a description of one moment of the board, and the renderer draws it onto the canvas. Below these are two boxes: the record and the replay of events, and the end of the game with the facts of the game.input: top to bottompicture: bottom to topBoardInputtouch or click → eventtap { cell }coreInteraction.tapdice controller: picksthe attacker and the targetcoreFlow.humanAttackrules check the move, recordwrites it, the move is madegameRules + Enginedice roll from the stateand a new state of the gamegamecanvaspicture on the screenrenderer of the boarddraws the board description,calls no rules, reads no gamecoreStacksBoard.viewdescription of one moment:what is on which squaregamehooks of FlowonAttackEnd, onState:the app redrawsgamethen, from the same state and recordrecord → eventsReplay.run replays decisions:replay, picture, music,analysis read the same eventsgameend of the gamefacts(): result, length, score→ XP, coins, achievements(so far only Colony, Lines)gamecorepackage core (library and the application shell)gamepackage of the game kastgard/stacks
The way of one move in the dice game: a scheme of the code, not a measurement. The names are read in the code of the game 0.122.0 (6 Nov 2026); the package of each box is taken from tools/packages-table.json (core, or the game kastgard/stacks).

The input goes down. A touch or a click is caught by BoardInput (140 lines, js/ui/board-input.js). It tells a tap from a drag (up to six pixels it is a tap), from a pinch with two fingers and from a wheel, and sends the event tap with the number of the square. It does not know which game is running: it sends the event to the controller of the game, which the wrapper gives it. In the dice game that controller is Interaction.tap (js/ui/interaction.js). It knows that first an attacker is chosen and then a target, and that on touch the move is confirmed by a second tap if the setting asks for it. Then it calls Flow.humanAttack(from, to). Flow checks the move with the rules (the square must belong to seat 0 and the attack must be allowed), writes it into the record and performs it: the roll of the dice is computed from the state of the game, and Engine.resolveAttack makes a new state from it. Colony and Lines have their own controller (ColonyView, ChainsView) and their own game cycle, which answers to the same names, so the shared parts of the screen (the status line, the buttons) do not know which of them is running.

The picture goes up. When an attack ends, Flow calls the hooks of the wrapper (onAttackEnd, onState) and the wrapper redraws. The view of the board is made by StacksBoard.view(game, ui) (122 lines, js/realms/kastgard/games/stacks/ui/board.js): a description of one moment of the board, that is what stands on which square (the owner, the stack of dice, the terrain), which chances are shown on the edges, and which squares will still take a die. It is pure and only reads; a test runs it over a frozen copy of the game in every state of the collection of scenes that are drawn, and checks that the game did not change. The renderer js/ui/board.js (577 lines) draws that description. It calls no rules and reads no game. Colony and Lines have their own description of the board; the renderer is shared.

A state is a function of three things. A game is the setting, the number of the game (the seed) and the decisions. That is why the record of format 2 (A game record that can be replayed (forthcoming article no. 51)) needs to store nothing but the decisions of each seat, and Replay.run plays it again from them: the map is made from the seed, and Flow plays with the decisions from the record. From the game comes a stream of events (start, an attack with a path from one square to another, round, over). The replay player reads them through BoardEvents (338 lines, js/core/board-events.js: the verbs act and set, that is who did what and how the content of the squares changed). The picture of the game, the music and the analysis read them straight from the Replay stream. None of them changes the game; the narrator only observes as well (The first three minutes and the first weeks).

The end of a game is so far split into two ways. The game adapter can issue facts(game, ctx): the result, the length, the seat of the human, the level of the AI and the score. recordBoard in js/ui/app.js makes from them a line of the history, experience, coins and achievements of the realm, but only for Colony and Lines. The dice game has its own path in showEnd. Its facts exists, and a test compares it with the old path (on twelve golden records and 32 games from 16 setups, even the profile byte for byte, DESIGN §53.3 of 27 October), but nothing reads it.

Seats: who answers "what is your move?"

Each seat at the table answers the cycle of the game with the same question: what is your move? The answer differs only by who gives it.

Seats: who answers the question "what is your move"Scheme of the seats of the game. Four kinds of seats: a human (seat 0, a tap on the board, Interaction.tap and Flow.humanAttack), AI in the main thread (Kastgard, the brain of the cycle of the game and the function AI.choose), AI in a worker (Colony and Lines, the function choose and a worker with AI) and a remote player, who is only a plan. All four answer the same cycle of the game Flow, which asks what the move of the seat is; the result is the state of the game and the events. Below are the modes that change only who sits where: watch the game (all seats AI), let the AI finish (the AI takes the seat of the human), replay of the record (the seats read the decisions from the record) and the planned challenge, arena and game with friends.humanseat 0tap on the boardInteraction.tap→ Flow.humanAttackAI in the mainthread(Kastgard)brain of Flow:attack(…) →AI.chooseAI in a worker(Colony andLines)choose(…) →worker with AI,move backremoteplayer(plan)network move(so farnothing)Flow: the cycle of the gameasks each seat for a move, one shapethe state of the game and eventsthe screen, record and statistics are read from themthe modes only change who sits wherewatchthe game:each seatis AIlet the AI finish:AI takesyourseatreplay of therecord:seats readfrom the recordchallenge,arena, friends(plan)plan, nothing in the code of the game yet (6 Nov 2026)
Seats: a scheme of the code, not a measurement. The names are read in the code of the game 0.122.0 (6 Nov 2026). The dashed parts are only a plan (ROADMAP chapters 4 and 11, docs/ARENA.md); the code of the game under js/ has no network code, so they are dashed.

A human answers with a tap, through the door Flow.humanAttack (and its siblings: moving dice, distributing dice, the end of the turn). The game cycle waits for that. AI in the Kastgard game answers with a function. Flow has a brain for the seats that are not a human, and that is a contract with two functions, attack(game, player, k, rng) and place(…). The ordinary brain Bots.brain calls AI.choose(game, player, …) in the main thread of the page; the level (1 to 3) and the personality of the seat it takes from the state of the game. AI in Colony and in Lines answers with the function choose(game, player, level). The view sends it to the worker (worker/bot.js) as a snapshot of the state and gets the move back, because a search at level 3 takes up to a second (in Lines on a large board), and the worker keeps the page alive; if the worker fails, the simplest legal move is played.

Two other "brains" are not the AI of a game, but the same question. When a record is replayed, Flow gets a script that reads the decisions from the record, and no AI is asked. Let the AI finish lets the AI play through the same door as a human (Flow.autoHuman), so the game is the same game with the same dice. The modes therefore change who sits where, and not the rules.

To be honest about it, a seat today is more a direction than a finished abstraction. The cycle of the game has one brain for all seats that are not a human, not a separate controller for each seat, and the human is always seat 0 (humanAttack checks whether the owner of the square is 0). The mode Watch the game must therefore switch off four places where the code counts seat 0 as the human (the header of watch.js). A real second human seat would not do without touching the cycle of the game.

Remote seats, the arena and playing with friends are a plan. ROADMAP chapter 4 (rooms with a code, AI for the missing players) says "nothing is built", docs/ARENA.md is a concept of 23 October that is "not approved and not started", and in js/ there is no network code (a search for WebSocket, RTCPeerConnection and EventSource found nothing there; the findings are only in the tools of the game, for example the checks in the browser). What is built is what such a seat would need: a record with the decisions of each seat, and a replay that verifies a game of a stranger without AI. In my view that is the base, not the network, and the state of the plans is not a promise.

What holds it together

The pictures would be only drawing if nobody guarded them. In this project the guards are the tests and tools that fail a change which breaks a rule. The checks run on a copy of the game's tree:

GuardToolCheck
direction of usepackages.js --checka line in Colony reaches into Rules → FAIL rokgard/colony -> kastgard/stacks (above)
the realm manager knows no gametest "the manager knows no game"the string 'colony' in realms.js → the test prints 7: const favourite = 'colony';
file names by rolefile-template.js --checkcore/colony-extras.js in Colony → the name carries "colony", which the folder already says; rename it by its purpose
layout of teststests-layout.js --checka test in the root of tests/ → belongs in the folder of the package whose behaviour it proves
purity of a library filetest "the file is pure" (board-events.test.js)not tried, the test is read → forbids DOM, clocks, storage, randomness, require and the names of games

Two answers in the table have an important property: they say how to fix it. A file with an unfit name gets the sentence "rename it by its purpose, without the name of the package (the roles of Colony in core/ are game, ai, flow, setup, ruleset, events)". A test in the root of tests/ gets "put it into the folder of the package whose behaviour it proves, or into tests/tools/ for a tool". In my view this is why such a guard is not switched off at the first delay: a rule that only fails the build and does not say what to do gets bypassed.

The purity test of board-events.js shows a third kind of guard. It is not about the direction of the edges but about the character of a file. The file board-events.js must be a pure function, so its code (without comments and texts) must not contain document, window, localStorage, Date, Math.random, fetch or require(, and it must not name a game or its move (dice, colony, attack and others). The purity of the core without the DOM is not only a wish: the same files run in the game in the browser, in tests without a browser and in a worker.

Code and tests by packageFor each of the nine packages two bars: the lines of code and data (without the catalogues of texts) and the lines of the tests that lie in the folder of the package. The largest is the core (27,598 lines of code and 43,724 lines of tests), then stacks (21,823 and 28,651) and campaign (6,029 and 8,055). Vitgard and Telgard have about 185 lines of code and 143 lines of tests each.code and datatestscore102 / 121 files27 59843 724kastgard - stacks72 / 67 files21 82328 651kastgard - campaign32 / 26 files6 0298 055kastgard8 / 4 files2 0181 088rokgard - colony10 / 9 files1 9993 068rokgard - lines11 / 10 files2 5854 479rokgard12 / 9 files1 6372 620telgard3 / 2 files186143vitgard3 / 2 files185143Below the name: code files / test files.In all 64 060 lines of code and data and 91 971 lines of tests.In addition 102 test files of the tools (13 247 lines);texts (catalogues in nine languages) are not counted.
Lines of the files js/ without the folders of texts, and lines of the files *.test.js that lie in the folder of the package (game 0.122.0, 6 Nov 2026). Under the name is the number of code files and of test files.

Tests lie where the code is: the test of the file js/<folder>/x.js is in the mirror tests/<folder of the package>/<folder>/x.test.js. The tool tests-layout.js reports 352 test files (250 tests of packages and 102 tests of tools). The test of a clean package may name only the files of the core and of its own package, with one written exception: the test of Colony needs the real dice game, to prove that both games refuse the snapshot of the other. There are 4,609 tests in all; the full verify.js on a clean tree passed (4,608 passed, 1 skipped, 1,890 seconds), which is described in the article on the stamp (forthcoming article no. 37).

What the building changed from the plan, and what is debt

Building departed from the design, and those departures are the instructive part. Four were found during the work. The first: the core is not clean, it has 95 edges upward (see above). The second: Kastgard physically moved into js/realms/kastgard/ on 31 October (028), but the realm's id in the code stayed stacks, because an id does not change when a name changes (so says the header of the manifest). It was renamed only on 6 November 2026, to kastgard, and the header has since one written exception. Only what the player had saved under the old id was rewritten: the prefix of the achievements (stacks_… to kastgard_…) and the layout of the home screen, once, at the start of the game; the time and the order of the achievements stayed. The id of the game, its rules and the package kastgard/stacks, nor the text keys of the game, changed. It was proved on the data of the old code: 51 profiles, 1,193 keys, 357 transitions and 13 layouts came out the same after the rewrite, apart from the renamed id. The other way round does not hold: the old code loads the new data, but it does not know the new ids, so it would unlock achievements again and pay out Golden Dice. After publication, one therefore does not return to the old code. The third: names and status changed. The realm of board games was called Sporgard, then Taflgard, and from 31 October Rokgard; the campaign was first a realm, then a section, and from 31 October a game that builds on another game, although in the code it still attaches with a call to Realms.registerSection (028, Two renamings in one day (forthcoming article no. 44)). The fourth: one common core of texts for everyone was split into trees in the packages, so that a new realm need not write into foreign files (038).

The fifth was found only while reading the code for this article. The contract says that the realm manager can ask a realm for hub, saves, daily and weekly. A search in js/ showed that those hooks are called only by tests: the tiles, the games in progress and the daily challenge are read from the table of modes and from the wrapper. The contract is in the code, tested, and waiting for a caller.

Today's state of the parts of the design, in one table (game 0.122.0, 6 Nov 2026):

PartState (game 0.122.0, 6 Nov)
view of the board, renderer, StacksBoard.viewdone; Colony and Lines have their own description of the board too
BoardInput and one decision to the controller of the gamedone (29 Oct); controllers: Interaction, ColonyView, ChainsView
BoardEvents (act, set)done (30 Oct); the replay player of the dice game reads them; the adapter of Colony exists, but the page does not load it (tests only); the picture, the music and the analysis still read the Replay stream
facts()used by Colony and Lines; the dice game has its own path
realm manager, manifests, sections, start(ctx)done, four realms and one section; the hooks hub, saves, daily, weekly have no caller
profile, level and coin per realmdone; the wardrobe of Rokgard, 5 Nov
AIKastgard in the main thread, Colony and Lines in a worker; the shared kit for search (step B9) is waiting: two separate searches, 474 and 490 lines
remote seats, arena, playing with friendsa plan, nothing in the code of the game

The debt has five named pieces: 95 edges against the direction (of them 40 in app.js), facts for the dice game, hooks without a caller, shared places when a new game is made, and the search kit for the AI of boards. All are in the documents of the game; none is a promise that it will be done.

What I take from it

  • A rule without a ratchet is a wish. "The core does not know the game" is a nice sentence, but its value comes only with a table that says that today 95 edges hold and there will be no more. The number can be lowered, and an increase is visible in the history.
  • A scheme ages faster than the code. The design of 29 October had stale states after a week (step B3 "not merged", events "planned", the profile per realm "running"), two false claims (that the core does not know the game, and that the screens read the unfinished games and the challenges from the realm manager) and one overstated claim (that each seat has a controller of its own kind). That is why the pictures are drawn from the tool and not from memory, and why they carry a date.
  • Registration shrinks the shared places, it does not remove them. Of the 20 registration places, 13 are in files that every game edits. The truth is more useful than the sentence "without touching the wrapper".
  • A seat is a direction, not a finished thing. The cycle has one brain and a human on seat 0. A network would change it the way the mode Watch the game changed it.
  • A guard should say how to fix it. A message that does not state the procedure is bypassed later; the ones in the table do state it.
  • What is a plan should be dashed. In the pictures and in the text, the plan and the state are kept apart: a difference that misleads the player, the reader and the developer alike the most.

Sources and notes

  • State and data: the game Audamir 0.122.0 (6 Nov 2026); the game was only read. The design of 29 Oct 2026 is in the documents of the game (docs/mockups/architecture.html).
  • Packages, edges and lines: node tools/packages.js --check (338 files, 1,370 edges, 95 against the direction in 21 files), tools/packages-table.json and the history of the ratchet in its commits; the tests by the testDirs table.
  • Registration, move and seats: a search for the calls register in the files of the packages, js/ui/board-input.js, js/core/board-events.js, flow.js and bots.js; DESIGN §53.3, §80.6, §104.3 and §104.5.

Notes

  1. Up to version 0.65.6 of 31 October 2026 it was called Classic. ↩︎