data/claims/pokecrystal.yamlPokémon Crystal (pret/pokecrystal)
Game: Pokémon Crystal. Concept: Type effectiveness.
Crystal's type chart (TypeMatchups) has 108 non-neutral rows over 17 types, then a -2 marker, Normal→Ghost and Fighting→Ghost ×0, and a -1 end. pokecrystal/type-chart
Value
{
"kind": "type-chart",
"types": [
"Normal",
"Fighting",
"Flying",
"Poison",
"Ground",
"Rock",
"Bug",
"Ghost",
"Steel",
"Fire",
"Water",
"Grass",
"Electric",
"Psychic",
"Ice",
"Dragon",
"Dark"
],
"matchups": [
[
"Normal",
"Rock",
5,
3
],
[
"Normal",
"Steel",
5,
4
],
[
"Fire",
"Fire",
5,
5
],
[
"Fire",
"Water",
5,
6
],
[
"Fire",
"Grass",
20,
7
],
[
"Fire",
"Ice",
20,
8
],
[
"Fire",
"Bug",
20,
9
],
[
"Fire",
"Rock",
5,
10
],
[
"Fire",
"Dragon",
5,
11
],
[
"Fire",
"Steel",
20,
12
],
[
"Water",
"Fire",
20,
13
],
[
"Water",
"Water",
5,
14
],
[
"Water",
"Grass",
5,
15
],
[
"Water",
"Ground",
20,
16
],
[
"Water",
"Rock",
20,
17
],
[
"Water",
"Dragon",
5,
18
],
[
"Electric",
"Water",
20,
19
],
[
"Electric",
"Electric",
5,
20
],
[
"Electric",
"Grass",
5,
21
],
[
"Electric",
"Ground",
0,
22
],
[
"Electric",
"Flying",
20,
23
],
[
"Electric",
"Dragon",
5,
24
],
[
"Grass",
"Fire",
5,
25
],
[
"Grass",
"Water",
20,
26
],
[
"Grass",
"Grass",
5,
27
],
[
"Grass",
"Poison",
5,
28
],
[
"Grass",
"Ground",
20,
29
],
[
"Grass",
"Flying",
5,
30
],
[
"Grass",
"Bug",
5,
31
],
[
"Grass",
"Rock",
20,
32
],
[
"Grass",
"Dragon",
5,
33
],
[
"Grass",
"Steel",
5,
34
],
[
"Ice",
"Water",
5,
35
],
[
"Ice",
"Grass",
20,
36
],
[
"Ice",
"Ice",
5,
37
],
[
"Ice",
"Ground",
20,
38
],
[
"Ice",
"Flying",
20,
39
],
[
"Ice",
"Dragon",
20,
40
],
[
"Ice",
"Steel",
5,
41
],
[
"Ice",
"Fire",
5,
42
],
[
"Fighting",
"Normal",
20,
43
],
[
"Fighting",
"Ice",
20,
44
],
[
"Fighting",
"Poison",
5,
45
],
[
"Fighting",
"Flying",
5,
46
],
[
"Fighting",
"Psychic",
5,
47
],
[
"Fighting",
"Bug",
5,
48
],
[
"Fighting",
"Rock",
20,
49
],
[
"Fighting",
"Dark",
20,
50
],
[
"Fighting",
"Steel",
20,
51
],
[
"Poison",
"Grass",
20,
52
],
[
"Poison",
"Poison",
5,
53
],
[
"Poison",
"Ground",
5,
54
],
[
"Poison",
"Rock",
5,
55
],
[
"Poison",
"Ghost",
5,
56
],
[
"Poison",
"Steel",
0,
57
],
[
"Ground",
"Fire",
20,
58
],
[
"Ground",
"Electric",
20,
59
],
[
"Ground",
"Grass",
5,
60
],
[
"Ground",
"Poison",
20,
61
],
[
"Ground",
"Flying",
0,
62
],
[
"Ground",
"Bug",
5,
63
],
[
"Ground",
"Rock",
20,
64
],
[
"Ground",
"Steel",
20,
65
],
[
"Flying",
"Electric",
5,
66
],
[
"Flying",
"Grass",
20,
67
],
[
"Flying",
"Fighting",
20,
68
],
[
"Flying",
"Bug",
20,
69
],
[
"Flying",
"Rock",
5,
70
],
[
"Flying",
"Steel",
5,
71
],
[
"Psychic",
"Fighting",
20,
72
],
[
"Psychic",
"Poison",
20,
73
],
[
"Psychic",
"Psychic",
5,
74
],
[
"Psychic",
"Dark",
0,
75
],
[
"Psychic",
"Steel",
5,
76
],
[
"Bug",
"Fire",
5,
77
],
[
"Bug",
"Grass",
20,
78
],
[
"Bug",
"Fighting",
5,
79
],
[
"Bug",
"Poison",
5,
80
],
[
"Bug",
"Flying",
5,
81
],
[
"Bug",
"Psychic",
20,
82
],
[
"Bug",
"Ghost",
5,
83
],
[
"Bug",
"Dark",
20,
84
],
[
"Bug",
"Steel",
5,
85
],
[
"Rock",
"Fire",
20,
86
],
[
"Rock",
"Ice",
20,
87
],
[
"Rock",
"Fighting",
5,
88
],
[
"Rock",
"Ground",
5,
89
],
[
"Rock",
"Flying",
20,
90
],
[
"Rock",
"Bug",
20,
91
],
[
"Rock",
"Steel",
5,
92
],
[
"Ghost",
"Normal",
0,
93
],
[
"Ghost",
"Psychic",
20,
94
],
[
"Ghost",
"Dark",
5,
95
],
[
"Ghost",
"Steel",
5,
96
],
[
"Ghost",
"Ghost",
20,
97
],
[
"Dragon",
"Dragon",
20,
98
],
[
"Dragon",
"Steel",
5,
99
],
[
"Dark",
"Fighting",
5,
100
],
[
"Dark",
"Psychic",
20,
101
],
[
"Dark",
"Ghost",
20,
102
],
[
"Dark",
"Dark",
5,
103
],
[
"Dark",
"Steel",
5,
104
],
[
"Steel",
"Fire",
5,
105
],
[
"Steel",
"Water",
5,
106
],
[
"Steel",
"Electric",
5,
107
],
[
"Steel",
"Ice",
20,
108
],
[
"Steel",
"Rock",
20,
109
],
[
"Steel",
"Steel",
5,
110
]
],
"foresightOnly": [
[
"Normal",
"Ghost",
0,
115
],
[
"Fighting",
"Ghost",
0,
116
]
],
"foresightMarkerLine": 112
}data/types/type_matchups.asm#L1-L118 db -2 ; end (with Foresight)
; Foresight removes Ghost's immunities.
db NORMAL, GHOST, NO_EFFECT
db FIGHTING, GHOST, NO_EFFECTpokecrystal: disassembly of Pokémon Crystal · constants/type_constants.asm#L7-L37 — 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–L118 and the type constants at the pinned commit; probes/pokemon-types/type-charts.mjs re-parses the table and diffs it against this valueRows are [attacking, defending, stored multiplier, line]; foresightOnly holds the rows after the -2 marker (pokecrystal/foresight).
Cited by: Pokémon Crystal, Type effectiveness
Multipliers are unchanged from Red/Blue: scaled by 10, with SUPER_EFFECTIVE 20, NOT_VERY_EFFECTIVE 05, NO_EFFECT 00, and EFFECTIVE 10. pokecrystal/multiplier-encoding
Value
{
"kind": "multiplier-encoding",
"neutral": 10,
"super": 20,
"notVery": 5,
"none": 0
}constants/battle_constants.asm#L20-L25; type effectiveness factors, scaled by 10
DEF SUPER_EFFECTIVE EQU 20Checked by claude-agent, 2026-10-20 — read the constants at the pinned commitCited by: Pokémon Crystal, Type effectiveness
Crystal's type constants add STEEL (physical), DARK (special), and an unused CURSE_TYPE named “???”; BIRD remains, still with no rows. pokecrystal/new-types
constants/type_constants.asm#L9-L37 const STEEL
…
const CURSE_TYPE
…
const DARKpokecrystal: disassembly of Pokémon Crystal · data/types/names.asm#L37CurseType: db "???@"Checked by claude-agent, 2026-10-20 — read the constants and names; the probe lists the type constants with no table rows (Bird, Curse)Probe: probes/pokemon-types/type-charts.mjsCited by: Pokémon Crystal, Type effectiveness
BattleCommand_Stab applies weather and badge type boosts, then STAB ( if either attacker type matches), then the type chart. pokecrystal/stab
About: Pokémon Crystal Same-type attack bonus
Value
{
"kind": "stab",
"form": "half-add"
}engine/battle/effect_commands.asm#L1251-L1288 farcall DoWeatherModifiers
…
farcall DoBadgeTypeBoosts
…
srl b
rr c
add hl, bcChecked by claude-agent, 2026-10-20 — read BattleCommand_Stab L1214–L1396 at the pinned commitCited by: Pokémon Crystal, Same-type attack bonus, Type effectiveness
A comment in pokecrystal's BattleCommand_Stab expands STAB as “Same Type Attack Bonus”. pokecrystal/stab-name
About: Pokémon Crystal Same-type attack bonus
T3 code-verifiedpokecrystal: disassembly of Pokémon Crystal ·engine/battle/effect_commands.asm#L1214-L1215BattleCommand_Stab:
; STAB = Same Type Attack BonusChecked by claude, 2026-10-20 — read the routine's first lines at the pinned commitThe comment is the disassemblers', not the game's. No source here says who coined the term.
Cited by: Same-type attack bonus
Struggle returns from BattleCommand_Stab at once, so it skips weather, badge boosts, STAB, and the type chart. pokecrystal/struggle-skips
engine/battle/effect_commands.asm#L1216-L1219 ld a, BATTLE_VARS_MOVE_ANIM
call GetBattleVar
cp STRUGGLE
ret zChecked by claude-agent, 2026-10-20 — read the routine entryCited by: Same-type attack bonus, Type effectiveness
Each matching row computes ; a nonzero product becomes , raised to 1 if that truncates to 0. pokecrystal/type-step
Value
{
"kind": "type-step",
"div": 10,
"zero": "min1",
"immune": "miss"
}engine/battle/effect_commands.asm#L1312-L1386 jr z, .ok ; This is a very convoluted way to get back that we've essentially dealt no damage.
; Take the product and divide it by 10.
…
ld a, 1
ldh [hMultiplicand + 2], aChecked by claude-agent, 2026-10-20 — read .SkipForesightCheck through .SkipType; checked in ram/hram.asm L63–L82 that hMultiplicand + 1/+2 alias hQuotient + 2/+3 (and hProduct + 2/+3), so the stored bytes are the quotient (or the zero product)Cited by: Pokémon Crystal, Type effectiveness
A ×0 row now marks the attack as missed outright, instead of relying on the damage reaching 0. pokecrystal/immunity-miss
engine/battle/effect_commands.asm#L1329-L1336; If the target is immune to the move, treat it as a miss and calculate the damage as 0
ld a, [hl]
and a
jr nz, .NotImmune
inc a
ld [wAttackMissed], aChecked by claude-agent, 2026-10-20 — read the .GotMatchup codeCited by: Pokémon Crystal, Type effectiveness
A ×¼ hit no longer truncates to a miss: 2 damage through two ½ rows gives ⌊2 × 5 / 10⌋ = 1, then ⌊1 × 5 / 10⌋ = 0, raised to 1. pokecrystal/quarter-min-one
engine/battle/effect_commands.asm#L1361-L1373Checked by claude-agent, 2026-10-20 — the probe replays the modeled step for a Grass move against a Grass/Poison defenderProbe: probes/pokemon-types/type-charts.mjsCited by: Type effectiveness
Against an identified (Foresight) target, the loop stops at the -2 marker, skipping the Normal→Ghost and Fighting→Ghost immunities after it. pokecrystal/foresight
engine/battle/effect_commands.asm#L1302-L1310 ; foresight
cp -2
jr nz, .SkipForesightCheck
ld a, BATTLE_VARS_SUBSTATUS1_OPP
call GetBattleVar
bit SUBSTATUS_IDENTIFIED, a
jr nz, .endpokecrystal: disassembly of Pokémon Crystal · data/types/type_matchups.asm#L112-L116Checked by claude-agent, 2026-10-20 — read the loop and the table tailCited by: Pokémon Crystal, Type effectiveness
After the loop, CheckTypeMatchup's combined value ( from 10) replaces the effectiveness byte, so the text reflects every row: ×4 is 40, ×¼ is 2, and ½ with 2× is 10. pokecrystal/effectiveness-message
Value
{
"kind": "message",
"rule": "combined"
}engine/battle/effect_commands.asm#L1388-L1396 call BattleCheckTypeMatchup
ld a, [wTypeMatchup]
ld b, a
ld a, [wTypeModifier]
and STAB_DAMAGE
or b
ld [wTypeModifier], apokecrystal: disassembly of Pokémon Crystal · engine/battle/effect_commands.asm#L1405-L1471 — CheckTypeMatchup seeds wTypeMatchup with EFFECTIVE and folds each row in with Multiply / Divide by 10pokecrystal: disassembly of Pokémon Crystal · engine/battle/effect_commands.asm#L2324-L2333 — BattleCommand_SuperEffectiveText compares the masked byte with EFFECTIVEpokecrystal: disassembly of Pokémon Crystal · engine/battle/effect_commands.asm#L2197-L2202 — GetFailureResultText picks DoesntAffectText when the masked byte is 0Checked by claude-agent, 2026-10-20 — read the end of BattleCommand_Stab, CheckTypeMatchup, BattleCommand_SuperEffectiveText and GetFailureResultTextCited by: Pokémon Crystal, Type effectiveness
An Ice move against Water/Flying (½ at L35, 2× at L39) prints no effectiveness text: the combined value goes 10 → 5 → 10. pokecrystal/message-net-neutral
data/types/type_matchups.asm#L35-L39Checked by claude-agent, 2026-10-20 — the probe replays the combined-value ruleProbe: probes/pokemon-types/type-charts.mjsCited by: Type effectiveness
Row order still matters: an Ice move against Water/Flying takes 3 damage to 1, then 2 (½ row at L35, 2× at L39). pokecrystal/truncation-order
data/types/type_matchups.asm#L35-L39 db ICE, WATER, NOT_VERY_EFFECTIVE
…
db ICE, FLYING, SUPER_EFFECTIVEChecked by claude-agent, 2026-10-20 — read the rows and the step code; the probe replays itProbe: probes/pokemon-types/type-charts.mjsCited by: Type effectiveness
Crystal's type chart makes Ghost-type moves super effective on Psychic types. pokecrystal/ghost-psychic
Value: 2 ×
T3 code-verifiedpokecrystal: disassembly of Pokémon Crystal ·data/types/type_matchups.asm#L94db GHOST, PSYCHIC_TYPE, SUPER_EFFECTIVEChecked by claude-agent, 2026-10-20 — read L94 at the pinned commitCited by: Type effectiveness
Crystal's table adds Steel and Dark and changes four Red/Blue matchups: Poison→Bug ×2 → ×1, Bug→Poison ×2 → ×½, Ghost→Psychic ×0 → ×2, and Ice→Fire ×1 → ×½. pokecrystal/chart-diff
Value
{
"kind": "chart-diff",
"from": "pokered",
"newTypes": [
"Steel",
"Dark"
],
"changed": [
[
"Poison",
"Bug",
20,
10
],
[
"Bug",
"Poison",
20,
5
],
[
"Ghost",
"Psychic",
0,
20
],
[
"Ice",
"Fire",
10,
5
]
]
}data/types/type_matchups.asm#L1-L85pokecrystal: disassembly of Pokémon Crystal · data/types/type_matchups.asm#L1-L118Type/Type chart · Changes: Between Generations I and IIThe Dark and Steel types were introduced.
Bug was made ½× against Poison instead of 2×.
Poison was made 1× against Bug instead of 2×.
Ghost was made 2× against Psychic instead of 0×.
Ice was made ½× against Fire instead of 1×.Checked by claude-agent, 2026-10-20 — the probe parses both tables and compares every attacker × defender cell; the result matches Bulbapedia's listProbe: probes/pokemon-types/type-charts.mjsRow order also changed: Red/Blue's table is loosely grouped, and Crystal's is grouped by attacking type. The probe compares stored values and counts the Foresight rows as active.
Cited by: Pokémon Crystal, Type effectiveness
Type still picks the stats: Steel is physical (below SPECIAL); Dark is special, using Special Attack against Special Defense. pokecrystal/physical-special-by-type
About: Pokémon Crystal Damage formula
T3 code-verifiedpokecrystal: disassembly of Pokémon Crystal ·engine/battle/effect_commands.asm#L2543-L2545 cp SPECIAL
jr nc, .specialpokecrystal: disassembly of Pokémon Crystal · constants/type_constants.asm#L9-L35Checked by claude-agent, 2026-10-20 — read PlayerAttackDamage and the type constantsCited by: Damage formula, Type effectiveness
A plain damaging move runs critical, damagestats, damagecalc (base formula, item boosts, and critical ×2), stab (weather, badges, STAB, and type rows), damagevariation, and then checkhit (accuracy). pokecrystal/damage-order
About: Pokémon Crystal Damage formula
T3 code-verifiedpokecrystal: disassembly of Pokémon Crystal ·data/moves/effects.asm#L5-L14NormalHit:
checkobedience
usedmovetext
doturn
critical
damagestats
damagecalc
stab
damagevariation
checkhitpokecrystal: disassembly of Pokémon Crystal · engine/battle/effect_commands.asm#L2983-L3023 — item boosts and the call to .CriticalMultiplier (L3108–L3120, doubles the damage) inside BattleCommand_DamageCalcChecked by claude-agent, 2026-10-20 — read the NormalHit effect script and BattleCommand_DamageCalcCited by: Damage formula, Type effectiveness
The random factor is unchanged from Red/Blue, a random byte from 217 to 255 over 255. pokecrystal/random-factor
About: Pokémon Crystal Damage formula
Value
[ 217, 255 ]
engine/battle/effect_commands.asm#L1496-L1544 cp 85 percent + 1
…
ld a, 100 percentChecked by claude-agent, 2026-10-20 — read BattleCommand_DamageVariation and macros/data.asm L23 (percent = * $ff / 100)Cited by: Damage formula, Type effectiveness