The collection

Trait architecture

Twelve categories, nine independent art rigs, and one rule that shapes all of it: a racer must still read as its meme at 64 pixels, on its rarest possible roll.

No shared body template

The 2021 generative failure mode is one body wearing 200 hats. This collection has no shared body at all. Each faction is its own art rig with its own layer stack, palette and pose set, authored as parameterized SVG rather than bitmap layers. What the nine rigs share is the category schema, the canvas geometry, and one fixed three-quarter front-left hero camera.

The practical consequence: there is no cross-faction hat pool. A deerstalker exists in Pipedog's rig and nowhere else. A trait name that appears in two factions is a coincidence of language, not a shared asset.

The twelve categories

CategoryScopePoolWhat it carries
BackgroundShared12Chain-lore environments, from Sherwood Fork to the Earnings Call Stage. Tiered: PONS Pit Row is Uncommon, the NOXA Tollbooth Ruin and Testnet Void are Rare, Earnings Call Stage is Epic.
CharacterVariantPer faction5Palette, fur and finish shifts inside the faction's anchors. MowCat shifts hue within green and never loses the glow.
ExpressionPer faction6 to 7Drawn per faction and never swapped across. HMM gets seven grades of hmm, Pipedog seven grades of puzzled.
HeadwearPer faction6 to 7Faction-appropriate only. Pipedog and Robin have no None option, because their headwear is part of the identity anchor.
KartChassisPer faction4Trim levels of the faction's one kart concept. Second biggest rarity carrier after the background.
WheelsPer faction5Coin stacks, office casters, lilypads, cartwheels. Wheels alone should identify the faction.
ExhaustPer faction4Visual and implied audio tiers, from a single ellipsis puff to a full column.
KartModPer faction6 to 7Lore props: sauce racks, staff racks, evidence tags, countdown clocks, a dashboard abacus.
DecalShared10Fictionalized ecosystem sponsors: PONS RACING FUEL, PipePad Pit Crew, a torn NOXA sticker, the 4663 plate.
WearShared4Showroom, Raced, Trench-Worn, Post-Rug Scorched.
BoostEffectPer faction4Bill flutter, smoke rings, green flame, bubbles, feathers. Shared logic, per-faction art.
PosePer faction3Neutral, drift lean, victory. Pose multiplies every other layer's draw count, so three is the ceiling.
Seat and steering are folded into the chassis: invisible at PFP crop, and pure QA cost as separate categories.

Camera angle is deliberately not a trait. All 2,940 generative pieces use one angle, which keeps compositing sane and makes a marketplace grid read as a collection. Alternate angles are reserved for the legendaries and the one of ones.

Pool sizes per faction

FactionCharacterVariantExpressionHeadwearKartChassisWheelsExhaustKartModBoostEffectPoseTrait vectors
CashCat567454743677M
Pipedog576454743677M
Brodie567454643581M
FRONG577454743790M
HMM577454743790M
MowCat567454643581M
TENDIES576454743677M
Little John577454743790M
Robin577454743790M
Trait vectors multiplies the per-faction pools by the three shared pools. Every faction has hundreds of millions of possible combinations, so 3,000 unique tokens is nowhere near tight.

How a trait is rolled

Every entry in every pool carries a tier tag. Picking a trait is two steps: roll a tier by weight across the tiers actually present in that pool, then pick uniformly inside the tier.

generator/src/rng.js
export const TIER_WEIGHTS = { Common: 60, Uncommon: 28, Rare: 10, Epic: 2 };

// Pick one trait from a pool of {name, tier, ...}: roll tier by 60/28/10/2,
// then uniform within the tier. Falls back to nearest populated tier.
export function pickTrait(rng, pool) { /* ... */ }

Reweighting across present tiers matters. A pool with no Epic entry does not silently lose 2% of its probability mass, it redistributes it, so every pool sums to one and no category quietly biases toward Common.

An Epic pull is a concept upgrade, never a palette swap. A solid-gold Fistful is Epic. FRONG's shipped it smile is Epic, and it is the only smile that faction has.

Constraints

Eight rules in generator/src/constraints.json catch combinations that are individually fine and jointly stupid. When all the when pairs match, the listed category is re-rolled from the same deterministic stream until the rule passes.

generator/src/constraints.json
{
  "faction": "hmm",
  "when": { "Headwear": "Nightcap", "Expression": "Eureka" },
  "reroll": "Expression",
  "reason": "Asleep cats do not have breakthroughs."
},
{
  "faction": "frong",
  "when": { "KartChassis": "Mainnet Build", "KartMod": "Unmerged-PR Flag" },
  "reroll": "KartMod",
  "reason": "Mainnet build means the PR merged."
}

Identity anchors

Every faction has one visual element that no layer may cover, at any rarity. In the rigs these are structural rather than layers, so occluding one is not something a roll can do by accident. Rarity makes the anchor more itself. A gold-plated cash fist is still a cash fist.

FactionAnchor
CashCatThe cash fist
PipedogThe pipe and the deerstalker
BrodieThe neon bandana
FRONGThe night-vision green cast
HMMChin on paw
MowCatThe glow outline
TENDIESThe breading texture
Little JohnThe quarterstaff
RobinGreen cap and red breast

Two factions have no None option in Headwear as a direct consequence. Pipedog's deerstalker and Robin's green cap are part of the anchor, so their headwear pools are trims on it rather than replacements for it.

The 64 pixel test

The QA pipeline renders five random tokens per faction at true 64 pixels into one grid. If a faction is not identifiable there, the rig gets redrawn. The shared outline language is tuned for exactly this: 7px strokes at generation size land at roughly 2px at PFP crop, which is the width at which a silhouette survives.

generator
npm run qa --workspace generator   # output/qa/thumb-grid.png

Determinism

The whole collection is a pure function of one string. Same seed, same 3,000 racers, forever.

  • Collection seed: RHGP-GENESIS-2026-08-12.
  • Per-token, per-category streams from a sha256-seeded xorshift128+, so adding a category later cannot shift the rolls of the ones before it.
  • Token to faction assignment is a deterministic shuffle of the allocation list, which is why faction is unpredictable from token ID without running the generator.
  • Uniqueness is enforced on the sha256 of the trait vector. A collision re-rolls, deterministically.

The sha256 over all 3,000 finished metadata documents is the provenance hash, and it goes on chain before anyone can mint. That is what makes the shuffle unriggable after the fact. Provenance and chain.

Metadata shape

generator/output/metadata/1.json
{
  "name": "RH Grand Prix Racer #1",
  "description": "Pipedog. A Shiba in a deerstalker who insists, between puffs, that this is not a kart.",
  "image": "ipfs://__IMAGES_CID__/1.png",
  "attributes": [
    { "trait_type": "Faction",          "value": "Pipedog" },
    { "trait_type": "Archetype",        "value": "The Investigator" },
    { "trait_type": "Background",       "value": "NOXA Tollbooth Ruin" },
    { "trait_type": "CharacterVariant", "value": "Sesame" },
    { "trait_type": "Expression",       "value": "Puzzled" },
    { "trait_type": "Headwear",         "value": "Tweed Deerstalker" },
    { "trait_type": "KartChassis",      "value": "Briar Classic" },
    { "trait_type": "Wheels",           "value": "Tweed-Wrap" },
    { "trait_type": "Exhaust",          "value": "Single Ring" },
    { "trait_type": "KartMod",          "value": "Tobacco-Tin Fuel Cell" },
    { "trait_type": "Decal",            "value": "TRENCHES GP" },
    { "trait_type": "Wear",             "value": "Raced" },
    { "trait_type": "BoostEffect",      "value": "None" },
    { "trait_type": "Pose",             "value": "Neutral" },
    { "trait_type": "RarityTier",       "value": "Common" }
  ]
}

Legendaries and one of ones drop the trait categories and carry a Moment attribute instead, because they are scenes rather than rolls.