Code map
Every file of code in Plinth, in the order the build joins them, and what is in it. Each file also opens with a comment saying the same, with a list of its main names (“What’s here”) and what it keeps in the save. Start with part 2 of the manual for how they fit together, or with Reading the code if the code is new to you.
The paths are as a game sees them, in its copy of Plinth (engine/). In Plinth’s own folder, leave off engine/.
The build
| File | What it does |
|---|---|
build.py (the game’s) | runs the engine’s build; --check checks only, --watch builds again on every save, --debug writes a debug build with the play log |
engine/build.py | reads edition.jsonc, content/settings.jsonc and every content file and checks them all (layouts dealt by the rules through Node, every picture, look, key, sound, run effect and word the engine asks for), keeps the game’s own words out of the engine (the guard), turns pictures into symbols, scopes the looks’ stylesheets and joins everything into one HTML file; it refuses to write it if anything is wrong, if two top-level names clash or if it would reach the network |
engine/web/shell.html | the page the build fills in: the bar, the board, the sheets and screens |
The code runs as one script, in this order: engine/src/*.js, then engine/src/audio/*.js, then the content as data (EDITION, LAYOUTS, SETS, LOOKS, PAGES, TABLES, RUN_DATA, CARD_PICTURES, DEBUG), then engine/src/game/*.js.
The rules (no browser)
| File | What’s in it |
|---|---|
engine/src/01-core.js | a stack and its rules: makeRandom and shuffled (a seeded order, never a sort that answers at random), kindSets and pickKinds, readLayout, neighbours, makeStack, isOpen, isFree, matches, freeOnes, freePairs, take, remove, undo, fill (the deal, played forwards as a player could), deal (with special tiles, gem pairs and buried twins), dealChosen (the deal nearest a trap rate, from trapRate), shuffle (lifts a pair when no deal can be cleared), freedBy and carefulPair (the careful choice), canClear and lostAt (where a lost stack was lost), BOT |
engine/src/02-run.js | a journey’s basics: RUN_EFFECTS (what boons, relics and omens can do), PLACE_BLOCKS (what a place may be made of), useRunContent, the run’s own chance (runRandom, runPick, runShuffled), the relics carried (hasRelic, relicsWith, sumOf, productOf), newRun, nextPlaces, goTo, leavePlace, endRun |
engine/src/03-run-map.js | the map in seasons: makeMap, makeSeason (the pattern of rows, the ways up), patternKind and placeKind (a place drawn by weight), seasonOf |
engine/src/04-run-stacks.js | what the stack at a place is: stackFor (its row, its level, the gentle start, an omen, its layout), stifferOn (a phone’s and a computer’s shapes), sceneryFor, placeCover, withKinds |
engine/src/05-run-play.js | a stack’s play: startStack, afterPair, afterWrong, whenStuck, mercyDue, godsLeft and askGods, undosLeft and undoPair, loseLife, leaveStack, afterClear, hintCost |
engine/src/06-run-places.js | the places between stacks: shopStock, rarePick, itemPrice, buy, boonChoice, relicOffer, placeEvent, gain, placeGift, eventGain |
engine/src/07-run-boons.js | boons: BOON_TARGETS, canTarget, useBoon |
They all run in Node too, which is how the tests and simulators use them: tools/engine.js reads them one after another, as the build joins them into the page.
Sound and music (engine/src/audio/, from Kiln)
| File | What’s in it |
|---|---|
10-audio.js | the audio engine (a gentle compressor, a small room), KEY and setKey, note(), the instruments (plucked strings, bells, a flute, noise) |
15-recorded.js | the sounds kept as WAV files (sounds/): a button, a stone button, a choice, a page |
20-music.js | the calm music, made as it plays: startMusic, musicBegins, musicFollow, musicFlourish, musicResolve, musicOn |
30-acid.js | acid music: AcidMusic({ context, scale, tempo, out }). Kept for other games; Sema-tawy doesn’t play it |
40-songs.js | songs with a tune that comes back, a walking bass and hand drums, in the game’s styles (SONG_STYLES, from MUSIC: the game’s content/music/): songStart(style), songBegins, songFollow, songFlourish, songSchedule. Another style is heard in try-out mode (?try&music=<id>) |
The page (engine/src/game/)
| File | What’s in it |
|---|---|
10-settings.js | SETTINGS (look, set, page, table, pair effect, sound, music and its style, vibration, less motion, high contrast, the corner amulet, scenery, the controls’ size, the stack), applySettings, old saves read under new names (fromOldNames) and try-out mode (TRYING, SAVE_PREFIX) |
20-sound.js | sfx(event), RECIPES (every sound), a click listener that sounds every button and choice, vibrate (the Android app’s bridge or the browser’s), armSound, soundForStack, soundFollows, musicStart (the game’s song or the calm music) |
30-pictures.js | showSet (the amulets as symbols, drawn once), pictureURL (a picture as an image’s address, made once), tilePictures (for home, Customise and the cards) |
40-board.js | where the stack lies: placeAt, outline, fitSize (never more than TILE_MOST), chooseShape (as drawn, tall or for a small phone), drawStack (paints it and places a button that draws nothing over each tile: the tap, the screen reader, the rings), tileAt, sayChosen |
44-paint-pictures.js | the pictures the stack is painted from, each made once and kept: made (a picture’s canvas, or one standing in until it is ready), picturesReady, paintColour (the skin’s --paint-*), bodyOf (the look’s body photographed from a hidden tile wearing it) |
45-paint.js | the stack painted on one canvas, as Amulets of Anubis paints its board: paintTile (each tile a picture made once: the body, the amulet, what a journey adds), paintTileParts, lonePainted, tileCanvas |
46-paint-specials.js | the marks a journey puts on a tile: paintVeil, paintRubble, paintSeal, paintGem |
47-paint-moves.js | the canvas and what moves on it: paintStack, repaint, moveTile and moveLeaving (the deal, the shuffle and the shake), boardSnapshot, tileShowing, stackMoving, finishMoves |
50-effects.js | what moves: ghost (a painted copy of a tile), ring, FX (each effect by kind and name; open, fly-off and drift move a picture of the game’s), playFx and less motion |
60-play.js | GAME (with trail, the stack before each pair since it was dealt), newGame, dealStack, tap, giveHint, useShuffle, shuffleStack (for a shuffle, the last few, the Gods), useUndo, showUndo, canUndo, redraw, resized |
61-journey.js | a journey’s keeping: JOURNEY, HOME (what journeys bring home and what a player has seen, with HOME_DEFAULTS), loadJSON, storeJSON, layoutOpen, saveRun |
62-screens.js | the parts of a journey’s screens: card(), what is carried (runCounts, runShelf, runStrip, runList, runProgress), the seasons’ names, showScreen, scene(html, place) (a place’s screen over its scenery), meter (how far something got, drawn), act (a way on, as Amulets draws them: main, way, quiet) |
63-home.js | the home screen (as Amulets’ title: one way forward, the daily challenges and free play, then small ways; showHome, levelSuggested, homeLevel), showLevels (the levels on a slider, levelStats drawing their numbers), fitHome, startFree, startRun, continueRun |
64-journey-map.js | the map (showMap, placeChip), previewPlace, enterPlace, goOn, the seasons (seasonTurns) |
65-journey-stack.js | a stack on a journey: the scenery and omen (applyScenery, applyOmen), startRunStack and weighing, newHere, runPair, runStuck, runHint, runCleared, endJourney |
65-places.js | the places between stacks (showShop, showChoice, showRest, showEvent, chooseOne), stackLost, stackLeft |
65-satchel.js | the bar in a journey (runBar), the movements over it (relicsAtWork, floatMoney), the satchel and aiming a boon (openSatchel, aimAt, applyBoon), giveUp |
66-map.js | the map’s picture, drawn for each journey: mapPicture, riverX, mapY |
67-daily.js | the daily challenges, from the settings’ days: DAYS, dailyFor(date, id) (the stack, its omen and cover), dayTile (a challenge as a tile, covered until cleared), showDays (today’s and the week’s marks), startDaily, dailyTry, dailyStuck, dailyCleared, dayDone |
68-sheets.js | the menu and what it opens, as sheets in the page style’s panel: openSheet, closeSheet, sheetBack, openMenu, openStacks, stackPicture, openSettings (SETTING_PARTS), openCustomise (CUSTOMISE_TABS, customiseGroups: yours, found on a journey, to buy), owns, openBuy (a thing bought with gems), keepOwned |
69-how.js | How to play in chapters, from the edition’s text.help, and the way into the tutorial: showHowTo, openChapter, HOW_SHOWS, HOW_FILL |
70-menu.js | the bar: makeMenu, ICONS, showProgress (the progress mark, the dots, the glow), a tile answering as the finger touches it, a button’s buzz on its press, Back and Escape (a step at a time) |
71-museum.js | gems, deeds and the museum: gainGems, notice, deed, checkDeeds, bringHome, openMuseum (MUSEUM_TABS) |
72-label.js | the game’s own label for a thing’s name (data-label, data-line): on a mouse’s hover, the keyboard’s focus and a tap on a thing marked tell; showLabel, hideLabel, and pointAt, the game pointing with its own words (a tip, a hint’s reason, the tutorial) |
73-log.js | the play log, in a debug build only: logNote, stackState, openLog (save it as a file, clear it, show a stack again move by move: replayStack, replayTo) |
74-help.js | help for a new player and a gentler loss: afterDraw, hintWhy, warnDeadEnd, giveMercy, stuckChoice (the Gods, an undo or leave the stack), lostStack, lostLines, findLostAt and lookBack (where a stack was lost), TIPS and showTip, the tutorial (startTutorial, tutorialStep, tutorialDone) |
90-boot.js | starts it all: the tutorial the first time, else home, or try-out mode |
Styles
| File | What’s in it |
|---|---|
engine/web/css/00-tokens.css | every colour and typeface the frame uses, as a token with a plain default; a game’s skin fills them in |
engine/web/css/10-page.css | the page, the bar, the table, the satchel’s sheet |
engine/web/css/20-run.css | a journey’s screens: panels, home, the map, cards’ layout, the coins, the satchel, How to play, the label, notices, the stuck choice, where a stack was lost, the replay’s bar, try-out’s label |
engine/web/css/30-sheets.css | the menu’s sheets: the head row, stone buttons, the menu’s tiles, settings’ choices, Customise’s cards, the stacks |
engine/web/css/39-type.css, 40-tiles.css, 41-bar.css, 42-special.css, 45-cards.css | the type, the tiles (the chosen and hinted marks, high contrast), the bar’s buttons, special amulets and omens, the cards |
web/css/*.css (the game’s) | its skin (00-skin.css: the tokens), fonts, scenery and whatever else is its own |
web/looks/, web/pages/, web/tables/ (the game’s) | one stylesheet per look, page style and table |
Tools
| File | What it does |
|---|---|
engine/tools/rules-test.js | 97 checks of the rules |
engine/tools/sim.js | the bot plays every stack, each of its shapes |
engine/tools/run-sim.js | the bot plays whole journeys at each level, as a more or less careless person who overlooks some pairs, or as a real person fitted from play logs (PLAYER); its last line (STOPS) is for the difficulty table |
engine/tools/difficulty.js | how hard each level is, in one table: a careful and a careless player play 200 journeys at every level, set against each level’s wins; then each stop of a journey, how stacks are lost and how often the help was needed |
engine/tools/play-log.js | reads a play log saved from a debug build: what was picked and passed over, what never used, how long a pair takes, where stacks were lost and the move after which each could no longer be cleared |
engine/tools/fit-player.js | a pretend player fitted to play logs: what weighs with the person choosing a pair, how often they look ahead, their wrong pairs, their ways on the map, what they buy and their pace; saved as player.json for PLAYER=player.json node engine/tools/run-sim.js |
engine/tools/smoke.js | plays the built game in headless Chromium at four sizes: the tutorial, free play, the menu and every sheet, How to play, the stack of the day and a whole journey (run-checks.js); photographs into dist/smoke/ |
engine/tools/run-checks.js | a journey step by step, shared by the smoke test and the phone |
engine/tools/phone-lib.js, phone.js, phone-run.js, phone-paint.js, phone-levels.js | the same on a real Android phone over adb: every page, table and look photographed, a whole journey, every sheet painted, the music measured |
engine/tools/phone-soak.js | the soak test, as Amulets has one: a long session on the phone, sampling the heap, elements, listeners, live audio nodes, the game’s caches and Android’s graphics memory; says whether anything kept climbing |
engine/tools/loudness.js | measures every sound (--phone on the phone) |
engine/tools/specimen.js | the design language’s specimen: the same screens of each game, on a laptop and a phone |
engine/tools/build-android.py, build-desktop.py | the Android app and the desktop programs |
engine/tools/new.py | a new piece of content from a template |
engine/tools/docs/build.py | the manual as a website (dist/docs/) and a PDF, from the game’s docs/site.json |
engine/tools/make-sounds.html | makes the sounds kept as files again |