show_menu() now calls set_value_no_signal() to reflect the current
GameState volume values without re-triggering value_changed handlers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Floor N spans from N*-720 to (N-1)*-720. The camera must center at the
floor midpoint, so target_y = floor_index * -720 + 360 (half floor height).
Previous formula placed the camera at the floor boundary, showing content
split between two floors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Vector2 is not a JSON-native type — JSON.stringify converts it to a string,
which cannot be assigned back to a Vector2 return type on load. Positions are
now saved as [x, y] float arrays and reconstructed as Vector2 in apply_save_data.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Area2D.input_event is unreliable on Android with gl_compatibility renderer.
Switched to manual _input() hit detection using canvas_transform coordinate
conversion, consistent with the DragDropComponent approach already used in
this project.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
character.gd referenced CharacterData.State as a compile-time constant dict,
causing export to fail when character.gd was compiled before character_data.gd
(alphabetical order). The preload forces character_data.gd to be compiled first.
Changing SubResource type to "Resource" removes the ClassDB lookup for the
custom class name during scene export, relying on the explicit script reference
instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Godot 4 Android export cannot resolve custom class names from the global
script cache during scene export. Adding an explicit ExtResource reference
to character_data.gd ensures the type is resolved at load time without
relying on the class cache.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Godot 4 throws "Class hides an autoload singleton" when a script declares
class_name with the same name as its registered autoload. Removed class_name
from AudioManager and RoomNavigator — both are accessible globally via their
autoload name without it. Also ignores Godot-generated *.uid files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix SaveManager reset_game to use DirAccess.remove correctly
- Add null check for FileAccess.open in save_game
- Fix AudioManager crossfade tween callback chain
- Replace fragile absolute HUD path with relative onready
- Guard character position save against empty id
- Add GameState.has_character_position helper
- Emit room_changed signal after tween completes
- Add target_floor validation in ElevatorButton
- Persist audio settings via GameState
- Add class_name to RoomNavigator, AudioManager, HUD
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- RoomNavigator autoload: smooth camera pan between floors
- Floor1 and Floor2 placeholder rooms with elevator buttons
- CharacterData Resource with State enum (HEALTHY/SICK/SLEEPING/TIRED)
- Character visual state feedback via ColorRect color
- Main scene loads saved state on startup
- SettingsMenu with music/sfx sliders and game reset
- HUD settings button to open SettingsMenu
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add RectangleShape2D to Character and InteractiveObject collision areas
- Fix HUD button signal connections in _ready()
- Fix character_placed signal emitting global_position
- Extract DEFAULT_DRAG_RADIUS constant in DragDropComponent
- Type Variant on JSON parsed variable in SaveManager
- Extract music symbol constants in HUD
- Refactor duplicated drag input code in InputManager
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- project.godot with autoload configuration
- Reception room with placeholder visuals
- Draggable Character with DragDropComponent
- Interactive flower object with bounce animation
- GameState, SaveManager, AudioManager, InputManager autoloads
- HUD with back button and music toggle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>