tarinai/docs/ARCHITECTURE.md
2026-06-22 02:03:19 +09:00

5.1 KiB

Architecture

Build target: static browser page. No bundler. Globals and ordered deferred scripts are intentional. Current inspected version: 15.20.16.

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 in js/world.js; methods split into view, family/social, combat/effects, environment, spatial/budget, ants, update, placement/log, bootstrap.
  • Tarinai: constructor in js/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 in js/items.js.
  • Effect: transient visuals in js/sim_core.js; combat/weather/food effects are spawned through World helpers.
  • 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 in render.js.

Startup path

main.js owns the user-visible boot sequence:

  1. Start the loading showcase and preload the initial sprite/image set through loadImages.
  2. Bind UI, apply the default garden field layout, reset the world, and select observe.
  3. Render logs, family archive, first frame, and stats.
  4. Start deferred background image loading, enter requestAnimationFrame(loop), and hide the loading screen.
  5. Register service-worker.js with updateViaCache: "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), direct eating context, 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_TYPES in js/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.16 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.