feat(client): permanent dialogue panel + protocol v13 + build check
- dialogue_box.gd: panel is always visible as permanent insert UI element per D-061 — content fades but frame stays on screen - protocol.gd: bump PROTOCOL_VERSION to 13 - Makefile: add check-protocol target that verifies server/client protocol versions match, runs automatically before build Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
GODOT := $(shell command -v godot4 2>/dev/null || command -v godot 2>/dev/null)
|
||||
|
||||
.PHONY: help setup build client server game stop test lint ci ci-client ci-server clean \
|
||||
.PHONY: help setup build check-protocol client server game stop test lint ci ci-client ci-server clean \
|
||||
decisions-sync decisions-coverage decisions-active decisions-orphan \
|
||||
db-backup db-install validate-content content-ron check-fact-ids setup-hooks \
|
||||
pre-pr pre-pr-lint pre-pr-build pre-pr-test pre-pr-validate pre-pr-fixtures \
|
||||
@@ -28,6 +28,7 @@ help:
|
||||
@echo " make ci Run full CI pipeline locally"
|
||||
@echo " make ci-client Run client CI checks"
|
||||
@echo " make ci-server Run server CI checks"
|
||||
@echo " make check-protocol Verify server/client protocol versions match"
|
||||
@echo " make clean Remove build artifacts and caches"
|
||||
@echo ""
|
||||
@echo " make db-backup Backup shared database to git (main only)"
|
||||
@@ -82,7 +83,16 @@ setup-hooks:
|
||||
|
||||
# --- Build ---
|
||||
|
||||
build: build-server build-client
|
||||
check-protocol:
|
||||
@SERVER_V=$$(grep 'pub const PROTOCOL_VERSION' server/src/bridge/types.rs | sed 's/.*= *//;s/[^0-9]//g'); \
|
||||
CLIENT_V=$$(grep 'const PROTOCOL_VERSION' client/scripts/protocol/protocol.gd | sed 's/.*= *//;s/[^0-9]//g'); \
|
||||
if [ "$$SERVER_V" != "$$CLIENT_V" ]; then \
|
||||
echo "ERROR: Protocol version mismatch — server=$$SERVER_V, client=$$CLIENT_V"; \
|
||||
echo " Fix: update client/scripts/protocol/protocol.gd to match server/src/bridge/types.rs"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
build: check-protocol build-server build-client
|
||||
|
||||
build-server:
|
||||
cd server && cargo build
|
||||
|
||||
@@ -11,7 +11,7 @@ class_name Protocol
|
||||
|
||||
## Protocol version — must match server PROTOCOL_VERSION in bridge/types.rs.
|
||||
## Reject snapshots where version != this value.
|
||||
const PROTOCOL_VERSION: int = 12
|
||||
const PROTOCOL_VERSION: int = 13
|
||||
|
||||
|
||||
# -- Decode: bytes from server → GDScript types --------------------------------
|
||||
|
||||
@@ -41,7 +41,6 @@ var _option_is_confrontation: Array[bool] = []
|
||||
var _npc_name: String = ""
|
||||
|
||||
# -- UI state --
|
||||
var _is_showing: bool = false
|
||||
var _active_tween: Tween = null
|
||||
var _beat_tween: Tween = null # D-063: confrontation beat delay
|
||||
|
||||
@@ -77,9 +76,10 @@ const _WALK_AWAY_ACTIONS: Array[StringName] = [
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
panel.modulate.a = 0.0
|
||||
visible = false
|
||||
_is_showing = false
|
||||
# Panel is always visible as a permanent insert UI element (D-061).
|
||||
# Content fades in/out but the panel frame stays on screen.
|
||||
visible = true
|
||||
panel.modulate.a = 1.0
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_load_theme()
|
||||
_update_layout()
|
||||
@@ -94,8 +94,6 @@ func _process(_delta: float) -> void:
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if not _is_showing:
|
||||
return
|
||||
if not _in_player_conversation:
|
||||
return
|
||||
|
||||
@@ -327,25 +325,13 @@ func _end_player_conversation() -> void:
|
||||
hide_dialogue()
|
||||
|
||||
|
||||
## Hide the entire panel with fade.
|
||||
## End active dialogue state. Panel stays visible (permanent insert UI element).
|
||||
func hide_dialogue() -> void:
|
||||
if not _is_showing:
|
||||
return
|
||||
|
||||
if _in_player_conversation:
|
||||
_end_player_conversation()
|
||||
return # _end_player_conversation may call hide_dialogue if log is empty
|
||||
|
||||
_is_showing = false
|
||||
|
||||
if _active_tween and _active_tween.is_valid():
|
||||
_active_tween.kill()
|
||||
_active_tween = create_tween()
|
||||
_active_tween.tween_property(panel, "modulate:a", 0.0, FADE_OUT)
|
||||
_active_tween.tween_callback(func():
|
||||
visible = false
|
||||
GameState.dialogue_active = false # D-064: unblock movement after fade completes
|
||||
)
|
||||
GameState.dialogue_active = false
|
||||
|
||||
|
||||
func is_dialogue_active() -> bool:
|
||||
@@ -621,16 +607,9 @@ func _expire_entries() -> void:
|
||||
|
||||
# -- Visibility --
|
||||
|
||||
## Ensure panel is visible (fade in if needed).
|
||||
## No-op — panel is always visible as a permanent insert UI element.
|
||||
func _ensure_visible() -> void:
|
||||
if _is_showing:
|
||||
return
|
||||
visible = true
|
||||
_is_showing = true
|
||||
if _active_tween and _active_tween.is_valid():
|
||||
_active_tween.kill()
|
||||
_active_tween = create_tween()
|
||||
_active_tween.tween_property(panel, "modulate:a", 1.0, FADE_IN)
|
||||
pass
|
||||
|
||||
|
||||
func _clear_options() -> void:
|
||||
|
||||
Reference in New Issue
Block a user