mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
18fdb0f232
Retraining from scratch removes the constraint that blocked these: the existing checkpoints in Game/bots/promoted/ no longer need byte-identical geometry. - Fix the goal aperture constants (were 1.85/1.65, now match objects/goal.tscn's actual sensor exactly at 1.75/1.5) so a ball crossing the visible edge can't fail to score. - Cut a real navigable hole in each end wall's collision (_build_end_wall_colliders), replacing the previous solid box — the ball now genuinely enters the net instead of triggering the sensor a hair before hitting a solid wall. Correct for both FLOOR and ELEVATED goal modes via _goal_surround_bounds. A separate, slightly wider GOAL_VISUAL_APERTURE_* pair keeps the collision hole exact while still giving goal.gd's bezel/rim frame clearance to be seen against the hull cut. - Resize the play volume 1.5x (INNER_HALF_X/Z/HEIGHT 12/18/12 -> 18/27/18) to comfortably fit a 5v5 roster: updates every hand-authored literal in arena_boundary.tscn/arena_base.tscn/the elevated arena variants that doesn't derive from those constants, adds 5 spawn markers per team, and rescales ship_observations.gd's normalization scales and arena_02's cosmetic decoration/nebula-dust shader uniforms to match. - Bake the ~170 runtime-generated CollisionShape3D nodes into the scene via a new bake_colliders()/tools/bake_arena_boundary.gd instead of rebuilding them on every load — a real load-time cost repeated in every parallel headless training env. Colliders must be direct children of the StaticBody3D to register at all, so bake_colliders() parents them onto self and tags them with a group for idempotent re-baking, rather than grouping them under an intermediate container node. _ready() self-heals: it skips regenerating only when an existing bake's goal_mode metadata matches the current one, so the FLOOR-mode bake in the shared scene is never silently reused by an ELEVATED arena variant.
48 lines
1.8 KiB
GDScript
48 lines
1.8 KiB
GDScript
extends SceneTree
|
|
|
|
# One-off bake: runs ArenaBoundary's collider generation once and commits the
|
|
# result into objects/arena_boundary.tscn, so every arena load (and every
|
|
# parallel headless training env) skips regenerating ~170 CollisionShape3D
|
|
# nodes at runtime — ArenaBoundary._ready() already skips this itself once a
|
|
# bake matching the current goal_mode exists (see bake_colliders).
|
|
#
|
|
# Safe to re-run any time a geometry constant changes (arena size, corner/
|
|
# fillet radii, goal aperture, segment counts, etc.) — bake_colliders() clears
|
|
# its own prior output first, so this replaces rather than duplicates:
|
|
# godot --headless --path Game --script res://tools/bake_arena_boundary.gd
|
|
|
|
const ARENA_BOUNDARY_PATH := "res://objects/arena_boundary.tscn"
|
|
|
|
|
|
func _initialize() -> void:
|
|
var packed: PackedScene = load(ARENA_BOUNDARY_PATH)
|
|
var instance := packed.instantiate()
|
|
instance.bake_colliders()
|
|
# PackedScene.pack() only serializes nodes whose `owner` is set to the
|
|
# scene root — newly created nodes have no owner by default, so without
|
|
# this, pack() silently produces a scene with none of the just-built
|
|
# colliders in it.
|
|
_set_owner_recursive(instance, instance)
|
|
|
|
var rebaked := PackedScene.new()
|
|
var pack_result := rebaked.pack(instance)
|
|
if pack_result != OK:
|
|
push_error("bake_arena_boundary: pack() failed with error %d" % pack_result)
|
|
quit(1)
|
|
return
|
|
|
|
var save_result := ResourceSaver.save(rebaked, ARENA_BOUNDARY_PATH)
|
|
if save_result != OK:
|
|
push_error("bake_arena_boundary: save() failed with error %d" % save_result)
|
|
quit(1)
|
|
return
|
|
|
|
print("bake_arena_boundary: baked colliders into %s" % ARENA_BOUNDARY_PATH)
|
|
quit()
|
|
|
|
|
|
func _set_owner_recursive(node: Node, scene_root: Node) -> void:
|
|
for child in node.get_children():
|
|
child.owner = scene_root
|
|
_set_owner_recursive(child, scene_root)
|