Files
tactical-shooter/server/scripts/simulation_server_stub.gd
T
shawn e70ce76207 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
2026-07-02 17:57:09 -04:00

124 lines
3.4 KiB
GDScript

## SimulationServerStub — lightweight GDScript replacement for GDExtension C++ core.
##
## Provides the same API surface so game_server.gd and FPSCharacterController
## work without the compiled GDExtension library. No 128Hz simulation — just
## stores entity state and passes through input. Replace with the C++
## SimulationServer once `scons` builds cleanly.
extends RefCounted
# ---------------------------------------------------------------------------
# Nested: StubEntity state data
# ---------------------------------------------------------------------------
class StubEntity:
var id: int = -1
var peer_id: int = -1
var position: Vector3 = Vector3.ZERO
var rotation: Vector3 = Vector3.ZERO
var velocity: Vector3 = Vector3.ZERO
var alive: bool = true
var health: float = 100.0
var input_sequence: int = 0
func is_alive() -> bool:
return alive
# ---------------------------------------------------------------------------
# Config
# ---------------------------------------------------------------------------
var _tick_rate: int = 128
var _movement_config: Dictionary = {}
var _weapon_config: Dictionary = {}
var _history_depth: int = 64
var _next_entity_id: int = 1
var _entities: Dictionary = {} # entity_id → StubEntity
var _running: bool = false
var _last_hit_result: Dictionary = {}
# ---------------------------------------------------------------------------
# SimulationServer API
# ---------------------------------------------------------------------------
func set_tick_rate(hz: int) -> void:
_tick_rate = hz
func get_tick_rate() -> int:
return _tick_rate
func set_movement_config(cfg: Dictionary) -> void:
_movement_config = cfg
func set_weapon_config(cfg: Dictionary) -> void:
_weapon_config = cfg
func set_history_depth(depth: int) -> void:
_history_depth = depth
func start() -> void:
_running = true
func stop() -> void:
_running = false
func can_tick(delta: float) -> bool:
return _running
func tick() -> PackedByteArray:
# Stub: returns empty snapshot
return PackedByteArray()
func get_stats() -> Dictionary:
return {
"tick_count": 0,
"entity_count": _entities.size(),
}
func get_last_hit_result() -> Dictionary:
return _last_hit_result
func apply_input(entity_id: int, input_dict: Dictionary) -> void:
var e: StubEntity = _entities.get(entity_id)
if e == null:
return
# Apply movement from input (simplified)
if input_dict.has("move_direction"):
var dir: Vector3 = input_dict["move_direction"]
var speed: float = 5.0
if input_dict.get("sprint", false):
speed = 8.0
elif input_dict.get("crouch", false):
speed = 2.5
e.velocity = dir * speed
e.position += e.velocity * (1.0 / _tick_rate)
# Track input sequence
if input_dict.has("input_sequence"):
e.input_sequence = input_dict["input_sequence"]
func fire_weapon(entity_id: int) -> void:
# Stub: log the event
pass
func get_entity(entity_id: int) -> StubEntity:
return _entities.get(entity_id)
func spawn_entity(pos: Vector3) -> int:
var e = StubEntity.new()
e.id = _next_entity_id
e.position = pos
e.alive = true
e.health = 100.0
_entities[_next_entity_id] = e
_next_entity_id += 1
return e.id
func spawn_player_entity(peer_id: int, pos: Vector3) -> int:
var entity_id = spawn_entity(pos)
var e: StubEntity = _entities.get(entity_id)
if e:
e.peer_id = peer_id
return entity_id
func despawn_entity(entity_id: int) -> void:
_entities.erase(entity_id)
func get_entity_count() -> int:
return _entities.size()