## 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: Entity state data # --------------------------------------------------------------------------- class Entity: 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 → Entity # --------------------------------------------------------------------------- # 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 apply_input(entity_id: int, input_dict: Dictionary) -> void: var e: Entity = _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) -> Entity: return _entities.get(entity_id) func spawn_player_entity(peer_id: int, pos: Vector3) -> int: var e = Entity.new() e.id = _next_entity_id e.peer_id = peer_id e.position = pos e.alive = true e.health = 100.0 _entities[_next_entity_id] = e _next_entity_id += 1 return e.id func despawn_player_entity(entity_id: int) -> void: _entities.erase(entity_id) func tick(delta: float) -> void: # Stub: in the real C++ SimulationServer this runs the 128Hz simulation pass func get_entity_count() -> int: return _entities.size()