- 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
- Replaced TeamData.Team type hints with int in all scripts
- Added explicit preloads for headless mode class resolution
- Created stub LagCompensation and DamageProcessor scripts
- Fixed PluginManager, SpawnManager, EconomyManager, BuyZone,
RoundManager, BuyMenuHandler, BombObjective class_name references
- Updated server config to match ServerConfig.gd format
Gray screen root cause: server scripts failed to parse in headless
mode due to Godot 4 class_name loading order (Resource after Node),
leaving server_main.gd non-functional — accepted connections but
never spawned players.
NEW: server/scripts/combat/lag_compensation.gd
- 128-entry ring buffer of player positions per server tick
- rewind_and_raycast(tick, origin, direction, range, exclude):
saves current positions, rewinds to tick-time positions,
performs PhysicsDirectSpaceState3D.intersect_ray(), restores
- Falls back to normal raycast if history missing for tick
- shot_processed signal
NEW: scripts/combat/damage_processor.gd
- Processes WeaponServer hit results: applies damage, tracks kills
- Optional distance-based damage falloff
- player_damaged / player_killed signals
- Health and kill-count queries
MODIFY: server/scripts/weapons/weapon_server.gd
- fire() now takes tick parameter: fire(tick, player_id, ...)
- _perform_hitscan() uses LagCompensation.rewind_and_raycast()
when lag_compensation reference is set and tick >= 0
- Non-compensated fallback path preserved
MODIFY: server/scripts/game_server.gd
- Adds _current_tick counter, incremented each simulation tick
- Creates WeaponServer + LagCompensation + DamageProcessor as children
- record_tick() called before each tick's simulation
- register/unregister_player_node() for player lifecycle
- _on_player_killed() relays kill events via player_damaged signal
MODIFY: scripts/network/server_main.gd
- _spawn_player() registers node with GameServer.register_player_node()
- _despawn_player() unregisters via unregister_player_node()
- WeaponData resource class with configurable weapon properties and
pre-configured constants for rifle, pistol, shotgun, and SMG
- WeaponDefinitions singleton/static registry with WEAPONS dictionary
- WeaponServer node for server-authoritative weapon logic including
fire rate cooldowns, ammo tracking, reload state machine, and
multi-pellet hit-scan raycasting
- Extended WeaponManager with weapon inventory array, weapon switching,
per-weapon state persistence, fire_animation_triggered signal