.card: what each byte does in the game, and the offsets the community had wrong. Verified against real cards by the doc_card.py codec (round-trips byte-exact). A wrong offset doesn't throw an error: it silently changes the wrong thing.a1[6]=0x3F, hood at a2[26]=0x70, correct track-reversal), but its personality control was a lossy 5-choice dropdown that wrote only {0,48,64,80,208}. So re-saving any card whose personality byte wasn't one of those five silently rewrote it (100→80, 128/180/200→64, 244→208): even if you never touched personality. That's what changed JJ's horse. Fixed (Jun 2026): the editor now preserves the exact 0–255 personality byte and only changes it when you deliberately pick a different one.The card is 207 bytes = 3 tracks of 69. Within a track the logical bytes are stored back-to-front: logical aN[k] lives at file offset t*69 + (69−k). If a tool addresses the card by raw offset without undoing the reversal, every field after the first is shifted: the root cause of most historical mismaps. There is no whole-card checksum, so any byte is freely editable (and silently mis-editable).
Four adjacent track-0 bytes, all cosmetic-looking, one of which is not:
| file | logical | field | gameplay effect |
|---|---|---|---|
| 0x3C | a1[9] | Coat modifier | cosmetic (coat variant) |
| 0x3D | a1[8] | Coat base | cosmetic (coat color) |
| 0x3E | a1[7] | Run-style seed | creation seed only: does NOT reliably set displayed running style (leg-type is derived from externals at race time). A known false lever. |
| 0x3F | a1[6] | PERSONALITY (0–255) | sets the horse's personality: the game reads the top four bits and maps them to one of five personalities (Imposing, Honest, Rough, Coward, Sloppy). Change this and the horse's personality changes for good. (Which post-race reply pays depends on the message the game shows as well as the personality: see the per-message reply table in the Personality Reader. The bond-multiplier claim this row used to make was wrong.) |
| field | OLD / community | CORRECTED | why it matters |
|---|---|---|---|
| Hood | "0x73" | 0x70 (a2[26]) | 0x73 is the printed birth SHARP: editing "hood" at 0x73 silently changes a stat. |
| Personality | 5 buckets {R,I,C,H,S} | raw 0–255 @0x3F; the game uses the top four bits to pick one of five personalities | the 5-bucket write was lossy (it overwrote the other bits); the ROM has five personalities, not the 8-band scale (Calm, Firm, Sensitive, Moody, Gentle, Proud are not in the game) |
| Run-style (0x3E) | "the running style" | creation seed only | editing it to change style usually does nothing visible |
| Track storage | raw forward offsets | reversed per track | the master cause of shifted maps |
| Checksum | "don't edit, it'll corrupt" | no whole-card checksum | cards are freely editable; bad edits aren't caught |
| Personality on CPU horses | "horses have a personality byte" | player-card only | CPU racing horses don't store it |
Reversal already applied: these are final file offsets a hex editor can use directly. All byte-exact.
| file | field | gameplay effect |
|---|---|---|
| 0x00–0x12 | Horse name (18 ASCII, reversed) | identity |
| 0x14–0x26 | Sire name | pedigree / lineage |
| 0x28–0x3A | Dam name | pedigree |
| 0x3C–0x3D | Coat (mod / base) | cosmetic |
| 0x3E | Run-style seed | creation seed only |
| 0x3F | Personality | personality (one of five, from the top four bits) |
| 0x40–0x43 | UID / horse id (mirrored all 3 tracks) | identity / lineage links |
| 0x45–0x4D | Internals: stamina / speed / sharp (current) | core stats; Rev C clamps each to 60 after every race, Rev D grows each only to 55 (and not while the three total more than 160) |
| 0x51–0x53 | G1 titles (bitfield) | career titles |
| 0x55–0x57 | Earnings | prize total |
| 0x59–0x67 | Race record + hearts (@0x65) | career stats |
| 0x5F–0x64 | Externals (current): start/corner/oob/competing/tenacious/spurt (stored display−1) | race stats; they also decide the running style (Start's rank among Start, Out of the Box, Competing, Tenacious and Spurt; Almighty = all six equal, Corner included). Not passed to foals |
| 0x69–0x6E | Breeding bands (the six symbols), stored 0 to 15, shown 1 to 16 | fixed at birth (floor average of the parents' bands) and passed to foals; racing, training and retiring never change them |
| 0x70 | Hood (0–63) | cosmetic: NOT 0x73 |
| 0x71–0x73 | Printed birth stats stamina/speed/sharp | written at birth, never grow (0x73 = printed birth sharp, not hood); usually the true birth internals, but one 1-in-32 roll prints lower than the truth (the true stats gain 5) and another 1-in-32 roll prints higher on stats under 40 (true stats unchanged) |
| 0x7A | Sex (0 M / 1 F / 2 Gelding) | breeding role |
| 0x7B–0x7D | Silk pattern / color1 (0x7C) / color2 (0x7D) | cosmetic |
| 0x8A–0x91 | SEGABEF0 marker | card-type signature (US/WE) |
| 0x92 | Dirt aptitude (0–255) | dirt vs turf suitability |
| 0x96 / 0x9A | Retired flag / breeds | retirement state; breed count (bytes 0x9A and 0x9B, +2 per breeding, stops at 60 = 30 breedings). There is no breeding limit. From a horse’s 11th breeding at a World Edition cabinet its foals are made from a weakened copy (stats 2 to 5 lower, symbols 1 or 2 lower); the card itself only gains the count |
doc_card.py (they apply the reversal for you). Don't trust a raw-offset edit from an older tool.Gameplay effects of these bytes → The Hidden Rules. Layout details → the ROM architecture doc.