using Godot; using IslaApocalypse.Core; namespace IslaApocalypse.Tools { /// /// A print-and-quit diagnostic: resolves and reports this project's user:// directory, then /// exits. It generates nothing and writes nothing. /// /// ═══ WHY IT EXISTS ═══ /// /// The old prototype is named "islaApocalypse" and owns /// ~/.local/share/godot/app_userdata/islaApocalypse/, which holds the PRESERVED reference /// seeds, blueprints and batches. A v2 project sharing that name would read and clobber them /// at runtime. project.godot pins the isolation two ways (distinct name + custom user dir); /// this probe CONFIRMS the pin actually resolves, rather than trusting that it does. /// /// Run it after any change to project.godot's [application] block: /// /// Godot_v4.7.2-stable_mono_linux.x86_64 --headless \ /// --path ~/celerNexus/islaApocalypse-v2 res://Tools/Scenes/UserDirProbe.tscn /// /// --headless is fine HERE — it hangs only on the snapshot capture's render-frame awaits, and /// this awaits nothing. → Tools/README.md, `Design - Tooling - Iteration and Batching.md`. /// public partial class UserDirProbe : Node { public override void _Ready() { string userDir = OS.GetUserDataDir(); // Hand Core the engine-resolved directory — Core is engine-free and never asks Godot itself. ToolingPaths.Configure(userDir); GD.Print("=================================================================="); GD.Print(" user:// PROBE — islaApocalypse-v2"); GD.Print("=================================================================="); GD.Print($"project name : {ProjectSettings.GetSetting("application/config/name")}"); GD.Print($"custom user dir : {ProjectSettings.GetSetting("application/config/use_custom_user_dir")} " + $"(\"{ProjectSettings.GetSetting("application/config/custom_user_dir_name")}\")"); GD.Print($"user:// resolves : {userDir}"); GD.Print($"globalized : {ProjectSettings.GlobalizePath("user://")}"); GD.Print("------------------------------------------------------------------"); GD.Print(" ISOLATION CHECK"); GD.Print("------------------------------------------------------------------"); // The one path this project must never resolve to. const string forbidden = "app_userdata/islaApocalypse"; bool clash = userDir.Replace('\\', '/').TrimEnd('/').EndsWith(forbidden, System.StringComparison.Ordinal); GD.Print(clash ? " ✗ FAIL — resolves to the OLD prototype's dir. Do not run anything else." : " ✓ PASS — not the old prototype's app_userdata/islaApocalypse/."); GD.Print("------------------------------------------------------------------"); GD.Print(" RESOLVED TOOLING PATHS (env-overridable)"); GD.Print("------------------------------------------------------------------"); GD.Print(ToolingPaths.Describe()); GD.Print("------------------------------------------------------------------"); GD.Print($" Core self-check: {MaterialRegistry.TerrainCount} terrain materials, " + $"{MaterialRegistry.BuildingCount} building materials, " + $"{RecipeRegistry.Count} recipes (0 is correct — the seam is deliberately empty)."); GD.Print($" Scale self-check: {new GenerationScale(10240)}"); GD.Print("=================================================================="); GetTree().Quit(clash ? 1 : 0); } } }