Files
FoxyzandClaude Opus 5.5 df7a2c5a89 Maps are editor-built scenes: [Tool] Playground/Crag, headless rebuild for agents
scenes/maps/playground.tscn and crag.tscn are generated by the map scripts' Rebuild (inspector
button, or godot-mono --headless --path . tools/rebuild_maps.tscn) and loaded as saved by the game,
so hand edits stick. The crag route is saved as Marker3D nodes and crag_spike checks the saved
scene. Layout verified identical to the code-built one (tools/map_dump.tscn).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:10:10 +03:00

69 lines
2.3 KiB
C#

using Godot;
// Headless map rebuild for agents (same as pressing each map's "Rebuild" button in the editor and
// saving): loads each map scene, regenerates its children from code and saves it back.
// godot-mono --headless --path . tools/rebuild_maps.tscn [-- only=playground|crag]
// Prints "MAPS: rebuilt <path> (<n> nodes)" per map and "MAPS: done". Overwrites hand edits in those
// scenes — that's what Rebuild means.
public partial class RebuildMaps : Node
{
public static readonly string[] Maps = { "res://scenes/maps/playground.tscn", "res://scenes/maps/crag.tscn" };
public override void _Ready()
{
string only = null;
foreach (string a in OS.GetCmdlineUserArgs())
if (a.StartsWith("only="))
only = a[5..];
bool ok = true;
foreach (string path in Maps)
{
if (only != null && !path.Contains(only))
continue;
ok &= RebuildOne(path);
}
GD.Print(ok ? "MAPS: done" : "MAPS: FAILED");
GetTree().Quit(ok ? 0 : 1);
}
private bool RebuildOne(string path)
{
Node map = ResourceLoader.Load<PackedScene>(path, null, ResourceLoader.CacheMode.Ignore).Instantiate();
AddChild(map); // in the tree, so joint paths and globals resolve like in the editor
switch (map)
{
case Playground p:
p.Rebuild();
break;
case Crag c:
c.Rebuild();
break;
default:
GD.PushError($"MAPS: {path} root is not a map ({map.GetType().Name})");
return false;
}
RemoveChild(map);
PackedScene packed = new();
Error err = packed.Pack(map);
if (err == Error.Ok)
err = ResourceSaver.Save(packed, path);
int count = CountOwned(map, map);
map.Free();
if (err != Error.Ok)
{
GD.PushError($"MAPS: saving {path} failed: {err}");
return false;
}
GD.Print($"MAPS: rebuilt {path} ({count} nodes)");
return true;
}
private static int CountOwned(Node root, Node n)
{
int c = 0;
foreach (Node child in n.GetChildren())
c += (child.Owner == root ? 1 : 0) + CountOwned(root, child);
return c;
}
}