## NetfoxHeadlessBootstrap — Preload netfox dependencies for headless/server mode. ## ## In headless mode (`--headless`), Godot doesn't run EditorPlugin script ## scanning, so `class_name` registrations from addon scripts don't happen ## automatically. This causes parse errors when netfox autoloads reference ## class_names like `NetfoxLogger`, `NorayProtocolHandler`, etc. ## ## This bootstrap MUST be the FIRST autoload in project.godot (before any ## netfox autoload). It preloads all dependency scripts so their class_names ## are registered before netfox's own autoloads are parsed. ## ## Architecture: ## project.godot autoload order: ## 1. NetfoxHeadlessBootstrap (this script) ← preloads all deps ## 2. Async ## 3. Noray ## 4. NetworkTime ## 5. NetworkEvents ## 6. ... (all other netfox autoloads) ## ## This only executes in headless mode. In editor mode, the EditorPlugin ## handles class_name registration normally. extends Node func _init() -> void: # Only needed in headless mode — editor mode handles class_names via EditorPlugin if DisplayServer.get_name() != "headless": return print("[NetfoxHeadlessBootstrap] Headless mode detected — preloading netfox dependencies...") # Core netfox internals used by all netfox modules _load_safe("res://addons/netfox.internals/logger.gd") # NetfoxLogger # Time system — used by NetworkTime autoload _load_safe("res://addons/netfox/time/network-clocks.gd") # NetworkClocks _load_safe("res://addons/netfox/time/network-tickrate-handshake.gd") # NetworkTickrateHandshake _load_safe("res://addons/netfox/network-time-synchronizer.gd") # NetworkTimeSynchronizer # Noray system — used by Noray autoload _load_safe("res://addons/netfox.noray/protocol-handler.gd") # NorayProtocolHandler # Rollback internals — used by NetworkRollback _load_safe("res://addons/netfox.internals/ring-buffer.gd") # _RingBuffer _load_safe("res://addons/netfox.internals/history-buffer.gd") # _HistoryBuffer _load_safe("res://addons/netfox.internals/bimap.gd") # _BiMap _load_safe("res://addons/netfox.internals/set.gd") # _Set _load_safe("res://addons/netfox/properties/property-cache.gd") # PropertyCache _load_safe("res://addons/netfox/properties/property-entry.gd") # PropertyEntry _load_safe("res://addons/netfox/properties/property-config.gd") # _PropertyConfig _load_safe("res://addons/netfox/properties/property-snapshot.gd") # _PropertySnapshot _load_safe("res://addons/netfox/rollback/rollback-synchronizer.gd") # RollbackSynchronizer _load_safe("res://addons/netfox/rewindable-action.gd") # RewindableAction _load_safe("res://addons/netfox/tick-interpolator.gd") # TickInterpolator _load_safe("res://addons/netfox.extras/base-net-input.gd") # BaseNetInput # Weapon system (for multiplayer-fps) _load_safe("res://addons/netfox.extras/weapon/network-weapon.gd") # NetworkWeapon _load_safe("res://addons/netfox.extras/weapon/network-weapon-hitscan-3d.gd") # NetworkWeaponHitscan3D _load_safe("res://addons/netfox.extras/weapon/network-weapon-proxy.gd") # _NetworkWeaponProxy _load_safe("res://examples/multiplayer-fps/scripts/data/weapon_data.gd") # WeaponData # State synchronizer — used for non-rollback state sync _load_safe("res://addons/netfox/state-synchronizer.gd") # StateSynchronizer # Schema system — used behind the scenes _load_safe("res://addons/netfox/schemas/network-schema.gd") # _NetworkSchema _load_safe("res://addons/netfox/schemas/network-schemas.gd") # NetworkSchemas _load_safe("res://addons/netfox/schemas/network-schema-serializer.gd") # NetworkSchemaSerializer # Serializers — needed internally _load_safe("res://addons/netfox/serializers/base-snapshot-serializer.gd") # _BaseSnapshotSerializer _load_safe("res://addons/netfox/serializers/tickset-serializer.gd") # _TicksetSerializer # Servers — some needed for NetworkRollback internals _load_safe("res://addons/netfox/servers/data/snapshot.gd") # _Snapshot _load_safe("res://addons/netfox/servers/data/network-identifier.gd") # _NetworkIdentifier _load_safe("res://addons/netfox/servers/data/network-identity-reference.gd") # _NetworkIdentityReference _load_safe("res://addons/netfox/servers/data/object-snapshot.gd") # _ObjectSnapshot _load_safe("res://addons/netfox/servers/data/per-object-history.gd") # _PerObjectHistory _load_safe("res://addons/netfox/servers/data/property-pool.gd") # _PropertyPool print("[NetfoxHeadlessBootstrap] ✓ All netfox dependencies preloaded") ## Load a script and catch errors gracefully. func _load_safe(path: String) -> void: var script = load(path) if script == null: push_warning("[NetfoxHeadlessBootstrap] Failed to load: %s" % path)