Chris' Tutorials
Docs/Grid Placement

Grid Placement v5.0.8

Save and Load

Persist Grid Placement v5 state in consuming projects.

StatusCurrent
Versionv5.0.8
UpdatedActive v5.0.8 guide line from Grid Placement repo
Source note:This page rendered plugin-owned docs or generated metadata inside unified Astro docs shell.

This guide covers how to persist placed objects across game sessions in GridBuilding 5.0.8. While the maintenance version uses component-based persistence, it establishes patterns that carry forward into future versions.

Core Concepts

Persistence in 5.0.8 relies on three key elements:

  1. PlaceableInstance: A runtime component attached to every valid placement. It holds the "DNA" of the object (template ID, original resource path).
  2. Serialization: The process of converting the node hierarchy into a flat Dictionary.
  3. Deserialization: Reconstructing the node tree from data, ensuring all dependencies (scripts, resources) are relinked.

The Serialization Contract

A valid save entry in 5.0.8 looks like this:

{
    "instance_name": "Chair_001",
    "transform": Transform2D(...),
    "placeable_id": "**res://placeables/chair.tres**",
    "custom_data": {
        "durability": 50,
        "owner_id": "player_1"
    }
}

PlaceableInstance Component

The PlaceableInstance script (res://addons/grid_placement/placeable_instance.gd) exposes two critical methods:

  • save(with_custom_data: bool) -> Dictionary: serializes the node.
  • instance_from_save(data: Dictionary, parent: Node) -> Node: static factory method to rebuild the node.

Implementation Guide

Step 1: Saving the World

To save your level, iterate through the PlaceableInstance group. This group is automatically managed by the system.

func save_level() -> void:
    var save_data: Array[Dictionary] = []

    # Iterate all placed objects
    for node in get_tree().get_nodes_in_group("PlaceableInstance"):

        # 1. Validate it's a valid placement (not a preview)
        if node.get_parent().has_meta("gb_preview"):
            continue

        # 2. Serialize
        # Assumes the node structure: PlaceableRoot -> PlaceableInstance
        var data = node.save(true)

        # 3. Add custom game logic data (optional)
        if node.get_parent().has_method("get_custom_save_data"):
            data["custom_data"] = node.get_parent().get_custom_save_data()

        save_data.append(data)

    # Write to file
    _write_to_disk(save_data)

Step 2: Loading the World

Loading is a two-step process: Clear the existing world, then rebuild from data.

func load_level(data: Array[Dictionary]) -> void:
    # 1. Clear existing
    get_tree().call_group("PlaceableInstance", "queue_free")
    await get_tree().process_frame

    # 2. Rebuild
    for entry in data:
        # Static factory method handles resource loading
        var new_node = PlaceableInstance.instance_from_save(entry, world_root)

        # Restore custom data if needed
        if "custom_data" in entry and new_node.has_method("restore_custom_data"):
            new_node.restore_custom_data(entry["custom_data"])

Handling Edge Cases

  • Missing Resources: If a placeable_id resource path no longer exists (e.g., you deleted the file), instance_from_save will fail gracefully. Ensure your loading logic handles null returns.
  • Version Migrations: 5.0.8 does not have a built-in schema migration system. If you change your data structure, you must handle version checking in your own code.

Validated By

The save/load architecture and serialization patterns are verified by the following test suites:

  • Serialization Protocol: res://addons/grid_placement/test/building/placement/placement_report_unit_test.gd — Validates the serialization of placement metadata and report integrity.
  • Component Implementation: res://addons/grid_placement/placeable_instance.gd — Core component that manages instance lifecycle and serialization hooks.
  • Metadata Integrity: res://addons/grid_placement/test/utilities/data/composition_container_subresources_test.gd — Ensures that configuration data used during reconstruction is properly persisted.

Related Guides

Source

docs/v5-0/guides/save-and-load.md

Plugin docs root:gdscript/plugins/grid_placement_dev/docs