PC3 Phase 1.1: game boots clean from a bare clone
Root cause: a stale .godot/global_script_class_cache.cfg was force-committed to the repo (last regenerated before the avatar system merged), and Godot does not rebuild the global class registry on a plain headless scene run -- only an editor scan / `--import` does. So every cross-file `class_name` reference in the avatar module failed to resolve from a fresh clone, and the AvatarSystem autoload failed to instantiate entirely. - Untrack .godot/ and sandbox_probe/.godot/ (already in .gitignore; were force-added during old WIP checkpoints) - Reference sibling avatar scripts via preload() constants instead of their global class_name, so the module parses independent of scan order. Keeps the class_name declarations for editor/tooling use. - avatar_loadout.gd's static from_json() factory self-references via a preload const too (a script can't resolve its own class_name mid-compile on a cold cache). - smoke_test_avatar_system.gd: same preload treatment so it runs from a bare `--script` invocation. Verified from a wiped .godot/: main_menu.tscn and game.tscn boot with zero script errors; smoke_test_avatar_system 10/10, smoke_test_player 15/15, smoke_test_main_menu_ui 13/13, smoke_test_test_level PASS. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
This commit is contained in:
@@ -9,6 +9,9 @@
|
||||
class_name AvatarCatalog
|
||||
extends RefCounted
|
||||
|
||||
# Preloaded rather than referenced by global class_name -- see avatar_loadout.gd.
|
||||
const AvatarLoadout := preload("res://scripts/avatar/avatar_loadout.gd")
|
||||
|
||||
|
||||
## Emitted when the catalog is loaded successfully.
|
||||
signal catalog_loaded
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
class_name AvatarCustomizationUI
|
||||
extends Control
|
||||
|
||||
# Preloaded rather than referenced by global class_name -- see avatar_loadout.gd.
|
||||
const AvatarLoadout := preload("res://scripts/avatar/avatar_loadout.gd")
|
||||
const AvatarCatalog := preload("res://scripts/avatar/avatar_catalog.gd")
|
||||
const AvatarLoader := preload("res://scripts/avatar/avatar_loader.gd")
|
||||
const AvatarVisualizer := preload("res://scripts/avatar/avatar_visualizer.gd")
|
||||
const AvatarSlotRegistry := preload("res://scripts/avatar/avatar_slot_registry.gd")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Signals
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
class_name AvatarLoader
|
||||
extends Node
|
||||
|
||||
# Preloaded rather than referenced by global class_name -- see avatar_loadout.gd.
|
||||
const AvatarCatalog := preload("res://scripts/avatar/avatar_catalog.gd")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Constants
|
||||
|
||||
@@ -8,6 +8,15 @@
|
||||
class_name AvatarLoadout
|
||||
extends RefCounted
|
||||
|
||||
# Sibling avatar scripts are referenced via preload rather than by their
|
||||
# global class_name so this module parses correctly from a bare clone (a
|
||||
# headless `godot <scene>` run does not rebuild the global class registry;
|
||||
# only an editor scan / `--import` does). See docs/architecture/avatar.md.
|
||||
const AvatarSlotRegistry := preload("res://scripts/avatar/avatar_slot_registry.gd")
|
||||
# Self-reference for the static factory below -- referring to our own
|
||||
# class_name doesn't resolve during a cold-cache compile (see note above).
|
||||
const _Self := preload("res://scripts/avatar/avatar_loadout.gd")
|
||||
|
||||
|
||||
## Maximum number of accessories allowed in the accessory slot.
|
||||
const MAX_ACCESSORIES: int = 8
|
||||
@@ -58,7 +67,7 @@ func _init() -> void:
|
||||
|
||||
## Create a loadout from a JSON string.
|
||||
static func from_json(json_string: String) -> AvatarLoadout:
|
||||
var loadout := AvatarLoadout.new()
|
||||
var loadout := _Self.new()
|
||||
var data: Variant = JSON.parse_string(json_string)
|
||||
if not (data is Dictionary):
|
||||
loadout.validation_errors.append("Loadout JSON root is not an object")
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
|
||||
extends Node
|
||||
|
||||
# Sibling avatar scripts are referenced via preload rather than by their global
|
||||
# class_name so this autoload parses correctly from a bare clone -- a headless
|
||||
# `godot <scene>` run does not rebuild the global class registry (only an editor
|
||||
# scan / `--import` does), and this script is parsed at startup before any such
|
||||
# scan could have happened. See docs/architecture/avatar.md.
|
||||
const AvatarCatalog := preload("res://scripts/avatar/avatar_catalog.gd")
|
||||
const AvatarLoader := preload("res://scripts/avatar/avatar_loader.gd")
|
||||
const AvatarLoadout := preload("res://scripts/avatar/avatar_loadout.gd")
|
||||
const AvatarSlotRegistry := preload("res://scripts/avatar/avatar_slot_registry.gd")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Signals
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
class_name AvatarVisualizer
|
||||
extends Object
|
||||
|
||||
# Preloaded rather than referenced by global class_name -- see avatar_loadout.gd.
|
||||
const AvatarLoadout := preload("res://scripts/avatar/avatar_loadout.gd")
|
||||
const AvatarLoader := preload("res://scripts/avatar/avatar_loader.gd")
|
||||
const AvatarSlotRegistry := preload("res://scripts/avatar/avatar_slot_registry.gd")
|
||||
|
||||
|
||||
## Emitted when the visualizer has finished building the render tree.
|
||||
signal build_complete
|
||||
|
||||
@@ -13,6 +13,10 @@ extends SceneTree
|
||||
## Run with:
|
||||
## godot --headless --path . --script res://scripts/smoke_test_avatar_system.gd
|
||||
|
||||
# Preloaded rather than referenced by global class_name so this test also
|
||||
# runs from a cold cache (a bare `--script` run with no prior --import).
|
||||
const AvatarLoadout := preload("res://scripts/avatar/avatar_loadout.gd")
|
||||
|
||||
var passed := 0
|
||||
var failed := 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user