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

75 lines
3.6 KiB
Markdown

# 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.
### 2. Use a `struct` for Time-Related Variables
- **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:*
```asm
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:*
```asm
!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.