From ec8eabe7ebf051e0f514c2aff0cc4db814530653 Mon Sep 17 00:00:00 2001 From: FireFoxPhoenix <171633349+FireFoxPhoenix@users.noreply.github.com> Date: Tue, 10 Feb 2026 18:15:19 +1000 Subject: [PATCH 1/6] Logging --- Content.MapRenderer/Logger.cs | 42 +++++++++++++++++++ Content.MapRenderer/Painters/DecalPainter.cs | 4 +- Content.MapRenderer/Painters/EntityPainter.cs | 4 +- Content.MapRenderer/Painters/GridPainter.cs | 8 ++-- Content.MapRenderer/Painters/MapPainter.cs | 4 +- Content.MapRenderer/Painters/TilePainter.cs | 4 +- Content.MapRenderer/Program.cs | 37 ++++++++-------- 7 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 Content.MapRenderer/Logger.cs diff --git a/Content.MapRenderer/Logger.cs b/Content.MapRenderer/Logger.cs new file mode 100644 index 000000000000..c6f8d32d743f --- /dev/null +++ b/Content.MapRenderer/Logger.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; + +namespace Content.MapRenderer +{ + internal static class Logger + { + private static readonly string LogFilePath = "RenderLog.txt"; + + public static void Init() + { + try + { + File.WriteAllText(LogFilePath, string.Empty); + Log("Started", sendInConsole = false); + } + catch {} + } + + private static void Log(string message, Exception? ex = null, bool sendInConsole = true) + { + try + { + if (sendInConsole) + { + if (ex != null) + Console.Error.WriteLine($"{message}\n{ex}"); + else + Console.WriteLine(message); + } + + var line = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {message}{Environment.NewLine}"; + if (ex != null) + line += $"Exception details: {ex}{Environment.NewLine}"; + + + File.AppendAllText(LogFilePath, line); + } + catch {} + } + } +} diff --git a/Content.MapRenderer/Painters/DecalPainter.cs b/Content.MapRenderer/Painters/DecalPainter.cs index acc9e5615a39..38e20f7fbaf0 100644 --- a/Content.MapRenderer/Painters/DecalPainter.cs +++ b/Content.MapRenderer/Painters/DecalPainter.cs @@ -51,7 +51,7 @@ public void Run(Image canvas, Span decals, Vector2 customOffset = def Run(canvas, decal, customOffset); } - Console.WriteLine($"{nameof(DecalPainter)} painted {decals.Length} decals in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); + Logger.Log($"{nameof(DecalPainter)} painted {decals.Length} decals in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); } private void Run(Image canvas, DecalData data, Vector2 customOffset = default) @@ -59,7 +59,7 @@ private void Run(Image canvas, DecalData data, Vector2 customOffset = default) var decal = data.Decal; if (!_decalTextures.TryGetValue(decal.Id, out var sprite)) { - Console.WriteLine($"Decal {decal.Id} did not have an associated prototype."); + Logger.Log($"Decal {decal.Id} did not have an associated prototype."); return; } diff --git a/Content.MapRenderer/Painters/EntityPainter.cs b/Content.MapRenderer/Painters/EntityPainter.cs index 0c751b858399..3e4c4ce01f3b 100644 --- a/Content.MapRenderer/Painters/EntityPainter.cs +++ b/Content.MapRenderer/Painters/EntityPainter.cs @@ -49,7 +49,7 @@ public void Run(Image canvas, List entities, Vector2 customOffset = Run(canvas, entity, xformSystem, customOffset); } - Console.WriteLine($"{nameof(EntityPainter)} painted {entities.Count} entities in {(int)stopwatch.Elapsed.TotalMilliseconds} ms"); + Logger.Log($"{nameof(EntityPainter)} painted {entities.Count} entities in {(int)stopwatch.Elapsed.TotalMilliseconds} ms"); } public void Run(Image canvas, EntityData entity, SharedTransformSystem xformSystem, Vector2 customOffset = default) @@ -120,7 +120,7 @@ public void Run(Image canvas, EntityData entity, SharedTransformSystem xformSyst var rect = new Rectangle(x, y, width, height); if (!new Rectangle(Point.Empty, image.Size).Contains(rect)) { - Console.WriteLine($"Invalid layer {rsi!.Path}/{layer.RsiState.Name}.png for entity {_sEntityManager.ToPrettyString(entity.Owner)} at ({entity.X}, {entity.Y})"); + Logger.Log($"Invalid layer {rsi!.Path}/{layer.RsiState.Name}.png for entity {_sEntityManager.ToPrettyString(entity.Owner)} at ({entity.X}, {entity.Y})"); return; } diff --git a/Content.MapRenderer/Painters/GridPainter.cs b/Content.MapRenderer/Painters/GridPainter.cs index ed17d0d3d66e..9aee0f098f71 100644 --- a/Content.MapRenderer/Painters/GridPainter.cs +++ b/Content.MapRenderer/Painters/GridPainter.cs @@ -50,7 +50,7 @@ public void Run(Image gridCanvas, EntityUid gridUid, MapGridComponent grid, Vect if (!_entities.TryGetValue(gridUid, out var entities)) { - Console.WriteLine($"No entities found on grid {gridUid}"); + Logger.Log($"No entities found on grid {gridUid}"); return; } @@ -60,7 +60,7 @@ public void Run(Image gridCanvas, EntityUid gridUid, MapGridComponent grid, Vect _entityPainter.Run(gridCanvas, entities, customOffset); - Console.WriteLine($"{nameof(GridPainter)} painted grid {gridUid} in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); + Logger.Log($"{nameof(GridPainter)} painted grid {gridUid} in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); } private ConcurrentDictionary> GetEntities() @@ -96,7 +96,7 @@ private ConcurrentDictionary> GetEntities() } } - Console.WriteLine($"Found {components.Values.Sum(l => l.Count)} entities on {components.Count} grids in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); + Logger.Log($"Found {components.Values.Sum(l => l.Count)} entities on {components.Count} grids in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); return components; } @@ -128,7 +128,7 @@ private Dictionary> GetDecals() } } - Console.WriteLine($"Found {decals.Values.Sum(l => l.Count)} decals on {decals.Count} grids in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); + Logger.Log($"Found {decals.Values.Sum(l => l.Count)} decals on {decals.Count} grids in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); return decals; } diff --git a/Content.MapRenderer/Painters/MapPainter.cs b/Content.MapRenderer/Painters/MapPainter.cs index 991fa74fe1c8..bbdb9464928a 100644 --- a/Content.MapRenderer/Painters/MapPainter.cs +++ b/Content.MapRenderer/Painters/MapPainter.cs @@ -55,7 +55,7 @@ public async Task Initialize() }; _pair = await PoolManager.GetServerClient(poolSettings, _testContextLike); - Console.WriteLine($"Loaded client and server in {(int)stopwatch.Elapsed.TotalMilliseconds} ms"); + Logger.Log($"Loaded client and server in {(int)stopwatch.Elapsed.TotalMilliseconds} ms"); if (_map is RenderMapFile mapFile) { @@ -192,7 +192,7 @@ await server.WaitPost(() => var tiles = mapSys.GetAllTiles(uid, grid).ToList(); if (tiles.Count == 0) { - Console.WriteLine($"Warning: Grid {uid} was empty. Skipping image rendering."); + Logger.Log($"Warning: Grid {uid} was empty. Skipping image rendering."); continue; } var tileXSize = grid.TileSize * TilePainter.TileImageSize; diff --git a/Content.MapRenderer/Painters/TilePainter.cs b/Content.MapRenderer/Painters/TilePainter.cs index 114db8cb5eb8..6295f54f2839 100644 --- a/Content.MapRenderer/Painters/TilePainter.cs +++ b/Content.MapRenderer/Painters/TilePainter.cs @@ -81,7 +81,7 @@ public void Run(Image gridCanvas, EntityUid gridUid, MapGridComponent grid, Vect i++; }); - Console.WriteLine($"{nameof(TilePainter)} painted {i} tiles on grid {gridUid} in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); + Logger.Log($"{nameof(TilePainter)} painted {i} tiles on grid {gridUid} in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); } private Dictionary> GetTileImages( @@ -119,7 +119,7 @@ private Dictionary> GetTileImages( } } - Console.WriteLine($"Indexed all tile images in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); + Logger.Log($"Indexed all tile images in {(int) stopwatch.Elapsed.TotalMilliseconds} ms"); return images; } diff --git a/Content.MapRenderer/Program.cs b/Content.MapRenderer/Program.cs index 9d7843bcd07b..824216d2ede0 100644 --- a/Content.MapRenderer/Program.cs +++ b/Content.MapRenderer/Program.cs @@ -22,6 +22,8 @@ internal sealed class Program internal static async Task Main(string[] args) { + Logger.Logger.Init(); + if (!CommandLineArguments.TryParse(args, out var arguments)) return; @@ -49,7 +51,7 @@ internal static async Task Main(string[] args) var input = Console.ReadLine(); if (input == null) { - Console.WriteLine(NoMapsChosenMessage); + Logger.Log(NoMapsChosenMessage); return; } @@ -63,7 +65,7 @@ internal static async Task Main(string[] args) var inputArray = input.Split(','); if (inputArray.Length == 0) { - Console.WriteLine(NoMapsChosenMessage); + Logger.Log(NoMapsChosenMessage); return; } @@ -71,7 +73,7 @@ internal static async Task Main(string[] args) { if (!int.TryParse(idString.Trim(), out var id)) { - Console.WriteLine(ChosenMapIdNotIntMessage(idString)); + Logger.Log(ChosenMapIdNotIntMessage(idString)); return; } @@ -84,7 +86,7 @@ internal static async Task Main(string[] args) { if (id < 0 || id >= mapIds.Length) { - Console.WriteLine(NoMapFoundWithIdMessage(id)); + Logger.Log(NoMapFoundWithIdMessage(id)); return; } @@ -95,18 +97,18 @@ internal static async Task Main(string[] args) if (selectedMapPrototypes.Count == 0) { - Console.WriteLine(NoMapsChosenMessage); + Logger.Log(NoMapsChosenMessage); return; } - Console.WriteLine($"Selected maps: {string.Join(", ", selectedMapPrototypes)}"); + Logger.Log($"Selected maps: {string.Join(", ", selectedMapPrototypes)}"); } var maps = new List(); if (arguments.ArgumentsAreFileNames) { - Console.WriteLine("Retrieving maps by file names..."); + Logger.Log("Retrieving maps by file names..."); // // Handle legacy command line processing: @@ -142,7 +144,7 @@ internal static async Task Main(string[] args) if (lookupPrototypeFiles.Count > 0) { - Console.Write($"Following map files did not exist on disk directly, searching through prototypes: {string.Join(", ", lookupPrototypeFiles)}"); + Logger.Log($"Following map files did not exist on disk directly, searching through prototypes: {string.Join(", ", lookupPrototypeFiles)}"); await using var pair = await PoolManager.GetServerClient(); var mapPrototypes = pair.Server @@ -157,12 +159,12 @@ internal static async Task Main(string[] args) if (mapPrototype.MapPath.Filename == toFind) { maps.Add(new RenderMapPrototype { Prototype = mapPrototype, }); - Console.WriteLine($"Found matching map prototype: {mapPrototype.MapName}"); + Logger.Log($"Found matching map prototype: {mapPrototype.MapName}"); goto found; } } - await Console.Error.WriteLineAsync($"Found no map prototype for file '{toFind}'!"); + Logger.Log($"Found no map prototype for file '{toFind}'!"); // was async found: ; } @@ -185,14 +187,14 @@ private static async Task Run( List toRender, ExternalTestContext testContext) { - Console.WriteLine($"Creating images for {toRender.Count} maps"); + Logger.Log($"Creating images for {toRender.Count} maps"); var parallaxOutput = arguments.OutputParallax ? new ParallaxOutput(arguments.OutputPath) : null; var mapNames = new List(); foreach (var map in toRender) { - Console.WriteLine($"Painting map {map}"); + Logger.Log($"Painting map {map}"); await using var painter = new MapPainter(map, testContext); await painter.Initialize(); @@ -215,7 +217,7 @@ private static async Task Run( var savePath = $"{directory}{Path.DirectorySeparatorChar}{mapShort}-{i}.{arguments.Format}"; - Console.WriteLine($"Writing grid of size {grid.Width}x{grid.Height} to {savePath}"); + Logger.Log($"Writing grid of size {grid.Width}x{grid.Height} to {savePath}"); switch (arguments.Format) { @@ -244,8 +246,7 @@ private static async Task Run( } catch (Exception ex) { - Console.WriteLine($"Painting map {map} failed due to an internal exception:"); - Console.WriteLine(ex); + Logger.Log($"Painting map {map} failed due to an internal exception:", ex); continue; } @@ -261,13 +262,13 @@ private static async Task Run( } catch (Exception e) { - Console.WriteLine($"Exception while shutting down painter: {e}"); + Logger.Log($"Exception while shutting down painter: {e}"); } } var mapNamesString = $"[{string.Join(',', mapNames.Select(s => $"\"{s}\""))}]"; - Console.WriteLine($@"::set-output name=map_names::{mapNamesString}"); - Console.WriteLine($"Processed {arguments.Maps.Count} maps."); + Logger.Log($@"::set-output name=map_names::{mapNamesString}"); + Logger.Log($"Processed {arguments.Maps.Count} maps."); Console.WriteLine($"It's now safe to manually exit the process (automatic exit in a few moments...)"); } } From 5044c41757193e65544d51898391f2f33338de6c Mon Sep 17 00:00:00 2001 From: FireFoxPhoenix <171633349+FireFoxPhoenix@users.noreply.github.com> Date: Tue, 10 Feb 2026 18:48:49 +1000 Subject: [PATCH 2/6] Render test --- Content.MapRenderer/Painters/MapPainter.cs | 24 +++++++++++++ Content.MapRenderer/Program.cs | 41 +++++++++++++++++++++- Content.MapRenderer/RenderMap.cs | 20 +++++------ 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/Content.MapRenderer/Painters/MapPainter.cs b/Content.MapRenderer/Painters/MapPainter.cs index bbdb9464928a..a960824dd264 100644 --- a/Content.MapRenderer/Painters/MapPainter.cs +++ b/Content.MapRenderer/Painters/MapPainter.cs @@ -78,6 +78,30 @@ await _pair.Server.WaitPost(() => _grids = loadResult.Grids.ToArray(); }); } + else if (_map is RenderMapGrid gridFile) + { + using var stream = File.OpenRead(gridFile.FileName); + + await _pair.Server.WaitPost(() => + { + var mapManager = _pair.Server.ResolveDependency(); + var sEntityManager = _pair.Server.ResolveDependency(); + var mapLoaderSystem = _pair.Server.System(); + + var loadOptions = new MapLoadOptions + { + DeserializationOptions = + { + LogOrphanedGrids = false, + }, + }; + + if (!mapLoaderSystem.TryLoadGeneric(stream, gridFile.FileName, out var loadResult, loadOptions)) + throw new IOException($"Grid file {gridFile.FileName} could not be read"); + + _grids = loadResult.Grids.ToArray(); + }); + } } public async Task SetupView(bool showMarkers) diff --git a/Content.MapRenderer/Program.cs b/Content.MapRenderer/Program.cs index 824216d2ede0..beb1b982525c 100644 --- a/Content.MapRenderer/Program.cs +++ b/Content.MapRenderer/Program.cs @@ -134,7 +134,14 @@ internal static async Task Main(string[] args) { if (File.Exists(map)) { - maps.Add(new RenderMapFile { FileName = map }); + if (IsGridFile(map)) + { + maps.Add(new RenderMapGrid { FileName = map }); + } + else + { + maps.Add(new RenderMapFile { FileName = map }); + } } else { @@ -271,5 +278,37 @@ private static async Task Run( Logger.Log($"Processed {arguments.Maps.Count} maps."); Console.WriteLine($"It's now safe to manually exit the process (automatic exit in a few moments...)"); } + + private static bool IsGridFile(string filePath) + { + try + { + using (var reader = new StreamReader(filePath)) + { + string? line; + while ((line = reader.ReadLine()) != null) + { + if (line.Contains("meta:")) + { + while ((line = reader.ReadLine()) != null) + { + if (line.Contains("category:")) + return line.Contains("Grid"); + + if (!line.StartsWith(" ") && !string.IsNullOrWhiteSpace(line)) + break; + } + break; + } + } + } + } + catch (Exception ex) + { + Logger.Log($"Error checking if file is grid: {ex.Message}"); + } + + return false; + } } } diff --git a/Content.MapRenderer/RenderMap.cs b/Content.MapRenderer/RenderMap.cs index 4ebf4ee5d4bc..9095bdfaa162 100644 --- a/Content.MapRenderer/RenderMap.cs +++ b/Content.MapRenderer/RenderMap.cs @@ -36,20 +36,18 @@ public override string ToString() } } -/// -/// Specifies a map file on disk that the map renderer should render. -/// -public sealed class RenderMapFile : RenderMap +public abstract class RenderMapFileBase : RenderMap { - /// - /// The path to the file that should be rendered. This is an OS disk path, *not* a . - /// public required string FileName; public override string ShortName => Path.GetFileNameWithoutExtension(FileName); - public override string ToString() - { - return $"{nameof(RenderMapFile)}({FileName})"; - } + public override string ToString() => $"{GetType().Name}({FileName})"; } + +/// +/// Specifies a map file on disk that the map renderer should render. +/// +public sealed class RenderMapFile : RenderMapFileBase {} + +public sealed class RenderMapGrid : RenderMapFileBase {} From 4235feb00a73556411b228bbe718935bab770a34 Mon Sep 17 00:00:00 2001 From: FireFoxPhoenix <171633349+FireFoxPhoenix@users.noreply.github.com> Date: Tue, 10 Feb 2026 19:17:48 +1000 Subject: [PATCH 3/6] =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D0=B8=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Content.MapRenderer/Logger.cs | 4 ++-- Content.MapRenderer/Program.cs | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Content.MapRenderer/Logger.cs b/Content.MapRenderer/Logger.cs index c6f8d32d743f..e9dd22e9d892 100644 --- a/Content.MapRenderer/Logger.cs +++ b/Content.MapRenderer/Logger.cs @@ -12,12 +12,12 @@ public static void Init() try { File.WriteAllText(LogFilePath, string.Empty); - Log("Started", sendInConsole = false); + Log("Started", sendInConsole: false); } catch {} } - private static void Log(string message, Exception? ex = null, bool sendInConsole = true) + public static void Log(string message, Exception? ex = null, bool sendInConsole = true) { try { diff --git a/Content.MapRenderer/Program.cs b/Content.MapRenderer/Program.cs index beb1b982525c..41e9dbf4867e 100644 --- a/Content.MapRenderer/Program.cs +++ b/Content.MapRenderer/Program.cs @@ -11,6 +11,7 @@ using Robust.Shared.Prototypes; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Webp; +//using Robust.Shared.Log; namespace Content.MapRenderer { @@ -22,7 +23,26 @@ internal sealed class Program internal static async Task Main(string[] args) { - Logger.Logger.Init(); + //LogManager.GlobalSawmill.Subscribe((level, message, exception) => + //{ + // if (level >= LogLevel.Error) + // { + // Logger.Log($"{message}", exception, false); + // } + //}); + Logger.Init(); + + AppDomain.CurrentDomain.UnhandledException += (sender, e) => + { + if (e.ExceptionObject is Exception ex) + Logger.Log("Unhandled exception", ex); + }; + + TaskScheduler.UnobservedTaskException += (sender, e) => + { + Logger.Log("Unobserved task exception", e.Exception); + e.SetObserved(); + }; if (!CommandLineArguments.TryParse(args, out var arguments)) return; From 77dfe29af88f09abe38f23ce76e44f0345d5489e Mon Sep 17 00:00:00 2001 From: FireFoxPhoenix <171633349+FireFoxPhoenix@users.noreply.github.com> Date: Tue, 10 Feb 2026 20:00:11 +1000 Subject: [PATCH 4/6] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Content.MapRenderer/Painters/MapPainter.cs | 25 ++++++------- Content.MapRenderer/Program.cs | 43 +++++++++++++++++++--- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/Content.MapRenderer/Painters/MapPainter.cs b/Content.MapRenderer/Painters/MapPainter.cs index a960824dd264..187cdfe0cfa8 100644 --- a/Content.MapRenderer/Painters/MapPainter.cs +++ b/Content.MapRenderer/Painters/MapPainter.cs @@ -20,6 +20,7 @@ using Robust.Shared.Map.Components; using Robust.Shared.Maths; using Robust.Shared.Timing; +using Robust.Shared.Utility; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; @@ -80,26 +81,22 @@ await _pair.Server.WaitPost(() => } else if (_map is RenderMapGrid gridFile) { - using var stream = File.OpenRead(gridFile.FileName); - await _pair.Server.WaitPost(() => { + var mapSystem = _pair.Server.System(); var mapManager = _pair.Server.ResolveDependency(); - var sEntityManager = _pair.Server.ResolveDependency(); - var mapLoaderSystem = _pair.Server.System(); + var mapLoader = _pair.Server.System(); - var loadOptions = new MapLoadOptions - { - DeserializationOptions = - { - LogOrphanedGrids = false, - }, - }; + var mapId = new MapId(1); + mapSystem.CreateMap(mapId, false); - if (!mapLoaderSystem.TryLoadGeneric(stream, gridFile.FileName, out var loadResult, loadOptions)) - throw new IOException($"Grid file {gridFile.FileName} could not be read"); + var path = new ResPath(gridFile.FileName); + var opts = new DeserializationOptions { StoreYamlUids = true }; - _grids = loadResult.Grids.ToArray(); + if (!mapLoader.TryLoadGrid(mapId, path, out var loadedGrid, opts)) + throw new IOException($"Grid file {gridFile.FileName} could not be loaded"); + + _grids = mapManager.GetAllGrids(mapId).ToArray(); }); } } diff --git a/Content.MapRenderer/Program.cs b/Content.MapRenderer/Program.cs index 41e9dbf4867e..3b912b56a90a 100644 --- a/Content.MapRenderer/Program.cs +++ b/Content.MapRenderer/Program.cs @@ -50,11 +50,15 @@ internal static async Task Main(string[] args) var testContext = new ExternalTestContext("Content.MapRenderer", Console.Out); PoolManager.Startup(); + + var maps = new List(); + if (arguments.Maps.Count == 0) { Console.WriteLine("Didn't specify any maps to paint! Loading the map list..."); await using var pair = await PoolManager.GetServerClient(testContext: testContext); + var protoManager = pair.Server.ResolveDependency(); var mapIds = pair.Server .ResolveDependency() .EnumeratePrototypes() @@ -113,19 +117,30 @@ internal static async Task Main(string[] args) selectedMapPrototypes.Add(mapIds[id]); } - arguments.Maps.AddRange(selectedMapPrototypes); - if (selectedMapPrototypes.Count == 0) { Logger.Log(NoMapsChosenMessage); return; } + foreach (var protoId in selectedMapPrototypes) + { + if (protoManager.TryIndex(protoId, out var proto)) + { + if (proto.IsGrid) + { + maps.Add(new RenderMapGrid { FileName = proto.MapPath.ToString() }); + } + else + { + maps.Add(new RenderMapPrototype { Prototype = protoId }); + } + } + } + Logger.Log($"Selected maps: {string.Join(", ", selectedMapPrototypes)}"); } - var maps = new List(); - if (arguments.ArgumentsAreFileNames) { Logger.Log("Retrieving maps by file names..."); @@ -199,9 +214,27 @@ internal static async Task Main(string[] args) } else { + await using var pair = await PoolManager.GetServerClient(); + var protoManager = pair.Server.ResolveDependency(); + foreach (var map in arguments.Maps) { - maps.Add(new RenderMapPrototype { Prototype = map }); + if (protoManager.TryIndex(map, out var proto)) + { + if (proto.IsGrid) + { + maps.Add(new RenderMapGrid { FileName = proto.MapPath.ToString() }); + Logger.Log($"Found grid prototype: {proto.MapName}"); + } + else + { + maps.Add(new RenderMapPrototype { Prototype = map }); + } + } + else + { + Logger.Log($"Failed to find prototype: {map}"); + } } } From d0df02051a27dfee1c59e34af0170b051918ffee Mon Sep 17 00:00:00 2001 From: FireFoxPhoenix <171633349+FireFoxPhoenix@users.noreply.github.com> Date: Tue, 10 Feb 2026 21:04:16 +1000 Subject: [PATCH 5/6] =?UTF-8?q?=D0=B5=D1=89=D0=B5=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Content.MapRenderer/Painters/MapPainter.cs | 17 ++++- Content.MapRenderer/Program.cs | 77 ++++++++++++++++++++-- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/Content.MapRenderer/Painters/MapPainter.cs b/Content.MapRenderer/Painters/MapPainter.cs index 187cdfe0cfa8..dee03731ae18 100644 --- a/Content.MapRenderer/Painters/MapPainter.cs +++ b/Content.MapRenderer/Painters/MapPainter.cs @@ -45,21 +45,27 @@ public async Task Initialize() { var stopwatch = RStopwatch.StartNew(); + Logger.Log($"Map type: {_map.GetType().Name}"); + Logger.Log($"Map: {_map}"); + var poolSettings = new PoolSettings { DummyTicker = false, Connected = true, Destructive = true, Fresh = true, - // Seriously whoever made MapPainter use GameMapPrototype I wish you step on a lego one time. Map = _map is RenderMapPrototype prototype ? prototype.Prototype : PoolManager.TestMap, }; + + Logger.Log($"Pool map setting: {poolSettings.Map}"); + _pair = await PoolManager.GetServerClient(poolSettings, _testContextLike); Logger.Log($"Loaded client and server in {(int)stopwatch.Elapsed.TotalMilliseconds} ms"); if (_map is RenderMapFile mapFile) { + Logger.Log($"Loading RenderMapFile: {mapFile.FileName}"); using var stream = File.OpenRead(mapFile.FileName); await _pair.Server.WaitPost(() => @@ -77,10 +83,12 @@ await _pair.Server.WaitPost(() => throw new IOException($"File {mapFile.FileName} could not be read"); _grids = loadResult.Grids.ToArray(); + Logger.Log($"Loaded {_grids.Length} grids from RenderMapFile"); }); } else if (_map is RenderMapGrid gridFile) { + Logger.Log($"Loading RenderMapGrid: {gridFile.FileName}"); await _pair.Server.WaitPost(() => { var mapSystem = _pair.Server.System(); @@ -88,17 +96,24 @@ await _pair.Server.WaitPost(() => var mapLoader = _pair.Server.System(); var mapId = new MapId(1); + Logger.Log($"Creating empty map with ID: {mapId}"); mapSystem.CreateMap(mapId, false); var path = new ResPath(gridFile.FileName); var opts = new DeserializationOptions { StoreYamlUids = true }; + Logger.Log($"Loading grid from: {path}"); if (!mapLoader.TryLoadGrid(mapId, path, out var loadedGrid, opts)) throw new IOException($"Grid file {gridFile.FileName} could not be loaded"); _grids = mapManager.GetAllGrids(mapId).ToArray(); + Logger.Log($"Loaded {_grids.Length} grids from RenderMapGrid"); }); } + else + { + Logger.Log($"Using RenderMapPrototype with default map loading"); + } } public async Task SetupView(bool showMarkers) diff --git a/Content.MapRenderer/Program.cs b/Content.MapRenderer/Program.cs index 3b912b56a90a..25a9bf036a77 100644 --- a/Content.MapRenderer/Program.cs +++ b/Content.MapRenderer/Program.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Content.IntegrationTests; using Content.MapRenderer.Painters; +using Robust.Shared.ContentPack; using Content.Server.Maps; using Robust.Shared.Prototypes; using SixLabors.ImageSharp; @@ -125,23 +126,49 @@ internal static async Task Main(string[] args) foreach (var protoId in selectedMapPrototypes) { + Logger.Log($"Processing prototype: {protoId}"); if (protoManager.TryIndex(protoId, out var proto)) { - if (proto.IsGrid) + Logger.Log($"Found prototype '{protoId}': IsGrid={proto.IsGrid}, MapPath={proto.MapPath}"); + + var treatAsGrid = proto.IsGrid; + try + { + if (!treatAsGrid) + { + var resMgr = pair.Server.ResolveDependency(); + if (IsGridResource(resMgr, proto.MapPath)) + { + Logger.Log($"Detected grid content in resource {proto.MapPath}"); + treatAsGrid = true; + } + } + } + catch (Exception e) + { + Logger.Log($"Error while checking resource {proto.MapPath}: {e.Message}"); + } + + if (treatAsGrid) { + Logger.Log($"Creating RenderMapGrid for '{protoId}'"); maps.Add(new RenderMapGrid { FileName = proto.MapPath.ToString() }); } else { + Logger.Log($"Creating RenderMapPrototype for '{protoId}'"); maps.Add(new RenderMapPrototype { Prototype = protoId }); } } + else + { + Logger.Log($"Failed to find prototype: {protoId}"); + } } - Logger.Log($"Selected maps: {string.Join(", ", selectedMapPrototypes)}"); + Logger.Log($"Selected maps: {string.Join(", ", selectedMapPrototypes)}. Total maps created: {maps.Count}"); } - - if (arguments.ArgumentsAreFileNames) + else if (arguments.ArgumentsAreFileNames) { Logger.Log("Retrieving maps by file names..."); @@ -214,20 +241,24 @@ internal static async Task Main(string[] args) } else { + Logger.Log("Processing prototypes from arguments"); await using var pair = await PoolManager.GetServerClient(); var protoManager = pair.Server.ResolveDependency(); foreach (var map in arguments.Maps) { + Logger.Log($"Processing prototype: {map}"); if (protoManager.TryIndex(map, out var proto)) { + Logger.Log($"Found prototype '{map}': IsGrid={proto.IsGrid}, MapPath={proto.MapPath}"); if (proto.IsGrid) { + Logger.Log($"Creating RenderMapGrid for '{map}'"); maps.Add(new RenderMapGrid { FileName = proto.MapPath.ToString() }); - Logger.Log($"Found grid prototype: {proto.MapName}"); } else { + Logger.Log($"Creating RenderMapPrototype for '{map}'"); maps.Add(new RenderMapPrototype { Prototype = map }); } } @@ -248,6 +279,11 @@ private static async Task Run( ExternalTestContext testContext) { Logger.Log($"Creating images for {toRender.Count} maps"); + Logger.Log($"Map types to render:"); + foreach (var map in toRender) + { + Logger.Log($"{map.GetType().Name}: {map}"); + } var parallaxOutput = arguments.OutputParallax ? new ParallaxOutput(arguments.OutputPath) : null; @@ -363,5 +399,36 @@ private static bool IsGridFile(string filePath) return false; } + + private static bool IsGridResource(IResourceManager resMgr, ResPath path) + { + try + { + using var stream = resMgr.ContentFileRead(path); + using var reader = new StreamReader(stream); + string? line; + while ((line = reader.ReadLine()) != null) + { + if (line.Contains("meta:")) + { + while ((line = reader.ReadLine()) != null) + { + if (line.Contains("category:")) + return line.Contains("Grid"); + + if (!line.StartsWith(" ") && !string.IsNullOrWhiteSpace(line)) + break; + } + break; + } + } + } + catch + { + return false; + } + + return false; + } } } From 3fd92c37dc7c93d29d35d90ed8cc3b99d8e27a50 Mon Sep 17 00:00:00 2001 From: FireFoxPhoenix <171633349+FireFoxPhoenix@users.noreply.github.com> Date: Tue, 10 Feb 2026 21:24:30 +1000 Subject: [PATCH 6/6] =?UTF-8?q?=D0=BF=D0=BE=D0=B1=D0=B5=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Content.MapRenderer/Painters/MapPainter.cs | 6 +++--- Content.MapRenderer/Program.cs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Content.MapRenderer/Painters/MapPainter.cs b/Content.MapRenderer/Painters/MapPainter.cs index dee03731ae18..0e39a6391bcd 100644 --- a/Content.MapRenderer/Painters/MapPainter.cs +++ b/Content.MapRenderer/Painters/MapPainter.cs @@ -95,9 +95,9 @@ await _pair.Server.WaitPost(() => var mapManager = _pair.Server.ResolveDependency(); var mapLoader = _pair.Server.System(); - var mapId = new MapId(1); - Logger.Log($"Creating empty map with ID: {mapId}"); - mapSystem.CreateMap(mapId, false); + Logger.Log($"Creating empty map"); + var mapUid = mapSystem.CreateMap(out var mapId, false); + Logger.Log($"Created map entity {mapUid} with ID: {mapId}"); var path = new ResPath(gridFile.FileName); var opts = new DeserializationOptions { StoreYamlUids = true }; diff --git a/Content.MapRenderer/Program.cs b/Content.MapRenderer/Program.cs index 25a9bf036a77..f839d1ad0225 100644 --- a/Content.MapRenderer/Program.cs +++ b/Content.MapRenderer/Program.cs @@ -12,6 +12,7 @@ using Robust.Shared.Prototypes; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Webp; +using Robust.Shared.Utility; //using Robust.Shared.Log; namespace Content.MapRenderer