fix: frame now frames interactable, billboard effect improved

This commit is contained in:
tiger tiger tiger 2026-01-15 18:07:50 +01:00
parent 10bfcc2e8a
commit c442e2cd79
7 changed files with 195 additions and 32 deletions

110
CHANGELOG.md Normal file
View File

@ -0,0 +1,110 @@
# Changelog
All notable changes to Frame of Mind since commit `c75348845a5136379ce9ab09d2ff64b7bec90f12`.
## [Unreleased]
### Features
- New interactable system with action prompts that can play scenes
- Added new interactables to youth room with repositioned layout
- Interactable prompts now update dynamically based on collected state (shows \"read again\" after collection)
- Type-safe interactive handling for player
- Room loading system implementation
- Basic room start logic
- Room play functionality
### Fixes
#### Interactables & Positioning
- Small improvements to positioning
- Sorting function was not according to spec
#### Save System
- Save game parsing failure no longer crashes the game
- Save game directory creation on first load
- Fixed race condition with settings initialization
- New save game only creates once (reduced from multiple duplicates)
- Save game picker layout improvements
#### UI & Menus
- Fixed markdown not loading nonexistent resources
- Markdown now uses application theme
- Fixed masking on loading indicator
- Fixed loading spinner animation states
- Fixed screenshot size (was 261, corrected to 216 height)
- Nav UI in accessibility settings is now accessible again
- Card picker input propagation fixed
- Card picker now closes properly
- Cards now derived from prefab scene
- Text updates now forced to deferred
- Skip buttons work via mouse
- Cardboard can now be clicked and opened
#### Player & Controls
- Player crouching on leaving bed fixed
- Line renderer errors due to zero magnitude axis fixed
- Climb volume now automatically crouches the player
- Player raising and crouching stabilized
- Removed annoying half-second wait
- Player controller cleanup
#### Rooms & Scenes
- Theme files reconstructed
- Regenerated missing UIDs in theme files
- Resaved various scenes to fix UIDs
- Removed forced preload of all 3 base rooms
- Fixed various path and hierarchy issues in youth room
- Viewport children no longer break
- Found and fixed many broken/orphaned viewports in youth room
- Main scene is no longer a Control (fixed input issues)
- Removed broken LightmapGI node that was causing scene to be dirtied on every load
#### Story & Playables
- Story playables no longer destroy their own serialized text
- Reinstated accidentally deleted paragraph length data
- Fixed Draven/Draeven naming inconsistencies
- Manual scroll enable on Draven and Voice fixed
- Story playables now control their own canvas layer visibility
- Board now correctly identifies itself
#### Code Quality
- Fixed hardcoded localization load (en) removed from scene player
- Fixed settings panel refactoring path
- Fixed shadowing issues in card-board
- Fixed syntax errors
- Removed all warnings
- Fixed untyped variables throughout codebase
- Fixed unknown fields issues
### Refactored
- New interactable system replaces old interactive_sprite.gd system
- Interactable now has separate `_update_caption()` and `_update_prompt()` methods
- Renamed `collectable.gd` to `interactive_sprite.gd`
- Moved various embedded scripts to their own `.gd` files
- Focus system refactored
- Removed deprecated sequencing calls
- Removed deprecated signals and `is_board`
- Stage system refactored, dead code cleared
- Collectable logic refactored
- Renamed `SaveGameHandle` to `SaveGameList`
- Renamed `scnees` folder to `scenes`
- Menu animations moved to tweens/subscenes
- Better inheritance and render order for mementos
- New direct interactable system
### Changed
- Replaced all bare `print()` statements with `print_debug()`
- Game window set to 1600x900 for better testing/debugging
- Explicit search index layout
- Main scene changed from Control to different node type
### Tests
- Added player tests for crouching and raiser functionality
- Raiser now uses AnimatableBody3D
### Chores
- Generated missing .import files
- Added IDE configuration files
- Fixed button/Button filename case issues
- Cleaned up project structure
- Updated .gitignore files

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=117 format=4 uid="uid://b3b0gyvklqn50"] [gd_scene load_steps=117 format=4 uid="uid://b3b0gyvklqn50"]
[ext_resource type="Script" uid="uid://bsop46tqngddc" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"] [ext_resource type="Script" path="res://base-environments/youth_room/youth_room.gd" id="1_aitp0"]
[ext_resource type="AudioStream" uid="uid://1h6k2d8q1kw3" path="res://base-environments/youth_room/import/sounds/rain_on_window.mp3" id="2_3haaq"] [ext_resource type="AudioStream" uid="uid://1h6k2d8q1kw3" path="res://base-environments/youth_room/import/sounds/rain_on_window.mp3" id="2_3haaq"]
[ext_resource type="PackedScene" uid="uid://mkccbig41bqb" path="res://logic-scenes/player_controller/player_controller.tscn" id="3_foj4y"] [ext_resource type="PackedScene" uid="uid://mkccbig41bqb" path="res://logic-scenes/player_controller/player_controller.tscn" id="3_foj4y"]
[ext_resource type="AudioStream" uid="uid://bbpo1hu35yer8" path="res://base-environments/youth_room/import/sounds/thunder.mp3" id="3_wcypa"] [ext_resource type="AudioStream" uid="uid://bbpo1hu35yer8" path="res://base-environments/youth_room/import/sounds/thunder.mp3" id="3_wcypa"]
@ -19,7 +19,7 @@
[ext_resource type="PackedScene" uid="uid://g2a27jwdapai" path="res://logic-scenes/card_burner/card_burner.tscn" id="11_5bsh1"] [ext_resource type="PackedScene" uid="uid://g2a27jwdapai" path="res://logic-scenes/card_burner/card_burner.tscn" id="11_5bsh1"]
[ext_resource type="PackedScene" uid="uid://c3l8tm8ku50vt" path="res://base-environments/youth_room/scenes/childhood.tscn" id="12_viwxf"] [ext_resource type="PackedScene" uid="uid://c3l8tm8ku50vt" path="res://base-environments/youth_room/scenes/childhood.tscn" id="12_viwxf"]
[ext_resource type="PackedScene" uid="uid://23bshas7sk6h" path="res://base-environments/youth_room/scenes/jui_jutsu.tscn" id="12_x3dlb"] [ext_resource type="PackedScene" uid="uid://23bshas7sk6h" path="res://base-environments/youth_room/scenes/jui_jutsu.tscn" id="12_x3dlb"]
[ext_resource type="Script" uid="uid://c3xbkwm4x3es7" path="res://base-environments/youth_room/youth_room_scene_player.gd" id="13_5bsh1"] [ext_resource type="Script" path="res://base-environments/youth_room/youth_room_scene_player.gd" id="13_5bsh1"]
[ext_resource type="Texture2D" uid="uid://d005qvnbnishb" path="res://import/interface-elements/cursor_grab.png" id="13_lqj71"] [ext_resource type="Texture2D" uid="uid://d005qvnbnishb" path="res://import/interface-elements/cursor_grab.png" id="13_lqj71"]
[ext_resource type="PackedScene" uid="uid://cj1ccdk0686ke" path="res://base-environments/youth_room/scenes/voice_training.tscn" id="13_v3447"] [ext_resource type="PackedScene" uid="uid://cj1ccdk0686ke" path="res://base-environments/youth_room/scenes/voice_training.tscn" id="13_v3447"]
[ext_resource type="Material" uid="uid://cvm8e6vek3bne" path="res://base-environments/youth_room/import/materials/starlight_shader.material" id="17_ea6x8"] [ext_resource type="Material" uid="uid://cvm8e6vek3bne" path="res://base-environments/youth_room/import/materials/starlight_shader.material" id="17_ea6x8"]
@ -39,7 +39,7 @@
[ext_resource type="Texture2D" uid="uid://dabnlcnuticww" path="res://base-environments/intro/textures/sky_textures_2.png" id="33_mvrs2"] [ext_resource type="Texture2D" uid="uid://dabnlcnuticww" path="res://base-environments/intro/textures/sky_textures_2.png" id="33_mvrs2"]
[ext_resource type="Shader" uid="uid://dspme86ky8yj0" path="res://base-environments/youth_room/rainy-window.gdshader" id="35_ea6x8"] [ext_resource type="Shader" uid="uid://dspme86ky8yj0" path="res://base-environments/youth_room/rainy-window.gdshader" id="35_ea6x8"]
[ext_resource type="Texture2D" uid="uid://ds1n0xhxqlp4b" path="res://base-environments/youth_room/shaders/universe_noise.png" id="36_bgk6f"] [ext_resource type="Texture2D" uid="uid://ds1n0xhxqlp4b" path="res://base-environments/youth_room/shaders/universe_noise.png" id="36_bgk6f"]
[ext_resource type="Script" uid="uid://c5eiqpr1q41xk" path="res://base-environments/youth_room/youth_room_environment.gd" id="38_ypa88"] [ext_resource type="Script" path="res://base-environments/youth_room/youth_room_environment.gd" id="38_ypa88"]
[ext_resource type="PackedScene" uid="uid://cg70r0102t8nl" path="res://base-environments/youth_room/fairylights.tscn" id="39_q6rov"] [ext_resource type="PackedScene" uid="uid://cg70r0102t8nl" path="res://base-environments/youth_room/fairylights.tscn" id="39_q6rov"]
[ext_resource type="VoxelGIData" uid="uid://hvk1wkuw4maq" path="res://base-environments/youth_room/youth_room.VoxelGI_data.res" id="40_ea6x8"] [ext_resource type="VoxelGIData" uid="uid://hvk1wkuw4maq" path="res://base-environments/youth_room/youth_room.VoxelGI_data.res" id="40_ea6x8"]
@ -1871,7 +1871,7 @@ light_size = 20.0
omni_range = 16.8518 omni_range = 16.8518
[node name="MaskInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="MaskInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(0.8630244, 0, -0.50515974, 0, 1, 0, 0.50515974, 0, 0.8630244, 0.0754588, 0.8061602, 2.42068) transform = Transform3D(-0.8827416, 0, 0.4698562, 0, 1, 0, -0.4698562, 0, -0.8827416, -0.025371574, 0.55708295, 2.5263817)
interaction = ExtResource("12_viwxf") interaction = ExtResource("12_viwxf")
[node name="MindBoardInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="MindBoardInteractable" parent="logic" instance=ExtResource("22_ks23q")]
@ -1879,22 +1879,25 @@ transform = Transform3D(-4.371126e-08, 0, -0.9999984, 0, 1, 0, 0.9999984, 0, -4.
interaction = ExtResource("4_gyjxx") interaction = ExtResource("4_gyjxx")
[node name="CeilingInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="CeilingInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.7148993, 0, -0.6992254, 0, 1, 0, 0.6992254, 0, -0.7148993, -0.13478619, 2.0720484, -0.42032808) transform = Transform3D(0.78626597, 0, 0.6178859, 0, 1, 0, -0.6178859, 0, 0.78626597, -0.13478619, 2.0720484, -0.42032808)
interaction = ExtResource("19_d3c7p") interaction = ExtResource("19_d3c7p")
[node name="ComicInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="ComicInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.9699434, 0, -0.24332677, 0, 1, 0, 0.24332677, 0, -0.9699434, 2.806591, 0.11460018, -0.75655603) transform = Transform3D(0.9797145, 0, 0.20039362, 0, 1, 0, -0.20039362, 0, 0.9797145, 2.9196055, 0.2537475, -0.5924908)
interaction = ExtResource("13_v3447") interaction = ExtResource("13_v3447")
[node name="ClothesInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="ClothesInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.86042935, 0, 0.5095668, 0, 1, 0, -0.5095668, 0, -0.86042935, 1.376315, 1.0840173, -0.68175197) transform = Transform3D(0.7935111, 0, -0.60855323, 0, 1, 0, 0.60855323, 0, 0.7935111, 1.6713148, 1.089737, -0.92289597)
interaction = ExtResource("12_x3dlb") interaction = ExtResource("12_x3dlb")
[node name="Sprite3D" parent="logic/ClothesInteractable/View" index="0"]
transform = Transform3D(1, 0, 2.9802322e-08, 0, 1, 0, -2.9802322e-08, 0, 1, -0.003991425, -0.04700005, 0.09138596)
[node name="collectable_particles" parent="logic/ClothesInteractable" index="3"] [node name="collectable_particles" parent="logic/ClothesInteractable" index="3"]
transform = Transform3D(0.99999976, 0, -2.9802322e-08, 0, 1, 0, 2.9802322e-08, 0, 0.99999976, -0.0057822466, -0.09358537, 0.2777158) transform = Transform3D(0.99999976, 0, 0, 0, 1, 0, 0, 0, 0.99999976, 0.10009599, -0.040801764, -0.19775379)
[node name="DoorInteractable" parent="logic" instance=ExtResource("22_ks23q")] [node name="DoorInteractable" parent="logic" instance=ExtResource("22_ks23q")]
transform = Transform3D(-0.9999984, 0, 8.7422585e-08, 0, 1, 0, -8.7422585e-08, 0, -0.9999984, 0.115203, 1.3931, -0.954428) transform = Transform3D(-0.9999984, 0, 8.7422585e-08, 0, 1, 0, -8.7422585e-08, 0, -0.9999984, 0.067167796, 1.3931, -0.954428)
[node name="AnimationPlayer" type="AnimationPlayer" parent="."] [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = { libraries = {

BIN
src/import/interface-elements/frame-square.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,42 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://0j2nrhijh7lm"
path.s3tc="res://.godot/imported/frame-square.png-2b90f8a920b492285fa408ffcde6389d.s3tc.ctex"
path.etc2="res://.godot/imported/frame-square.png-2b90f8a920b492285fa408ffcde6389d.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://import/interface-elements/frame-square.png"
dest_files=["res://.godot/imported/frame-square.png-2b90f8a920b492285fa408ffcde6389d.s3tc.ctex", "res://.godot/imported/frame-square.png-2b90f8a920b492285fa408ffcde6389d.etc2.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@ -59,8 +59,8 @@ func collapse() -> void:
tween.parallel().tween_property(frame, "modulate:a", 0, 0.6) tween.parallel().tween_property(frame, "modulate:a", 0, 0.6)
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
_process_hover()
_process_billboard() _process_billboard()
_process_hover()
func _process_billboard() -> void: func _process_billboard() -> void:
if shown: if shown:
@ -127,6 +127,7 @@ func collect_memento() -> void:
if interaction_ui is StoryPlayable: if interaction_ui is StoryPlayable:
play_story() play_story()
if interaction_ui is CardBoard: if interaction_ui is CardBoard:
play_board() play_board()

View File

@ -1,14 +1,14 @@
[gd_scene load_steps=8 format=3 uid="uid://dreokijo757l1"] [gd_scene load_steps=8 format=3 uid="uid://dreokijo757l1"]
[ext_resource type="Script" uid="uid://bp6s7vhdd6btk" path="res://logic-scenes/interactable/interactable.gd" id="1_ih54h"] [ext_resource type="Script" uid="uid://bp6s7vhdd6btk" path="res://logic-scenes/interactable/interactable.gd" id="1_ih54h"]
[ext_resource type="Texture2D" uid="uid://d0ucjqi8tx6vt" path="res://import/interface-elements/frame.png" id="2_khok5"] [ext_resource type="Texture2D" uid="uid://0j2nrhijh7lm" path="res://import/interface-elements/frame-square.png" id="2_ih54h"]
[ext_resource type="Texture2D" uid="uid://epjksqlw8frf" path="res://logic-scenes/collectable/decorative_paper.png" id="3_cjk23"] [ext_resource type="Texture2D" uid="uid://epjksqlw8frf" path="res://logic-scenes/collectable/decorative_paper.png" id="3_cjk23"]
[ext_resource type="FontFile" uid="uid://c084lmfai0iig" path="res://import/fonts/ArchitectsDaughter-Regular.ttf" id="4_dujq2"] [ext_resource type="FontFile" uid="uid://c084lmfai0iig" path="res://import/fonts/ArchitectsDaughter-Regular.ttf" id="4_dujq2"]
[ext_resource type="FontFile" uid="uid://qalmecrbkxyp" path="res://import/fonts/icon.ttf" id="5_wl31y"] [ext_resource type="FontFile" uid="uid://qalmecrbkxyp" path="res://import/fonts/icon.ttf" id="5_wl31y"]
[ext_resource type="PackedScene" uid="uid://bdnesuqroi7ss" path="res://vfx/collectable_particles.tscn" id="6_a6wx8"] [ext_resource type="PackedScene" uid="uid://bdnesuqroi7ss" path="res://vfx/collectable_particles.tscn" id="6_a6wx8"]
[sub_resource type="SphereShape3D" id="SphereShape3D_3rbj1"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ih54h"]
radius = 0.3 height = 1.1483154
[node name="Interactable" type="Node3D" groups=["interactables"]] [node name="Interactable" type="Node3D" groups=["interactables"]]
transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 0, 0, 0) transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 0, 0, 0)
@ -16,24 +16,27 @@ script = ExtResource("1_ih54h")
metadata/_custom_type_script = "uid://bp6s7vhdd6btk" metadata/_custom_type_script = "uid://bp6s7vhdd6btk"
[node name="Frame" type="Sprite3D" parent="."] [node name="Frame" type="Sprite3D" parent="."]
transform = Transform3D(0.9928179, -0.11963433, 6.278711e-10, 0.11963433, 0.9928179, -1.04587645e-08, 6.27864e-10, 1.0458765e-08, 1, -0.15, 0.05, 0.1) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.15)
pixel_size = 0.0005 pixel_size = 0.0005
billboard = 1
no_depth_test = true no_depth_test = true
render_priority = 100 render_priority = 100
texture = ExtResource("2_khok5") texture = ExtResource("2_ih54h")
[node name="View" type="Node3D" parent="."] [node name="View" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.52599776, 0.1, 4.5984184e-08)
[node name="Sprite3D" type="Sprite3D" parent="View"] [node name="Sprite3D" type="Sprite3D" parent="View"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.072, -0.047, -0.1)
pixel_size = 0.0007 pixel_size = 0.0007
billboard = 1
no_depth_test = true no_depth_test = true
render_priority = 50 render_priority = 50
texture = ExtResource("3_cjk23") texture = ExtResource("3_cjk23")
[node name="Caption" type="Label3D" parent="View"] [node name="Caption" type="Label3D" parent="View/Sprite3D"]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.03170359, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.031703584, 0)
double_sided = false double_sided = false
no_depth_test = true no_depth_test = true
render_priority = 75 render_priority = 75
@ -44,8 +47,8 @@ font = ExtResource("4_dujq2")
font_size = 10 font_size = 10
outline_size = 0 outline_size = 0
[node name="Icon" type="Label3D" parent="View"] [node name="Icon" type="Label3D" parent="View/Sprite3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.13325092, -0.084207475, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.13325092, -0.084207475, 3.5527137e-15)
double_sided = false double_sided = false
no_depth_test = true no_depth_test = true
render_priority = 75 render_priority = 75
@ -55,7 +58,7 @@ font = ExtResource("5_wl31y")
font_size = 10 font_size = 10
outline_size = 0 outline_size = 0
[node name="Prompt" type="Label3D" parent="View/Icon"] [node name="Prompt" type="Label3D" parent="View/Sprite3D/Icon"]
unique_name_in_owner = true unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0353532, 0, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0353532, 0, 0)
double_sided = false double_sided = false
@ -73,7 +76,8 @@ collision_layer = 16
collision_mask = 16 collision_mask = 16
[node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D"] [node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D"]
shape = SubResource("SphereShape3D_3rbj1") transform = Transform3D(-4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, 0, 1, -0.2727661, -1.1922985e-08, 0)
shape = SubResource("CapsuleShape3D_ih54h")
[node name="collectable_particles" parent="." instance=ExtResource("6_a6wx8")] [node name="collectable_particles" parent="." instance=ExtResource("6_a6wx8")]

View File

@ -199,7 +199,7 @@ mesh = SubResource("SphereMesh_7dqkp")
shape = SubResource("WorldBoundaryShape3D_nl0nc") shape = SubResource("WorldBoundaryShape3D_nl0nc")
[node name="Interactable" parent="." instance=ExtResource("2_nl0nc")] [node name="Interactable" parent="." instance=ExtResource("2_nl0nc")]
transform = Transform3D(-1, 0, 1.509958e-07, 0, 1, 0, -1.509958e-07, 0, -1, 0.0017054975, 0.59263134, 2.5304449) transform = Transform3D(-0.9138857, -0.15697953, 0.37439322, 0, 0.9222155, 0.38667625, -0.4059715, 0.3533779, -0.8427996, 0.0017054975, 0.59263134, 2.5304449)
interaction = ExtResource("3_am5gj") interaction = ExtResource("3_am5gj")
[node name="visuals" parent="." instance=ExtResource("5_3rbj1")] [node name="visuals" parent="." instance=ExtResource("5_3rbj1")]