generated from krampus/template-godot4
Save state checks game & level version compatibility before deserializing
This commit is contained in:
parent
94e993e92d
commit
2078dd14bc
@ -9,6 +9,8 @@ const SAVE_PATH_FMT := "user://{0}.state.res"
|
||||
## Human-readable name
|
||||
@export var pretty_name: String
|
||||
|
||||
@export var version := 0
|
||||
|
||||
|
||||
func get_save_path() -> String:
|
||||
return SAVE_PATH_FMT.format([id])
|
||||
|
@ -1,17 +1,18 @@
|
||||
class_name SaveState extends Resource
|
||||
## Serializable container for gameplay state.
|
||||
|
||||
const CURRENT_VERSION := 0
|
||||
const CURRENT_VERSION := 1
|
||||
const PERSISTENT_GROUP := "Persistent"
|
||||
const SERIALIZE_METHOD := "serialize"
|
||||
const DESERIALIZE_METHOD := "deserialize"
|
||||
|
||||
@export var save_version := CURRENT_VERSION
|
||||
|
||||
@export var level_path: String
|
||||
|
||||
@export var persistent_state: Dictionary[String, Dictionary] = {}
|
||||
|
||||
@export_group("Compatibility Data")
|
||||
@export var save_version := CURRENT_VERSION
|
||||
@export var level_path: String
|
||||
@export var level_version := -1
|
||||
|
||||
@export_group("WorldManager State")
|
||||
@export var grunk_tank_limit: int
|
||||
@export var mp3_player_unlocked: bool
|
||||
@ -28,14 +29,34 @@ static func node_key(node: Node, world: World) -> String:
|
||||
|
||||
|
||||
func load_to_world(world: World) -> void:
|
||||
# Check save compatibility
|
||||
if save_version != SaveState.CURRENT_VERSION:
|
||||
push_warning(
|
||||
"Save state version ",
|
||||
save_version,
|
||||
" is incompatible with the current game version ",
|
||||
SaveState.CURRENT_VERSION
|
||||
)
|
||||
return
|
||||
|
||||
if level_path != world.current_level_scene.resource_path:
|
||||
push_warning(
|
||||
"This save is for ",
|
||||
"Save state for level ",
|
||||
level_path,
|
||||
" but the loaded level is for ",
|
||||
" is incompatible with the current level ",
|
||||
world.current_level_scene.resource_path
|
||||
)
|
||||
return
|
||||
|
||||
if level_version != world.current_level.version:
|
||||
push_warning(
|
||||
"Save state for level version ",
|
||||
level_version,
|
||||
" is incompatible with the current level version ",
|
||||
world.current_level.version
|
||||
)
|
||||
|
||||
# Deserialize world state
|
||||
world.manager.grunk_tank_limit = grunk_tank_limit
|
||||
world.manager.mp3_player_unlocked = mp3_player_unlocked
|
||||
world.manager.toothbrush_unlocked = toothbrush_unlocked
|
||||
@ -44,9 +65,8 @@ func load_to_world(world: World) -> void:
|
||||
world.manager.grunk_vault = grunk_vault
|
||||
world.manager.alert_level = alert_level
|
||||
|
||||
var persistent := world.get_tree().get_nodes_in_group(PERSISTENT_GROUP)
|
||||
|
||||
for node: Node in persistent:
|
||||
# Deserialize persistent level nodes
|
||||
for node: Node in world.get_tree().get_nodes_in_group(PERSISTENT_GROUP):
|
||||
var key := SaveState.node_key(node, world)
|
||||
if key in persistent_state:
|
||||
# Node is in our persistent state, so load it with data.
|
||||
@ -59,8 +79,11 @@ func load_to_world(world: World) -> void:
|
||||
static func serialize(world: World) -> SaveState:
|
||||
var save := SaveState.new()
|
||||
|
||||
# Serialize compatibility data
|
||||
save.level_path = world.current_level_scene.resource_path
|
||||
save.level_version = world.current_level.version
|
||||
|
||||
# Serialize world state
|
||||
save.grunk_tank_limit = world.manager.grunk_tank_limit
|
||||
save.mp3_player_unlocked = world.manager.mp3_player_unlocked
|
||||
save.toothbrush_unlocked = world.manager.toothbrush_unlocked
|
||||
@ -69,11 +92,8 @@ static func serialize(world: World) -> SaveState:
|
||||
save.grunk_vault = world.manager.grunk_vault
|
||||
save.alert_level = world.manager.alert_level
|
||||
|
||||
# NOTE: I'm assuming that `persistent` will have the same order ever time the world is loaded.
|
||||
# This may not be the case. If so, we need to find a different way to uniquely identify nodes.
|
||||
var persistent := world.get_tree().get_nodes_in_group(PERSISTENT_GROUP)
|
||||
|
||||
for node: Node in persistent:
|
||||
# Serialize persistent level nodes
|
||||
for node: Node in world.get_tree().get_nodes_in_group(PERSISTENT_GROUP):
|
||||
var key := SaveState.node_key(node, world)
|
||||
var data: Dictionary = Callable(node, SERIALIZE_METHOD).call()
|
||||
save.persistent_state[key] = data
|
||||
|
Loading…
x
Reference in New Issue
Block a user