Conversation
A (non persisted) state used to communicate when lights should be turned on or off between components.
A drop-in node that adds a day-night cycle animation. Using post-processing and overlay visual effects. It's possible to continue with the same time-of-day in the next scene. Nothing is persisted. Instead, the in-game time is derived from the system time. If two scenes have TimeAndWeather nodes with "use system time" enabled and same setting for time scale, they'll be in sync. See the weather museum scene for an example. Duck typing is used to call methods in the visual effects: randomize, fade_in, fade_out. For now every day is the same cloudy and every night is the same foggy. Later more weather conditions and randomization can be added. This is crying for sound effects too!
A behavior node that can manage lights and turn them on/off according to the game state.
No delay because we want the area around the player to immediately be illuminated.
For houses, add some random delay so there is variation in stacks of houses.
To be used in CanvasItem nodes with reflective surfaces.
Two scenes to show how the next scene continues at the same time.
Add a TimeAndWeather node with the default settings. And remove the clouds shadow overlay effect, because the new node provides it now. Add a ModulateAsSkyBehavior to the water tilemap layer.
|
Play this branch at https://play.threadbare.game/branches/endlessm/time-of-day. (This launches the game from the start, not directly at the change(s) in this pull request.) |
|
Things that were in the prototype but not in this pull request:
New or changed things since the prototype:
Other followups:
|
| ## Current state of artificial lights. | ||
| var lights_on: bool |
There was a problem hiding this comment.
Interesting that this (correctly) adds another non-persisted field to the state. intro_dialogue_shown is already not persisted.
To me this suggests that we should (later) split the state up into:
- This singleton
- A resource holding the persisted state
- and some functions to load and save it
- Another resource holding transient state
Don't change it in this branch!
There was a problem hiding this comment.
Sounds like a plan. It has become a bag of cats. The separation between persisted and transient is a great idea.
| [sub_resource type="GDScript" id="GDScript_oruto"] | ||
| script/source = "# SPDX-FileCopyrightText: The Threadbare Authors | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| extends Label | ||
|
|
||
| @onready var animation_player: AnimationPlayer = $\"../../AnimationPlayer\" | ||
|
|
||
|
|
||
| func _process(_delta: float) -> void: | ||
| var time := animation_player.current_animation_position | ||
| var period: String | ||
| if time > 5 and time <= 12: | ||
| period = \"morning\" | ||
| elif time > 12 and time <= 18: | ||
| period = \"afternoon\" | ||
| elif time > 18 and time <= 22: | ||
| period = \"evening\" | ||
| else: | ||
| period = \"night\" | ||
| text = \"%.1f %s\" % [time, period] | ||
| " |
There was a problem hiding this comment.
Did you mean to leave this here? It's just a debug node so probably OK to have it be embedded in the scene.
There was a problem hiding this comment.
Hmm maybe I move this script to components/.
| func _process(_delta: float) -> void: | ||
| if Engine.is_editor_hint(): | ||
| return |
There was a problem hiding this comment.
Something I learnt recently is that it is better to use set_process(false) in _ready rather than have this guard here, because calling a method 60 times per second in the editor has a cost even if it just returns immediately.
(This could be fixed later.)
There was a problem hiding this comment.
Good point. I'll fix it before merging!
There was a problem hiding this comment.
Done! I remember what happened here. Yesterday I had:
func _ready() -> void:
if Engine.is_editor_hint():
process_mode = Node.PROCESS_MODE_DISABLED
return
But this effectively disabled the node in the editor, and the scene was saved with the node disabled. So I removed it. Using set_process(false) is the correct thing to do.
scenes/game_elements/fx/time_and_weather/components/2_time_and_weather_museum.tscn
Show resolved
Hide resolved
| ## How fast should time pass in the game.[br] | ||
| ## - 1: One day in game matches one day in reality. Don't do this![br] | ||
| ## - 24: One hour in game matches one day in reality.[br] | ||
| ## - 144: 10 minutes in game matches one day in reality (default).[br] | ||
| ## - 1440: One minute in game matches one day in reality.[br] | ||
| ## - 3600: 24 seconds in game matches one day in reality.[br] | ||
| @export_range(1.0, 3600.0, 1.0) var time_scale: float = 144.0: |
There was a problem hiding this comment.
I find these numbers a bit hard to think about.
One option is to describe this number in a different way: this number is the number of game-days in a real-world day! I only realised this while writing this comment.
The alternative would be to store the reciprocal: the length of an in-game day, in seconds. So the new default would become 600.0 seconds.
Or store the fractional number of real-world minutes in an in-game day, so the new default would be 10.0 minutes.
We don't have to change this - I'm mainly thinking aloud.
There was a problem hiding this comment.
This is the feedback I most welcome, because it's the part I had more doubts. Let me think about it.
There was a problem hiding this comment.
I wonder if we can have both... Have one real property that is adjustable and stored; and another which is not stored, readonly, shown in the editor, that converts to the other number. So you adjust e.g. this time_scale factor, and below it you would see "In-Game Day Length: 10.0 minutes".
There was a problem hiding this comment.
That's almost certainly overengineering though!
There was a problem hiding this comment.
One option is to describe this number in a different way: this number is the number of game-days in a real-world day! I only realised this while writing this comment.
I've been scratching my head and haven't thought about this. Well wording!
|
I pushed a fixup to make it possible to toggle the current-time debug label while the game is running. |
|
@wjt thanks for the detailed review! |
GameState: Add lights on/off state
A (non persisted) state used to communicate when lights
should be turned on or off between components.
Add TimeAndWeather node
A drop-in node that adds a day-night cycle animation. Using
post-processing and overlay visual effects.
It's possible to continue with the same time-of-day in the next scene.
Nothing is persisted. Instead, the in-game time is derived from the
system time.
If two scenes have TimeAndWeather nodes with "use system time" enabled
and same setting for time scale, they'll be in sync. See the weather
museum scene for an example.
Duck typing is used to call methods in the visual effects:
randomize, fade_in, fade_out.
For now every day is the same cloudy and every night is the same foggy.
Later more weather conditions and randomization can be added.
This is crying for sound effects too!
Add ArtificialLightBehavior
A behavior node that can manage lights and turn them
on/off according to the game state.
Player: Use artificial light
No delay because we want the area around the player to immediately
be illuminated.
Houses and loom: Add artificial light
For houses, add some random delay so there is variation in
stacks of houses.
Add ModulateAsSkyBehavior
To be used in CanvasItem nodes with reflective surfaces.
Add time and weather museum
Two scenes to show how the next scene continues at the same time.
Fray's End: Use TimeAndWeather
Add a TimeAndWeather node with the default settings. And
remove the clouds shadow overlay effect, because the new
node provides it now.
Add a ModulateAsSkyBehavior to the water tilemap layer.
Initial prototype: #1913