--- name: godot-game-loop-collection description: "Expert collection-loop systems for collectible IDs, scavenger hunts, completion archives, nearest-item compass UI, hidden spawners, and persistent find-all-X progress. Use when implementing collectibles, scavenger hunts, completion% archives, or compass-guided item hunts. Keywords: collectible_id, scavenger_hunt, collection_manager, collection_compass, completion_archive, hidden_item_spawner, find_all, collectible_item." --- ## NEVER Do (collection landmines) - **NEVER reuse or omit stable collectible IDs** — Duplicate IDs double-count or overwrite; missing IDs break completion % and saves. - **NEVER count the same Area overlap twice** — `body_entered` can re-fire on re-entry; gate with "already collected" / one-shot disable of monitoring. - **NEVER persist NodePaths as the identity of collectibles** — Paths break on scene moves; save **IDs** (StringName / int), not `get_path()`. - **NEVER soft-lock the last item** — If compass / spawn logic depends on "remaining > 1", the final pickup becomes unfindable. - **NEVER store hunt progress only in scene-local nodes** — Level reload wipes progress; keep collected set in [collection_manager.gd](scripts/collection_manager.gd) + save. - **NEVER `queue_free()` collectibles with zero juice and no ID commit** — Commit ID first (signal), then VFX, then free. - **NEVER scale collectible collision shapes non-uniformly** — Breaks overlap math; edit shape resources. - **NEVER hardcode spawn positions in code** — Use Marker3D / designer points with [hidden_item_spawner.gd](scripts/hidden_item_spawner.gd). - **NEVER drive collection truth from UI silhouettes** — Archive UI mirrors manager state; manager is authoritative. - **NEVER load massive levels synchronously on hunt complete** — use threaded `ResourceLoader` (see references). - **NEVER manipulate SceneTree from worker threads** — `call_deferred` only. --- ## Golden Path (MANDATORY) 1. [collectible_item.gd](scripts/collectible_item.gd) — `item_id` (unique) + `collection_id` (hunt), one-shot Area pickup 2. [collection_manager.gd](scripts/collection_manager.gd) — authoritative collected-ID set via `register_item()` + `get_remaining_ids()` 3. [collection_compass.gd](scripts/collection_compass.gd) — nearest node whose `item_id` is still in manager remainders 4. Persist collected IDs via [godot-save-load-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-save-load-systems/SKILL.md) Optional: [hidden_item_spawner.gd](scripts/hidden_item_spawner.gd) for randomized hunts; [collection_loop_patterns.gd](scripts/collection_loop_patterns.gd) for advanced loop/MainLoop helpers. ## Available Scripts (full set) - [collectible_item.gd](scripts/collectible_item.gd) — **MANDATORY** pickup actor; export stable `item_id` per instance and hunt `collection_id` - [collection_manager.gd](scripts/collection_manager.gd) — **MANDATORY** progress brain; `start_collection(id, item_ids)` then `register_item(id, item_id)` - [collection_compass.gd](scripts/collection_compass.gd) — **MANDATORY** when guiding players; wire `collection_manager` and query `get_remaining_ids()` - [hidden_item_spawner.gd](scripts/hidden_item_spawner.gd) — designer markers / chance spawns (Do NOT Load for fixed placed-only hunts) - [collection_loop_patterns.gd](scripts/collection_loop_patterns.gd) — advanced loop patterns (Do NOT Load for simple ID hunts) ## Expert Collection Patterns ### 1. Persistent Collection (Save/Load) Serialize the manager’s collected `item_id` set per `collection_id` (`PackedStringArray` via `get_collected_ids()` / `restore_collected_ids()`), not node paths. Reload: manager restores set → collectibles self-disable if `item_id` already owned. ### 2. Collection Archive UI (Silhouettes) Grid of icons: uncollected `modulate` silhouette; reveal when manager signals that ID. UI never invents collected state. > **MANDATORY** for threaded loads, MainLoop helpers, and archive/save depth: [collection-loop-advanced.md](references/collection-loop-advanced.md). **Do NOT Load** for simple fixed-ID scavenger hunts. ## Reference > Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice. ### Official Documentation - [Area3D](https://docs.godotengine.org/en/stable/classes/class_area3d.html) — `body_entered` pickup volumes for 3D collectibles and layer/mask setup so only the player triggers collection. - [Using Area2D](https://docs.godotengine.org/en/stable/tutorials/physics/using_area_2d.html) — 2D overlap patterns when adapting the same collectible loop to Area2D/Sprite2D radar UIs. - [Groups](https://docs.godotengine.org/en/stable/tutorials/scripting/groups.html) — register collectibles and broadcast resets via `get_nodes_in_group` / `call_group` without hard-coded node paths. - [Idle and physics processing](https://docs.godotengine.org/en/stable/tutorials/scripting/idle_and_physics_processing.html) — keep collision-driven progress in `_physics_process` / physics frames; throttle compass/UI work in `_process`. - [SceneTree](https://docs.godotengine.org/en/stable/classes/class_scenetree.html) — pause flags, groups, `physics_frame`, and `current_scene` ownership used by collection state transitions. - [Change scenes manually](https://docs.godotengine.org/en/stable/tutorials/scripting/change_scenes_manually.html) — deferred free + instantiate handoff when finishing a hunt and loading the next level. - [Background loading](https://docs.godotengine.org/en/stable/tutorials/io/background_loading.html) — `ResourceLoader.load_threaded_request` / status polling so large collectible levels do not hitch the main thread. - [Saving games](https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html) — persist collected IDs and progress dictionaries with `FileAccess` under `user://`. - [Vector math](https://docs.godotengine.org/en/stable/tutorials/math/vector_math.html) — `direction_to` / `get_angle_to` for nearest-collectible compass pointing. - [Marker3D](https://docs.godotengine.org/en/stable/classes/class_marker3d.html) — designer-placed spawn anchors for hidden-item hunts instead of hard-coded coordinates. - [Using signals](https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html) — typed `item_collected` / `collection_updated` wiring from pickups into the manager and UI. - [MainLoop](https://docs.godotengine.org/en/stable/classes/class_mainloop.html) — custom loop extension surface referenced by advanced collection_loop_patterns (rarely needed over SceneTree). ### Related Skills #### Prerequisites - [godot-project-foundations](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-project-foundations/SKILL.md) — scene tree, `@onready`, and resource basics before wiring managers, markers, and collectible scenes. - [godot-gdscript-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-gdscript-mastery/SKILL.md) — typed signals, `match`, `await`, and deferred calls used throughout collection managers and loop patterns. - [godot-physics-3d](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-physics-3d/SKILL.md) — Area3D/CollisionShape3D layers and non-uniform scale pitfalls that break pickup detection. #### Complements - [godot-signal-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-signal-architecture/SKILL.md) — safe dynamic connections and event-bus patterns when many collectibles notify one manager. - [godot-scene-management](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-scene-management/SKILL.md) — threaded scene swaps and ownership rules for end-of-hunt level transitions. - [godot-save-load-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-save-load-systems/SKILL.md) — durable save schemas for which items remain collected across sessions. - [godot-ui-containers](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-ui-containers/SKILL.md) — silhouette archive grids and progress HUD layouts driven by `collection_updated`. - [godot-particles](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-particles/SKILL.md) — spawn juice VFX before `queue_free` so pickups feel responsive. - [godot-audio-systems](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-audio-systems/SKILL.md) — one-shot pickup SFX and bus routing tied to collect events. - [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — tune spawn_chance, target counts, and hunt length against completion-time distributions. #### Downstream / consumers - [godot-quest-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-quest-system/SKILL.md) — wraps collection progress as quest objectives with rewards and branching. - [godot-inventory-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-inventory-system/SKILL.md) — turns collected pickups into inventory grants when items are kept rather than consumed. - [godot-theme-easter](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-theme-easter/SKILL.md) — seasonal egg-hunt presentation layered on the same collection loop. #### Master - [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — library router and mirrored module entry for cross-skill discovery.