v0.3.0: rendering pass, generated props, selection model and Web build
Rendering and presentation - Shared surface-material module (src/game/materials.gd) with per-surface roughness/metallic/uv profiles; ACES tonemapping, glow, fog and phase-driven sky energy. WorldBuilder rebuilt on those profiles with facade windows that light up, door trim/handles, curb, lane dashes, bollards, bench, bin and planter foliage. - NPC silhouettes: per-role clothing palettes, caps/hoods/backpacks/sunglasses, hands and shoes, arm/leg walk swing. - Six generated low-poly GLB props (bollards, bench, bin, planter, newspaper box, hydrant) built by tools/model_pipeline.py, loaded by WorldBuilder with a procedural fallback; ADR-0012. Selection and movement - Focus ranking by view angle then distance (NpcFocus.rank_indices); Tab and the mouse wheel cycle nearby people initially, right click clears focus with a re-acquire grace, HUD shows the candidate count, Shift walks at half speed. ADR-0011. Windowed smoke extended to cover wheel cycling and clearing. QA tooling - screen_designs.py catalogue grown to 19 screens (8 scene, 11 UI) plus a `list` subcommand; draft generation keeps existing AI references unless --force. Web export - New Web preset using the non-threaded Godot template (static hosting, no COOP/COEP). tools/build_releases.sh exports build/web and packages build/step-line-web-<ver>.zip; publish_release.sh uploads it with the desktop artifacts. test_web_export.gd covers the preset and release wiring. Verification - Headless suite 177 -> 181, Python tooling 53 tests, all eight smokes pass (including the windowed focus/wheel smoke). Web bundle serves index.html, index.wasm (35 MB) and index.pck (30 MB) with HTTP 200 from a static server. - Version 0.3.0; README, PLAN, RELEASING, TODO/DONE and MEMORY updated.
This commit is contained in:
1 parent
f763cff744
commit
afa1d6beec
48 files changed
+2602
-147
No files matched your search
@@ -93,8 +93,53 @@ func _advance() -> void:
|
||||
if state_frames >= 5:
|
||||
if gm.radial.is_open:
|
||||
_fail("action wheel did not close on cancel")
|
||||
state = 4
|
||||
state_frames = 0
|
||||
4:
|
||||
# Aim-free selection (ADR-0011): the cycled target stays pinned, the
|
||||
# HUD reports how many people can be cycled, and the mouse wheel is
|
||||
# bound to the same ring.
|
||||
if state_frames >= 5:
|
||||
if gm.targeted_npc == null:
|
||||
_fail("target lost after the wheel closed")
|
||||
if not gm.guard.target_pinned:
|
||||
_fail("cycled target was not pinned")
|
||||
if gm.hud.nearby_label.text == "":
|
||||
_fail("nearby hint empty while people are in range")
|
||||
_wheel(true)
|
||||
state = 5
|
||||
state_frames = 0
|
||||
5:
|
||||
if state_frames >= 5:
|
||||
if gm.targeted_npc == null:
|
||||
_fail("mouse wheel dropped the target")
|
||||
elif not gm.guard.target_pinned:
|
||||
_fail("mouse wheel did not pin the cycled target")
|
||||
print("smoke: wheel cycled to %s" % gm.targeted_npc.name)
|
||||
# Right click with nothing open returns to cone focus.
|
||||
gm.call("_handle_cancel", true)
|
||||
state = 6
|
||||
state_frames = 0
|
||||
6:
|
||||
if state_frames >= 5:
|
||||
if gm.targeted_npc != null:
|
||||
_fail("right click did not clear the target")
|
||||
if gm.guard.target_pinned:
|
||||
_fail("clearing the target left it pinned")
|
||||
_finish()
|
||||
|
||||
## Synthesised mouse-wheel event, fed through the real handler so the input-map
|
||||
## binding is exercised as well as the cycling logic.
|
||||
func _wheel(down: bool) -> void:
|
||||
var ev := InputEventMouseButton.new()
|
||||
ev.button_index = MOUSE_BUTTON_WHEEL_DOWN if down else MOUSE_BUTTON_WHEEL_UP
|
||||
ev.pressed = true
|
||||
ev.position = Vector2(640, 360)
|
||||
ev.global_position = ev.position
|
||||
if not ev.is_action_pressed("cycle_target_next"):
|
||||
_fail("cycle_target_next is not bound to the mouse wheel")
|
||||
gm.call("_handle_mouse_button", ev)
|
||||
|
||||
func _stage_target() -> void:
|
||||
if stage_npc == null or not is_instance_valid(stage_npc):
|
||||
stage_npc = gm.npcs[0] if gm.npcs.size() > 0 else null
|
||||
@@ -127,7 +172,7 @@ func _fail(message: String) -> void:
|
||||
|
||||
func _finish() -> void:
|
||||
if failures.is_empty():
|
||||
print("SMOKE OK: focus circle + action wheel opened and cancelled")
|
||||
print("SMOKE OK: focus circle + action wheel + aim-free cycling")
|
||||
quit(0)
|
||||
else:
|
||||
for message in failures:
|
||||
|
||||
Reference in new issue
Block a user