5 KiB
Architecture
Build target: static browser page. No bundler. Globals and ordered deferred scripts are intentional. Current inspected version: 15.20.11.
Load order
app_manifest.json owns CSS/JS order. Regenerate index.html and service-worker.js with python3 scripts/generate_app_files.py after version/order changes. js/version.js exposes TARINAI_APP.version, cache name, and query helper.
The old css/styles.css compatibility shim and js/ui_family.js split marker have been removed. The family tree entry point now starts at ui_family_data.js and continues through async/layout/path/render modules.
Runtime objects
World: constructor injs/world.js; methods split into view, family/social, combat/effects, environment, spatial/budget, ants, update, placement/log, bootstrap.Tarinai: constructor injs/tarinai.js; methods split into identity/social, disease/nest, item effects, needs/items, social/move/life, render.Item: item state, lifecycle, scaling, and field rendering injs/items.js.Effect: transient visuals injs/sim_core.js; combat/weather/food effects are spawned throughWorldhelpers.TarinaiEvents: global event bus for logs, terrain dirtiness, audio failures, phase/performance changes.TarinaiPerformance: FPS quality manager; provides effect caps, ant stride, terrain redraw cadence, UI intervals.TarinaiInputMode: input classification and mobile-mode state. UI code reads this manager instead of duplicating touch heuristics.TarinaiWeatherSystem: weather transitions and rain-spawned water item creation. Rain overlay drawing remains inrender.js.
Startup path
main.js owns the user-visible boot sequence:
- Start the loading showcase and preload the initial sprite/image set through
loadImages. - Bind UI, apply the default
gardenfield layout, reset the world, and selectobserve. - Render logs, family archive, first frame, and stats.
- Start deferred background image loading, enter
requestAnimationFrame(loop), and hide the loading screen. - Register
service-worker.jswithupdateViaCache: "none"after window load.
Data ownership
js/data.js: base item/tool definitions,TOOL_CATEGORIES, config, image metrics, field presets.js/item_visual_registry.js: canonical item visual descriptors used by field drawing and generated tool-icon previews.js/food_registry.js: food/medicine semantics such as labels, serving classes, decay multipliers, and hygiene penalties.js/disease_registry.js: disease labels, flags, display metadata, cure-rule notes, and mystery-drug eligibility.js/input_mode_manager.js: touch/mobile classification, mobile mode persistence, and gesture capability policy.js/weather_system.js: weather state transitions and rain-water item spawning.js/text_catalog.js: Japanese UI copy/tooltips. Keep JS strings escaped where existing style uses escapes.js/effect_registry.js: item-effect labels, colors, modifiers, exclusivity/removal metadata, behavior callbacks (onApply,onTick,onRemove), and random-effect candidates.js/sound_pack.js: canonical sound metadata: IDs, categories, gain multipliers, cooldowns, optional sample paths, and ID-to-category mapping.FIELD_TYPESinjs/data.js: cage/garden/park field labels, responsive heights, world scale, starting population, and initial grass.
State loops
main.js starts asset preload, world bootstrap, animation loop, deferred image loading, service-worker registration. World.update(dt) advances time, weather, items, ants, Tarinai, effects, budgets, terrain dirtiness. render() draws cached background/terrain, visible entities, weather overlay, cards, HUD, and debug overlays.
World time is CONFIG.dayLength seconds per day. Version 15.20.11 uses 120 seconds/day and weather changes every 46-96 seconds. The phase boundary rules live in World.phaseName().
Domain events are emitted at central mutation points: placement, eating, decay, effect apply/remove, disease infect/cure, damage/death/birth, fight hit/loss/end, ant spawn/grab/carry/death, weather changes, and rain item drops. Logs/audio still use direct calls where they already existed; do not add duplicate log or sound side effects when subscribing to these events.
Ant behavior remains intentionally conservative. ANT_EXTENSION_HOOKS names future ecology slots for nest hunger, nest growth, queen reproduction, worker lifecycle, carrying success, and territorial behavior, but this pass does not rebalance those mechanics.
Spatial/performance rules
Use World.nearby* helpers rather than full-array scans in hot paths. Terrain cache uses dirty/version flags; do not reintroduce every-frame full terrain hashing. Performance degradation should be centralized in performance_manager.js.
Family tree rendering is intentionally asynchronous and cached. ui_family_async.js chunks component discovery with requestIdleCallback when available; ui_family_render.js hydrates cached HTML, keeps archive dirty/version state, and exposes validateFamilyTree() plus familyTreeDiagnostics() for browser-console checks.