1.0.0 Release - Stateful Shared Resources


Here is the first full release of the World Time plugin for Godot 4 games. The plugin provides systems that manage the progression of time in your game world updating a TimeState with game seconds, DateTime, and TimeOfDay. A key point of the plugin is that is that the time scales to your game world with a settable game speed, a customizable calendar system and time scale resource for having full control over how time progresses in your game.

Majorly improved over the previous releases is the introduction of the TimeState and AgeState resources. Pulling from the idea of a signal / event bus, these state resources also store the current and in some cases historical values of Time and Age within the game world. By sharing a world TimeState and AgeState between objects that want to reference the data, you can reference the data as it is updated with values and signals are emitted without ever connecting directly to the GameTimeSystem, DayNightCycleSystem, or WorldAgeSystem.

Pretty much every other component you may attach to other objects and scenes in your game like AgeingComponents or the basic UI controls provided in the plugin pull their data and react to signals being emitted from TimeState and AgeState resources.


Demo Project

To go along with the 1.0.0 release of the plugin, I am also providing a copy of the dev project with a working demo showcasing basic usage of all 3 systems (GameTimeSystem, DayNightCycleSystem, WorldAgeSystem), and demoing how you can seamlessly switch scenes while all systems continue working in the background. One key difference that's possible now but not before is that on loading a new level, a TimeOfDayDirectionalLight2D can immediately read the world TimeState to set it's current light settings values. There is no need to wait for the next signal to be emitted because the states record their last updated values as well.

I will be updating the demo project with samples of how to use the plugin and include accompanying videos (subscribe to my YouTube channel to keep updated.)

Breaking Changes

This is a major update going from the last version to the 1.0 release. Please see the README.md file for instructions on how to set up the plugin with the new version.

  • Any scripts that referenced a TimeSignalBus or AgeingSignalBus in most cases now reference a TimeState or AgeState resource. The signal bus scripts have been fully replaced with TimeState and AgeState which emit signals when their values are set but also store the current state values in their properties. Effected nodes include GameTimeSystem, DayNightCycleSystem, WorldAgeSystem, AgeingComponent, world_speed_control (previously slider), DateTimeDisplay, and TimeOfDayDisplay.
  • In most cases, settings specific to systems will have been reset since their values have been moved into nested resources. For GameTimeSystem, look to the TimeMovementSettings resource in the inspector to view and set the settings. For DayNightCycleSystem, the times of day are stored in a TimesOfDaySet resource now. For WorldAgeSystem, look to AgeingSettings.
  • Each system needs to reference a GameCalendar for DateTime calculations and conversions to / from GameSeconds. You can use the default_game_calendar.tres in the project to mirror a real world calendar or define your own. Generally, you want to share the same calendar between all your systems for consistent time calculations (save and reference like any other resource)
  • AgedSceneComponent Node has been replaced with SceneReplacement resource. To have an AgeingComponent replace a target scene with an instance of a PackedScene and pass along AgeData to the new scene, set a SceneReplacement resource on your AgeingComponent and choose your settings.
  • world_speed_slider.tscn has been renamed world_speed_control.tscn (the .gd script too). World speed slider needs to reference the TimeMovementSettings resource that's shared with your GameTimeSystem to work properly but no longer needs a direct reference to the GameTimeSystem in the inspector.

Improvements

  • TimeState and AgeState directly replace the TimeSignalBus and AgeingSignalBus from before. They are still resources that hold signals, but also hold the state properties related to your game world and emit the signals directly from the resources whenever their values change.
  • AgeingComponent now handles scene replacement directly on the AgeingComponent by using the new SceneReplacement resource. AgedSceneReplacement node has been completely replaced because the extra node referencing an AgeingComponent during replacement was just needlessly complicated.
  • Most settings have been moved into resource classes. As a resource, saving, loading, and sharing data between scenes and objects is much simpler than a direct reference to a system. For example, imagine the system is in a different scene than your level and they are loaded at different times - Finding the System node is a pain but referencing a resource saved to your project to access the data is easy. Going forward, this pattern of design will be my go to in Gdscript.
  • Added the TimeOfDaySet and TimeOfDayLightSettingsGroup resources to hold the array of TimeOfDay and array of TimeOfDayLightSettings that already existed for the DayNightCycleSystem and TimeOfDayDirectionalLight2D respectively. As a resource that holds the array, it is much easier to save and share the whole group than an array where each nested resource must be assigned one at a time.
  • World Speed Control had it's connection to the TimeMovementSettings fixed so it updates whenever the game_speed changes and sets the game_speed whenever a successful slider drag to a new value occurs.
  • Added the option for GameTimeSystem to manually adjust the date or game seconds forwards and backwards. There may be times when during the game you want to pause the regular flow of the game and make manual adjustments (perhaps a pause at the end of the day for a Game Day results screen that doesn't move forward until the player presses OK and then immediately jumps to the morning of the next day). The GameCalendar which handles actual calculations, has also had it's methods modified to support these kinds of jumps.
  • The GameCalendar has had many new methods added for conversions between game seconds, HoursTime, DateTime, and calculations related to finding dates within months and years.

Bug Fixes

  • TimeOfDayDirectionalLight2D should have proper transition progress and time of day values on loading into a new scene before the time_of_day_entered signal is called. The TimeOfDayDirectionalLight2D now checks the current & last time of day values and the transition progress off the TimeSignalBus so it is able to have an initial value before receiving updates from the time_of_day_entered signal.
  • GameCalendar: Fixed a bug where get_hours_time_from_seconds did not adjust for negative game time seconds values to scope within a game day hours
  • Fixed a bug where the month didn't change after the day went above the days in the month (ex. day 32 in a 31 day)
  • Fixed a bug where TimeOfDay transition_progress started at the wrong progress values
  • Fixed a problem where TimeOfDayDirectionalLight2D could only update their lights after they exist in the scene and a updated progress signal got emitted (The TimeState now stores their current values so the lights can read them immediately)
  • Fixed a bug where AgeingComponents were not initiatlizing with the right age values after being created through a SceneReplacement (previously AgedSceneReplacement node)
  • Fixed a bug where TimeOfDayDirectionalLight2D was displaying the wrong light settings in some time values

Get World Time Plugin for Godot 4

Buy Now$30.00 USD or more

Leave a comment

Log in with itch.io to leave a comment.