Sema-tawy: the docs

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

FileWhat 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.pyreads 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.htmlthe 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)

FileWhat’s in it
engine/src/01-core.jsa 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.jsa 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.jsthe 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.jswhat 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.jsa stack’s play: startStack, afterPair, afterWrong, whenStuck, mercyDue, godsLeft and askGods, undosLeft and undoPair, loseLife, leaveStack, afterClear, hintCost
engine/src/06-run-places.jsthe places between stacks: shopStock, rarePick, itemPrice, buy, boonChoice, relicOffer, placeEvent, gain, placeGift, eventGain
engine/src/07-run-boons.jsboons: 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)

FileWhat’s in it
10-audio.jsthe audio engine (a gentle compressor, a small room), KEY and setKey, note(), the instruments (plucked strings, bells, a flute, noise)
15-recorded.jsthe sounds kept as WAV files (sounds/): a button, a stone button, a choice, a page
20-music.jsthe calm music, made as it plays: startMusic, musicBegins, musicFollow, musicFlourish, musicResolve, musicOn
30-acid.jsacid music: AcidMusic({ context, scale, tempo, out }). Kept for other games; Sema-tawy doesn’t play it
40-songs.jssongs 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/)

FileWhat’s in it
10-settings.jsSETTINGS (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.jssfx(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.jsshowSet (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.jswhere 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.jsthe 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.jsthe 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.jsthe marks a journey puts on a tile: paintVeil, paintRubble, paintSeal, paintGem
47-paint-moves.jsthe canvas and what moves on it: paintStack, repaint, moveTile and moveLeaving (the deal, the shuffle and the shake), boardSnapshot, tileShowing, stackMoving, finishMoves
50-effects.jswhat 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.jsGAME (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.jsa journey’s keeping: JOURNEY, HOME (what journeys bring home and what a player has seen, with HOME_DEFAULTS), loadJSON, storeJSON, layoutOpen, saveRun
62-screens.jsthe 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.jsthe 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.jsthe map (showMap, placeChip), previewPlace, enterPlace, goOn, the seasons (seasonTurns)
65-journey-stack.jsa stack on a journey: the scenery and omen (applyScenery, applyOmen), startRunStack and weighing, newHere, runPair, runStuck, runHint, runCleared, endJourney
65-places.jsthe places between stacks (showShop, showChoice, showRest, showEvent, chooseOne), stackLost, stackLeft
65-satchel.jsthe bar in a journey (runBar), the movements over it (relicsAtWork, floatMoney), the satchel and aiming a boon (openSatchel, aimAt, applyBoon), giveUp
66-map.jsthe map’s picture, drawn for each journey: mapPicture, riverX, mapY
67-daily.jsthe 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.jsthe 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.jsHow to play in chapters, from the edition’s text.help, and the way into the tutorial: showHowTo, openChapter, HOW_SHOWS, HOW_FILL
70-menu.jsthe 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.jsgems, deeds and the museum: gainGems, notice, deed, checkDeeds, bringHome, openMuseum (MUSEUM_TABS)
72-label.jsthe 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.jsthe 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.jshelp 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.jsstarts it all: the tutorial the first time, else home, or try-out mode

Styles

FileWhat’s in it
engine/web/css/00-tokens.cssevery 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.cssthe page, the bar, the table, the satchel’s sheet
engine/web/css/20-run.cssa 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.cssthe 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.cssthe 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

FileWhat it does
engine/tools/rules-test.js97 checks of the rules
engine/tools/sim.jsthe bot plays every stack, each of its shapes
engine/tools/run-sim.jsthe 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.jshow 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.jsreads 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.jsa 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.jsplays 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.jsa 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.jsthe 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.jsthe 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.jsmeasures every sound (--phone on the phone)
engine/tools/specimen.jsthe design language’s specimen: the same screens of each game, on a laptop and a phone
engine/tools/build-android.py, build-desktop.pythe Android app and the desktop programs
engine/tools/new.pya new piece of content from a template
engine/tools/docs/build.pythe manual as a website (dist/docs/) and a PDF, from the game’s docs/site.json
engine/tools/make-sounds.htmlmakes the sounds kept as files again