feat: Neon Alley — urban-Japan movement map built on the acoustic materials
New map (scenes/maps/neon_alley/, auto-appears in the level selectors): Layout for movement flow: - Main N-S street = the long sightline, crossed by a pedestrian bridge (slide ramps up both ends, underpass cover below, railed high ground) - West machiya row: wooden two-story houses with a jump route (awning -> balcony -> roof deck) and 25-degree slide roofs facing the street - East concrete towers with glass storefronts; brick wallrun alley between them (AC units to vault); metal fire-escape platform route to the roofs; angled rooftop billboard as cover + grapple anchor - Three power pylons with crossarms over the street chain a grapple route; the torii gate crossbeam at the north shrine plaza is a fourth anchor - South market: wooden stalls with neon canopies + metal vending machines = scattered mid cover; shipping container corner piece - Spawns ring the block and face the map center Acoustics as level design: every surface is tagged (machiya/stalls/torii wood, towers concrete, storefronts glass, alley+perimeter brick, escapes/ AC/rails/container metal) so occlusion tells you which structure a shot came through and reflections differ per street. Style: sunset sky + fixed dusk-lavender ambient (calibrated for the toon shader's 1/PI light response), warm low sun, neon sign columns, shop signs, lantern strings, billboard glow, underpass strip lights. Verified: aerial + street-level + third-person captures; movement 11/11, smoke 0 failures, acoustics ALL PASSED. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a51595e3b9
commit
0813d0b40d
@@ -90,8 +90,9 @@ func _box_static(pos: Vector3, size: Vector3, color: Color, node_name: String =
|
||||
return body
|
||||
|
||||
|
||||
func _ramp_static(pos: Vector3, size: Vector3, rot_deg: Vector3, color: Color, node_name: String = "") -> StaticBody3D:
|
||||
var body := _box_static(pos, size, color, node_name)
|
||||
func _ramp_static(pos: Vector3, size: Vector3, rot_deg: Vector3, color: Color, node_name: String = "",
|
||||
acoustic: String = "") -> StaticBody3D:
|
||||
var body := _box_static(pos, size, color, node_name, acoustic)
|
||||
body.rotation_degrees = rot_deg
|
||||
return body
|
||||
|
||||
|
||||
+17
-3
@@ -2,17 +2,21 @@ extends SceneTree
|
||||
|
||||
## Dev tool: launch with rendering, screenshot the main menu and a level,
|
||||
## then quit. Run:
|
||||
## godot --path . -s res://debug/visual_capture.gd -- <output_dir>
|
||||
## Screenshots land in <output_dir>/shot_menu.png and shot_level.png.
|
||||
## godot --path . -s res://debug/visual_capture.gd -- <output_dir> [scene_path]
|
||||
## Screenshots land in <output_dir>/shot_menu.png, shot_level.png, shot_tp_run.png
|
||||
## and shot_aerial.png. scene_path defaults to the test level.
|
||||
|
||||
var _frames := 0
|
||||
var _out_dir := "."
|
||||
var _scene := "res://scenes/maps/test_level/test_level.tscn"
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var args := OS.get_cmdline_user_args()
|
||||
if args.size() > 0:
|
||||
_out_dir = args[0]
|
||||
if args.size() > 1:
|
||||
_scene = args[1]
|
||||
change_scene_to_file("res://ui/main_menu/main_menu.tscn")
|
||||
|
||||
|
||||
@@ -23,7 +27,7 @@ func _process(_delta: float) -> bool:
|
||||
var nm = root.get_node_or_null("NetworkManager")
|
||||
if nm and nm.has_method("start_singleplayer_match"):
|
||||
nm.start_singleplayer_match("Deathmatch")
|
||||
change_scene_to_file("res://scenes/maps/test_level/test_level.tscn")
|
||||
change_scene_to_file(_scene)
|
||||
elif _frames == 240:
|
||||
_shot("level")
|
||||
# Third person + run forward, to eyeball model grounding and animation
|
||||
@@ -34,6 +38,16 @@ func _process(_delta: float) -> bool:
|
||||
elif _frames == 320:
|
||||
_shot("tp_run")
|
||||
Input.action_release("move_forward")
|
||||
# Aerial overview of the whole map
|
||||
var cam := root.get_camera_3d()
|
||||
if cam:
|
||||
var aerial := Camera3D.new()
|
||||
current_scene.add_child(aerial)
|
||||
aerial.global_position = Vector3(0, 55, 42)
|
||||
aerial.look_at(Vector3(0, 0, -5), Vector3.UP)
|
||||
aerial.current = true
|
||||
elif _frames == 340:
|
||||
_shot("aerial")
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user