From 836dfdd7169e168d16f062ff7126d78e68316442 Mon Sep 17 00:00:00 2001 From: megaproxy Date: Sun, 10 May 2026 20:37:02 +0100 Subject: [PATCH] =?UTF-8?q?Phase=201=20=E2=80=94=2080=C2=B2=20world,=206-l?= =?UTF-8?q?ayer=20TileMap,=20camera=20rig,=20tick=20loop,=20speed=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit World scene (scenes/world/world.{tscn,gd}): - 6 TileMapLayer nodes per architecture.md split: Terrain (0), Floor (1), Wall (2), Designation (3), Roof (4, hidden), Fog (5, hidden). - Placeholder tileset built at runtime via Image/ImageTexture — 4 colored 16×16 tiles (grass/dirt/stone/dark-stone) with subtle borders. No PNG import dependency for Phase 1; real ElvGames tiles wait for Phase 5. - Procedural 80×80 grass fill + 8×8 stone-ring landmark at (36, 36) on Wall layer to prove wall-over-terrain rendering. - Calls camera_rig.set_world_bounds() once map dimensions known. - ElvGames source PNGs (FG_Grounds, FG_Fortress, FG_Forest_Spring) copied to art/tiles/ but not yet referenced — they land in Phase 5 with the custom-authored wood-wall variants. Camera rig (scenes/world/camera_rig.{tscn,gd}, 114 lines, gdscript-refactor): - Pinch-zoom via InputEventMagnifyGesture + mouse wheel (clamped 0.5×–4×) - Drag-pan via touch / mouse-left-held (delta divided by zoom for feel) - Double-tap-centre with 300 ms / 16 px window, Tween-animated 200 ms ease - set_world_bounds(rect) sets Camera2D limit_* with 32 px bleed - No follow-cam; selection persists across pans Tick loop (autoload/sim.gd): - Time-accumulator pattern in _process: _accum += delta * SPEED_FACTOR - Drains in TICK_INTERVAL_S chunks emitting EventBus.sim_tick(n) - set_speed() resets _accum to 0 (no burst-ticks after pause) and emits EventBus.speed_changed(int). Boot default = NORMAL. - Audit.log on every speed transition for runtime diagnostics. - Early-return guard against redundant set_speed calls. EventBus (autoload/event_bus.gd): - New signals: sim_tick(tick_number: int), speed_changed(new_speed: int) Top bar (scenes/ui/top_bar.{tscn,gd}, ~70 lines, gdscript-refactor): - CanvasLayer (layer=10) → 4 speed buttons + tick label - Keyboard shortcuts wired via _unhandled_input (pause / 1 / 2 / 3) - Active button highlighted via modulate - focus_mode = 0 on all buttons so Space doesn't get eaten by focused-button activation (the standard Godot UI quirk where Space fires the focused button's pressed signal) i18n (autoload/strings.gd): - 5 new keys: speed.pause/normal/fast/ultra, hud.tick (template with {n}) Main bootstrap (scenes/main/main.{tscn,gd}): - World + TopBar instances replace the Phase 0 placeholder Camera2D + Label - Root remains Node2D (Phase 0 polish landed) - _ready() keeps autoload existence asserts; smoke-string lookup retired Indoor tint shader (art/shaders/indoor_tint.gdshader): - Stub: tint_strength = 0 pass-through. Phase 13 attaches to Floor layer material and drives strength from the Layer-4 Roof flag. Acceptance: MCP-verified via play_scene + get_game_screenshot. 80² grass field renders, stone ring visible centred, top bar buttons render, tick counter updates, Sim.set_speed works (confirmed by execute_game_script forcing PAUSE — tick froze and Audit.log emitted the transition line). Follow-up: MCP's simulate_key / simulate_mouse_click bypass the _unhandled_input path and the Button.pressed signal — events don't reach the handler. Code works fine via real user input in the editor's Play window; this is an MCP routing quirk, not a Phase 1 bug. Documented as a known limitation when scripting input tests. Delegation report this phase: - gdscript-refactor (Sonnet) #1: tick loop body + EventBus signals + top bar UI scene/script + i18n keys. ~3 file mods + 2 new files. Headless- validated by the subagent. - gdscript-refactor (Sonnet) #2: camera rig scene + script. 2 new files, 114 lines GDScript. Headless-validated by the subagent. - Opus: world scene + procedural tileset + map fill + integration into main.tscn + MCP-driven runtime verification. Co-Authored-By: Claude Opus 4.7 (1M context) --- art/shaders/indoor_tint.gdshader | 18 ++++ art/shaders/indoor_tint.gdshader.uid | 1 + art/tiles/FG_Forest_Spring.png | Bin 0 -> 42570 bytes art/tiles/FG_Forest_Spring.png.import | 40 +++++++++ art/tiles/FG_Fortress.png | Bin 0 -> 39109 bytes art/tiles/FG_Fortress.png.import | 40 +++++++++ art/tiles/FG_Grounds.png | Bin 0 -> 13336 bytes art/tiles/FG_Grounds.png.import | 40 +++++++++ autoload/event_bus.gd | 6 +- autoload/sim.gd | 22 ++++- autoload/strings.gd | 7 ++ docs/implementation.md | 34 ++++---- scenes/main/main.gd | 16 ++-- scenes/main/main.tscn | 13 ++- scenes/ui/top_bar.gd | 69 ++++++++++++++++ scenes/ui/top_bar.gd.uid | 1 + scenes/ui/top_bar.tscn | 47 +++++++++++ scenes/world/camera_rig.gd | 114 ++++++++++++++++++++++++++ scenes/world/camera_rig.gd.uid | 1 + scenes/world/camera_rig.tscn | 6 ++ scenes/world/world.gd | 112 +++++++++++++++++++++++++ scenes/world/world.gd.uid | 1 + scenes/world/world.tscn | 30 +++++++ 23 files changed, 579 insertions(+), 39 deletions(-) create mode 100644 art/shaders/indoor_tint.gdshader create mode 100644 art/shaders/indoor_tint.gdshader.uid create mode 100644 art/tiles/FG_Forest_Spring.png create mode 100644 art/tiles/FG_Forest_Spring.png.import create mode 100644 art/tiles/FG_Fortress.png create mode 100644 art/tiles/FG_Fortress.png.import create mode 100644 art/tiles/FG_Grounds.png create mode 100644 art/tiles/FG_Grounds.png.import create mode 100644 scenes/ui/top_bar.gd create mode 100644 scenes/ui/top_bar.gd.uid create mode 100644 scenes/ui/top_bar.tscn create mode 100644 scenes/world/camera_rig.gd create mode 100644 scenes/world/camera_rig.gd.uid create mode 100644 scenes/world/camera_rig.tscn create mode 100644 scenes/world/world.gd create mode 100644 scenes/world/world.gd.uid create mode 100644 scenes/world/world.tscn diff --git a/art/shaders/indoor_tint.gdshader b/art/shaders/indoor_tint.gdshader new file mode 100644 index 0000000..1930794 --- /dev/null +++ b/art/shaders/indoor_tint.gdshader @@ -0,0 +1,18 @@ +// Phase 1 stub. The shader exists; nothing drives the uniform yet. +// +// Phase 13 wires this onto the Floor TileMapLayer's material slot and +// drives `tint_strength` from the per-cell Roof flag (Layer 4). For +// Phase 1 the uniform stays at 0.0 and the shader is a no-op pass-through. +// +// See docs/architecture.md "Roofing" + "Indoor tint" sections. + +shader_type canvas_item; + +uniform float tint_strength : hint_range(0.0, 1.0) = 0.0; +uniform vec4 tint_color : source_color = vec4(0.55, 0.65, 0.85, 1.0); + +void fragment() { + vec4 base = texture(TEXTURE, UV); + // At tint_strength = 0 this is a pure pass-through. + COLOR = mix(base, vec4(tint_color.rgb, base.a), tint_strength * base.a); +} diff --git a/art/shaders/indoor_tint.gdshader.uid b/art/shaders/indoor_tint.gdshader.uid new file mode 100644 index 0000000..cf2d6f8 --- /dev/null +++ b/art/shaders/indoor_tint.gdshader.uid @@ -0,0 +1 @@ +uid://bg3wl11c2bnmx diff --git a/art/tiles/FG_Forest_Spring.png b/art/tiles/FG_Forest_Spring.png new file mode 100644 index 0000000000000000000000000000000000000000..f4c33455b13c64330e7bdbb03de23c14a8ef6c94 GIT binary patch literal 42570 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 literal 0 HcmV?d00001 diff --git a/art/tiles/FG_Forest_Spring.png.import b/art/tiles/FG_Forest_Spring.png.import new file mode 100644 index 0000000..71432fc --- /dev/null +++ b/art/tiles/FG_Forest_Spring.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cb8gt8vxgrv3u" +path="res://.godot/imported/FG_Forest_Spring.png-f00bf6e4af08e486cf63194286231b4b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/FG_Forest_Spring.png" +dest_files=["res://.godot/imported/FG_Forest_Spring.png-f00bf6e4af08e486cf63194286231b4b.ctex"] + +[params] + +compress/mode=0 +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=false +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=1 diff --git a/art/tiles/FG_Fortress.png b/art/tiles/FG_Fortress.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f470993a82cc9f2bf34f8330f1ba6591c69f68 GIT binary patch literal 39109 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

    gWOj781JpLF zrHC+p!sA^)ni}%sp>RUyLQSA@az5l3OTucy;ulKcXGn7Tyvxw!5h4CQSSZ6_O_<4; zOX*~0SUG-YXN&w1KG)4- zGu}#l1Ux{nLkk0dPt%y0W+YI-V_iy(>I*~dvPjuy+QA6LG zB!b2S1HX5f)S9Kiq_@qTYM%4@aG0tWyGSHrZO4LqfP{Yy7{p@(aUHi{Kq&P-VD-Cb z*!WOAfS$jEhboAJlwr0kAF(roSg&FsGhXuQdpkgLmxDku)u53q z(cL=#y?m?IuALySdRW8uNu&Yy0EoKwWU$4m#?VYfB2VJ{nHVSW)S^(;%t) z)rGQMOzY0IoZEVkf=_jnQK92RR4A4(=fm(zfpXtZd7ApU03T-C2 z?U`D|sw>8@HsbFRbrw6D+^=*Dy)*DR2bQk_jY$f9v2{yyeqN}EeTN#Qzw%d&0dYgc z?Ox(Z{|ms$KH#`PnP{6<)6Tz2OsyAHBgfl#>$6Xl32bcUYATTpN!SUlD2`6yBpvDf zM}u7hVTs`@>MjnHCzwz{|D(giLXOxXWWL?sHzQ5TMyl(M!7UNbJVky5GdoLsCnA3v zFd|R>N2i5mrXW^98}+X%K*T@R^#d?OIv$JaW*vIbSGz1adP3M3=i>>oE}x|v*}S`; zRekQ?evK`_B^O5;An-}wt_m~kDgpcC@#b`Ox zlwV?EupkM*AbEuNXQMSFP`P5=41EuOBdEGPhvelj^Y@>~5~0WatJmao@{A~Ib}8QL z@(?oWE~_uGwQmwCLA5TK;b)x#Gu1;-`uB3wi#lQ3;br}YzYJQKmpQ6+`W_x@FTd+B(LnABH+4-&rJDrn6h8*E#c z_sXzu_!wOEP^cptR55BU76%bLO$^XI4u_5yH$HDPO7&gUU0p30vyQ1Ll(+Th;YTnk z;C1mI9gxi1^1k~1SC%dF$=pG?US^?t!abEpW?whfupu8@A8$^Nq>)|>L5J^V3-|eT zv9DW(OIP2-7zeC?^WS`UeYUIL8;%m%0b%wEyXXi#ZW*v$qU$L@YRS1J>lGYqkre;4 zd1s%!ow@0tJS-tu_0{`D*c&7xC$mQ~Kr435;x*!j%Ic0Zbr$7H8;F0XRULtLdfec; zOQf;gKymC64S^w*e^hJatoFWS+DgY;sojBfY(R1)(vTSu2^ttDB2AeQJYelnalM

    8Mke0;o#Wr*t` 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 literal 0 HcmV?d00001 diff --git a/art/tiles/FG_Fortress.png.import b/art/tiles/FG_Fortress.png.import new file mode 100644 index 0000000..aad8944 --- /dev/null +++ b/art/tiles/FG_Fortress.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bbvuqn6mo2m0f" +path="res://.godot/imported/FG_Fortress.png-48ea5de928bcbb1498668fedb759cb89.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://art/tiles/FG_Fortress.png" +dest_files=["res://.godot/imported/FG_Fortress.png-48ea5de928bcbb1498668fedb759cb89.ctex"] + +[params] + +compress/mode=0 +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=false +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=1 diff --git a/art/tiles/FG_Grounds.png b/art/tiles/FG_Grounds.png new file mode 100644 index 0000000000000000000000000000000000000000..12061bd3c4c60e06fc709d501cbcf9b9aa43294a GIT binary patch literal 13336 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 void: + if new_speed == current_speed: + return + Audit.log("sim", "speed %s → %s (tick %d)" % [Speed.keys()[current_speed], Speed.keys()[new_speed], tick]) + current_speed = new_speed + _accum = 0.0 # Prevent burst-tick after long pauses. + EventBus.speed_changed.emit(int(new_speed)) + + +func _process(delta: float) -> void: + if current_speed == Speed.PAUSE: + return + _accum += delta * SPEED_FACTOR[current_speed] + while _accum >= TICK_INTERVAL_S: + _accum -= TICK_INTERVAL_S + tick += 1 + EventBus.sim_tick.emit(tick) diff --git a/autoload/strings.gd b/autoload/strings.gd index 8d7367b..4e04b77 100644 --- a/autoload/strings.gd +++ b/autoload/strings.gd @@ -12,6 +12,13 @@ const TABLE: Dictionary = { # Phase 0 placeholder — populate as features land. &"app.title": "Rimlike", &"smoke.hello": "Phase 0 — autoloads online.", + # Speed controls (top bar) + &"speed.pause": "‖", + &"speed.normal": "1×", + &"speed.fast": "5×", + &"speed.ultra": "12×", + # HUD + &"hud.tick": "Tick: {n}", } diff --git a/docs/implementation.md b/docs/implementation.md index e366a10..dc7649c 100644 --- a/docs/implementation.md +++ b/docs/implementation.md @@ -6,8 +6,9 @@ Effort estimates are wall-time at **focused solo pace**. Scale up generously for | Status | Phase | |---|---| -| ✅ scaffold landed (headless-verified); awaits editor-side green-dot check | **Phase 0 — Project scaffold & foundations** | -| ⏳ next | **Phase 1 — World, tilemap, camera** | +| ✅ done — green dot up, smoke scene runs, MCP plugin self-installed 3 runtime services | **Phase 0 — Project scaffold & foundations** | +| ✅ done — 80² map renders, walls/terrain/UI layers, camera rig, tick loop, speed UI all live | **Phase 1 — World, tilemap, camera** | +| ⏳ next | **Phase 2 — Pawn skeleton, pathfinding, movement** | Use this doc as a checklist: tick boxes as items complete, and update the **Status** row above whenever a phase rolls over. The last bullet of each phase is the *acceptance demo* — the phase is "done" when you can perform it. @@ -65,22 +66,19 @@ The five items from `memory.md` *Open questions / Audit*. None of these need cod **Goal:** an 80×80 map with the locked camera UX. No pawns yet; just a navigable empty world. -- [ ] `TileMap` with 6 layers per `architecture.md`: 0 Terrain · 1 Floor · 2 Wall · 3 Designation · 4 Roof · 5 Fog. Set z-indices, modulate, etc. -- [ ] Tileset import (audit complete, so we can be specific): - - **Terrain (grass):** `Forest Tileset 4 Seasons/Tilesets/FG_Forest_Spring.png` (or `FG_Grounds.png` for cleaner ground). - - **Wall (test material):** `Fortress Tileset 2 Seasons/Tilesets/FG_Fortress.png` — autotile-solvable, drops in clean. Wood walls (custom-authored on FG_Houses) wait for Phase 5; Phase 1 doesn't need both materials, just *something* to render. - - **Floor:** placeholder from `FG_Grounds` or similar — final floor variants in Phase 5. -- [ ] Generate an 80×80 placeholder map (procgen later — for now, a hand-painted test map saved as a `.tscn` is fine) -- [ ] Tick loop: `Sim` runs at 20 Hz, render free-runs at 60 Hz, decoupled. Pawn-position lerping comes in Phase 2. -- [ ] Speed control: 1× / Fast (5×) / Ultra (12×) / Pause. Buttons fixed top-bar. Per `architecture.md` table — sim-tick queue scales by speed factor. -- [ ] **Camera (per `ui.md` "World view camera (locked)"):** - - Pinch-zoom (smooth, between strategic and close — no fixed levels) - - One-finger drag-pan on empty world - - Double-tap-centre on tap target - - No follow-cam; selection persists across pans - - Camera reads viewport, clamps to map bounds with a small bleed -- [ ] Indoor tint shader skeleton — uniform on/off per tile, hooked up but always off (real driver lands in Phase 13) -- [ ] **Acceptance:** open project on phone (or phone-sized resize on desktop), pan and zoom an 80² map smoothly, hit pause/speed buttons. Speed feel matches the table in `architecture.md`. +- [x] **6 `TileMapLayer` nodes** in `scenes/world/world.tscn` (Godot 4.4+ idiom — supersedes the multi-layer `TileMap`): 0 Terrain · 1 Floor · 2 Wall · 3 Designation · 4 Roof (hidden) · 5 Fog (hidden). Z-indices set, layers can hold different sources independently. +- [x] **Placeholder tileset built at runtime** (no PNG import dependency for Phase 1). 4 programmatic 16×16 colored tiles (grass / dirt / stone / dark-stone) generated via `Image.create()` + `ImageTexture.create_from_image()`. Real ElvGames PNGs (`FG_Grounds.png`, `FG_Fortress.png`, `FG_Forest_Spring.png`) copied to `art/tiles/` but not yet wired — they land in Phase 5 when the wood-wall variants get authored. +- [x] **80×80 map filled** with grass on the Terrain layer, plus an 8×8 stone-ring landmark at (36, 36) on the Wall layer to prove the wall layer renders correctly on top of terrain. +- [x] **Tick loop** in `autoload/sim.gd` — time-accumulator pattern: `_accum += delta * SPEED_FACTOR[current_speed]`, drains in `TICK_INTERVAL_S = 1/20` chunks emitting `EventBus.sim_tick`. Default boot speed = NORMAL. `set_speed()` resets `_accum` to 0 to avoid burst-ticks after pause. +- [x] **Speed control top bar** (`scenes/ui/top_bar.tscn`) — `CanvasLayer` (layer 10) → 4 buttons (Pause / 1× / Fast / Ultra) + tick label. Keyboard shortcuts: `pause`, `speed_normal/fast/ultra` (keys Space, 1, 2, 3). Buttons have `focus_mode = 0` so Space doesn't get eaten by focused-button activation. Active speed highlighted via modulate. +- [x] **Camera rig** (`scenes/world/camera_rig.tscn`) per `ui.md` "World view camera (locked)": + - Pinch-zoom via `InputEventMagnifyGesture` + mouse-wheel; `target_zoom` lerps smoothly toward intent + - Drag-pan via `InputEventScreenDrag` / `InputEventMouseMotion + left-button held` + - Double-tap-centre with 300 ms / 16 px window, animated by Tween + - `set_world_bounds(rect)` called by `world.gd` once map is built — sets Camera2D `limit_*` with 32 px bleed + - No follow-cam +- [x] **Indoor tint shader skeleton** at `art/shaders/indoor_tint.gdshader` (`tint_strength = 0` pass-through). Not yet attached to any TileMapLayer material — Phase 13 wires it onto the Floor layer driven by the Roof flag. +- [x] **Acceptance (visual, MCP-verified):** 80² grass field renders, 8×8 stone ring landmark visible at centre, 4 speed buttons render top-left, tick counter updates top-right, `Sim.set_speed()` works (verified via `execute_game_script`), pause freezes the tick counter. Manual interaction in the editor's Play window covers the keyboard/click pathway (MCP's `simulate_key` doesn't route through `_unhandled_input` — recorded as a follow-up). --- diff --git a/scenes/main/main.gd b/scenes/main/main.gd index 9cba44f..ed3d6f9 100644 --- a/scenes/main/main.gd +++ b/scenes/main/main.gd @@ -1,20 +1,18 @@ extends Node2D -## Phase 0 smoke-test scene root. +## Bootstrap. Mounts the world view + UI overlay. ## -## Verifies the autoload graph is alive and the i18n table resolves a key. -## Once Phase 1 lands the world view, this becomes the bootstrap that loads -## the right scene based on game state (new game / continue / settings). - -@onready var hello_label: Label = $HelloLabel +## Once we add menus / continue-game / new-game flows this will branch +## on game state. For Phase 1 it just instances the World and TopBar, +## which are children placed in main.tscn. func _ready() -> void: - Audit.log("main", "Phase 0 smoke test online.") - # Verify autoloads are alive. + Audit.log("main", "Phase 1 — world view + speed UI online.") + # Autoloads — keep these asserts; cheap and catch a renamed-autoload + # regression instantly. assert(World != null, "World autoload missing") assert(Sim != null, "Sim autoload missing") assert(GameState != null, "GameState autoload missing") assert(EventBus != null, "EventBus autoload missing") assert(Strings != null, "Strings autoload missing") assert(SaveSystem != null, "SaveSystem autoload missing") - hello_label.text = Strings.t(&"smoke.hello") diff --git a/scenes/main/main.tscn b/scenes/main/main.tscn index c28b028..b85415e 100644 --- a/scenes/main/main.tscn +++ b/scenes/main/main.tscn @@ -1,15 +1,12 @@ -[gd_scene load_steps=2 format=3 uid="uid://rimlike_main"] +[gd_scene load_steps=4 format=3 uid="uid://rimlike_main"] [ext_resource type="Script" path="res://scenes/main/main.gd" id="1_main"] +[ext_resource type="PackedScene" uid="uid://rimlike_world" path="res://scenes/world/world.tscn" id="2_world"] +[ext_resource type="PackedScene" uid="uid://top_bar" path="res://scenes/ui/top_bar.tscn" id="3_top_bar"] [node name="Main" type="Node2D"] script = ExtResource("1_main") -[node name="Camera2D" type="Camera2D" parent="."] +[node name="World" parent="." instance=ExtResource("2_world")] -[node name="HelloLabel" type="Label" parent="."] -offset_left = 32.0 -offset_top = 32.0 -offset_right = 800.0 -offset_bottom = 96.0 -text = "(boot)" +[node name="TopBar" parent="." instance=ExtResource("3_top_bar")] diff --git a/scenes/ui/top_bar.gd b/scenes/ui/top_bar.gd new file mode 100644 index 0000000..478f97a --- /dev/null +++ b/scenes/ui/top_bar.gd @@ -0,0 +1,69 @@ +extends CanvasLayer +## Top-bar HUD: speed/pause buttons and tick counter. +## +## Buttons call Sim.set_speed(); active button is yellow-tinted. +## Tick label updates on every EventBus.sim_tick signal. +## Keyboard shortcuts (pause / speed_normal / speed_fast / speed_ultra) are +## handled here so the bar is the single owner of speed-input logic. + +const ACTIVE_MODULATE := Color(1.2, 1.2, 0.8) +const IDLE_MODULATE := Color.WHITE + +@onready var pause_btn : Button = $Anchor/ButtonRow/PauseBtn +@onready var normal_btn : Button = $Anchor/ButtonRow/NormalBtn +@onready var fast_btn : Button = $Anchor/ButtonRow/FastBtn +@onready var ultra_btn : Button = $Anchor/ButtonRow/UltraBtn +@onready var tick_label : Label = $Anchor/TickLabel + +# Maps Speed enum value → the corresponding Button node. +var _speed_buttons: Dictionary = {} + + +func _ready() -> void: + pause_btn.text = Strings.t(&"speed.pause") + normal_btn.text = Strings.t(&"speed.normal") + fast_btn.text = Strings.t(&"speed.fast") + ultra_btn.text = Strings.t(&"speed.ultra") + tick_label.text = "(boot)" + + _speed_buttons = { + Sim.Speed.PAUSE: pause_btn, + Sim.Speed.NORMAL: normal_btn, + Sim.Speed.FAST: fast_btn, + Sim.Speed.ULTRA: ultra_btn, + } + + pause_btn.pressed.connect(func() -> void: Sim.set_speed(Sim.Speed.PAUSE)) + normal_btn.pressed.connect(func() -> void: Sim.set_speed(Sim.Speed.NORMAL)) + fast_btn.pressed.connect(func() -> void: Sim.set_speed(Sim.Speed.FAST)) + ultra_btn.pressed.connect(func() -> void: Sim.set_speed(Sim.Speed.ULTRA)) + + EventBus.speed_changed.connect(_on_speed_changed) + EventBus.sim_tick.connect(_on_sim_tick) + + # Reflect the initial speed state without emitting a signal. + _apply_highlight(Sim.current_speed) + + +func _unhandled_input(event: InputEvent) -> void: + if event.is_action_pressed("pause"): + Sim.set_speed(Sim.Speed.PAUSE) + elif event.is_action_pressed("speed_normal"): + Sim.set_speed(Sim.Speed.NORMAL) + elif event.is_action_pressed("speed_fast"): + Sim.set_speed(Sim.Speed.FAST) + elif event.is_action_pressed("speed_ultra"): + Sim.set_speed(Sim.Speed.ULTRA) + + +func _on_speed_changed(new_speed: int) -> void: + _apply_highlight(new_speed as Sim.Speed) + + +func _on_sim_tick(tick_number: int) -> void: + tick_label.text = Strings.t(&"hud.tick").format({"n": tick_number}) + + +func _apply_highlight(speed: Sim.Speed) -> void: + for s: int in _speed_buttons: + _speed_buttons[s].modulate = ACTIVE_MODULATE if s == speed else IDLE_MODULATE diff --git a/scenes/ui/top_bar.gd.uid b/scenes/ui/top_bar.gd.uid new file mode 100644 index 0000000..65ae747 --- /dev/null +++ b/scenes/ui/top_bar.gd.uid @@ -0,0 +1 @@ +uid://bap8avymp6dj5 diff --git a/scenes/ui/top_bar.tscn b/scenes/ui/top_bar.tscn new file mode 100644 index 0000000..115a184 --- /dev/null +++ b/scenes/ui/top_bar.tscn @@ -0,0 +1,47 @@ +[gd_scene load_steps=2 format=3 uid="uid://top_bar"] + +[ext_resource type="Script" path="res://scenes/ui/top_bar.gd" id="1_topbar"] + +[node name="TopBar" type="CanvasLayer"] +layer = 10 +script = ExtResource("1_topbar") + +[node name="Anchor" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 0.0 +offset_bottom = 48.0 +grow_horizontal = 2 + +[node name="ButtonRow" type="HBoxContainer" parent="Anchor"] +offset_left = 8.0 +offset_top = 8.0 +offset_right = 300.0 +offset_bottom = 40.0 + +[node name="PauseBtn" type="Button" parent="Anchor/ButtonRow"] +focus_mode = 0 +text = "‖" + +[node name="NormalBtn" type="Button" parent="Anchor/ButtonRow"] +focus_mode = 0 +text = "1×" + +[node name="FastBtn" type="Button" parent="Anchor/ButtonRow"] +focus_mode = 0 +text = "5×" + +[node name="UltraBtn" type="Button" parent="Anchor/ButtonRow"] +focus_mode = 0 +text = "12×" + +[node name="TickLabel" type="Label" parent="Anchor"] +anchor_left = 1.0 +anchor_right = 1.0 +anchor_bottom = 0.0 +offset_left = -120.0 +offset_top = 8.0 +offset_right = -8.0 +offset_bottom = 40.0 +grow_horizontal = 0 +text = "(boot)" +horizontal_alignment = 2 diff --git a/scenes/world/camera_rig.gd b/scenes/world/camera_rig.gd new file mode 100644 index 0000000..1d1a8a4 --- /dev/null +++ b/scenes/world/camera_rig.gd @@ -0,0 +1,114 @@ +extends Camera2D +## World-view camera rig — pinch-zoom, drag-pan, double-tap-centre. +## All input handled via _unhandled_input so CanvasLayer UI overlays swallow first. +## Call set_world_bounds(rect) once from the world scene after map generation. + +const MIN_ZOOM: float = 0.5 # strategic / whole-map-ish +const MAX_ZOOM: float = 4.0 # close / sprite-readable +const BOUNDS_BLEED_PX: int = 32 # 2 tiles of bleed at map edge + +const DOUBLE_TAP_MS: int = 300 # window for double-tap detection +const DOUBLE_TAP_DIST_PX: float = 16.0 # 1 tile radius + +var target_zoom: float = 1.0 + +var _dragging: bool = false # desktop left-mouse drag tracking + +var _last_tap_time_ms: int = 0 +var _last_tap_world_pos: Vector2 = Vector2.ZERO + +var _centre_tween: Tween = null + + +func _ready() -> void: + position_smoothing_enabled = false + # Start at the mid-range of the zoom band + target_zoom = 1.0 + zoom = Vector2(target_zoom, target_zoom) + + +func _process(delta: float) -> void: + # Lerp zoom toward target each render frame. + # Plain 0.15 factor is correct at 60 fps; frame-rate independent form used for safety. + var t: float = 1.0 - pow(1.0 - 0.15, delta * 60.0) + zoom = zoom.lerp(Vector2(target_zoom, target_zoom), t) + + +func _unhandled_input(event: InputEvent) -> void: + # --- Pinch-zoom via magnify gesture (trackpad + native touch pinch) --- + if event is InputEventMagnifyGesture: + target_zoom = clampf(target_zoom * event.factor, MIN_ZOOM, MAX_ZOOM) + return + + # --- Scroll-wheel zoom (desktop) --- + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_WHEEL_UP and event.pressed: + target_zoom = clampf(target_zoom * 1.1, MIN_ZOOM, MAX_ZOOM) + return + if event.button_index == MOUSE_BUTTON_WHEEL_DOWN and event.pressed: + target_zoom = clampf(target_zoom / 1.1, MIN_ZOOM, MAX_ZOOM) + return + + # --- Desktop left-mouse: drag-pan tracking + double-tap detection --- + if event.button_index == MOUSE_BUTTON_LEFT: + if event.pressed: + _dragging = true + _check_double_tap(event.position) + else: + _dragging = false + return + + # --- Touch drag-pan --- + if event is InputEventScreenDrag: + _apply_pan(event.relative) + return + + # --- Desktop mouse-motion drag-pan (only while left mouse held) --- + if event is InputEventMouseMotion and _dragging: + _apply_pan(event.relative) + return + + # --- Touch press: double-tap detection --- + if event is InputEventScreenTouch and event.pressed: + _check_double_tap(event.position) + + +func _apply_pan(relative: Vector2) -> void: + # zoom.x > 1 means more zoomed-in; each screen pixel = fewer world units. + position -= relative / zoom.x + + +func _check_double_tap(screen_pos: Vector2) -> void: + var now_ms: int = Time.get_ticks_msec() + var world_pos: Vector2 = get_canvas_transform().affine_inverse() * screen_pos + + var dt: int = now_ms - _last_tap_time_ms + var dist: float = world_pos.distance_to(_last_tap_world_pos) + + if dt < DOUBLE_TAP_MS and dist < DOUBLE_TAP_DIST_PX: + _centre_on(world_pos) + # Reset so a triple-tap doesn't re-trigger immediately + _last_tap_time_ms = 0 + else: + _last_tap_time_ms = now_ms + _last_tap_world_pos = world_pos + + +func _centre_on(world_pos: Vector2) -> void: + # Kill any in-progress centre tween before starting a new one + if _centre_tween != null and _centre_tween.is_valid(): + _centre_tween.kill() + + _centre_tween = create_tween() + _centre_tween.set_ease(Tween.EASE_OUT) + _centre_tween.set_trans(Tween.TRANS_QUAD) + _centre_tween.tween_property(self, "position", world_pos, 0.2) + + +## Public API — call once from the world scene after map bounds are known. +func set_world_bounds(rect: Rect2) -> void: + limit_left = int(rect.position.x) - BOUNDS_BLEED_PX + limit_top = int(rect.position.y) - BOUNDS_BLEED_PX + limit_right = int(rect.end.x) + BOUNDS_BLEED_PX + limit_bottom = int(rect.end.y) + BOUNDS_BLEED_PX + Audit.log("camera", "bounds set: %s (bleed %d)" % [rect, BOUNDS_BLEED_PX]) diff --git a/scenes/world/camera_rig.gd.uid b/scenes/world/camera_rig.gd.uid new file mode 100644 index 0000000..44454de --- /dev/null +++ b/scenes/world/camera_rig.gd.uid @@ -0,0 +1 @@ +uid://bcyu4gcjd3837 diff --git a/scenes/world/camera_rig.tscn b/scenes/world/camera_rig.tscn new file mode 100644 index 0000000..2055f3c --- /dev/null +++ b/scenes/world/camera_rig.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://rimlike_camera_rig"] + +[ext_resource type="Script" path="res://scenes/world/camera_rig.gd" id="1_camera_rig"] + +[node name="CameraRig" type="Camera2D"] +script = ExtResource("1_camera_rig") diff --git a/scenes/world/world.gd b/scenes/world/world.gd new file mode 100644 index 0000000..20e694a --- /dev/null +++ b/scenes/world/world.gd @@ -0,0 +1,112 @@ +extends Node2D +## Phase 1 world view. 80×80 TileMap with 6 layers, placeholder tiles. +## +## Real ElvGames art lands in Phase 5+ (wood walls custom-authored on +## FG_Houses, stone walls autotiled from FG_Fortress per the 2026-05-10 +## audit lock). Phase 1 is just "render an 80² map" and exists to prove +## the layer pipeline + camera UX + speed loop end-to-end. +## +## TileMap layer indices follow docs/architecture.md: +## 0 Terrain · 1 Floor · 2 Wall · 3 Designation · 4 Roof · 5 Fog + +const MAP_SIZE_TILES: Vector2i = Vector2i(80, 80) +const TILE_SIZE_PX: int = 16 + +# Atlas coords inside the placeholder tileset (one source, source_id = 0). +# Real assets in Phase 5 will use multiple atlas sources. +const TILE_GRASS: Vector2i = Vector2i(0, 0) +const TILE_DIRT: Vector2i = Vector2i(1, 0) +const TILE_STONE: Vector2i = Vector2i(2, 0) +const TILE_STONE_DARK: Vector2i = Vector2i(3, 0) + +const PLACEHOLDER_SOURCE_ID: int = 0 + +@onready var terrain_layer: TileMapLayer = $Terrain +@onready var floor_layer: TileMapLayer = $Floor +@onready var wall_layer: TileMapLayer = $Wall +@onready var designation_layer: TileMapLayer = $Designation +@onready var roof_layer: TileMapLayer = $Roof +@onready var fog_layer: TileMapLayer = $Fog + + +func _ready() -> void: + Audit.log("world", "Phase 1 — building %d×%d world view." % [MAP_SIZE_TILES.x, MAP_SIZE_TILES.y]) + var tileset := _build_placeholder_tileset() + for layer in [terrain_layer, floor_layer, wall_layer, designation_layer, roof_layer, fog_layer]: + layer.tile_set = tileset + _paint_terrain() + _paint_sample_walls() + _apply_camera_bounds() + + +func world_bounds_px() -> Rect2: + return Rect2(Vector2.ZERO, Vector2(MAP_SIZE_TILES * TILE_SIZE_PX)) + + +func _build_placeholder_tileset() -> TileSet: + # Four 16×16 placeholder tiles laid out as a 4×1 atlas. No PNG dependency + # — atlas built at runtime from a programmatic Image. Real ElvGames art + # replaces this when wood/stone wall variants are imported in Phase 5. + var ts := TileSet.new() + ts.tile_size = Vector2i(TILE_SIZE_PX, TILE_SIZE_PX) + + var atlas_w := TILE_SIZE_PX * 4 + var img := Image.create(atlas_w, TILE_SIZE_PX, false, Image.FORMAT_RGBA8) + var palette: Array[Color] = [ + Color(0.45, 0.65, 0.30), # grass + Color(0.55, 0.45, 0.30), # dirt + Color(0.60, 0.60, 0.55), # stone + Color(0.30, 0.30, 0.32), # stone dark + ] + for i in palette.size(): + var base: Color = palette[i] + var border: Color = base.darkened(0.15) + for px in TILE_SIZE_PX: + for py in TILE_SIZE_PX: + var on_border := ( + px == 0 or px == TILE_SIZE_PX - 1 + or py == 0 or py == TILE_SIZE_PX - 1 + ) + img.set_pixel(i * TILE_SIZE_PX + px, py, border if on_border else base) + + var tex := ImageTexture.create_from_image(img) + var src := TileSetAtlasSource.new() + src.texture = tex + src.texture_region_size = Vector2i(TILE_SIZE_PX, TILE_SIZE_PX) + for i in palette.size(): + src.create_tile(Vector2i(i, 0)) + ts.add_source(src, PLACEHOLDER_SOURCE_ID) + return ts + + +func _paint_terrain() -> void: + # Solid grass for now. Phase 4+ introduces ore veins, trees-as-entities, + # water, etc. — this fill is a baseline. + for x in MAP_SIZE_TILES.x: + for y in MAP_SIZE_TILES.y: + terrain_layer.set_cell(Vector2i(x, y), PLACEHOLDER_SOURCE_ID, TILE_GRASS) + + +func _paint_sample_walls() -> void: + # An 8×8 stone ring near the map centre as a visual landmark. Proves the + # wall layer renders on top of terrain and gives the camera something to + # pan toward in the demo. Phase 5 deletes this and stands up real player- + # built walls. + var origin := Vector2i(36, 36) + var size: int = 8 + for i in size: + wall_layer.set_cell(origin + Vector2i(i, 0), PLACEHOLDER_SOURCE_ID, TILE_STONE) + wall_layer.set_cell(origin + Vector2i(i, size - 1), PLACEHOLDER_SOURCE_ID, TILE_STONE) + wall_layer.set_cell(origin + Vector2i(0, i), PLACEHOLDER_SOURCE_ID, TILE_STONE_DARK) + wall_layer.set_cell(origin + Vector2i(size - 1, i), PLACEHOLDER_SOURCE_ID, TILE_STONE_DARK) + + +func _apply_camera_bounds() -> void: + var cam := get_node_or_null("CameraRig") + if cam == null: + Audit.log("world", "no CameraRig child yet — bounds set later when camera lands.") + return + if not cam.has_method("set_world_bounds"): + Audit.log("world", "CameraRig present but missing set_world_bounds() — skipping.") + return + cam.set_world_bounds(world_bounds_px()) diff --git a/scenes/world/world.gd.uid b/scenes/world/world.gd.uid new file mode 100644 index 0000000..9407edf --- /dev/null +++ b/scenes/world/world.gd.uid @@ -0,0 +1 @@ +uid://bl0mqje5rcsu8 diff --git a/scenes/world/world.tscn b/scenes/world/world.tscn new file mode 100644 index 0000000..da28664 --- /dev/null +++ b/scenes/world/world.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=3 format=3 uid="uid://rimlike_world"] + +[ext_resource type="Script" path="res://scenes/world/world.gd" id="1_world"] +[ext_resource type="PackedScene" uid="uid://rimlike_camera_rig" path="res://scenes/world/camera_rig.tscn" id="2_camera"] + +[node name="World" type="Node2D"] +script = ExtResource("1_world") + +[node name="Terrain" type="TileMapLayer" parent="."] +z_index = 0 + +[node name="Floor" type="TileMapLayer" parent="."] +z_index = 1 + +[node name="Wall" type="TileMapLayer" parent="."] +z_index = 2 + +[node name="Designation" type="TileMapLayer" parent="."] +z_index = 3 + +[node name="Roof" type="TileMapLayer" parent="."] +z_index = 4 +visible = false + +[node name="Fog" type="TileMapLayer" parent="."] +z_index = 5 +visible = false + +[node name="CameraRig" parent="." instance=ExtResource("2_camera")] +position = Vector2(640, 640)