data/claims/pokered.yamlPoké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
]
]
}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 valueEach 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
}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 0Cited by: Pokémon Crystal, Type effectiveness
AdjustDamageForMoveType applies STAB before any type row: 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"
}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 ; 0 marks a miss. pokered/type-step
Value
{
"kind": "type-step",
"div": 10,
"zero": "miss"
}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 commitThe 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
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.mjsCited 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
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.mjsCited 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 agreesCited 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
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
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"
}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 ExecutePlayerMoveBit 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
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.mjsCited 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
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.mjsCited 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
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
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, AIMoveChoiceModification3pret 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
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.mjsNo 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 commitCited by: Damage formula, Type effectiveness
CalculateDamage computes , 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 commitCritical 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 ]
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 macroCited by: Damage formula, Type effectiveness