Set up the complete Godot 4.6 client foundation as a pure renderer (D-020): - project.godot with 2D rendering, autoloads, input actions - Main scene: Game > World (TileMapLayer, Entities, FogOverlay) + Camera2D + UILayer - Autoloads: SimBridge (connection state machine + test mode), GameState, InputMapper - Rendering stubs: WorldRenderer, EntityRenderer, FogRenderer - UI stubs: HUD (health/perception/time), Minimap, MonologueDisplay - Input mapping: WASD/arrows, E (interact), Tab (perception), Esc (menu), Space (pause) - gdUnit4 smoke tests: scene loads, autoloads registered (2/2 passing) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
81 lines
2.1 KiB
GDScript
81 lines
2.1 KiB
GDScript
extends Node
|
|
|
|
# Connection states
|
|
enum ConnectionState { DISCONNECTED, CONNECTING, CONNECTED, ERROR }
|
|
|
|
var state: ConnectionState = ConnectionState.DISCONNECTED
|
|
var test_mode: bool = true # Enable test mode for development without Rust server
|
|
|
|
# Signals
|
|
signal connection_state_changed(old_state: ConnectionState, new_state: ConnectionState)
|
|
signal snapshot_received(snapshot: Dictionary)
|
|
|
|
func _ready() -> void:
|
|
if test_mode:
|
|
print("SimBridge: Running in test mode (hardcoded snapshot)")
|
|
|
|
# Change connection state and emit signal
|
|
func _set_state(new_state: ConnectionState) -> void:
|
|
if state != new_state:
|
|
var old_state = state
|
|
state = new_state
|
|
connection_state_changed.emit(old_state, new_state)
|
|
|
|
# Connect to simulation server (real implementation comes later)
|
|
func connect_to_sim() -> void:
|
|
_set_state(ConnectionState.CONNECTING)
|
|
# TODO: Actual connection logic when IPC/MessagePack is implemented
|
|
if test_mode:
|
|
_set_state(ConnectionState.CONNECTED)
|
|
else:
|
|
_set_state(ConnectionState.ERROR)
|
|
|
|
# Disconnect from simulation server
|
|
func disconnect_from_sim() -> void:
|
|
_set_state(ConnectionState.DISCONNECTED)
|
|
|
|
# Send input to simulation (real implementation comes later)
|
|
func send_input(player_input: Dictionary) -> void:
|
|
if state != ConnectionState.CONNECTED:
|
|
return
|
|
# TODO: Serialize and send via MessagePack when IPC is implemented
|
|
pass
|
|
|
|
# Poll for snapshot from simulation
|
|
func poll_snapshot() -> Variant:
|
|
if state != ConnectionState.CONNECTED:
|
|
return null
|
|
|
|
if test_mode:
|
|
var snapshot = _test_snapshot()
|
|
snapshot_received.emit(snapshot)
|
|
return snapshot
|
|
|
|
# TODO: Actual polling logic when IPC/MessagePack is implemented
|
|
return null
|
|
|
|
# Hardcoded test snapshot for development
|
|
func _test_snapshot() -> Dictionary:
|
|
return {
|
|
"tick": Time.get_ticks_msec() / 100, # Increment over time for testing
|
|
"player": {
|
|
"position": [10, 10],
|
|
"health": 100
|
|
},
|
|
"entities": [
|
|
{
|
|
"id": 1,
|
|
"type": "npc",
|
|
"position": [12, 8],
|
|
"name": "Test NPC"
|
|
},
|
|
],
|
|
"fog": {
|
|
"radius": 8
|
|
},
|
|
"hud": {
|
|
"perception_mode": "baseline",
|
|
"time": "08:00"
|
|
}
|
|
}
|