67 lines
3.7 KiB
Org Mode
67 lines
3.7 KiB
Org Mode
:PROPERTIES:
|
||
:ID: ff8aa6b7-61ff-444c-9301-c0b666b0b573
|
||
:END:
|
||
|
||
#+title: trmn/schedule
|
||
#+filetags: :project: :knowledge: :schedule:
|
||
|
||
:PROPERTIES:
|
||
:ID: trmn-schedule
|
||
:END:
|
||
|
||
#+title: trmn/schedule
|
||
#+filetags: :project: :knowledge: :schedule:
|
||
|
||
** Architecture
|
||
~schedule.js~ is a standalone ES module that exports:
|
||
- ~generateDaySchedule(today, traits, dayEvents, currentDay, masterSeed)~ → ~ScheduleEntry[]~
|
||
- ~SCENES~ — plain object catalog of all ~68 scenes
|
||
- ~slotToTime(slot)~ → ~"HH:MM"~ string (slot 0 = 06:00)
|
||
- ~SLOTS~ (96), ~SLOT_MIN~ (15)
|
||
|
||
~ScheduleEntry~: ~{ slot, duration, sceneId, location, label }~. Array is sorted by slot, non-overlapping, always covers all 96 slots with no gaps (builder fills remainder with ~sleep~).
|
||
|
||
RNG isolation: schedule uses ~makeRng(masterSeed, currentDay + 50000)~. Offset of 50,000 clears the life sim's 0–36,500 range — no interference with protagonist daily streams.
|
||
|
||
~window.__life~ exposes ~{ ..., schedule }~ alongside ~buf~, ~eventLog~, ~people~.
|
||
|
||
** Slot Layout
|
||
#+begin_example
|
||
Slots 0–11 06:00–09:00 morning routine (12 slots)
|
||
Slots 12–23 09:00–12:00 early daytime (12 slots)
|
||
Slots 24–43 12:00–17:00 afternoon (20 slots)
|
||
Slots 44–55 17:00–20:00 early evening (12 slots)
|
||
Slots 56–63 20:00–22:00 late evening (8 slots)
|
||
Slots 64–95 22:00–06:00 sleep (32 slots)
|
||
#+end_example
|
||
|
||
** Life Stage Detection
|
||
~detectLifeStage(today, age)~ → one of 10 tags, checked in priority order:
|
||
~very_sick~ (sick + health<25) → ~sick~ → ~toddler~ (age<5) → ~kindergarten~ (eduStage=1) → ~school~ (eduStage=2/3) → ~college~ (inCollege) → ~retired~ → ~worker~ (employed) → ~unemployed~ (age≥16) → ~child~
|
||
|
||
** Forced Events
|
||
Events in ~dayEvents~ (from ~eventLog.get(currentDay)~) that override normal blocks:
|
||
| Event ID | Override |
|
||
|---|---|
|
||
| ~illness_acute~ | daytime → rest_in_bed; skip work/school |
|
||
| ~serious_accident~ / ~injury_serious~ | afternoon → emergency_room |
|
||
| ~first_child~ / ~subsequent_child~ | daytime → hospital_stay |
|
||
| ~marry~ | afternoon → wedding_ceremony; evening → wedding_reception |
|
||
| ~family_member_death~ (attended=true) | afternoon → funeral_ceremony + wake |
|
||
| ~move_city~ | full day → moving_boxes |
|
||
| ~premature_death~ | minimal day, idle |
|
||
|
||
** Gotchas
|
||
- ~jobCategory~ is NOT in the packed ~Float32Array~ buffer (not a field in ~F~). Schedule derives a stable per-character type from ~makeRng(masterSeed ^ 0x5A5A5A5A, 0)~. This is deterministic per character but may not match what was rolled in the life sim.
|
||
- Young-child stages (~toddler~, ~kindergarten~, ~school~, ~child~) must be branched BEFORE adult defaults in morning and evening blocks. The ~isYoungChild~ flag gates: no ~make_breakfast~, no ~cook_dinner~, no ~morning_coffee~, no ~morning_exercise~. The adult fallthrough path always ran these — easy to regress.
|
||
- ~go_to_park_with_parents~ is from the CHILD's perspective; ~hasYoungChildren~ is from the PARENT's perspective. They are mutually exclusive: ~hasYoungChildren = numChildren > 0 && age < 40~.
|
||
- The schedule builder (~makeBuilder~) clamps at slot 96: ~push~ is a no-op once cursor ≥ SLOTS. ~fill(sceneId, toSlot)~ is safe to call even if cursor is already past ~toSlot~.
|
||
|
||
** Debug Tool
|
||
~schedule-debug.mjs~ — CLI tool, ~nix run .#schedule~
|
||
- No args: random seed + random day from character's living years, full output
|
||
- Prints seed, day, age, full state, traits, events, then schedule table
|
||
- All state fields overridable: ~--seed~, ~--day~, ~--age~, ~--health~, ~--sick~, ~--employed~, ~--retired~, ~--married~, ~--children~, ~--friends~, ~--job-tier~, ~--loneliness~
|
||
- ~--event <id>~ injects a forced event (repeatable); injected events are labelled ~(injected)~ in output
|
||
- ~--help~ prints usage
|