feat(mvp): complete M13 clean-up milestone (real usernames, avatar studio redesign, pause menu, audio manager)
checkpoint / checkpoint (push) Successful in 6m22s

This commit is contained in:
2026-09-18 21:54:01 +00:00
parent 4c8a60fbc8
commit ee4006d217
31 changed files with 2394 additions and 262 deletions
+29 -2
View File
@@ -24,6 +24,7 @@ extends Control
## UI and the in-memory `ChunkEditorModel` is unaffected either way.
signal closed
signal exit_browser_requested
var core: EditorCore
@@ -32,12 +33,17 @@ var _palette: PalettePanel
var _inspector: InspectorPanel
var _viewport: EditorViewport
var _close_button: Button
var _exit_browser_button: Button
var _save_button: Button
var _save_as_button: Button
var _save_status_label: Label
var _instruction_label: Label
var _save_as_modal: Control = null
var AudioManager: Node:
get:
return get_node_or_null("/root/AudioManager")
## Save-path state (world_persistence_impl.md §8.1/§8.2), set via
## `setup_persistence()`. `_save_service == null` means there is nothing to
@@ -118,11 +124,18 @@ func _build_ui() -> void:
_close_button = Button.new()
_close_button.text = "Close (F2 / Esc)"
_close_button.tooltip_text = "Exit build mode and return to game"
_close_button.text = "▶ Playtest (F2)"
_close_button.tooltip_text = "Exit build mode and test world in 3D play mode (F2 / Esc)"
_close_button.add_theme_color_override("font_color", Color(0.4, 0.9, 0.5))
_close_button.pressed.connect(_on_close_pressed)
top_bar.add_child(_close_button)
_exit_browser_button = Button.new()
_exit_browser_button.text = "🚪 Exit to Browser"
_exit_browser_button.tooltip_text = "Exit world and return to world browser"
_exit_browser_button.pressed.connect(_on_exit_browser_pressed)
top_bar.add_child(_exit_browser_button)
_instruction_label = Label.new()
_instruction_label.add_theme_font_size_override("font_size", 13)
_instruction_label.add_theme_color_override("font_color", Color(0.75, 0.92, 1.0))
@@ -206,6 +219,12 @@ func _unhandled_key_input(event: InputEvent) -> void:
_on_tool_selected("erase")
_toolbar.set_active_tool("erase")
get_viewport().set_input_as_handled()
elif key.keycode == KEY_ESCAPE:
if _save_as_modal != null and is_instance_valid(_save_as_modal):
_save_as_modal.queue_free()
_save_as_modal = null
get_viewport().set_input_as_handled()
return
func _on_tool_selected(tool_id: String) -> void:
@@ -311,6 +330,7 @@ func _on_save_pressed() -> void:
_save_button.disabled = false
if result.get("ok", false):
AudioManager.play_chime()
_base_revision = int(result.get("revision", _base_revision))
var msg := "Saved (revision %d)." % _base_revision
if bool(result.get("retried", false)):
@@ -506,3 +526,10 @@ func _api_client() -> Node:
func _session() -> Node:
return get_node_or_null("/root/Session")
func _on_exit_browser_pressed() -> void:
exit_browser_requested.emit()
var sess := _session()
if sess != null:
sess.clear()
get_tree().change_scene_to_file("res://scenes/world_list.tscn")