Conventions
Almost every rule here fails silently when broken: a file the bundle never loads, a method the compiler cannot see, a setting that renders and does nothing, a document that is now a lie. The build catches some; the rest are held by review.
The code
- No imports, no modules. Every
src/*.tsis concatenated into one bundle sharing one global scope. Order intsconfig.jsonmatters for load-time work; duplicate names silently overwrite. The bundle. - Adding a
Tsummethod means adding its signature tointerface Tsuminglobals.d.ts, under the header for the implementing file. Prototype assignments carry no annotations of their own —thisand the parameters come from the interface. - Three compilations. The game bundle (
strict, ES2023), the settings page and the Quick Bar page (ES5, for the WebView). They share only the.d.tsvocabularies and the files listed in both page configs.npm run typecheckruns all three. - A setting is named by
SettingKey, never by a literal. The enum keysinterface Settings, the schema row, the share slot and the read inbuildRun. Misspelling one is a build error; forgetting the read is not. - String vocabularies are
const enums —PageName,SkillType,SettingKey,RecordKey,Log,Emit,UiText. Use the member, not the literal. A string used twice is a member, not a repeated literal. PAGE_DISPATCH.mdandEVENTS.mdare generated. Change the source and rebuild; a hand edit is lost at the next build.- Some oddities are deliberate. The script's behaviour was held identical
to a working original for a long time, so a value or ordering that looks
arbitrary may be load-bearing. Prefer a measurement to a tidy-up; the drag
timing in
link(10/10/10 ms) and theminMsfloor onsettleBoardare two that bite. - The version lives in
package.jsonand nowhere else. The pages carry a$VERSIONplaceholder substituted at build time, and so does the bundle. - Robotmon is gone on purpose. ES2023, quality-100 captures, no
BOOTCLASSPATH, no guards around optional natives — every documented native is present. Do not reintroduce a fallback for a host that no longer exists. - The settings page is a WebView in an overlay. No native popups (a
<select>does nothing when tapped), nolocation.reload()(it navigates to the script directory). Redraw withrenderPage(). - A log line is one JSON record, not a sentence. Everything goes through
logInfoand friends, values go in fields, and nothing new belongs at the top level of the record. Logging and events. - Every timestamp is UTC.
Date.now(),toISOString(), and the stats CSV'sgetUTC*getters. A local-time reading makes files from two devices unmergeable. async/awaitbuys nothing. The host has no timers and no workers; every native call is synchronous and blocking. Script-side JavaScript is about 1 % of a detection sweep; the cost is captures and native image work.index.tsstays thin. It is concatenated near the end, so anything living there can quietly overwrite anything.- Bubble taps go through the Bubble Strategy, or say why not —
sweepsBubblesorclaimsBubbleson the skill. A new bubble tap that reads neither undoes the player's setting. - A subscription's band is a contract.
observetakes no captures and taps nothing;recordmay capture but not tap; the rest may tap;notifydecides nothing. Nothing checks this. - A mode of a screen is not a page. Read it from its own probe table, never from the matched key.
The comments
Every source file opens with a header comment that says what the file owns and why it is shaped the way it is — the long form of the code map's one clause. Keep that pattern for a new file. Inline comments say why, concisely, at the level a junior developer can follow; the reasoning behind a number belongs beside the number, not in a document elsewhere.
The documents
CODEMAP.mdis the index and is read before anything is searched, so a row there is one clause, never a paragraph.map:checkholds it to the tree.CHANGELOG.mdis filed under the version inpackage.json;### Summaryis the release note, one line per player-visible feature; the rest goes below. Keep it succinct.README.mdis the user's document: the settings table, the Quick Bar, presets, sharing, reporting.- The header comments are where a decision and its reasoning are kept together. When a file's job changes, its header and its code-map row change with it.
What must not be in the tree
The tree is public. It may not name the private toolkit repository, describe what it holds beyond "the development toolkit", or carry anything of the game's — screenshots, art, the readers of its data files. Comments cite the toolkit's commands by name and stop there. Nothing from the host app's code is copied here; its behaviour is described in prose and its natives are declared, not implemented.