Skip to content

MenuWriter

Namespace Nfty.Core.Publish in assembly Nfty.Core.

public static class MenuWriter

Writes a CookBook's every weight, rule, colorization and art into a .mnu Menu — the file a runtime host reads to roll and render an asset with no .cbk present.

Remarks

Built on MenuProjection, never a second walk of the manifests. That type already resolves recipe weights, layer order, rules and absent percents correctly from a LoadedCookBook; this fills in the one thing a projection for rolling alone does not need — where the art is.

Identical art is packed once. Two cell keys whose encoded PNG bytes hash the same share one rect — the demo book's two chest recipes share several layers outright, and a Menu should not pay for the same pixels twice. Placement is sorted by each shared image's own least cell key, Ordinal, so the same book always produces the same atlas regardless of the order the manifests happen to enumerate in.

Methods

CheckAtlasFits(int, int, int, int)

public static void CheckAtlasFits(int columns, int rows, int cellWidth, int cellHeight);

Refuses an atlas past the pixel ceiling before anything is allocated.

Parameters

  • columns (int) - Cells across.
  • rows (int) - Cells down.
  • cellWidth (int) - One cell's width — the book's canvas width.
  • cellHeight (int) - One cell's height — the book's canvas height.

Exceptions

Remarks

Public so the refusal is testable without allocating a huge atlas — the same reasoning SpriteSheet.ProblemWith is checked before SpriteSheet.WriteAsync allocates its sheet. It reuses that type's constants and reasoning directly: a Menu atlas is one contiguous raster exactly like a spritesheet, so the same ceiling applies for the same reasons.

Write(LoadedCookBook, string, MenuWriteOptions, Parallelism?)

public static void Write(LoadedCookBook book, string path, MenuWriteOptions options, Parallelism? parallelism = null);

Writes a Menu. See MenuWriter.WriteAsync() for the real implementation.

Parameters

  • book (LoadedCookBook) - The book to project and pack. The caller keeps ownership.
  • path (string) - The .mnu to write.
  • options (MenuWriteOptions) - Atlas or loose.
  • parallelism (Parallelism?) - How wide the PNG encoding may run; null means Parallelism.Default. The file never depends on it.

Exceptions

  • InvalidOperationException - Validator reports a problem with the book (the message lists every one, as Generator's does, and nothing is written); or the atlas would exceed the pixel ceiling — retry with MenuArtMode.Loose.

WriteAsync(LoadedCookBook, string, MenuWriteOptions, IProgress<MenuWriteProgress>?, CancellationToken, Parallelism?)

public static Task WriteAsync(LoadedCookBook book, string path, MenuWriteOptions options, IProgress<MenuWriteProgress>? progress, CancellationToken ct, Parallelism? parallelism = null);

Writes a Menu, reporting progress and stopping when asked.

Parameters

  • book (LoadedCookBook) - The book to project and pack. The caller keeps ownership.
  • path (string) - The .mnu to write.
  • options (MenuWriteOptions) - Atlas or loose.
  • progress (IProgress<MenuWriteProgress>?) - One step per cell encoded, then per cell placed or written.
  • ct (CancellationToken) - Stops between cells.
  • parallelism (Parallelism?) - How wide the PNG encoding may run; null means Parallelism.Default. The file never depends on it.

Exceptions

  • InvalidOperationException - Validator reports a problem with the book (the message lists every one, as Generator's does, and nothing is written); or the atlas would exceed the pixel ceiling — retry with MenuArtMode.Loose.

Remarks

This is the real implementation and the sync twin blocks on it — a Menu write is stream and PNG-codec work end to end, the same reasoning SetExporter.ExportAsync gives for an export. Blocking is safe because nothing in Core captures a synchronization context.