P7.9: fix headless export — resolve Resource class_name ordering + duplicate RoundManager + simulation stub API

- Fix dead code in server_main.gd (unreachable lag compensation print)
- Remove WeaponData type hints from weapon_server.gd (Resource class_name in Node scripts = headless fail)
- Use preload() instead of WeaponData class_name in weapon_definitions.gd for const refs
- Lazy-init WEAPONS dict (const can't reference preload members)
- Remove duplicate class_name RoundManager from server/scripts/round/round_manager.gd
- Remove DamageProcessor type hints from round/round_manager.gd and bomb_objective.gd
- Add start()/stop()/can_tick()/tick()/spawn_entity()/despawn_entity() to simulation_server_stub.gd
- Fix get_world_3d() → get_tree().root.world_3d in weapon_server.gd Node context
- Fix var data := → var data = for untyped WeaponDefinitions.get_weapon() returns
- Clean export cache and verify server starts with zero parse errors
This commit is contained in:
2026-07-02 17:57:09 -04:00
parent 926446e5cf
commit e70ce76207
14 changed files with 356 additions and 305 deletions
+42 -37
View File
@@ -9,7 +9,9 @@
## print(data.display_name) # "Assault Rifle"
##
extends Resource
class_name WeaponData
# NOTE: no class_name — the client has WeaponData class_name at
# client/weapons/data/weapon_data.gd with different field names.
# Server code uses preload() + untyped references to avoid conflicts.
# ---------------------------------------------------------------------------
# Properties
@@ -46,31 +48,34 @@ class_name WeaponData
@export var pellets_per_shot: int = 1
# ---------------------------------------------------------------------------
# Pre-configured weapon instances (class-level constants)
# Pre-configured weapon instances (class-level static vars)
# ---------------------------------------------------------------------------
# NOTE: static var initializers CAN call functions (unlike const).
# These run when the script is loaded, which avoids the "not a constant
# expression" error that occurs with const + .new().
## Assault Rifle — 30 dmg, 10 rps, 30 mag, 2.1s reload, automatic, 0.5° spread, 200m range.
const RIFLE: Resource = pref(
"rifle", "Assault Rifle",
30.0, 10.0, 30, 2.1, true, 0.5, 200.0, 1
static var RIFLE: Resource = pref(
"rifle", "Assault Rifle",
30.0, 10.0, 30, 2.1, true, 0.5, 200.0, 1
)
## Pistol — 25 dmg, 4 rps, 12 mag, 1.5s reload, semi-auto, 0.3° spread, 80m range.
const PISTOL: Resource = pref(
"pistol", "Pistol",
25.0, 4.0, 12, 1.5, false, 0.3, 80.0, 1
static var PISTOL: Resource = pref(
"pistol", "Pistol",
25.0, 4.0, 12, 1.5, false, 0.3, 80.0, 1
)
## Shotgun — 8 dmg × 8 pellets, 1 rps, 8 mag, 3.0s reload, semi-auto, 3° spread, 30m range.
const SHOTGUN: Resource = pref(
"shotgun", "Shotgun",
8.0, 1.0, 8, 3.0, false, 3.0, 30.0, 8
static var SHOTGUN: Resource = pref(
"shotgun", "Shotgun",
8.0, 1.0, 8, 3.0, false, 3.0, 30.0, 8
)
## SMG — 18 dmg, 12 rps, 25 mag, 1.8s reload, automatic, 1.5° spread, 100m range.
const SMG: Resource = pref(
"smg", "Submachine Gun",
18.0, 12.0, 25, 1.8, true, 1.5, 100.0, 1
static var SMG: Resource = pref(
"smg", "Submachine Gun",
18.0, 12.0, 25, 1.8, true, 1.5, 100.0, 1
)
# ---------------------------------------------------------------------------
@@ -80,26 +85,26 @@ const SMG: Resource = pref(
## Internal helper that constructs a WeaponData instance from raw values.
## This avoids repeating the constructor boilerplate for every constant.
static func pref(
_weapon_id: String,
_display_name: String,
_damage: float,
_fire_rate: float,
_mag_size: int,
_reload_time: float,
_is_automatic: bool,
_spread_degrees: float,
_range: float,
_pellets: int = 1
) -> WeaponData:
var w := WeaponData.new()
w.weapon_id = _weapon_id
w.display_name = _display_name
w.damage = _damage
w.fire_rate = _fire_rate
w.mag_size = _mag_size
w.reload_time = _reload_time
w.is_automatic = _is_automatic
w.spread_degrees = _spread_degrees
w.range = _range
w.pellets_per_shot = _pellets
return w
_weapon_id: String,
_display_name: String,
_damage: float,
_fire_rate: float,
_mag_size: int,
_reload_time: float,
_is_automatic: bool,
_spread_degrees: float,
_range: float,
_pellets: int = 1
): # -> WeaponData (untyped for headless compat)
var w = WeaponData.new()
w.weapon_id = _weapon_id
w.display_name = _display_name
w.damage = _damage
w.fire_rate = _fire_rate
w.mag_size = _mag_size
w.reload_time = _reload_time
w.is_automatic = _is_automatic
w.spread_degrees = _spread_degrees
w.range = _range
w.pellets_per_shot = _pellets
return w
+25 -10
View File
@@ -12,23 +12,38 @@
extends RefCounted
class_name WeaponDefinitions
# Preload WeaponData script directly (no class_name dependency — the server
# weapon_data.gd intentionally avoids class_name to avoid conflicts with
# client/weapons/data/weapon_data.gd which also registers WeaponData).
const _WD = preload("res://scripts/combat/weapon_data.gd")
# ---------------------------------------------------------------------------
# Weapon Registry
# Weapon Registry — lazily initialised to avoid const + .new() errors
# ---------------------------------------------------------------------------
## Whether the WEAPONS dictionary has been populated.
static var _initialized: bool = false
## All weapons indexed by weapon_id — the single source of truth for the
## game's starter arsenal. Add new weapons here and in WeaponData.
const WEAPONS: Dictionary = {
"rifle": WeaponData.RIFLE,
"pistol": WeaponData.PISTOL,
"shotgun": WeaponData.SHOTGUN,
"smg": WeaponData.SMG,
}
## game's starter arsenal. Populated on first access via _ensure_init().
static var WEAPONS: Dictionary = {}
static func _ensure_init() -> void:
if _initialized:
return
_initialized = true
WEAPONS = {
"rifle": _WD.RIFLE,
"pistol": _WD.PISTOL,
"shotgun": _WD.SHOTGUN,
"smg": _WD.SMG,
}
# ---------------------------------------------------------------------------
# Lookup
# ---------------------------------------------------------------------------
## Return the WeaponData for the given weapon_id, or null if unknown.
static func get_weapon(id: String) -> WeaponData:
return WEAPONS.get(id, null) as WeaponData
static func get_weapon(id: String):
_ensure_init()
return WEAPONS.get(id, null)