4 Commits

Author SHA1 Message Date
3d1933399e Fix POI hitbox/sprite mismatch and tight interaction range
Both poi.tscn and poi_gate.tscn had two problems stacking on top of
each other: the solid StaticBody3D collider was a fixed-orientation
BoxShape3D (with a Z-offset originally tuned for the old non-billboard
ruins sprite), and the Area3D's own proximity-detection sphere also
carried that same leftover Z-offset. Neither rotates with the sprite,
which now billboards to face the camera (billboard=2) — so depending
on viewing angle you'd either bump into invisible air or walk clean
through the visible sprite, and the interact prompt appeared at wildly
different distances depending on approach direction.

Fix: replaced the oriented box with a centered CylinderShape3D
(radius 1.0) for the solid collider — rotationally symmetric around Y,
so it matches a billboarded sprite from any camera angle by
construction, no per-frame reorientation needed. Removed the Z-offset
from the Area3D's detection sphere and grew its radius to 1.3 (>= the
solid cylinder's radius), so interaction becomes available at or
before physical contact, not after pushing further in.

Verified headless: drove the player at a POI from 4 different
approach angles (0/90/180/270°) and measured both the distance where
movement gets blocked and the distance where player_nearby flips true.
Blocking distance is now consistent (~1.16-1.17 units) across all four
angles instead of varying with direction, and in every case
interaction was ready at or before the blocking distance.
2026-08-27 09:47:57 +02:00
0c76705cca Populate regions 2-6 with the region-1 template, chain all 6 gates
Extends the proven region-1 pattern (6 placeholder POIs + a gate) to
the remaining 5 outer regions, and rewires the gate chain to match the
confirmed progression plan: visit all 6 outer regions in order, then
reach the center — not "region 1 unlocks the center directly" as it
was built initially.

- Repurposed the old GateToCenter into GateR1toR2 (still gated on
  region1_pois, now leads into region 2 instead of the center).
- Added GateR2toR3 .. GateR5toR6, each gated on its own region's POI
  group, sitting just off the radial ridge between two regions
  (2.5 units perpendicular offset — a hard analytical lower bound on
  clearance, since border props' jitter+radius can reach at most
  ~0.75 units off the ridge centerline).
- Added GateR6toCenter (gated on region6_pois) at the region-6 table
  edge, using the same positioning approach as the original center
  gate.
- 30 new POI instances (R2_Ort1..R6_Ort6), positions computed by
  rotating region 1's verified-safe (angle-offset, radius) template by
  60° per region rather than re-deriving hex geometry by hand again —
  region 1's own Ort6 mistake was exactly this kind of hand-arithmetic
  error, not repeating it this time.

Verified headless: all 6 groups have exactly 6 POIs; every gate stays
locked ("Verschlossen", non-interactive) until its whole group is
visited, then unlocks and its "Ja" teleports the player to exactly
target_position — checked for all 6 gates in sequence. Also measured
actual distance from every gate to the nearest border-prop hitbox
across 3 independent runs (border placement is randomized each scene
load) — consistently 1.3-2.2 units clear, no overlaps.
2026-08-27 09:31:59 +02:00
67862a46f3 Add boot flow, save-system skeleton, and Equipment skeleton
boot/: opening_screen (attribution -> title/flavor text placeholder,
explicitly marked TODO for a later real cinematic, skippable by
keypress/click) -> main_menu (Neues Spiel/Fortsetzen/Optionen/Credits/
Beenden, ConfirmationDialog for overwrite-existing-save) -> options_menu
(TabContainer with 4 empty placeholder categories: Grafik/Sound/
Steuerung/Spieloptionen) and credits_screen, both just navigable stubs.
project.godot's run/main_scene now points at boot/opening_screen.tscn
instead of directly at the gameplay scene.

autoload/save_manager.gd: new SaveManager singleton. Deliberately
minimal — persists only a timestamp to user://savegame.json — but a
real, working has_save()/save_game()/load_game()/start_new_game()
round trip, enough to back the menu's Start/Continue/overwrite-confirm
logic without inventing game state that doesn't exist yet.

player/equipment/: Equipment (Node) + EquipmentItem (Resource) stub
classes per the user's explicit ask for a "class diagram skeleton" to
build on later — exported fields and empty TODO methods, no logic.
Wired as a child of world/island.tscn's real Player (not player.tscn,
which is only a debug prototype scene, not the actual game's player).
player.gd's new `equipment` onready var uses get_node_or_null() since
that child only exists on the real player, not every scene reusing
this script.

Verified headless: all new boot scenes load cleanly, a full boot smoke
test via run/main_scene succeeds, and — since button-click navigation
can't be simulated headlessly — SaveManager's actual save/load/
overwrite/cleanup cycle was exercised directly and behaves correctly
(has_save flips true/false correctly, loaded data matches what was
saved). Manual in-editor check of the menu navigation itself is still
needed and not yet done.
2026-08-27 09:21:15 +02:00
c6d7e6c84e Restructure project into boot/autoload/world/player folders
Flat root layout replaced with a domain-based structure:
- autoload/    the two existing singleton scripts (InteractionManager,
               InteractionUI) — grouped by role, matching project.godot's
               [autoload] section
- world/       the flying island: terrain.gd, and world/poi/ for the POI
               marker + gate scripts/scenes
- player/      everything about the player as a character: player.gd/.tscn,
               camera_rig.gd (it only exists to follow the player)
- boot/        created empty for now, will hold the opening/menu screens

main.tscn renamed to world/island.tscn — "main" stops making sense once
the actual run/main_scene becomes a boot screen (next commit). Verified
via grep that main.tscn was referenced nowhere else by path (only by UID
elsewhere, which self-heals).

Every .gd got its .uid sidecar moved alongside it. Two ext_resource
entries had no UID (poi_gate.tscn's own script ref, and island.tscn's
ref to poi_gate.tscn) and needed their path= fixed by hand; everything
else is UID-based and resolved itself after a project reimport.

Also removed two untracked-looking but actually committed editor temp
files (preview_scene.tscn*.tmp, leftovers from the unused hterrain
addon, referenced nowhere).

Verified headless: all 8 affected scenes (island, poi, poi_gate,
player, interaction_ui, and the three debug prototypes that reference
moved files) load with exit code 0. No behavior change, pure move.
2026-08-27 09:18:17 +02:00