-
Notifications
You must be signed in to change notification settings - Fork 0
Time Era Calendar
Navigation: Home - Runtime & engine - Time Era Calendar
MM2 ("Gates to Another World") tracks an in-game calendar and supports time
travel between parallel timelines / eras. This subsystem is pure runtime
state in the A4 workspace β it is not stored in attrib.dat. Content that
"only happens in certain years" is gated by event.dat scripts reading this
state.
All confirmed from EXTRACTED/mm2.capstone.asm.
| Global | Type | Meaning |
|---|---|---|
A4-$79B4 |
word | Sub-day time accumulator. 256 units = 1 day (rolls over at 0x100). |
A4-$79B6 |
word | Current era / timeline index, range 0..9. Time travel switches this. |
A4-$79DE[era] |
word[10] | Day-of-year, 1..180 (one slot per era). |
A4-$79CA[era] |
word[10] | Year counter, capped at 999 (one slot per era). Year 1000 = doomsday. |
A4-$798C, A4-$798D
|
byte | Periodic reset flags, cleared at day 60 / 120 / 180. |
Correction (ASM-verified, see
14-game-state-struct.md): earlier revisions of this table listedA4-$79B1as a "month/sign byte" andA4-$79F2/-$79F1/-$79F0as "month/season display fields". The disassembly shows those are session bytes, not calendar fields:-$79B1($864F) is the movement key (cmpi 'N'/'S'/'E'/'W'),-$79F2($860E) is the screen/mode id, and-$79F0($8610) is a map coordinate. The month/season for display are derived from the day-of-year via the word tables below.
The day array -$79DE is exactly 0x14 (20) bytes = 10 words, ending right
where the year array -$79CA begins β i.e. 10 parallel calendars, one per era.
006a0a add.w d0, -$79b4(a4) ; advance sub-day time
006a0e cmpi.w #$100, -$79b4(a4) ; 256 units == 1 day?
006a14 blt $6aca ; not yet -> done
006a18 move.w -$79b6(a4), d0 ; era index
006a20 lea -$79de(a4), a0 ; day-of-year array
006a24 addq.w #$1, (a0,d0.l) ; ++day[era]
...
006a42 cmpi.w #$3c, -$2(a5) ; day == 60 ?
006a4a cmpi.w #$78, -$2(a5) ; day == 120 ?
006a52 cmpi.w #$b4, -$2(a5) ; day == 180 ? -> clear -$798c/-$798d
...
006a6e cmpi.w #$b4, (a0,d0.l) ; day[era] > 180 ?
006a76 ... move.w #$1, (a0,d0.l) ; new year: day = 1
006a90 lea -$79ca(a4), a0 ; year array
006a94 cmpi.w #$3e7, (a0,d0.l) ; year == 999 ?
006a9c ... addq.w #$1, (a0,d0.l) ; else ++year[era]
So: every 256 time units a day passes; every 180 days a year passes; the year saturates at 999 (the "World Will End In The Year 1000" condition).
Formats the current date for the selected era, with inline labels "Day="
(string at 0x63BA) and "Year=" (string at 0x63BF):
00631e move.w -$79b6(a4), d0 ; era
006326 lea -$79de(a4), a0
00632a move.w (a0,d0.l), -(a7) ; push day[era]
... print "Year="
00635e move.w -$79b6(a4), d0
006366 lea -$79ca(a4), a0
00636a move.w (a0,d0.l), -(a7) ; push year[era]
A4-$79B6 is bounded to 0..9:
-
0x0B112:cmpi.w #$9, -$79b6(a4)(withmove.w #$8, -$79b6fallback). -
0x19CF6:cmpi.w #$9, -$79b6(a4)/move.w #$9, -$79b6(a4).
The month mapping at 0x0B0EA walks a 13-entry word table at A4-$711C
(cmpi.w #$d) and tables at A4-$7102/A4-$70F5 to derive the month/season
display bytes from the day-of-year.
There is no per-era copy of map/attrib data. Instead:
- The current era index (
-$79B6) selects which timeline's day/year counters are live. -
event.datscripts gate on the calendar directly:-
OP_22(0x16A9E) sets the condition flag if the current era (-$79B5) is in a[lo,hi]range. -
OP_23(0x16ADA) range-checks the day-of-year (-$79DE[era]). - generic variable loads
OP_17(0x165A4) /OP_32(0x17190) and the 16-bit predicateOP_25(0x16B82) cover the rest.
-
- Conditional-skip opcodes
OP_10/OP_11(0x162B8/0x162DC) then run or skip a block based on that flag.
This is the same predicateβskip pattern documented for gold/ticket gates in
07-event-script-opcodes.md, applied to the calendar. The Pinehurst
time-travel hub ("Time travel at Pinehurst", str.dat) is the in-world entry
point that changes -$79B6.
There is also a per-screen era gate baked into attrib.dat. Each screen's
record carries an era_gate byte at offset 0x0F. In the event interpreter:
0172b6 move.b -$79b5(a4), -$2(a5) ; current era (low byte of -$79b6)
0172bc move.b -$560b(a4), d0 ; attrib byte 0x0F of current screen
0172c0 cmp.b -$2(a5), d0 ; era_gate == current era ?
0172c4 beq $172ca ; yes -> process the event record
0172c6 rts ; no -> skip
So whether a screen's event record fires can depend on which era/timeline the
party is currently in. Combined with the 0x16/0x18 transition fields in the
same record, this is the mechanism behind "this level is a different era" and
"this event only happens in certain years". (-$79B5 is the low byte of the
era word -$79B6; era values 0..9 fit in that byte.)
From EXTRACTED/docs/11-str-decoded.txt and 09-event-decoded-events.txt:
Time / Will / End / In The / Year / 1000Time travel at PinehurstThere are only 180 days per year.... a year has passed."... I will only see you once a year."
- Docs Wiki Hub β full doc index
- Getting Started β read this first
- Overview
- Workspace Notes
- Open Questions
- Full Analysis
- Game Remake
- Startup and Init
- Runtime Memory Map
- Main Loop and Map
- Exploration Input and Options
- Party and Session
- Game State Struct
- Data Hunk mm2 data 00
- Time Era Calendar
- GFX Loading
- ANM TV Format
- PC DOS graphics
- SNES graphics
- 3D View and Game Screen
- Amiga 3D Render Process
- Scripted Scene Graphics
- Event Graphics Opcodes
- Title Screen Assets
- Title Screen Animation
- Format inventory
- items.dat
- monsters.dat
- roster.dat
- attrib.dat
- map.dat
- spells & item use
- event.dat
- Events by location β 71 maps
- Events hub (numbered)
- Event Script Opcodes
-
Event Script DSL β
.mm2evtauthoring - Event Text Rendering
- Event Graphics Opcodes
- Combat Overview
- Combat System
- Encounter Tables
- Spell Cast ASM
- monsters.dat abilities
- Spells and item use
- Amiga audio in exe β Paula / DATA / remake
- Controls: Sounds / Walk Beep
- MM2 music format (superseded)
- Title/death audio paths (superseded)
- Known songs catalog (superseded)
- Town Services
- Spell Sources
- Character Mechanics
- Skills and Hirelings
- Commerce Formulas
- Commerce World Services
- Mount Farview Class Quest
- Class Quest HP Bug
- Event Runtime
- Event to String Path
- Embedded Exe Strings
- Copy Protection
- Time Era Calendar
- Game State Struct
- MM1 Overview β hub + decode status
- MM1 MAZEDATA format
- MM1 to MM2 outdoor
- MM1 WALLPIX by sector
- MM1 art & graphics
- MM1 items / monsters (status)
- MM1 map walker β
- MM1 2D maps gallery
- MM1 WALLPIX gallery