Add Phase 4 Final Bugs Specification and Tests

- Introduced a new architecture specification for Phase 4 final bugs, detailing scope, decisions, runtime data contracts, action roles, execution lanes, speech ownership, and signal flow.
- Implemented changes in `scripts/action_registry.gd`, `scripts/action_editor.gd`, `scripts/sandbox_stage.gd`, `scripts/stage_gizmos.gd`, `scripts/stickman_factory.gd`, and `scripts/stickman_rig.gd` to address identified bugs.
- Created a new test suite `tests/test_phase4_final_bugs.gd` to validate the implementation, covering action roles, grid snapping, prop manipulation, reactive runtime lane, spawn pose preservation, and more.
- Added a unique identifier for the test file to ensure proper tracking and management.
This commit is contained in:
2026-09-13 23:20:01 -04:00
parent ce6bcecd00
commit 3a1d522ec9
11 changed files with 1281 additions and 79 deletions
+14 -2
View File
@@ -22,6 +22,8 @@ var _text_edit: LineEdit = null
var _duration_spin: SpinBox = null
var _target_label: Label = null
var _set_target_btn: Button = null
var _stop_current_check: CheckBox = null
var _show_reactive_options: bool = false
var _has_target: bool = false
var _target_pos: Vector2 = Vector2.ZERO
@@ -45,7 +47,8 @@ func _unhandled_input(event: InputEvent) -> void:
## Opens the editor in "add" mode (empty, default type walk_to).
func open_new() -> void:
func open_new(show_reactive_options: bool = false) -> void:
_show_reactive_options = show_reactive_options
_mode = "new"
_initial = {}
_has_target = false
@@ -57,7 +60,8 @@ func open_new() -> void:
## Opens the editor pre-filled from a flat queue action.
func open_edit(action: Dictionary) -> void:
func open_edit(action: Dictionary, show_reactive_options: bool = false) -> void:
_show_reactive_options = show_reactive_options
_mode = "edit"
_initial = action.duplicate(true)
var type := String(action.get("type", "walk_to"))
@@ -177,6 +181,7 @@ func _rebuild_params(type: String) -> void:
_duration_spin = null
_target_label = null
_set_target_btn = null
_stop_current_check = null
match type:
"walk_to":
@@ -203,6 +208,11 @@ func _rebuild_params(type: String) -> void:
_params_box.add_child(dlabel)
_duration_spin = _make_duration_spin(float(_initial.get("duration", 2.0)))
_params_box.add_child(_duration_spin)
if _show_reactive_options and ACTION_REGISTRY.is_overlay_eligible(type):
_stop_current_check = CheckBox.new()
_stop_current_check.text = "Stop what he's doing?"
_stop_current_check.button_pressed = bool(_initial.get("stop_current", false))
_params_box.add_child(_stop_current_check)
"wait":
var wlabel := Label.new()
wlabel.text = "Duration (s):"
@@ -247,6 +257,8 @@ func _on_ok_pressed() -> void:
"speak":
action["text"] = _text_edit.text if _text_edit != null else ""
action["duration"] = _duration_spin.value if _duration_spin != null else 2.0
if _show_reactive_options and _stop_current_check != null:
action["stop_current"] = _stop_current_check.button_pressed
"wait":
action["duration"] = _duration_spin.value if _duration_spin != null else 1.0
committed.emit(action)