On this page
  1. Clock source and advancement
  2. What the clock controls
  3. Related
  4. Games
  5. References
  6. Sources

Time-of-day systems use an external real-time clock or advance a clock inside the game1,2. They can divide a day into named periods, trigger scheduled updates, or impose a deadline that resets a cycle1,3,4.

  • Pokémon Crystal (2000). Morning, day, and night rates for wild encounters, as in Gold and Silver.5
  • External clockPokémon Gold and Silver (1999). Morning, day, and night from the cartridge clock's hour.1,6Animal Crossing (2001). The daily update compares the clock with the last update's time; the day turns over at 6:00, and one update makes up for every 6:00 missed.3,7Pokémon HeartGold and SoulSilver (2009). Platinum's five periods from the DS clock's hour, folded to three for wild Pokémon; night starts at 20:00.8,9
  • Game clockCastlevania II: Simon's Quest (1987). A running clock turns day to night and back, and at night most enemies have double hit points.2,10Harvest Moon 64 (1999). 10 game seconds per loop step on maps where time flows, at most 10 game minutes per real second.11Pikmin (2001). A day runs from 7:00 to 19:00 on a clock paced by a parameter file, and at sunset, outside challenge mode, the tutorial, and the ending, every Pikmin not following the captain, at an Onion, or in free mode near an Onion or the ship is lost.12,13The Legend of Zelda: The Wind Waker (2002). A day is 360 units, 15 an hour, advancing 0.02 an update where time passes; elsewhere it creeps only to 11:00 or 23:00.14
  • Time loopThe Legend of Zelda: Majora's Mask (2000). A day is 65,536 clock units; the moon falls at the third dawn unless the Song of Time resets the cycle to the first, keeping the bank but not Link's wallet.15,16,17,18,4

#Clock source and advancement

Pokémon Gold and Silver read morning, day, and night from the cartridge clock1. Pokémon Crystal keeps those periods’ wild-encounter rates5. HeartGold and SoulSilver read five periods from the Nintendo DS clock and fold them into three for wild Pokémon8,9. Night starts at 20:00 in HeartGold and SoulSilver, later than in Gold and Silver8,1.

Other games advance their own clock. Castlevania II: Simon’s Quest advances one game minute every 15 frames2. Harvest Moon 64 adds 10 seconds per eligible loop step on maps where time flows11. The Legend of Zelda: The Wind Waker advances by 0.02 units per update when its conditions permit; in other rooms, it advances only to 11:00 or 23:0014. Pikmin paces its clock from a parameter file and ends the day at 19:0012.

Animal Crossing compares the clock with the time of its last town update. It runs a daily pass at the first 6:00 after that update, or a back-in-time pass if the clock was set earlier3. The daily pass adds weeds in proportion to the number of 6:00 intervals missed7. The Legend of Zelda: Majora’s Mask advances through a three-day cycle; when the clock crosses 6:00 on day 3, the moon-crash sequence starts and sets the clock to 6:00 plus 10 units and the day counter to 44. The Song of Time calls the cycle-reset routine, which clears some saved progress and preserves other fields17.

#What the clock controls

Gold and Silver use the time period to change wild encounter rates6. Crystal retains period-specific encounter rates5. HeartGold and SoulSilver choose wild species by the folded period, and clock-bound evolution methods check whether it is day or night9.

The clock also gates world updates and consequences. Simon’s Quest doubles the hit points of enemies placed at night, with exceptions for some object types and mansions10. Animal Crossing’s daily pass adds up to 5 weeds per missed 6:00, subject to available spaces7. At sunset, Pikmin can lose any Pikmin left outside the specified safe states and areas13. In Majora’s Mask, the third dawn starts the moon crash4.

Games

GameYearHowNote
Pokémon Crystal2000morning, day, and night rates for wild encounters, as in Gold and Silver
Pokémon Gold and Silver1999External clockmorning, day, and night from the cartridge clock's hour
Animal Crossing2001External clockthe daily update compares the clock with the last update's time; the day turns over at 6:00, and one update makes up for every 6:00 missed
Pokémon HeartGold and SoulSilver2009External clockPlatinum's five periods from the DS clock's hour, folded to three for wild Pokémon; night starts at 20:00
Castlevania II: Simon's Quest1987Game clocka running clock turns day to night and back, and at night most enemies have double hit points
Dragon Warrior III1988Game clocktime passes as the party travels; at night castles shut, most shops close, and monsters come more often
Harvest Moon 641999Game clock10 game seconds per loop step on maps where time flows, at most 10 game minutes per real second
Pikmin2001Game clocka day runs from 7:00 to 19:00 on a clock paced by a parameter file, and at sunset, outside challenge mode, the tutorial, and the ending, every Pikmin not following the captain, at an Onion, or in free mode near an Onion or the ship is lost
The Legend of Zelda: The Wind Waker2002Game clocka day is 360 units, 15 an hour, advancing 0.02 an update where time passes; elsewhere it creeps only to 11:00 or 23:00
Factorio2016Game clocka seven-minute day that solar panels follow, with accumulators to cover the night
The Legend of Zelda: Majora's Mask2000Time loopa day is 65,536 clock units; the moon falls at the third dawn unless the Song of Time resets the cycle to the first, keeping the bank but not Link's wallet
Every claim about this mechanic, by game (18)
Castlevania II: Simon's Quest 1987Simon's Quest keeps a clock of days, hours, and minutes in BCD that advances one minute every 15 frames outside the stopped cases, and when the hour reaches 6 or 18 it starts the day-night transition; a day is 24 hours.Code
In Simon's Quest an enemy placed while it's night starts with double the hit points its level data gives, except a few object types and in the mansions.Code
Harvest Moon 64 1999In the US release, each step of the gameplay loop adds 10 to the clock's seconds, as long as the map's LEVEL_TIME_FLOWS flag is set, no animation has suspended time, and the player entity passes checkEntityMapSpaceDependent and isn't paused; 60 seconds make a minute. So a game minute is 6 steps and a game hour 360. The main loop steps at most once per video retrace (mainLoopUpdateInterval is 1), and the retrace callback counts 60 calls as its cycle. Assuming 60 retraces a second (NTSC's rate is about 59.94), the clock runs at most 10 game minutes per real second, an hour in 6 real seconds (computed under that assumption). The real rate depends on how many steps the game finishes each second, which the atlas hasn't measured.Code
Pokémon Gold and Silver 1999On each step, Gold and Silver's TryWildEncounter reads the map's encounter rate for the current time of day (morning, day, or night), or its water rate, doubles it for the Pokémon March or Ruins of Alph radio, halves it for the Pokémon Lullaby or a Cleanse Tag, and starts a battle when Random is below it; Crystal keeps this unchanged.Code
The time of day picks which of a grass area's three sets of 7 slots is used; a roll from 1 to 100 then picks a slot at 30, 30, 20, 10, 5, 4, and 1 percent, or one of 3 water slots at 60, 30, and 10 percent. Crystal's routine and table are the same.Code
Gold and Silver set the time of day from the cartridge clock's hour, morning from 4:00 to 9:59, day from 10:00 to 17:59, and night from 18:00 to 3:59.Code
The Legend of Zelda: Majora's Mask 2000In the N64 US 1.0 code the clock is a 16-bit count in which a day is 0x10000 units, so a game minute is about 45.5 units (computed; the macro CLOCK_TIME_MINUTE truncates it to 45). Each play update, Environment_UpdateTime adds the time speed R_TIME_SPEED and then, if that speed isn't 0, the save's timeSpeedOffset. It adds only when time isn't stopped, the game isn't paused or over, no textbox is open (or its message id is 0xF7, 0x20D2, 0x140C, or 0x100 through 0x200, or the game mode is the end credits), the debug frame advance (FrameAdvance_IsEnabled) is off, no transition is under way (transitionMode off, or a game mode other than normal) and none has been triggered, and no cutscene runs. From 18:00 until 6:00 it sets the save's isNight flag.Code
In the N64 US 1.0 code each scene's header sets its time speed, and a header value of 0xFF gives 0, a scene where time stands still. While Link's ocarina slot is empty, a nonzero scene speed becomes 5, under a decompilers' comment that reads "Increase time speed during first cycle"; the scene's speed becomes R_TIME_SPEED only while Sun's Song is inactive. The Inverted Song of Time is offered only where the scene's restriction flags allow it (otherwise text 0x1B95 and nothing) and the speed isn't 0; accepting it sets the offset to −2, or back to 0 if it was already set, and the update adds the offset only while the speed isn't 0. The game updates once every 3 video frames, set by GameState_SetFramerateDivisor(3) into a field whose comment reads "how many VIs should elapse before next swap". Assuming NTSC's 59.94 video frames a second (the atlas's assumption, not in the code), that is about 20 updates a second, and at speed 5 a game minute takes about 0.46 s, a day about 656 s, and the three days about 33 minutes (computed). The usual speed of a scene is in its header, ROM data the decompilation doesn't hold.Code
In the N64 US 1.0 code, answering yes to the Song of Time's prompt runs Sram_SaveEndOfCycle, whose comment says it is "Used by Song of Time (when clicking "Yes") and (indirectly) by the "Dawn of the New Day" cutscene". The function sets the day counter to 0 and the clock one unit before 6:00, clears the Inverted Song's offset, and adds one to a reset count capped at 999, but on the song's path the message code saves the day, the time, and the cutscene index before the call and puts them back right after it; where the cycle returns to the first dawn is untraced. It sets the rupees Link carries to 0 and every ammo count to 0 except the pictograph box's, and turns any bottle holding an item from ITEM_POTION_RED through ITEM_OBABA_DRINK back into an empty bottle. It sets a sword at or below the Razor Sword back to the Kokiri Sword (or the Gilded Sword if a stolen-item slot holds it), removes dungeon keys, boss keys, stray fairies, and the pictograph, and clears the event-info flags. Scene flags (switches, chests, collectibles) and week-event flags survive only where a per-scene or per-flag persistence table marks them. Among the rest, it resets five minigame high scores and the three Deku Playground scores, but not the bank balance, which is kept in the high-score slot HS_BANK_RUPEES.Code
In the N64 US 1.0 code, accepting the Song of Double Time's prompt sets the clock to 6:00 if the save's isNight flag is set and to 18:00 if not, and turns off the moon's countdown timer; this code doesn't change the day counter. The three-day events actor (En_Test4) then sees the clock cross 6:00 and, in its no-cutscene branch, adds a day; that the jump to exactly 6:00 trips its crossing test is the atlas's reading. The song isn't offered on the third night (day 3 with isNight set) or where a scene's restriction flags forbid it.Code
In the N64 US 1.0 code, the actor En_Test4, which its file's comment describes as "Three-Day Events: day-night transitions", compares each update the clock with the next transition time (6:00 by night, 18:00 by day) by multiplying the 16-bit differences of the current and previous times from it and treating a product of 0 or less as a crossing (the atlas's reading of the test), unless a transition, a cutscene, setup actors, a room load, or the debug camera is under way. When the clock crosses 6:00 with the day counter at 3, it calls Interface_StartMoonCrash, which sets the day to 4 and the clock to 6:00 plus 10 units and starts a white fade to a Termina Field entrance. On days 1 and 2 the same crossing adds a day when no transition cutscene is set or the telescope is on; the other branch (z_en_test4.c L446-L470), which sets a flag the decomp names EVENTINF_TRIGGER_DAYTELOP for the Dawn of a New Day screen, is untraced. Play_Init spawns this actor in dungeon and boss rooms on any day but 0; elsewhere it comes from scene data the atlas hasn't read.Code
Pikmin 2001The clock advances by the frame's real time (gsys->getFrameTime()), and a 24-hour game day lasts 60 × daySpeed × day_multiply real seconds: daySpeed (p00) comes from parms/gamePrms.bin, with a code default of 20 minutes that a decompilation comment gives as 27 in the file, and day_multiply comes from the stage file, 1 if it has none. Each day starts at startHour (t00, default 7.0) and ends when the time of day reaches endHour (t01, default 19.0), so the playable span is 12 ÷ 24 of a game day (computed): with day_multiply at 1, 10 real minutes at the code defaults and 13.5 at the comment's 27. The clock advances only while no reset is pending (gsys->resetPending()), no menu is open outside a cutscene, nothing is paused (mPauseAll), no window is over the screen (mIsUIOverlayActive), no cutscene plays, the section's update flags include UPDATE_WORLD_CLOCK, and the game isn't in the tutorial (isTutorial()).Code
When a day ends (GameCoreSection::cleanupDayEnd), outside challenge mode, the tutorial, and the game's ending (isEnding(): the 30th day, or all 30 ship parts), every Pikmin is killed and counted as left behind unless it is entering or leaving an Onion, or in its LookAt state, or following the captain (formation mode) in a state other than drowning, burning, swallowed, bubbled, dying, or flicked, or in free mode (FreeMode, in any state) within mSunsetSafetyRange (p60, "日没生き残り範囲", code default 200, read from parms/pikiMgr.bin) of an Onion or of the ship, measured by qdist2's ground-plane approximation (|dx| + |dz| − ½ min). Pikmin with mushroom heads die too. If any were left behind, the take-off cutscene plays its enemy-attack version. The survivors then all go into their color's Onion (exitDayEnd), and a Pikmin with no Onion of its color is killed.Code
The Legend of Zelda: The Wind Waker 2002In the USA build, the time of day is a float from 0 to 360, 15 to an hour (dKy_getdaytime_hour divides by 15); dKy_daynight_check calls 6:00 to 17:59 day. The environment's setup sets the advance mTimeAdv to 0.02, which dKy_custom_timeset can change. Each setDaytime call adds it only when no event-night stop is set, the save's get-item flag (2, 0) is set, no event runs, and (USA and PAL only) Link isn't on stage "sea" room 14 with stage layer 2 or 3. In rooms that pass time (getTimePass) the clock wraps from 360 to 0 and the day of the week goes up by one; in other rooms it advances only by day before 165 (11:00) and by night from 270 (18:00) to 345 (23:00). At 0.02 a day is 18,000 setDaytime calls (computed).Code
Pokémon HeartGold and SoulSilver 2009HeartGold and SoulSilver (the US releases, which share this code) split the clock's hour into five periods with a 24-entry table: morning from 4:00 to 9:59, day from 10:00 to 16:59, evening from 17:00 to 19:59, night from 20:00 to 23:59, and late night from 0:00 to 3:59. Platinum's table gives every hour the same period (its names are morning, day, twilight, night, and late night). Gold and Silver have three periods: morning from 4:00, day from 10:00, and night from 18:00.Code
HeartGold and SoulSilver fold the five periods into three for wild Pokémon (GF_RTC_GetTimeOfDayWildParamByHour: morning; day or evening; night or late night), and grass encounters pick their species list the same way. IsNighttime is true at night or late night, so from 20:00 to 3:59 (computed from the hour table), and the evolution methods tied to the clock read it: friendship of at least 220 by day (EVO_FRIENDSHIP_DAY) or by night (EVO_FRIENDSHIP_NIGHT), and a held item by day or by night (EVO_ITEM_DAY, EVO_ITEM_NIGHT).Code
A HeartGold or SoulSilver map's encounter record holds one walking rate and three full species lists for its 12 grass slots, morning, day, and night, sharing one list of levels. Gold and Silver keep a separate grass rate for each time of day and three sets of 7 slots. Platinum keeps one 12-slot list and swaps only slots 2 and 3 for their day or night species outside the morning.Code
Factorio 2016A solar panel gives up to 60 kW. Nauvis's day lasts 7 minutes (25,200 ticks). Wube's comment marks the phases: full output for half of it, a fall over the next fifth (dusk), nothing for a tenth (night), and a rise over a fifth (dawn). The wiki says the fall and rise are linear, which gives an average of 70%, the 42 kW per panel the wiki states.Code

References

  1. ^ abcdeGold and Silver set the time of day from the cartridge clock's hour, morning from 4:00 to 9:59, day from 10:00 to 17:59, and night from 18:00 to 3:59.Codepret/pokegold
    How we know
    25GetTimeOfDay::
    26; get time of day based on the current hour
    27	ldh a, [hHours] ; hour
    28	ld hl, TimesOfDay
    ⋮
    42; get time of day
    ⋮
    48TimesOfDay:
    49; hours for the time of day
    50; 0400-0959 morn | 1000-1759 day | 1800-0359 nite
    51	db MORN_HOUR, NITE_F
    52	db DAY_HOUR,  MORN_F
    53	db NITE_HOUR, DAY_F
    
    engine/rtc/rtc.asm lines 25–55 at fc702b6 · upstream ↗
    37DEF MORN_HOUR EQU 4  ; 4 AM
    38DEF DAY_HOUR  EQU 10 ; 10 AM
    39DEF NITE_HOUR EQU 18 ; 6 PM
    
    constants/misc_constants.asm lines 37–39 at fc702b6 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  2. ^ abcdSimon's Quest keeps a clock of days, hours, and minutes in BCD that advances one minute every 15 frames outside the stopped cases, and when the hour reaches 6 or 18 it starts the day-night transition; a day is 24 hours.Code“Castlevania II - Simon's Quest (USA)”
    How we know

    In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 7 $D767-$D7C9: no tick in map type 5, in Simon's action $0B, while $34 is set, or while $8F stops time; else a counter $84 to 15, then minute $85 + 1 to 60, hour $86 + 1 to 24 (then day $83 + 1, up to 99); hour 6 or 18 jumps to the transition; bank 7 $CED8-$CEDD, in the transition, IsNightTime $82 flipped with XOR 1. We don't reproduce the bytes.

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  3. ^ abcIn the USA GameCube release (GAFE01_00, ACreTeam/ac-decomp), the town's daily update (mAGrw_RenewalFgItem_ovl) runs when the outdoor town scene is built and no event notice is showing, and compares the clock with the time of the last update. If the clock is earlier than that time, it runs a back-in-time pass (mAGrw_GROW_FIRST_FORCE; the decompilers' comment says "Used when you go back in time"). Otherwise it runs the daily pass only once the clock reaches the first 6:00 after the last update: 6:00 the same day if that update came before 6:00, or the next day's. Either pass then records the clock as the last update.CodeACreTeam/ac-decomp
    How we know
    3075    if (Save_Get(scene_no) == SCENE_FG) {
    ⋮
    3086        if (Common_Get(event_notification_active) != TRUE) {
    ⋮
    3088            is_over_time = lbRTC_IsOverTime(last_grow_time, now_time);
    ⋮
    3090            if (is_grow_time_equal == TRUE || is_over_time == lbRTC_LESS) {
    ⋮
    3095                    proc_type = mAGrw_GROW_FIRST_FORCE;
    ⋮
    3117                if (grow_time.hour >= 6) {
    3118                    lbRTC_Add_DD(&grow_time, 1);
    ⋮
    3126                grow_time.hour = 6;
    ⋮
    3128                if (lbRTC_IsOverTime(&grow_time, now_time) == lbRTC_OVER) {
    
    src/game/m_all_grow_ovl.c lines 3075–3128 at 09ca8e8 · upstream ↗
    3110                lbRTC_TimeCopy(last_grow_time, now_time);
    
    src/game/m_all_grow_ovl.c line 3110 at 09ca8e8 · upstream ↗
    3150                    lbRTC_TimeCopy(last_grow_time, now_time);
    
    src/game/m_all_grow_ovl.c line 3150 at 09ca8e8 · upstream ↗
    30  mAGrw_GROW_FIRST_FORCE, /* Used when you go back in time */
    
    include/m_all_grow_ovl.h lines 27–37 at 09ca8e8 · upstream ↗
    421  if (t1->year < t0->year) {
    422    return lbRTC_LESS;
    ⋮
    435                      return lbRTC_LESS;
    ⋮
    439                  return lbRTC_LESS;
    ⋮
    443              return lbRTC_LESS;
    ⋮
    447          return lbRTC_LESS;
    ⋮
    451      return lbRTC_LESS;
    ⋮
    455  return lbRTC_OVER;
    
    src/lb_rtc.c lines 420–456 at 09ca8e8 · upstream ↗
    1196extern void mFM_FieldInit(GAME_PLAY* play) {
    ⋮
    1220    mAGrw_RenewalFgItem(Common_GetPointer(time.rtc_time));
    
    src/game/m_field_make.c lines 1196–1220 at 09ca8e8 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  4. ^ abcdIn the N64 US 1.0 code, the actor En_Test4, which its file's comment describes as "Three-Day Events: day-night transitions", compares each update the clock with the next transition time (6:00 by night, 18:00 by day) by multiplying the 16-bit differences of the current and previous times from it and treating a product of 0 or less as a crossing (the atlas's reading of the test), unless a transition, a cutscene, setup actors, a room load, or the debug camera is under way. When the clock crosses 6:00 with the day counter at 3, it calls Interface_StartMoonCrash, which sets the day to 4 and the clock to 6:00 plus 10 units and starts a white fade to a Termina Field entrance. On days 1 and 2 the same crossing adds a day when no transition cutscene is set or the telescope is on; the other branch (z_en_test4.c L446-L470), which sets a flag the decomp names EVENTINF_TRIGGER_DAYTELOP for the Dawn of a New Day screen, is untraced. Play_Init spawns this actor in dungeon and boss rooms on any day but 0; elsewhere it comes from scene data the atlas hasn't read.Codezeldaret/mmrevised
    How we know
    4 * Description: Three-Day Events: day-night transitions, shrink screen before next day,
    
    src/overlays/actors/ovl_En_Test4/z_en_test4.c line 4 at 710e1a7 · upstream ↗
    404void EnTest4_HandleEvents(EnTest4* this, PlayState* play) {
    405    static u16 sDayNightTransitionTimes[THREEDAY_DAYTIME_MAX] = {
    406        CLOCK_TIME(6, 0),  // THREEDAY_DAYTIME_NIGHT
    407        CLOCK_TIME(18, 0), // THREEDAY_DAYTIME_DAY
    ⋮
    411    if ((play->transitionMode == TRANS_MODE_OFF) && !Play_InCsMode(play) && (play->numSetupActors <= 0) &&
    412        (play->roomCtx.status == 0) && !Play_IsDebugCamEnabled()) {
    413        u16 transitionTime = sDayNightTransitionTimes[this->daytimeIndex];
    ⋮
    419        curTimeUntilTransition = CURRENT_TIME - transitionTime;
    420        prevTimeUntilTransition = this->prevTime - transitionTime;
    ⋮
    429        if ((curTimeUntilTransition * prevTimeUntilTransition) <= 0) {
    ⋮
    439            } else if (transitionTime == CLOCK_TIME(6, 0)) {
    440                // previously night, turning day
    ⋮
    
    src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 404–445 at 710e1a7 · upstream ↗
    446                } else if (((sCsIdList[this->daytimeIndex] <= CS_ID_NONE) ||
    447                            (play->actorCtx.flags & ACTORCTX_FLAG_TELESCOPE_ON)) &&
    448                           (CURRENT_DAY != 3)) {
    449                    // Turn day without cutscene
    450                    EnTest4_HandleDayNightSwap(this, play);
    451                } else {
    ⋮
    463                            } else {
    ⋮
    470                    SET_EVENTINF(EVENTINF_TRIGGER_DAYTELOP);
    
    src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 446–470 at 710e1a7 · upstream ↗
    115    } else if ((sCsIdList[this->daytimeIndex] <= CS_ID_NONE) || (play->actorCtx.flags & ACTORCTX_FLAG_TELESCOPE_ON)) {
    116        // Previously night, turning day, without a cutscene
    117        Sram_IncrementDay();
    118        gSaveContext.save.time = CLOCK_TIME(6, 0);
    
    src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 115–118 at 710e1a7 · upstream ↗
    655void Sram_IncrementDay(void) {
    656    if (CURRENT_DAY <= 3) {
    657        gSaveContext.save.day++;
    658        gSaveContext.save.eventDayCount++;
    
    src/code/z_sram_NES.c lines 655–658 at 710e1a7 · upstream ↗
    5612void Interface_StartMoonCrash(PlayState* play) {
    ⋮
    5617    gSaveContext.save.day = 4;
    5618    gSaveContext.save.eventDayCount = 4;
    5619    gSaveContext.save.time = CLOCK_TIME(6, 0) + 10;
    5620    play->nextEntrance = ENTRANCE(TERMINA_FIELD, 12);
    5621    gSaveContext.nextCutsceneIndex = 0;
    5622    play->transitionTrigger = TRANS_TRIGGER_START;
    5623    play->transitionType = TRANS_TYPE_FADE_WHITE;
    
    src/code/z_parameter.c lines 5612–5623 at 710e1a7 · upstream ↗
    2316    if ((CURRENT_DAY != 0) &&
    2317        ((this->roomCtx.curRoom.type == ROOM_TYPE_DUNGEON) || (this->roomCtx.curRoom.type == ROOM_TYPE_BOSS))) {
    2318        Actor_Spawn(&this->actorCtx, this, ACTOR_EN_TEST4, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0);
    
    src/code/z_play.c lines 2316–2318 at 710e1a7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  5. ^ abcOn each step, TryWildEncounter starts a battle when Random is below the map's rate for the time of day (morning, day, or night) or its water rate; the Pokémon March or Ruins of Alph radio doubles the rate, and the Pokémon Lullaby or a Cleanse Tag in the party halves it.Codepret/pokecrystal
    How we know
    195.EncounterRate:
    196	call GetMapEncounterRate
    197	call ApplyMusicEffectOnEncounterRate
    198	call ApplyCleanseTagEffectOnEncounterRate
    199	call Random
    200	cp b
    201	ret
    ⋮
    214	ret
    ⋮
    217; Pokemon March and Ruins of Alph signal double encounter rate.
    218; Pokemon Lullaby halves encounter rate.
    ⋮
    227	ret
    ⋮
    231	ret
    ⋮
    
    engine/overworld/wildmons.asm lines 195–250 at 97187cd · upstream ↗
    1237	def_grass_wildmons ROUTE_29
    1238	db 10 percent, 10 percent, 10 percent ; encounter rates: morn/day/nite
    
    data/wild/johto_grass.asm lines 1237–1238 at 97187cd · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-20.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  6. ^ abOn each step, Gold and Silver's TryWildEncounter reads the map's encounter rate for the current time of day (morning, day, or night), or its water rate, doubles it for the Pokémon March or Ruins of Alph radio, halves it for the Pokémon Lullaby or a Cleanse Tag, and starts a battle when Random is below it; Crystal keeps this unchanged.Codepret/pokegold · pret/pokecrystal
    How we know
    212.EncounterRate:
    213	call GetMapEncounterRate
    214	call ApplyMusicEffectOnEncounterRate
    215	call ApplyCleanseTagEffectOnEncounterRate
    216	call Random
    217	cp b
    218	ret
    ⋮
    220GetMapEncounterRate:
    221	ld hl, wMornEncounterRate
    222	call CheckOnWater
    223	ld a, wWaterEncounterRate - wMornEncounterRate
    224	jr z, .ok
    ⋮
    
    engine/overworld/wildmons.asm lines 212–251 at fc702b6 · upstream ↗
    engine/overworld/wildmons.asm#L176-L251 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  7. ^ abcIn the USA GameCube release (GAFE01_00, ACreTeam/ac-decomp), the daily pass of the town update adds up to 5 weeds for each 6:00 passed since the last update (computed from mAGrw_GetGrassMax), with no cap on the days counted. Each weed goes on a random empty square, in a random town block that has one, that is plantable ground (mCoBG_PLANT4) and not marked off by the cancel map; weeds stop when no such square is left. The weed kinds cycle through a shuffled table of 12. While clear_grass is set (a decompilers' comment: "set by Wisp, removes all weeds"), the next update removes every weed, adds none, and clears the flag; the back-in-time pass adds none either.CodeACreTeam/ac-decomp
    How we know
    2754    delta_days++;
    2755    if (delta_days > 1 && now_time->hour < 6) {
    2756        delta_days--;
    ⋮
    2759    return delta_days * mAGrw_GRASS_PER_DAY;
    
    src/game/m_all_grow_ovl.c lines 2744–2760 at 09ca8e8 · upstream ↗
    19#define mAGrw_GRASS_TABLE_NUM 12
    ⋮
    25#define mAGrw_GRASS_PER_DAY 5
    
    include/m_all_grow_ovl.h lines 19–25 at 09ca8e8 · upstream ↗
    601  days += t1->day - 1;
    602  days += total_days[over_leap][t1->month - 1];
    
    src/lb_rtc.c lines 542–609 at 09ca8e8 · upstream ↗
    2778            if (((cancel[0] >> ut_x) & 1) != 1 && (items[0] == EMPTY_NO) &&
    2779                (mCoBG_Attribute2CheckPlant(col->data.unit_attribute, &wpos_temp) == mCoBG_PLANT4)) {
    
    src/game/m_all_grow_ovl.c lines 2762–2792 at 09ca8e8 · upstream ↗
    2856    grass_max = mAGrw_GetGrassMax(now_time, grow_time);
    ⋮
    2876    for (i = 0; i < grass_max; i++) {
    2877        if (candidate_blocks > 0) {
    ⋮
    2883            selected_block = RANDOM(candidate_blocks);
    ⋮
    2910            grass_table_idx++;
    
    src/game/m_all_grow_ovl.c lines 2835–2918 at 09ca8e8 · upstream ↗
    3078        if (Save_Get(clear_grass)) {
    3079            mAGrw_ClearGrass();
    
    src/game/m_all_grow_ovl.c lines 3078–3080 at 09ca8e8 · upstream ↗
    2929            if (IS_ITEM_GRASS(items[0])) {
    2930                items[0] = EMPTY_NO;
    
    src/game/m_all_grow_ovl.c lines 2920–2936 at 09ca8e8 · upstream ↗
    3143                    if (Save_Get(clear_grass) == FALSE) {
    3144                        mAGrw_SetGrass(now_time, &grow_time, l_cancel_ut);
    ⋮
    3155            Save_Set(clear_grass, FALSE);
    
    src/game/m_all_grow_ovl.c lines 3143–3155 at 09ca8e8 · upstream ↗
    139    /* 0x021395 */ u8 clear_grass; /* set by Wisp, removes all weeds */
    
    include/m_common_data.h line 139 at 09ca8e8 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  8. ^ abcHeartGold and SoulSilver (the US releases, which share this code) split the clock's hour into five periods with a 24-entry table: morning from 4:00 to 9:59, day from 10:00 to 16:59, evening from 17:00 to 19:59, night from 20:00 to 23:59, and late night from 0:00 to 3:59. Platinum's table gives every hour the same period (its names are morning, day, twilight, night, and late night). Gold and Silver have three periods: morning from 4:00, day from 10:00, and night from 18:00.Codepret/pokeheartgold · pret/pokeplatinum · pret/pokegold
    How we know
    8typedef enum RTC_TimeOfDay {
    9    RTC_TIMEOFDAY_MORN = 0,
    10    RTC_TIMEOFDAY_DAY,
    11    RTC_TIMEOFDAY_EVE,
    12    RTC_TIMEOFDAY_NITE,
    13    RTC_TIMEOFDAY_LATE,
    
    include/gf_rtc.h lines 8–15 at 6988158 · upstream ↗
    164TIMEOFDAY GF_RTC_GetTimeOfDayByHour(s32 hour) {
    165    static const u8 sTimeOfDayByHour[24] = {
    166        RTC_TIMEOFDAY_LATE,
    167        RTC_TIMEOFDAY_LATE,
    168        RTC_TIMEOFDAY_LATE,
    169        RTC_TIMEOFDAY_LATE,
    170        RTC_TIMEOFDAY_MORN,
    171        RTC_TIMEOFDAY_MORN,
    172        RTC_TIMEOFDAY_MORN,
    173        RTC_TIMEOFDAY_MORN,
    174        RTC_TIMEOFDAY_MORN,
    175        RTC_TIMEOFDAY_MORN,
    ⋮
    
    src/gf_rtc.c lines 164–193 at 6988158 · upstream ↗
    153enum TimeOfDay TimeOfDayForHour(int hour)
    ⋮
    155    static const u8 lookup[24] = {
    156        TIMEOFDAY_LATE_NIGHT,
    157        TIMEOFDAY_LATE_NIGHT,
    158        TIMEOFDAY_LATE_NIGHT,
    159        TIMEOFDAY_LATE_NIGHT,
    160        TIMEOFDAY_MORNING,
    161        TIMEOFDAY_MORNING,
    162        TIMEOFDAY_MORNING,
    163        TIMEOFDAY_MORNING,
    164        TIMEOFDAY_MORNING,
    165        TIMEOFDAY_MORNING,
    ⋮
    
    src/rtc.c lines 153–183 at 49f78f3 · upstream ↗
    37DEF MORN_HOUR EQU 4  ; 4 AM
    38DEF DAY_HOUR  EQU 10 ; 10 AM
    39DEF NITE_HOUR EQU 18 ; 6 PM
    
    constants/misc_constants.asm lines 37–39 at fc702b6 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  9. ^ abcHeartGold and SoulSilver fold the five periods into three for wild Pokémon (GF_RTC_GetTimeOfDayWildParamByHour: morning; day or evening; night or late night), and grass encounters pick their species list the same way. IsNighttime is true at night or late night, so from 20:00 to 3:59 (computed from the hour table), and the evolution methods tied to the clock read it: friendship of at least 220 by day (EVO_FRIENDSHIP_DAY) or by night (EVO_FRIENDSHIP_NIGHT), and a held item by day or by night (EVO_ITEM_DAY, EVO_ITEM_NIGHT).Codepret/pokeheartgold
    How we know
    142BOOL IsNighttime(void) {
    143    switch (GF_RTC_GetTimeOfDay()) {
    144    case RTC_TIMEOFDAY_NITE:
    145    case RTC_TIMEOFDAY_LATE:
    146        return TRUE;
    147    default:
    148        return FALSE;
    
    src/gf_rtc.c lines 142–150 at 6988158 · upstream ↗
    196TimeOfDayWildParam GF_RTC_GetTimeOfDayWildParamByHour(s32 hour) {
    197    switch (GF_RTC_GetTimeOfDayByHour(hour)) {
    198    case RTC_TIMEOFDAY_MORN:
    199        return TIMEOFDAY_WILD_MORN;
    200    case RTC_TIMEOFDAY_DAY:
    201    case RTC_TIMEOFDAY_EVE:
    202        return TIMEOFDAY_WILD_DAY;
    203    default:
    204        return TIMEOFDAY_WILD_NITE;
    
    src/gf_rtc.c lines 196–205 at 6988158 · upstream ↗
    119static void EncSlotArray_Init_Land(const EncounterData *encData, EncounterSlot *encSlots) {
    120    TIMEOFDAY timeOfDay = GF_RTC_GetTimeOfDay();
    ⋮
    123    if (timeOfDay == RTC_TIMEOFDAY_MORN) {
    124        slotSpecies = encData->landSlots.species_morn;
    125    } else if (timeOfDay == RTC_TIMEOFDAY_DAY || timeOfDay == RTC_TIMEOFDAY_EVE) {
    126        slotSpecies = encData->landSlots.species_day;
    127    } else if (timeOfDay == RTC_TIMEOFDAY_NITE || timeOfDay == RTC_TIMEOFDAY_LATE) {
    128        slotSpecies = encData->landSlots.species_nite;
    
    src/field/encounter_check.c lines 119–130 at 6988158 · upstream ↗
    2829            case EVO_FRIENDSHIP_DAY:
    2830                if (IsNighttime() == 0 && friendship >= 220) {
    ⋮
    2835            case EVO_FRIENDSHIP_NIGHT:
    2836                if (IsNighttime() == 1 && friendship >= 220) {
    
    src/pokemon.c lines 2829–2839 at 6988158 · upstream ↗
    2902            case EVO_ITEM_DAY:
    2903                if (IsNighttime() == 0 && evoTable[i].param == heldItem) {
    ⋮
    2908            case EVO_ITEM_NIGHT:
    2909                if (IsNighttime() == 1 && evoTable[i].param == heldItem) {
    
    src/pokemon.c lines 2902–2909 at 6988158 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  10. ^ abIn Simon's Quest an enemy placed while it's night starts with double the hit points its level data gives, except a few object types and in the mansions.Code“Castlevania II - Simon's Quest (USA)” · FoxCunning/Castlevania2
    How we know

    In the cartridge (“Castlevania II - Simon's Quest (USA)”): bank 1 $810D-$814C: if IsNightTime ($82), and the type isn't $21, $22, $25-$27, $2D-$2F, or $34, and map type ($30) isn't 1, the HP byte is shifted left once before it's stored in $04C2. We don't reproduce the bytes.

    531LevelData_Stairs_1_Mansions_2_3_11_12:
    
    bank_2.asm line 531 at 2abe12c · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-21.

    Checked by a second AI model, 2026-10-21.

    In the claim ledger

  11. ^ abIn the US release, each step of the gameplay loop adds 10 to the clock's seconds, as long as the map's LEVEL_TIME_FLOWS flag is set, no animation has suspended time, and the player entity passes checkEntityMapSpaceDependent and isn't paused; 60 seconds make a minute. So a game minute is 6 steps and a game hour 360. The main loop steps at most once per video retrace (mainLoopUpdateInterval is 1), and the retrace callback counts 60 calls as its cycle. Assuming 60 retraces a second (NTSC's rate is about 59.94), the clock runs at most 10 game minutes per real second, an hour in 6 real seconds (computed under that assumption). The real rate depends on how many steps the game finishes each second, which the atlas hasn't measured.Codeharvestwhisperer/hm64-decomprevised
    How we know
    48    if ((getLevelFlags(gBaseMapIndex) & LEVEL_TIME_FLOWS) && !checkDailyEventBit(SUSPEND_TIME_DURING_ANIMATION)) {
    
    src/game/time.c lines 46–50 at 9824b88 · upstream ↗
    107        gSeconds += 10;
    
    src/game/time.c lines 104–113 at 9824b88 · upstream ↗
    59        handleTimeUpdates();
    
    src/game/transition.c lines 50–59 at 9824b88 · upstream ↗
    165    mainLoopUpdateInterval = 1;
    
    src/mainproc.c lines 164–165 at 9824b88 · upstream ↗
    307    if ((vblankCounter % mainLoopUpdateInterval) == 0) {
    
    src/mainLoop.c lines 305–325 at 9824b88 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  12. ^ abThe clock advances by the frame's real time (gsys->getFrameTime()), and a 24-hour game day lasts 60 × daySpeed × day_multiply real seconds: daySpeed (p00) comes from parms/gamePrms.bin, with a code default of 20 minutes that a decompilation comment gives as 27 in the file, and day_multiply comes from the stage file, 1 if it has none. Each day starts at startHour (t00, default 7.0) and ends when the time of day reaches endHour (t01, default 19.0), so the playable span is 12 ÷ 24 of a game day (computed): with day_multiply at 1, 10 real minutes at the code defaults and 13.5 at the comment's 27. The clock advances only while no reset is pending (gsys->resetPending()), no menu is open outside a cutscene, nothing is paused (mPauseAll), no window is over the screen (mIsUIOverlayActive), no cutscene plays, the section's update flags include UPDATE_WORLD_CLOCK, and the game isn't in the tutorial (isTutorial()).CodeprojectPiki/pikminrevised
    How we know
    599		    , mStartHour(this, 7.0f, 0.0f, 0.0f, "t00", "startHour")
    600		    , mEndHour(this, 19.0f, 0.0f, 0.0f, "t01", "endHour")
    601		    , mRealMinutesPerGameDay(this, 20.0f, 0.0f, 0.0f, "p00", "daySpeed")
    
    include/gameflow.h lines 599–601 at 9a21636 · upstream ↗
    619		Parm<f32> mRealMinutesPerGameDay; ///< _24, p00 - how many real-life minutes correspond to one (24-hr) in-game "day" - def: 27 mins.
    
    include/gameflow.h line 619 at 9a21636 · upstream ↗
    594	load("parms/", "gamePrms.bin", 1);
    
    src/plugPikiColin/gameflow.cpp line 594 at 9a21636 · upstream ↗
    737		gameflow.mWorldClock.mRealSecsPerGameDay  = 60.0f * (gameflow.mTimeMultiplier * gameflow.mParameters->mRealMinutesPerGameDay());
    738		gameflow.mWorldClock.mRealSecsPerGameHour = gameflow.mWorldClock.mRealSecsPerGameDay / gameflow.mWorldClock.mHoursInDay;
    
    include/gameflow.h lines 737–738 at 9a21636 · upstream ↗
    2226		gameflow.mTimeMultiplier = 1.0f;
    ⋮
    2236				} else if (stream->isToken("day_multiply")) {
    2237					sscanf(stream->getToken(true), "%f", &gameflow.mTimeMultiplier);
    
    src/plugPikiColin/newPikiGame.cpp lines 2226–2237 at 9a21636 · upstream ↗
    204	mRealSecsIntoHour += gsys->getFrameTime() * playRate;
    205	if (mRealSecsIntoHour >= mRealSecsPerGameHour) {
    206		mRealSecsIntoHour -= mRealSecsPerGameHour;
    207		mCurrentGameHour++;
    ⋮
    215	mTimeOfDay         = mCurrentGameHour + mRealSecsIntoHour / mRealSecsPerGameHour;
    
    src/plugPikiColin/gameflow.cpp lines 204–215 at 9a21636 · upstream ↗
    2155			if (!gsys->resetPending() && (!mActiveMenu || gameflow.mMoviePlayer->mIsActive)) {
    2156				if (!gameflow.mPauseAll && !gameflow.mIsUIOverlayActive) {
    2157					if (!gameflow.mMoviePlayer->mIsActive && (mUpdateFlags & UPDATE_WORLD_CLOCK) && !playerState->isTutorial()) {
    ⋮
    2159						gameflow.mWorldClock.update(1.0f);
    
    src/plugPikiColin/newPikiGame.cpp lines 2155–2159 at 9a21636 · upstream ↗
    286				// handle story mode world map screen if we've made a decision
    ⋮
    299								enterCourse(stage);
    ⋮
    302								gameflow.mWorldClock.setTime(gameflow.mParameters->mStartHour());
    
    src/plugPikiColin/mapSelect.cpp lines 286–302 at 9a21636 · upstream ↗
    864	if (!gameflow.mIsDayEndActive && !gameflow.mMoviePlayer->mIsActive
    865	    && gameflow.mWorldClock.mTimeOfDay >= gameflow.mParameters->mEndHour()) {
    ⋮
    870		gameflow.mIsDayEndTriggered = TRUE;
    
    src/plugPikiColin/newPikiGame.cpp lines 864–870 at 9a21636 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  13. ^ abWhen a day ends (GameCoreSection::cleanupDayEnd), outside challenge mode, the tutorial, and the game's ending (isEnding(): the 30th day, or all 30 ship parts), every Pikmin is killed and counted as left behind unless it is entering or leaving an Onion, or in its LookAt state, or following the captain (formation mode) in a state other than drowning, burning, swallowed, bubbled, dying, or flicked, or in free mode (FreeMode, in any state) within mSunsetSafetyRange (p60, "日没生き残り範囲", code default 200, read from parms/pikiMgr.bin) of an Onion or of the ship, measured by qdist2's ground-plane approximation (|dx| + |dz| − ½ min). Pikmin with mushroom heads die too. If any were left behind, the take-off cutscene plays its enemy-attack version. The survivors then all go into their color's Onion (exitDayEnd), and a Pikmin with no Onion of its color is killed.CodeprojectPiki/pikminrevised
    How we know
    598	PRINT("STEP (2) : remove objects (teki/boss/pellet/free pikis)\n");
    ⋮
    600	if (!playerState->isChallengeMode() && !playerState->isTutorial() && !playerState->isEnding()) {
    ⋮
    607			if (piki->isKinoko()) {
    ⋮
    614				piki->kill(false);
    
    src/plugPikiKando/gameCoreSection.cpp lines 598–618 at 9a21636 · upstream ↗
    630			if (mode == PikiMode::FormationMode) {
    631				if (state == PIKISTATE_Drown || state == PIKISTATE_Fired || state == PIKISTATE_Dead || state == PIKISTATE_Swallowed
    632				    || state == PIKISTATE_Bubble || state == PIKISTATE_Dying || state == PIKISTATE_Flick || !piki->isAlive()) {
    633					// do nothing
    634				} else {
    635					continue;
    ⋮
    638			if (mode == PikiMode::ExitMode || mode == PikiMode::EnterMode) {
    639				continue;
    640			} else if (state == PIKISTATE_LookAt) {
    641				continue;
    ⋮
    645			if (piki->mMode == PikiMode::FreeMode) {
    ⋮
    650						    <= pikiMgr->mPikiParms->mPikiParms.mSunsetSafetyRange()) {
    ⋮
    
    src/plugPikiKando/gameCoreSection.cpp lines 629–676 at 9a21636 · upstream ↗
    112		    , mSunsetSafetyRange(this, 200.0f, 0.0f, 5000.0f, "p60", "日没生き残り範囲")
    
    include/PikiMgr.h line 112 at 9a21636 · upstream ↗
    81	load("parms/", "pikiMgr.bin", 1);
    
    src/plugPikiKando/pikiMgr.cpp line 81 at 9a21636 · upstream ↗
    511	if (x1 > y1) {
    512		min = y1;
    513	} else {
    514		min = x1;
    ⋮
    517	return (x1 + y1) - (0.5f * min);
    
    src/sysCommon/sysMath.cpp lines 511–517 at 9a21636 · upstream ↗
    110bool PlayerState::isEnding()
    ⋮
    112	if (getCurrDay() >= (MAX_DAYS - 1)) {
    113		// we've hit our 30-day limit
    114		return true;
    ⋮
    116	} else if (getCurrParts() >= MAX_UFO_PARTS) {
    ⋮
    118		return true;
    
    src/plugPikiKando/playerState.cpp lines 110–118 at 9a21636 · upstream ↗
    1507			if (dayEndObjFlags == 0) {
    1508				// no dead pikmin! use correct (frustrated/neutral) animation
    1509				dayEndObjFlags |= CAF_DayEndEnemyNoDeaths;
    1510			} else {
    1511				// dead pikmin :( use killing animation
    1512				dayEndObjFlags |= CAF_DayEndEnemyAttack;
    
    src/plugPikiColin/newPikiGame.cpp lines 1507–1512 at 9a21636 · upstream ↗
    362		if (piki->isAlive()) {
    363			GoalItem* item = itemMgr->getContainer(piki->mColor);
    364			if (item) {
    365				item->enterGoal(piki);
    366				entered++;
    367			} else {
    368				piki->kill(false);
    
    src/plugPikiKando/gameCoreSection.cpp lines 362–369 at 9a21636 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  14. ^ abIn the USA build, the time of day is a float from 0 to 360, 15 to an hour (dKy_getdaytime_hour divides by 15); dKy_daynight_check calls 6:00 to 17:59 day. The environment's setup sets the advance mTimeAdv to 0.02, which dKy_custom_timeset can change. Each setDaytime call adds it only when no event-night stop is set, the save's get-item flag (2, 0) is set, no event runs, and (USA and PAL only) Link isn't on stage "sea" room 14 with stage layer 2 or 3. In rooms that pass time (getTimePass) the clock wraps from 360 to 0 and the day of the week goes up by one; in other rooms it advances only by day before 165 (11:00) and by night from 270 (18:00) to 345 (23:00). At 0.02 a day is 18,000 setDaytime calls (computed).Codezeldaret/tww
    How we know
    476    g_env_light.mTimeAdv = 0.02f;
    
    src/d/d_kankyo.cpp line 476 at cb24f55 · upstream ↗
    502void dScnKy_env_light_c::setDaytime() {
    ⋮
    504#if VERSION > VERSION_DEMO
    ⋮
    506#endif
    ⋮
    510#if VERSION > VERSION_JPN
    511    if (strcmp(dComIfGp_getStartStageName(), "sea") == 0 && dComIfGp_roomControl_getStayNo() == 14)
    ⋮
    513        if (dComIfGp_getStartStageLayer() == 2 || dComIfGp_getStartStageLayer() == 3) {
    514            var_r30 = true;
    ⋮
    517#endif
    ⋮
    519    if (!dKy_checkEventNightStop() && dComIfGs_isGetItem(2, 0) && dComIfGp_event_runCheck() == FALSE
    520#if VERSION > VERSION_DEMO
    521        && !var_r30
    522#endif
    ⋮
    
    src/d/d_kankyo.cpp lines 502–538 at cb24f55 · upstream ↗
    614int dKy_getdaytime_hour() {
    615    return dComIfGs_getTime() / 15.0f;
    ⋮
    625int dKy_daynight_check() {
    626    s32 hour = dKy_getdaytime_hour();
    ⋮
    628    if (hour >= 6 && hour < 18) {
    629        return dKy_TIME_DAY_e;
    
    src/d/d_kankyo.cpp lines 614–631 at cb24f55 · upstream ↗
    3361void dKy_custom_timeset(f32 i_speed) {
    3362    g_env_light.mTimeAdv = i_speed;
    
    src/d/d_kankyo.cpp lines 3361–3362 at cb24f55 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Checked by a second AI model, 2026-10-22.

    In the claim ledger

  15. ^In the N64 US 1.0 code the clock is a 16-bit count in which a day is 0x10000 units, so a game minute is about 45.5 units (computed; the macro CLOCK_TIME_MINUTE truncates it to 45). Each play update, Environment_UpdateTime adds the time speed R_TIME_SPEED and then, if that speed isn't 0, the save's timeSpeedOffset. It adds only when time isn't stopped, the game isn't paused or over, no textbox is open (or its message id is 0xF7, 0x20D2, 0x140C, or 0x100 through 0x200, or the game mode is the end credits), the debug frame advance (FrameAdvance_IsEnabled) is off, no transition is under way (transitionMode off, or a game mode other than normal) and none has been triggered, and no cutscene runs. From 18:00 until 6:00 it sets the save's isNight flag.Codezeldaret/mmrevised
    How we know
    23#define CLOCK_TIME(hr, min) (s32)(((hr) * 60 + (min)) * 0x10000 / (24 * 60))
    24#define CLOCK_TIME_MINUTE  (CLOCK_TIME(0, 1))
    25#define CLOCK_TIME_HOUR (CLOCK_TIME(1, 0))
    26#define DAY_LENGTH (CLOCK_TIME(24, 0))
    
    include/macros.h lines 23–26 at 710e1a7 · upstream ↗
    334    /* 0x0C */ u16 time;            // "zelda_time"
    ⋮
    336    /* 0x10 */ s32 isNight;         // "asahiru_fg"
    337    /* 0x14 */ s32 timeSpeedOffset; // "change_zelda_time"
    338    /* 0x18 */ s32 day;             // "totalday"
    
    include/z64save.h lines 334–338 at 710e1a7 · upstream ↗
    1203    if (!sEnvIsTimeStopped && (pauseCtx->state == PAUSE_STATE_OFF) && (gameOverCtx->state == GAMEOVER_INACTIVE)) {
    1204        if ((msgCtx->msgMode == MSGMODE_NONE) || (msgCtx->currentTextId == 0xF7) || (msgCtx->currentTextId == 0x20D2) ||
    1205            (msgCtx->currentTextId == 0x140C) ||
    1206            ((msgCtx->currentTextId >= 0x100) && (msgCtx->currentTextId <= 0x200)) ||
    1207            (gSaveContext.gameMode == GAMEMODE_END_CREDITS)) {
    1208            if (!FrameAdvance_IsEnabled(play) &&
    1209                ((play->transitionMode == TRANS_MODE_OFF) || (gSaveContext.gameMode != GAMEMODE_NORMAL))) {
    1210                if (play->transitionTrigger == TRANS_TRIGGER_OFF) {
    1211                    if ((CutsceneManager_GetCurrentCsId() == CS_ID_NONE) && !Play_InCsMode(play)) {
    1212                        gSaveContext.save.time = CURRENT_TIME + (u16)R_TIME_SPEED;
    1213                        if (R_TIME_SPEED != 0) {
    1214                            gSaveContext.save.time = CURRENT_TIME + (u16)((void)0, gSaveContext.save.timeSpeedOffset);
    
    src/code/z_kankyo.c lines 1203–1214 at 710e1a7 · upstream ↗
    1227    time = CURRENT_TIME;
    ⋮
    1229    if ((time >= CLOCK_TIME(18, 0)) || (time < CLOCK_TIME(6, 0))) {
    1230        gSaveContext.save.isNight = true;
    
    src/code/z_kankyo.c lines 1227–1230 at 710e1a7 · upstream ↗
    1774    if (pauseCtx->state == PAUSE_STATE_OFF) {
    ⋮
    1779        Environment_UpdateTime(play, envCtx, pauseCtx, msgCtx, gameOverCtx);
    
    src/code/z_kankyo.c lines 1774–1779 at 710e1a7 · upstream ↗
    1051    Environment_Update(this, &this->envCtx, &this->lightCtx, &this->pauseCtx, &this->msgCtx, &this->gameOverCtx,
    
    src/code/z_play.c line 1051 at 710e1a7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  16. ^In the N64 US 1.0 code each scene's header sets its time speed, and a header value of 0xFF gives 0, a scene where time stands still. While Link's ocarina slot is empty, a nonzero scene speed becomes 5, under a decompilers' comment that reads "Increase time speed during first cycle"; the scene's speed becomes R_TIME_SPEED only while Sun's Song is inactive. The Inverted Song of Time is offered only where the scene's restriction flags allow it (otherwise text 0x1B95 and nothing) and the speed isn't 0; accepting it sets the offset to −2, or back to 0 if it was already set, and the update adds the offset only while the speed isn't 0. The game updates once every 3 video frames, set by GameState_SetFramerateDivisor(3) into a field whose comment reads "how many VIs should elapse before next swap". Assuming NTSC's 59.94 video frames a second (the atlas's assumption, not in the code), that is about 20 updates a second, and at speed 5 a game minute takes about 0.46 s, a day about 656 s, and the three days about 33 minutes (computed). The usual speed of a scene is in its header, ROM data the decompilation doesn't hold.Codezeldaret/mmrevised
    How we know
    393    if (cmd->timeSettings.timeSpeed != 0xFF) {
    394        play->envCtx.sceneTimeSpeed = cmd->timeSettings.timeSpeed;
    395    } else {
    396        play->envCtx.sceneTimeSpeed = 0;
    ⋮
    399    // Increase time speed during first cycle
    400    if ((gSaveContext.save.saveInfo.inventory.items[SLOT_OCARINA] == ITEM_NONE) && (play->envCtx.sceneTimeSpeed != 0)) {
    401        play->envCtx.sceneTimeSpeed = 5;
    ⋮
    404    if (gSaveContext.sunsSongState == SUNSSONG_INACTIVE) {
    405        R_TIME_SPEED = play->envCtx.sceneTimeSpeed;
    
    src/code/z_scene.c lines 393–406 at 710e1a7 · upstream ↗
    5890                } else if (sLastPlayedSong == OCARINA_SONG_INVERTED_TIME) {
    5891                    if (interfaceCtx->restrictions.invSongOfTime == 0) {
    5892                        if (R_TIME_SPEED != 0) {
    ⋮
    5895                            } else {
    ⋮
    5898                            play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_INVERTED_TIME;
    5899                        } else {
    5900                            Message_StartTextbox(play, 0x1B8B, NULL);
    5901                            play->msgCtx.ocarinaMode = OCARINA_MODE_END;
    ⋮
    5903                    } else {
    5904                        sLastPlayedSong = 0xFF;
    5905                        Message_StartTextbox(play, 0x1B95, NULL);
    5906                        play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_RESTRICTED_SONG;
    
    src/code/z_message.c lines 5890–5906 at 710e1a7 · upstream ↗
    1212                        gSaveContext.save.time = CURRENT_TIME + (u16)R_TIME_SPEED;
    1213                        if (R_TIME_SPEED != 0) {
    1214                            gSaveContext.save.time = CURRENT_TIME + (u16)((void)0, gSaveContext.save.timeSpeedOffset);
    
    src/code/z_kankyo.c lines 1212–1214 at 710e1a7 · upstream ↗
    5683                } else if ((msgCtx->textboxEndType == TEXTBOX_ENDTYPE_TWO_CHOICE) &&
    5684                           (play->msgCtx.ocarinaMode == OCARINA_MODE_PROCESS_INVERTED_TIME)) {
    5685                    if (Message_ShouldAdvance(play)) {
    5686                        if (msgCtx->choiceIndex == 0) {
    5687                            Audio_PlaySfx_MessageDecide();
    5688                            if (gSaveContext.save.timeSpeedOffset == 0) {
    5689                                play->msgCtx.ocarinaMode = OCARINA_MODE_APPLY_INV_SOT_SLOW;
    5690                                gSaveContext.save.timeSpeedOffset = -2;
    5691                            } else {
    5692                                play->msgCtx.ocarinaMode = OCARINA_MODE_APPLY_INV_SOT_FAST;
    5693                                gSaveContext.save.timeSpeedOffset = 0;
    
    src/code/z_message.c lines 5683–5694 at 710e1a7 · upstream ↗
    40void GameState_SetFramerateDivisor(GameState* gameState, s32 divisor) {
    41    R_UPDATE_RATE = divisor;
    42    gameState->framerateDivisor = divisor;
    43    GameState_UpdateFramerateDivisors(divisor);
    
    src/code/game.c lines 40–43 at 710e1a7 · upstream ↗
    243    GameState_SetFramerateDivisor(gameState, 3);
    
    src/code/game.c line 243 at 710e1a7 · upstream ↗
    236        cfb->updateRate = gameState->framerateDivisor;
    
    src/code/graph.c line 236 at 710e1a7 · upstream ↗
    25    /* 0x11 */ s8 updateRate; // how many VIs should elapse before next swap
    
    include/scheduler.h line 25 at 710e1a7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  17. ^ abIn the N64 US 1.0 code, answering yes to the Song of Time's prompt runs Sram_SaveEndOfCycle, whose comment says it is "Used by Song of Time (when clicking "Yes") and (indirectly) by the "Dawn of the New Day" cutscene". The function sets the day counter to 0 and the clock one unit before 6:00, clears the Inverted Song's offset, and adds one to a reset count capped at 999, but on the song's path the message code saves the day, the time, and the cutscene index before the call and puts them back right after it; where the cycle returns to the first dawn is untraced. It sets the rupees Link carries to 0 and every ammo count to 0 except the pictograph box's, and turns any bottle holding an item from ITEM_POTION_RED through ITEM_OBABA_DRINK back into an empty bottle. It sets a sword at or below the Razor Sword back to the Kokiri Sword (or the Gilded Sword if a stolen-item slot holds it), removes dungeon keys, boss keys, stray fairies, and the pictograph, and clears the event-info flags. Scene flags (switches, chests, collectibles) and week-event flags survive only where a per-scene or per-flag persistence table marks them. Among the rest, it resets five minigame high scores and the three Deku Playground scores, but not the bank balance, which is kept in the high-score slot HS_BANK_RUPEES.Codezeldaret/mmrevised
    How we know
    5881                if (sLastPlayedSong == OCARINA_SONG_TIME) {
    5882                    if (interfaceCtx->restrictions.songOfTime == 0) {
    5883                        Message_StartTextbox(play, 0x1B8A, NULL);
    5884                        play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_SOT;
    
    src/code/z_message.c lines 5881–5884 at 710e1a7 · upstream ↗
    5668                } else if ((msgCtx->textboxEndType == TEXTBOX_ENDTYPE_TWO_CHOICE) &&
    5669                           (play->msgCtx.ocarinaMode == OCARINA_MODE_PROCESS_SOT)) {
    5670                    if (Message_ShouldAdvance(play)) {
    5671                        if (msgCtx->choiceIndex == 0) {
    5672                            Audio_PlaySfx_MessageDecide();
    5673                            msgCtx->msgMode = MSGMODE_NEW_CYCLE_0;
    
    src/code/z_message.c lines 5668–5673 at 710e1a7 · upstream ↗
    6022        case MSGMODE_NEW_CYCLE_0:
    6023            play->state.unk_A3 = 1;
    6024            sp44 = gSaveContext.save.cutsceneIndex;
    6025            sp3E = CURRENT_TIME;
    6026            sp40 = gSaveContext.save.day;
    ⋮
    6028            Sram_SaveEndOfCycle(play);
    6029            gSaveContext.timerStates[TIMER_ID_MOON_CRASH] = TIMER_STATE_OFF;
    6030            func_8014546C(&play->sramCtx);
    ⋮
    6032            gSaveContext.save.day = sp40;
    6033            gSaveContext.save.time = sp3E;
    6034            gSaveContext.save.cutsceneIndex = sp44;
    
    src/code/z_message.c lines 6022–6034 at 710e1a7 · upstream ↗
    428 * Used by Song of Time (when clicking "Yes") and (indirectly) by the "Dawn of the New Day" cutscene
    ⋮
    430void Sram_SaveEndOfCycle(PlayState* play) {
    ⋮
    437    gSaveContext.save.timeSpeedOffset = 0;
    438    gSaveContext.save.eventDayCount = 0;
    439    gSaveContext.save.day = 0;
    440    gSaveContext.save.time = CLOCK_TIME(6, 0) - 1;
    ⋮
    442    gSaveContext.save.saveInfo.playerData.threeDayResetCount++;
    443    if (gSaveContext.save.saveInfo.playerData.threeDayResetCount > 999) {
    444        gSaveContext.save.saveInfo.playerData.threeDayResetCount = 999;
    
    src/code/z_sram_NES.c lines 427–444 at 710e1a7 · upstream ↗
    450    play->actorCtx.sceneFlags.chest &= sPersistentCycleSceneFlags[sceneId].chest;
    ⋮
    456    for (i = 0; i < SCENE_MAX; i++) {
    457        gSaveContext.cycleSceneFlags[i].switch0 =
    458            ((void)0, gSaveContext.cycleSceneFlags[i].switch0) & sPersistentCycleSceneFlags[i].switch0;
    
    src/code/z_sram_NES.c lines 450–464 at 710e1a7 · upstream ↗
    486    for (i = 0; i < ARRAY_COUNT(sPersistentCycleWeekEventRegs); i++) {
    487        u16 isPersistentBits = sPersistentCycleWeekEventRegs[i];
    ⋮
    490            if (!(isPersistentBits & 3)) {
    491                gSaveContext.save.saveInfo.weekEventReg[i] =
    492                    ((void)0, gSaveContext.save.saveInfo.weekEventReg[i]) & (0xFF ^ sBitFlags8[j]);
    ⋮
    498    for (i = 0; i < ARRAY_COUNT(gSaveContext.eventInf); i++) {
    499        gSaveContext.eventInf[i] = 0;
    
    src/code/z_sram_NES.c lines 486–499 at 710e1a7 · upstream ↗
    537    for (i = 0; i < ITEM_NUM_SLOTS; i++) {
    538        if (gAmmoItems[i] != ITEM_NONE) {
    539            if ((gSaveContext.save.saveInfo.inventory.items[i] != ITEM_NONE) && (i != SLOT_PICTOGRAPH_BOX)) {
    540                item = gSaveContext.save.saveInfo.inventory.items[i];
    541                AMMO(item) = 0;
    ⋮
    546    for (i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_6; i++) {
    547        // Check for all bottled items
    548        if (gSaveContext.save.saveInfo.inventory.items[i] >= ITEM_POTION_RED) {
    549            if (gSaveContext.save.saveInfo.inventory.items[i] <= ITEM_OBABA_DRINK) {
    ⋮
    556                gSaveContext.save.saveInfo.inventory.items[i] = ITEM_BOTTLE;
    
    src/code/z_sram_NES.c lines 536–556 at 710e1a7 · upstream ↗
    561    REMOVE_QUEST_ITEM(QUEST_PICTOGRAPH);
    ⋮
    567    if (GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) <= EQUIP_VALUE_SWORD_RAZOR) {
    568        SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI);
    ⋮
    570        if (CUR_FORM == 0) {
    571            if ((STOLEN_ITEM_1 >= ITEM_SWORD_GILDED) || (STOLEN_ITEM_2 >= ITEM_SWORD_GILDED)) {
    572                CUR_FORM_EQUIP(EQUIP_SLOT_B) = ITEM_SWORD_GILDED;
    573                SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_GILDED);
    
    src/code/z_sram_NES.c lines 561–573 at 710e1a7 · upstream ↗
    637    Sram_ClearHighscores();
    ⋮
    639    for (i = 0; i < 8; i++) {
    640        gSaveContext.save.saveInfo.inventory.dungeonItems[i] &= (u8)~1; // remove boss key
    641        DUNGEON_KEY_COUNT(i) = 0;
    642        gSaveContext.save.saveInfo.inventory.strayFairies[i] = 0;
    ⋮
    645    gSaveContext.save.saveInfo.playerData.rupees = 0;
    
    src/code/z_sram_NES.c lines 637–645 at 710e1a7 · upstream ↗
    404void Sram_ClearHighscores(void) {
    405    HS_SET_BOAT_ARCHERY_HIGH_SCORE(19);
    406    HS_SET_HIGH_SCORE_3_LOWER(10);
    407    HS_SET_HORSE_BACK_BALLOON_TIME(SECONDS_TO_TIMER(60));
    408    HS_SET_TOWN_SHOOTING_GALLERY_HIGH_SCORE(39);
    409    HS_SET_SWAMP_SHOOTING_GALLERY_HIGH_SCORE(10);
    ⋮
    411    gSaveContext.save.saveInfo.dekuPlaygroundHighScores[0] = SECONDS_TO_TIMER(75);
    412    gSaveContext.save.saveInfo.dekuPlaygroundHighScores[1] = SECONDS_TO_TIMER(75);
    413    gSaveContext.save.saveInfo.dekuPlaygroundHighScores[2] = SECONDS_TO_TIMER(76);
    
    src/code/z_sram_NES.c lines 404–413 at 710e1a7 · upstream ↗
    613#define HS_GET_BANK_RUPEES() (HIGH_SCORE(HS_BANK_RUPEES) & 0xFFFF)
    614#define HS_SET_BANK_RUPEES(rupees) (HIGH_SCORE(HS_BANK_RUPEES) = ((HIGH_SCORE(HS_BANK_RUPEES) & 0xFFFF0000) | (rupees)))
    
    include/z64save.h lines 613–614 at 710e1a7 · upstream ↗
    694#if MM_VERSION >= N64_US
    695    include "$(BUILD_DIR)/src/code/z_sram_NES.o"
    696#endif
    
    spec/spec lines 694–696 at 710e1a7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

  18. ^In the N64 US 1.0 code, accepting the Song of Double Time's prompt sets the clock to 6:00 if the save's isNight flag is set and to 18:00 if not, and turns off the moon's countdown timer; this code doesn't change the day counter. The three-day events actor (En_Test4) then sees the clock cross 6:00 and, in its no-cutscene branch, adds a day; that the jump to exactly 6:00 trips its crossing test is the atlas's reading. The song isn't offered on the third night (day 3 with isNight set) or where a scene's restriction flags forbid it.Codezeldaret/mmrevised
    How we know
    419        curTimeUntilTransition = CURRENT_TIME - transitionTime;
    420        prevTimeUntilTransition = this->prevTime - transitionTime;
    ⋮
    429        if ((curTimeUntilTransition * prevTimeUntilTransition) <= 0) {
    
    src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 419–429 at 710e1a7 · upstream ↗
    115    } else if ((sCsIdList[this->daytimeIndex] <= CS_ID_NONE) || (play->actorCtx.flags & ACTORCTX_FLAG_TELESCOPE_ON)) {
    116        // Previously night, turning day, without a cutscene
    117        Sram_IncrementDay();
    118        gSaveContext.save.time = CLOCK_TIME(6, 0);
    
    src/overlays/actors/ovl_En_Test4/z_en_test4.c lines 115–118 at 710e1a7 · upstream ↗
    5908                } else if (sLastPlayedSong == OCARINA_SONG_DOUBLE_TIME) {
    5909                    if (interfaceCtx->restrictions.songOfDoubleTime == 0) {
    5910                        if ((CURRENT_DAY != 3) || (gSaveContext.save.isNight == 0)) {
    5911                            if (gSaveContext.save.isNight) {
    5912                                Message_StartTextbox(play, sDoubleTimeSkipToDayTextIds[CURRENT_DAY - 1], NULL);
    5913                            } else {
    5914                                Message_StartTextbox(play, sDoubleTimeSkipToNightTextIds[CURRENT_DAY - 1], NULL);
    ⋮
    5916                            play->msgCtx.ocarinaMode = OCARINA_MODE_PROCESS_DOUBLE_TIME;
    5917                        } else {
    5918                            Message_StartTextbox(play, 0x1B94, NULL);
    5919                            play->msgCtx.ocarinaMode = OCARINA_MODE_END;
    
    src/code/z_message.c lines 5908–5919 at 710e1a7 · upstream ↗
    5702                } else if ((msgCtx->textboxEndType == TEXTBOX_ENDTYPE_TWO_CHOICE) &&
    5703                           (play->msgCtx.ocarinaMode == OCARINA_MODE_PROCESS_DOUBLE_TIME)) {
    5704                    if (Message_ShouldAdvance(play)) {
    5705                        if (msgCtx->choiceIndex == 0) {
    5706                            Audio_PlaySfx_MessageDecide();
    5707                            if (gSaveContext.save.isNight != 0) {
    5708                                gSaveContext.save.time = CLOCK_TIME(6, 0);
    5709                            } else {
    5710                                gSaveContext.save.time = CLOCK_TIME(18, 0);
    ⋮
    5712                            play->msgCtx.ocarinaMode = OCARINA_MODE_APPLY_DOUBLE_SOT;
    5713                            gSaveContext.timerStates[TIMER_ID_MOON_CRASH] = TIMER_STATE_OFF;
    
    src/code/z_message.c lines 5702–5713 at 710e1a7 · upstream ↗
    5305s16 sDoubleTimeSkipToNightTextIds[] = {
    5306    0x1B91, // Night of 1st day
    5307    0x1B90, // Night of 2nd day
    5308    0x1B8F, // Night of final day
    ⋮
    5310s16 sDoubleTimeSkipToDayTextIds[] = {
    5311    0x1B92, // Dawn of 2nd day
    5312    0x1B8E, // Dawn of final day
    
    src/code/z_message.c lines 5305–5313 at 710e1a7 · upstream ↗

    Checked against the evidence by its author, an AI model, 2026-10-22.

    Revised after a check by a second AI model, 2026-10-22.

    In the claim ledger

Sources

Code