Skip to content

UniqueSpace

Namespace Nfty.Core.Generation in assembly Nfty.Core.

public static class UniqueSpace

Counts the unique DNA space of a cookbook: per recipe, the legal variant combinations (rules honoured) multiplied by each dynamic layer's quantized color buckets. Static and custom layers contribute a single bucket — a static layer's color is constant, so it adds no cross-asset uniqueness.

Fields

DefaultEnumerationBudget

public const long DefaultEnumerationBudget = 1000000;

How many things UniqueSpace.Count() will WALK before giving up.

Remarks

This bounds the two places that genuinely enumerate: the per-selection walk a recipe with rules needs, and the set of distinct colour buckets a colorization fills. Both cost time and memory proportional to the number, so both need a budget.

It does NOT bound the answer, and there is no longer a second number that does. The cap was 1,000,000 for everything once, so a book with five million distinct assets reported "more than 1000000" — a figure exactly computable in a single multiply, because once the walk has happened the rest is arithmetic. That was split into a budget and a reporting ceiling of long.MaxValue, which fixed the million and moved the wall to 9.2e18, where six ordinary layers walk straight through it. A BigInteger total has no wall at all, so the reporting ceiling is GONE rather than raised again: arithmetic is free and is now treated as free, and UniqueSpaceCount.IsExact means exactly one thing — no enumeration gave up — which is what every caller already read it as.

Methods

Combine(SpaceCertainty, SpaceCertainty)

public static SpaceCertainty Combine(SpaceCertainty a, SpaceCertainty b);

What a SUM of two spaces is, given what each of them is.

Parameters

  • a (SpaceCertainty) - How the first space is bounded.
  • b (SpaceCertainty) - How the second space is bounded.

Returns. How the sum of the two spaces is bounded; SpaceCertainty.Unknown when no direction can be claimed.

Remarks

A floor plus a floor is a floor; a ceiling plus a ceiling is a ceiling; either plus an exact figure keeps its direction. A floor plus a ceiling is nothing — the two bounds point opposite ways and their sum bounds the truth in neither direction, so claiming either would be inventing one. That combination is the reason this is a function rather than an &=.

Count(LoadedCookBook, long)

public static UniqueSpaceCount Count(LoadedCookBook book, long enumerationBudget = 1000000);

Counts the unique DNA a book admits.

Parameters

  • book (LoadedCookBook) - The book to count. May be mid-edit and invalid; this never throws.
  • enumerationBudget (long) - How much walking is allowed; see UniqueSpace.DefaultEnumerationBudget. Must be positive.

Returns. The total, whether it is exact, and the per-recipe breakdown.

Exceptions

  • ArgumentOutOfRangeException - The budget is zero or negative.

Remarks

The budget is validated even though this method is otherwise documented never to throw. Those are different promises: the no-throw contract is about the BOOK, which a GUI hands over mid-edit and invalid by design, and the budget is the CALLER's own argument. A negative one used to be laundered into an answer — DistinctBuckets() tripped its budget check on the first entry and returned the budget itself, so a layer reported a NEGATIVE bucket count, which the old saturating multiply then turned into the ceiling because a > ceiling / b is true for a negative b. The card printed the largest number it could hold. Refusing the argument is the fix; guarding the multiply against the consequences of accepting it is not.

CountColors(Colorization, long)

public static (long, bool) CountColors(Colorization colorization, long enumerationBudget = 1000000);

How many distinct quantized colors one colorization admits.

Parameters

  • colorization (Colorization) - The block to count. May be mid-edit and illegal; this never throws.
  • enumerationBudget (long) - How many buckets to enumerate before giving up; see UniqueSpace.DefaultEnumerationBudget. Filling this set is real work, so it is budgeted.

Returns. The bucket count, and whether it is exact rather than saturated.

Exceptions

  • ArgumentOutOfRangeException - The budget is zero or negative.

Remarks

This is the same counter UniqueSpace.Count() multiplies per dynamic layer, exposed because an editor showing the user a colors figure must show that figure. The Ingredient editor used to print the product of the two quantize STEPS, which is not a count of anything: a hue step of 30 and a saturation step of 20 read as "600 colors" where the layer actually admits 36, and coarsening a step — which can only ever remove colors — made the number go up.