v0.1 ⌊ALPHA⌉
Claim set · data/claims/pokered.yaml

Pokémon Red and Blue (pret/pokered)

Game: Pokémon Red and Blue. Concept: Type effectiveness.

Red and Blue's type chart (TypeEffects) has 82 non-neutral (attacker, defender, multiplier) rows over 15 types, ended by -1; unlisted pairs are neutral. pokered/type-chart

Value
{
 "kind": "type-chart",
 "types": [
  "Normal",
  "Fighting",
  "Flying",
  "Poison",
  "Ground",
  "Rock",
  "Bug",
  "Ghost",
  "Fire",
  "Water",
  "Grass",
  "Electric",
  "Psychic",
  "Ice",
  "Dragon"
 ],
 "matchups": [
  [
   "Water",
   "Fire",
   20,
   3
  ],
  [
   "Fire",
   "Grass",
   20,
   4
  ],
  [
   "Fire",
   "Ice",
   20,
   5
  ],
  [
   "Grass",
   "Water",
   20,
   6
  ],
  [
   "Electric",
   "Water",
   20,
   7
  ],
  [
   "Water",
   "Rock",
   20,
   8
  ],
  [
   "Ground",
   "Flying",
   0,
   9
  ],
  [
   "Water",
   "Water",
   5,
   10
  ],
  [
   "Fire",
   "Fire",
   5,
   11
  ],
  [
   "Electric",
   "Electric",
   5,
   12
  ],
  [
   "Ice",
   "Ice",
   5,
   13
  ],
  [
   "Grass",
   "Grass",
   5,
   14
  ],
  [
   "Psychic",
   "Psychic",
   5,
   15
  ],
  [
   "Fire",
   "Water",
   5,
   16
  ],
  [
   "Grass",
   "Fire",
   5,
   17
  ],
  [
   "Water",
   "Grass",
   5,
   18
  ],
  [
   "Electric",
   "Grass",
   5,
   19
  ],
  [
   "Normal",
   "Rock",
   5,
   20
  ],
  [
   "Normal",
   "Ghost",
   0,
   21
  ],
  [
   "Ghost",
   "Ghost",
   20,
   22
  ],
  [
   "Fire",
   "Bug",
   20,
   23
  ],
  [
   "Fire",
   "Rock",
   5,
   24
  ],
  [
   "Water",
   "Ground",
   20,
   25
  ],
  [
   "Electric",
   "Ground",
   0,
   26
  ],
  [
   "Electric",
   "Flying",
   20,
   27
  ],
  [
   "Grass",
   "Ground",
   20,
   28
  ],
  [
   "Grass",
   "Bug",
   5,
   29
  ],
  [
   "Grass",
   "Poison",
   5,
   30
  ],
  [
   "Grass",
   "Rock",
   20,
   31
  ],
  [
   "Grass",
   "Flying",
   5,
   32
  ],
  [
   "Ice",
   "Water",
   5,
   33
  ],
  [
   "Ice",
   "Grass",
   20,
   34
  ],
  [
   "Ice",
   "Ground",
   20,
   35
  ],
  [
   "Ice",
   "Flying",
   20,
   36
  ],
  [
   "Fighting",
   "Normal",
   20,
   37
  ],
  [
   "Fighting",
   "Poison",
   5,
   38
  ],
  [
   "Fighting",
   "Flying",
   5,
   39
  ],
  [
   "Fighting",
   "Psychic",
   5,
   40
  ],
  [
   "Fighting",
   "Bug",
   5,
   41
  ],
  [
   "Fighting",
   "Rock",
   20,
   42
  ],
  [
   "Fighting",
   "Ice",
   20,
   43
  ],
  [
   "Fighting",
   "Ghost",
   0,
   44
  ],
  [
   "Poison",
   "Grass",
   20,
   45
  ],
  [
   "Poison",
   "Poison",
   5,
   46
  ],
  [
   "Poison",
   "Ground",
   5,
   47
  ],
  [
   "Poison",
   "Bug",
   20,
   48
  ],
  [
   "Poison",
   "Rock",
   5,
   49
  ],
  [
   "Poison",
   "Ghost",
   5,
   50
  ],
  [
   "Ground",
   "Fire",
   20,
   51
  ],
  [
   "Ground",
   "Electric",
   20,
   52
  ],
  [
   "Ground",
   "Grass",
   5,
   53
  ],
  [
   "Ground",
   "Bug",
   5,
   54
  ],
  [
   "Ground",
   "Rock",
   20,
   55
  ],
  [
   "Ground",
   "Poison",
   20,
   56
  ],
  [
   "Flying",
   "Electric",
   5,
   57
  ],
  [
   "Flying",
   "Fighting",
   20,
   58
  ],
  [
   "Flying",
   "Bug",
   20,
   59
  ],
  [
   "Flying",
   "Grass",
   20,
   60
  ],
  [
   "Flying",
   "Rock",
   5,
   61
  ],
  [
   "Psychic",
   "Fighting",
   20,
   62
  ],
  [
   "Psychic",
   "Poison",
   20,
   63
  ],
  [
   "Bug",
   "Fire",
   5,
   64
  ],
  [
   "Bug",
   "Grass",
   20,
   65
  ],
  [
   "Bug",
   "Fighting",
   5,
   66
  ],
  [
   "Bug",
   "Flying",
   5,
   67
  ],
  [
   "Bug",
   "Psychic",
   20,
   68
  ],
  [
   "Bug",
   "Ghost",
   5,
   69
  ],
  [
   "Bug",
   "Poison",
   20,
   70
  ],
  [
   "Rock",
   "Fire",
   20,
   71
  ],
  [
   "Rock",
   "Fighting",
   5,
   72
  ],
  [
   "Rock",
   "Ground",
   5,
   73
  ],
  [
   "Rock",
   "Flying",
   20,
   74
  ],
  [
   "Rock",
   "Bug",
   20,
   75
  ],
  [
   "Rock",
   "Ice",
   20,
   76
  ],
  [
   "Ghost",
   "Normal",
   0,
   77
  ],
  [
   "Ghost",
   "Psychic",
   0,
   78
  ],
  [
   "Fire",
   "Dragon",
   5,
   79
  ],
  [
   "Water",
   "Dragon",
   5,
   80
  ],
  [
   "Electric",
   "Dragon",
   5,
   81
  ],
  [
   "Grass",
   "Dragon",
   5,
   82
  ],
  [
   "Ice",
   "Dragon",
   20,
   83
  ],
  [
   "Dragon",
   "Dragon",
   20,
   84
  ]
 ]
}
T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · data/types/type_matchups.asm#L1-L85TypeEffects: ; attacker, defender, *= db WATER, FIRE, SUPER_EFFECTIVE … db -1 ; endpokered: disassembly of Pokémon Red and Blue · constants/type_constants.asm#L1-L28 — type order used for `types` (constants that appear in at least one row)Checked by claude-agent, 2026-10-20 — read every row of data/types/type_matchups.asm L1–L85 and the type constants at the pinned commit; probes/pokemon-types/type-charts.mjs re-parses the table and diffs it against this value

Each row is [attacking, defending, stored multiplier, line]. Stored multipliers are scaled by 10 (pokered/multiplier-encoding).

Cited by: Pokémon Crystal, Pokémon Red and Blue, Type effectiveness

Multipliers are integers scaled by 10 (SUPER_EFFECTIVE 20, NOT_VERY_EFFECTIVE 05, and NO_EFFECT 00); the table never uses EFFECTIVE (10) or MORE_EFFECTIVE (15). pokered/multiplier-encoding

Value
{
 "kind": "multiplier-encoding",
 "neutral": 10,
 "super": 20,
 "notVery": 5,
 "none": 0
}
T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · constants/battle_constants.asm#L60-L65; type effectiveness factors, scaled by 10 DEF SUPER_EFFECTIVE EQU 20 DEF MORE_EFFECTIVE EQU 15 DEF EFFECTIVE EQU 10 DEF NOT_VERY_EFFECTIVE EQU 05 DEF NO_EFFECT EQU 00Checked by claude-agent, 2026-10-20 — read the constants; the probe confirms the table uses only 20, 5 and 0

Cited by: Pokémon Crystal, Type effectiveness

AdjustDamageForMoveType applies STAB before any type row: damage+⌊damage/2⌋ when the move's type matches either attacker type. pokered/stab

About: Pokémon Red and Blue Same-type attack bonus

Value
{
 "kind": "stab",
 "form": "half-add"
}
T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L5101-L5125 srl b rr c ; bc = floor(0.5 * damage) add hl, bc ; hl = floor(1.5 * damage)Checked by claude-agent, 2026-10-20 — read AdjustDamageForMoveType from the type comparison (L5102–L5107) to the STAB flag (L5125)

Cited by: Pokémon Crystal, Same-type attack bonus, Type effectiveness

In table order, each TypeEffects row matching the move's type and either defender type sets damage to ⌊damage×value/10⌋; 0 marks a miss. pokered/type-step

Value
{
 "kind": "type-step",
 "div": 10,
 "zero": "miss"
}
T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L5127-L5185 call Multiply ld a, 10 ldh [hDivisor], a ld b, 4 call DivideChecked by claude-agent, 2026-10-20 — read the .loop / .matchingPairFound / .skipTypeImmunity code at the pinned commit

The loop compares each row's defending type with type 1, then type 2 of the defender and applies the row once on either match. Single-type Pokémon store the same type twice (e.g. data/pokemon/base_stats/charmander.asm#L6: db FIRE, FIRE ; type), so they take one step per row. A dual type therefore gets the product of two rows, truncated after each.

Cited by: Pokémon Crystal, Pokémon Red and Blue, Type effectiveness

Under two ½ rows (×¼), 2 or 3 damage truncates to 0 and the move misses; 4 damage gives 1. pokered/zero-damage-miss

T4 reproducedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L5171-L5176; if damage is 0, make the move miss ; this only occurs if a move that would do 2 or 3 damage is 0.25x effective against the targetpokered: disassembly of Pokémon Red and Blue · data/types/type_matchups.asm#L14 — with L30 (GRASS, POISON) this is the ×¼ case the probe replays (Grass move vs a Grass/Poison defender)db GRASS, GRASS, NOT_VERY_EFFECTIVEChecked by claude-agent, 2026-10-20 — read L5162–L5176; the probe replays 2, 3, 4 damage through the modeled routine (→ 0 miss, 0 miss, 1)Probe: probes/pokemon-types/type-charts.mjs

Cited by: Type effectiveness

Truncating after each row costs a net-neutral hit damage when its ½ row comes first: Ice against Water/Flying takes 3 to ⌊3 × 5 / 10⌋ = 1, then ⌊1 × 20 / 10⌋ = 2. pokered/truncation-order

T4 reproducedpokered: disassembly of Pokémon Red and Blue · data/types/type_matchups.asm#L33-L36 db ICE, WATER, NOT_VERY_EFFECTIVE … db ICE, FLYING, SUPER_EFFECTIVEChecked by claude-agent, 2026-10-20 — read the two rows and the step code (pokered/type-step); the probe replays it and lists every attacker × type pair whose ½ row precedes its 2× rowProbe: probes/pokemon-types/type-charts.mjs

Cited by: Type effectiveness

The Red/Blue type chart gives Ghost-type moves no effect on Psychic types. pokered/ghost-psychic

Value: 0 ×

T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · data/types/type_matchups.asm#L78db GHOST, PSYCHIC_TYPE, NO_EFFECTType/Type chart · Changes: Between Generations I and IIGhost was made 2× against Psychic instead of 0×.Checked by claude-agent, 2026-10-20 — read L78 at the pinned commit; Bulbapedia agrees

Cited by: Pokémon Red and Blue, Type effectiveness

In Red and Blue, a Saffron Gym trainer's after-battle line contradicts the table: “Psychic #MON fear only ghosts and bugs!” pokered/ghost-psychic-dialogue

T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · text/SaffronGym.asm#L135-L139_SaffronGymYoungster1AfterBattleText:: text "Psychic #MON" line "fear only ghosts" cont "and bugs!"Checked by claude-agent, 2026-10-20 — read the text file at the pinned commit (pointed there by Bulbapedia's Ghost (type) trivia)

Cited by: Type effectiveness

Bulbapedia reports that the Gen 1 Ghost → Psychic ×0 “may have been an error”, citing Nintendo strategy guides, two anime episodes, and the Saffron Gym line. pokered/ghost-psychic-reported-error

T1 secondaryGhost (type) · TriviaIn Generation I, Ghost-type moves have no effect on Psychic-type Pokémon, though an abundance of evidence suggests that this may have been an error.

A report of intent, not evidence of it. No developer statement has been found (see the gap on the type-effectiveness page).

Cited by: Type effectiveness

Each matching row overwrites the byte wDamageMultipliers, so the text follows the last row: above 10 is “super effective”, below 10 “not very effective”, and a miss reads “doesn't affect” only at 0. pokered/effectiveness-message

Value
{
 "kind": "message",
 "rule": "last-row"
}
T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L5147-L5153 ld a, [hl] ; a = damage multiplier ldh [hMultiplier], a add b ld [wDamageMultipliers], apokered: disassembly of Pokémon Red and Blue · engine/battle/display_effectiveness.asm#L1-L10 ld a, [wDamageMultipliers] and $7F cp EFFECTIVEpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L3718-L3733 — PrintMoveFailureText picks DoesntAffectMonText only when the masked byte is 0pokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L3218-L3229 — a missed move goes to PrintMoveFailureText, a hit to DisplayEffectivenessChecked by claude-agent, 2026-10-20 — read the row loop, DisplayEffectiveness, PrintMoveFailureText and the call site in ExecutePlayerMove

Bit 7 of the byte is the STAB flag (constants/battle_constants.asm: BIT_STAB_DAMAGE EQU 7), masked off before the comparison. ExecutePlayerMove seeds the byte with EFFECTIVE (core.asm#L3084-L3085), so a move with no matching row prints nothing.

Cited by: Pokémon Crystal, Pokémon Red and Blue, Type effectiveness

Since the text follows the last row, an Ice move against Water/Flying, net ×1 (½ row at L33, then 2× at L36), prints “It's super effective!”. pokered/message-net-neutral

T4 reproducedpokered: disassembly of Pokémon Red and Blue · data/types/type_matchups.asm#L33-L36Checked by claude-agent, 2026-10-20 — the probe replays the row loop and the message rule; Gen 2 and Gen 3 print nothing for the same hitProbe: probes/pokemon-types/type-charts.mjs

Cited by: Type effectiveness

A Ground move against Rock/Flying (×0 row at L9, then ×2 at L55) does 0 damage and prints the plain miss text, not “doesn't affect”: the byte holds the last row's 20. pokered/message-immune-miss

T4 reproducedpokered: disassembly of Pokémon Red and Blue · data/types/type_matchups.asm#L9db GROUND, FLYING, NO_EFFECTpokered: disassembly of Pokémon Red and Blue · data/types/type_matchups.asm#L55db GROUND, ROCK, SUPER_EFFECTIVEChecked by claude-agent, 2026-10-20 — the probe replays the row loop and PrintMoveFailureText's choice; not yet observed in an emulatorProbe: probes/pokemon-types/type-charts.mjs

Cited by: Type effectiveness

SetDamageEffects moves (Sonic Boom, Seismic Toss, Dragon Rage, Night Shade, Psywave, and Super Fang) jump to the hit test, skipping CalculateDamage and AdjustDamageForMoveType, the only damage routine that reads TypeEffects. pokered/set-damage-skips-chart

T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L3134-L3139 jp c, .moveHitTest ; SetDamageEffects moves (e.g. Seismic Toss and Super Fang) skip damage calculationpokered: disassembly of Pokémon Red and Blue · data/battle/set_damage_effects.asm#L1-L6 db SUPER_FANG_EFFECT db SPECIAL_DAMAGE_EFFECTpokered: disassembly of Pokémon Red and Blue · data/moves/moves.asm#L62 — SONICBOOM; also L82 SEISMIC_TOSS, L95 DRAGON_RAGE, L114 NIGHT_SHADE, L162 PSYWAVE (SPECIAL_DAMAGE_EFFECT) and L175 SUPER_FANGChecked by claude-agent, 2026-10-20 — read both call sites (player L3134–L3139, enemy L5526–L5530) and grepped the repo for TypeEffects (only core.asm L5129 and L5202 read it)

Cited by: Type effectiveness

The trainer AI's AIGetTypeEffectiveness stops at the first row matching either defender type, ignoring dual-type products. pokered/ai-first-row

T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L5187-L5223; this doesn't take into account the effects that dual types can have ; (e.g. 4x weakness / resistance, weaknesses and resistances canceling)pokered: disassembly of Pokémon Red and Blue · engine/battle/trainer_ai.asm#L207-L216 ld a, [wTypeEffectiveness] cp $10Checked by claude-agent, 2026-10-20 — read the routine and its one caller, AIMoveChoiceModification3

pret marks the routine's neutral seed ld a, $10 as "bug: should be EFFECTIVE (10)"; the caller also compares with $10, so the seed still reads as neutral there.

Cited by: Type effectiveness

The type constants still define BIRD ($06), with a name string, but no TypeEffects row names it. pokered/bird-type

T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · constants/type_constants.asm#L11 const BIRD ; $06pokered: disassembly of Pokémon Red and Blue · data/types/names.asm#L40.Bird: db "BIRD@"Checked by claude-agent, 2026-10-20 — read the constants and the full table; the probe lists type constants with no rows (Bird only)Probe: probes/pokemon-types/type-charts.mjs

No file under data/pokemon/base_stats/ names BIRD (grep at the pinned commit).

Cited by: Pokémon Red and Blue, Type effectiveness

Type picks the stats: Fire, Water, Grass, Electric, Psychic, Ice, and Dragon (SPECIAL upward) use Special on both sides; the rest use Attack against Defense. pokered/physical-special-by-type

About: Pokémon Red and Blue Damage formula

T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L4040-L4042 cp SPECIAL ; types >= SPECIAL are all special jr nc, .specialAttackpokered: disassembly of Pokémon Red and Blue · constants/type_constants.asm#L19-L26Checked by claude-agent, 2026-10-20 — read GetDamageVarsForPlayerAttack through .specialAttackCritCheck (L4030–L4099)

Cited by: Damage formula, Type effectiveness

In Red and Blue, a damaging move runs CriticalHitTest, CalculateDamage (base formula), AdjustDamageForMoveType (STAB, then type rows), RandomizeDamage, and then MoveHitTest (accuracy). pokered/damage-order

About: Pokémon Red and Blue Damage formula

T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L3140-L3150 call CalculateDamage … call AdjustDamageForMoveType call RandomizeDamage .moveHitTest call MoveHitTestpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L5531-L5543 — same order on the enemy's turnChecked by claude-agent, 2026-10-20 — read ExecutePlayerMove and ExecuteEnemyMove at the pinned commit

Cited by: Damage formula, Type effectiveness

CalculateDamage computes ⌊⌊(⌊2×Level/5⌋+2)×Power×Attack/Defense⌋/50⌋, caps it at 997, and adds 2, so the type step receives 2–999. pokered/base-damage

About: Pokémon Red and Blue Damage formula

T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L4343-L4459; Multiply level by 2 ; Divide by 5 ; Add 2 ; Multiply by attack base power ; Multiply by attack stat ; Divide by defender's defense stat ; Divide by 50 ; Capped at MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE: 999 - 2 = 997.Checked by claude-agent, 2026-10-20 — read CalculateDamage L4299–L4465 at the pinned commit

Critical hits, Reflect/Light Screen, and stat stages change the inputs first (GetDamageVarsForPlayerAttack); this claim doesn't cover them.

Cited by: Damage formula

RandomizeDamage multiplies damage by a random byte, 217–255, and integer-divides by 255, leaving 0 or 1 damage untouched. pokered/random-factor

About: Pokémon Red and Blue Damage formula

Value
[
 217,
 255
]
T3 code-verifiedpokered: disassembly of Pokémon Red and Blue · engine/battle/core.asm#L5420-L5454; loop until a random number greater than or equal to 217 is generated cp 85 percent + 1pokered: disassembly of Pokémon Red and Blue · macros/data.asm#L3 — 85 × 255 / 100 = 216 in integer math, + 1 = 217DEF percent EQUS "* $ff / 100"Checked by claude-agent, 2026-10-20 — read RandomizeDamage and the percent macro

Cited by: Damage formula, Type effectiveness