db477b4c48
- Renamed inner class Entity→StubEntity (Godot has native Entity class) - Added await ServerConfig.config_loaded before reading map_list in server_main.gd - Config loads via call_deferred, so _ready() must wait for signal
98 lines
2.9 KiB
GDScript
98 lines
2.9 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
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 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: 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_player_entity(peer_id: int, pos: Vector3) -> int:
|
|
var e = StubEntity.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()
|