Review feedback from Hoshe + Tyre on PR #8: - Extract shared TILE_SIZE to Constants class_name (Tyre #5, Hoshe #7) - Fix tile invalidation: detect tile/visibility count changes instead of one-shot dirty flag, supports chunk loading (Tyre #3, #4) - Fog dirty tracking: only re-render when visible_positions changes - Add bounds warning for unknown tile types (Hoshe #1) - Add player-not-found warning in GameState (Hoshe #5) - Use Image.fill_rect() instead of pixel loops (Tyre #10) - Document _player_pos as reserved for fog decay #113 (Tyre #6) - Add TODO(#130) for D-033 relationship colors (Hoshe #3, Tyre #8) - Add class_name to EntityRenderer, FogRenderer, TileRenderer - 20 new rendering tests (D-030 Layer 1): entity lifecycle, fog registration, tile type mapping, snapshot completeness, constants - 65 total tests passing, 0 failures Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
43 lines
1.5 KiB
GDScript
43 lines
1.5 KiB
GDScript
extends Node
|
|
|
|
# Updated each frame from ObserverSnapshot data (Protocol format: {tick, entities, tiles}).
|
|
# Entities use Protocol decoded format: {entity_id, x, y, z, kind: {variant, data}}.
|
|
# Tiles use format: [{x, y, z, type}].
|
|
var current_snapshot: Dictionary = {}
|
|
var current_tick: int = 0
|
|
var player_position: Vector2 = Vector2.ZERO
|
|
var visible_entities: Array = []
|
|
var visible_tiles: Array = []
|
|
var visible_positions: Dictionary = {} # Vector2i -> true, for fast fog lookups
|
|
|
|
# Player entity ID — the first entity is assumed to be the player (will be
|
|
# refined when the server assigns explicit player entity IDs).
|
|
var player_entity_id: int = 1
|
|
|
|
func apply_snapshot(snapshot: Dictionary) -> void:
|
|
current_snapshot = snapshot
|
|
|
|
if snapshot.has("tick"):
|
|
current_tick = snapshot.tick
|
|
|
|
if snapshot.has("entities"):
|
|
visible_entities = snapshot.entities
|
|
# Derive player position from the player entity
|
|
var found_player := false
|
|
for entity in visible_entities:
|
|
if entity.has("entity_id") and entity.entity_id == player_entity_id:
|
|
player_position = Vector2(entity.x, entity.y)
|
|
found_player = true
|
|
break
|
|
if not found_player and visible_entities.size() > 0:
|
|
push_warning("GameState: player entity_id %d not found in %d entities" % [
|
|
player_entity_id, visible_entities.size()])
|
|
|
|
if snapshot.has("tiles"):
|
|
visible_tiles = snapshot.tiles
|
|
|
|
if snapshot.has("visible_positions"):
|
|
visible_positions.clear()
|
|
for pos in snapshot.visible_positions:
|
|
visible_positions[Vector2i(pos.x, pos.y)] = true
|