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
| Category | Scope | Pool | What it carries |
|---|---|---|---|
| Background | Shared | 12 | Chain-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. |
| CharacterVariant | Per faction | 5 | Palette, fur and finish shifts inside the faction's anchors. MowCat shifts hue within green and never loses the glow. |
| Expression | Per faction | 6 to 7 | Drawn per faction and never swapped across. HMM gets seven grades of hmm, Pipedog seven grades of puzzled. |
| Headwear | Per faction | 6 to 7 | Faction-appropriate only. Pipedog and Robin have no None option, because their headwear is part of the identity anchor. |
| KartChassis | Per faction | 4 | Trim levels of the faction's one kart concept. Second biggest rarity carrier after the background. |
| Wheels | Per faction | 5 | Coin stacks, office casters, lilypads, cartwheels. Wheels alone should identify the faction. |
| Exhaust | Per faction | 4 | Visual and implied audio tiers, from a single ellipsis puff to a full column. |
| KartMod | Per faction | 6 to 7 | Lore props: sauce racks, staff racks, evidence tags, countdown clocks, a dashboard abacus. |
| Decal | Shared | 10 | Fictionalized ecosystem sponsors: PONS RACING FUEL, PipePad Pit Crew, a torn NOXA sticker, the 4663 plate. |
| Wear | Shared | 4 | Showroom, Raced, Trench-Worn, Post-Rug Scorched. |
| BoostEffect | Per faction | 4 | Bill flutter, smoke rings, green flame, bubbles, feathers. Shared logic, per-faction art. |
| Pose | Per faction | 3 | Neutral, drift lean, victory. Pose multiplies every other layer's draw count, so three is the ceiling. |
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
| Faction | CharacterVariant | Expression | Headwear | KartChassis | Wheels | Exhaust | KartMod | BoostEffect | Pose | Trait vectors |
|---|---|---|---|---|---|---|---|---|---|---|
| CashCat | 5 | 6 | 7 | 4 | 5 | 4 | 7 | 4 | 3 | 677M |
| Pipedog | 5 | 7 | 6 | 4 | 5 | 4 | 7 | 4 | 3 | 677M |
| Brodie | 5 | 6 | 7 | 4 | 5 | 4 | 6 | 4 | 3 | 581M |
| FRONG | 5 | 7 | 7 | 4 | 5 | 4 | 7 | 4 | 3 | 790M |
| HMM | 5 | 7 | 7 | 4 | 5 | 4 | 7 | 4 | 3 | 790M |
| MowCat | 5 | 6 | 7 | 4 | 5 | 4 | 6 | 4 | 3 | 581M |
| TENDIES | 5 | 7 | 6 | 4 | 5 | 4 | 7 | 4 | 3 | 677M |
| Little John | 5 | 7 | 7 | 4 | 5 | 4 | 7 | 4 | 3 | 790M |
| Robin | 5 | 7 | 7 | 4 | 5 | 4 | 7 | 4 | 3 | 790M |
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.
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.
{
"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.
| Faction | Anchor |
|---|---|
| CashCat | The cash fist |
| Pipedog | The pipe and the deerstalker |
| Brodie | The neon bandana |
| FRONG | The night-vision green cast |
| HMM | Chin on paw |
| MowCat | The glow outline |
| TENDIES | The breading texture |
| Little John | The quarterstaff |
| Robin | Green 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.
npm run qa --workspace generator # output/qa/thumb-grid.pngDeterminism
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
{
"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.