- 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.
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 (
Hoursat$7EE000,Minutesat$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
orgpatches that modify vanilla game logic to hook in the time system. - Suggestion: Relocate all
orgblocks to the centralizedCore/patches.asmfile. 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:
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:
RunClockis a very large and complex subroutine with multiple responsibilities and deep nesting. - Suggestion: Break
RunClockinto 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
!ordefine().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.