Files
oracle-of-secrets/Docs/World/Overworld/TimeSystem.md
scawful 6ba634caa4 Add comprehensive documentation for sprites and systems
- Introduced detailed analysis for the Minecart system, highlighting its state machine, track system, and areas for improvement.
- Created an NPCs analysis document, summarizing various NPC sprites and their functionalities.
- Added an Objects analysis document, covering interactive elements like collectibles, ice blocks, and minecarts.
- Documented the Overlord sprite system, detailing its role in spawning other sprites and managing events.
- Compiled a Dungeons & Indoor Areas document, outlining custom room tags, enhanced mechanics, and advanced collision systems.
- Developed an Overworld Systems Analysis, focusing on the ZSCustomOverworld architecture and its core features.
- Added a Time System document, explaining the in-game clock and day/night cycle management.
- Documented the ZScream Custom Overworld, detailing its data-driven approach and key features.
2025-10-02 12:44:30 -04:00

3.6 KiB

Time System (Overworld/time_system.asm)

Overview

This system manages the in-game clock, day/night cycle, and associated palette effects. It runs continuously, updating the time and adjusting visual elements like the sky color and sprite palettes based on the current hour.

Key Functionality

  • Clock: A 24-hour clock is maintained in SRAM (Hours at $7EE000, Minutes at $7EE001).
  • Palette Modulation: The core of the system is ColorSubEffect, which subtracts values from the red, green, and blue components of palettes based on the time of day, using lookup tables.
  • Time-Based Events: The system checks for daily events (like the Magic Bean quest) and handles time manipulation effects (like the Song of Time).
  • HUD Display: It includes logic to draw the current time to the HUD.

Analysis & Areas for Improvement

The time system is functional but could be significantly improved in terms of structure, readability, and maintainability.

1. Move Patches to Core/patches.asm

  • Observation: The file contains numerous org patches that modify vanilla game logic to hook in the time system.
  • Suggestion: Relocate all org blocks to the centralized Core/patches.asm file. This is the most important cleanup step.
  • Benefit: This will separate the new system's implementation from the act of patching it into the original code, making both parts easier to understand and manage.
  • Observation: Time-related variables are defined as individual labels pointing to SRAM addresses (e.g., Hours, Minutes, TimeSpeed, !BlueVal).

  • Suggestion: Group these related variables into a single struct.

    Example:

    struct TimeState
      Hours     db
      Minutes   db
      TimeSpeed db
      ; ... other vars ...
      BlueVal   dw
      GreenVal  dw
      RedVal    dw
    endstruct
    
    ; Then access with:
    LDA TimeState.Hours, X
    
  • Benefit: This provides a clear, high-level definition of the data structure, improves readability, and makes it easier to manage memory layout.

3. Use subroutine for Code Blocks

  • Observation: The file consists of many large, labeled blocks of code (e.g., RunClock, DrawClockToHud, ColorSubEffect).
  • Suggestion: Convert these blocks to use subroutine/endsubroutine.
  • Benefit: This clearly defines the scope of each piece of logic, makes labels within them local by default, and improves overall code structure.

4. Refactor Large Subroutines

  • Observation: RunClock is a very large and complex subroutine with multiple responsibilities and deep nesting.
  • Suggestion: Break RunClock into smaller, more focused subroutines.
    • TimeSystem_CheckCanRun: A subroutine to check the game state ($10, $11) and decide if the clock should tick.
    • TimeSystem_IncrementTime: A subroutine to handle the core logic of incrementing minutes and hours.
    • TimeSystem_UpdatePalettes: A subroutine to call the palette update logic when the hour changes.
  • Benefit: Smaller, single-purpose functions are easier to read, debug, and maintain.

5. Replace Magic Numbers with Constants

  • Observation: The code is replete with hardcoded values for time, palettes, and game states.

  • Suggestion: Define constants for these values using ! or define().

    Example:

    !TIME_SPEED_NORMAL = $3F
    !GAME_STATE_OVERWORLD = $09
    
    LDA.b #!TIME_SPEED_NORMAL : STA.l TimeSpeed
    LDA $10 : CMP #!GAME_STATE_OVERWORLD : BEQ .overworld
    
  • Benefit: Makes the code self-documenting and reduces the risk of errors when modifying these values.