data/claims/pokeemerald.yamlPokémon Emerald (pret/pokeemerald)
Game: Pokémon Emerald. Concept: Type effectiveness.
Emerald's type chart, gTypeEffectiveness, is a flat u8 array of 108 non-neutral (attacker, defender, multiplier) rows over 17 types, then a TYPE_FORESIGHT marker, two Ghost immunities, and TYPE_ENDTABLE. pokeemerald/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,
337
],
[
"Normal",
"Steel",
5,
338
],
[
"Fire",
"Fire",
5,
339
],
[
"Fire",
"Water",
5,
340
],
[
"Fire",
"Grass",
20,
341
],
[
"Fire",
"Ice",
20,
342
],
[
"Fire",
"Bug",
20,
343
],
[
"Fire",
"Rock",
5,
344
],
[
"Fire",
"Dragon",
5,
345
],
[
"Fire",
"Steel",
20,
346
],
[
"Water",
"Fire",
20,
347
],
[
"Water",
"Water",
5,
348
],
[
"Water",
"Grass",
5,
349
],
[
"Water",
"Ground",
20,
350
],
[
"Water",
"Rock",
20,
351
],
[
"Water",
"Dragon",
5,
352
],
[
"Electric",
"Water",
20,
353
],
[
"Electric",
"Electric",
5,
354
],
[
"Electric",
"Grass",
5,
355
],
[
"Electric",
"Ground",
0,
356
],
[
"Electric",
"Flying",
20,
357
],
[
"Electric",
"Dragon",
5,
358
],
[
"Grass",
"Fire",
5,
359
],
[
"Grass",
"Water",
20,
360
],
[
"Grass",
"Grass",
5,
361
],
[
"Grass",
"Poison",
5,
362
],
[
"Grass",
"Ground",
20,
363
],
[
"Grass",
"Flying",
5,
364
],
[
"Grass",
"Bug",
5,
365
],
[
"Grass",
"Rock",
20,
366
],
[
"Grass",
"Dragon",
5,
367
],
[
"Grass",
"Steel",
5,
368
],
[
"Ice",
"Water",
5,
369
],
[
"Ice",
"Grass",
20,
370
],
[
"Ice",
"Ice",
5,
371
],
[
"Ice",
"Ground",
20,
372
],
[
"Ice",
"Flying",
20,
373
],
[
"Ice",
"Dragon",
20,
374
],
[
"Ice",
"Steel",
5,
375
],
[
"Ice",
"Fire",
5,
376
],
[
"Fighting",
"Normal",
20,
377
],
[
"Fighting",
"Ice",
20,
378
],
[
"Fighting",
"Poison",
5,
379
],
[
"Fighting",
"Flying",
5,
380
],
[
"Fighting",
"Psychic",
5,
381
],
[
"Fighting",
"Bug",
5,
382
],
[
"Fighting",
"Rock",
20,
383
],
[
"Fighting",
"Dark",
20,
384
],
[
"Fighting",
"Steel",
20,
385
],
[
"Poison",
"Grass",
20,
386
],
[
"Poison",
"Poison",
5,
387
],
[
"Poison",
"Ground",
5,
388
],
[
"Poison",
"Rock",
5,
389
],
[
"Poison",
"Ghost",
5,
390
],
[
"Poison",
"Steel",
0,
391
],
[
"Ground",
"Fire",
20,
392
],
[
"Ground",
"Electric",
20,
393
],
[
"Ground",
"Grass",
5,
394
],
[
"Ground",
"Poison",
20,
395
],
[
"Ground",
"Flying",
0,
396
],
[
"Ground",
"Bug",
5,
397
],
[
"Ground",
"Rock",
20,
398
],
[
"Ground",
"Steel",
20,
399
],
[
"Flying",
"Electric",
5,
400
],
[
"Flying",
"Grass",
20,
401
],
[
"Flying",
"Fighting",
20,
402
],
[
"Flying",
"Bug",
20,
403
],
[
"Flying",
"Rock",
5,
404
],
[
"Flying",
"Steel",
5,
405
],
[
"Psychic",
"Fighting",
20,
406
],
[
"Psychic",
"Poison",
20,
407
],
[
"Psychic",
"Psychic",
5,
408
],
[
"Psychic",
"Dark",
0,
409
],
[
"Psychic",
"Steel",
5,
410
],
[
"Bug",
"Fire",
5,
411
],
[
"Bug",
"Grass",
20,
412
],
[
"Bug",
"Fighting",
5,
413
],
[
"Bug",
"Poison",
5,
414
],
[
"Bug",
"Flying",
5,
415
],
[
"Bug",
"Psychic",
20,
416
],
[
"Bug",
"Ghost",
5,
417
],
[
"Bug",
"Dark",
20,
418
],
[
"Bug",
"Steel",
5,
419
],
[
"Rock",
"Fire",
20,
420
],
[
"Rock",
"Ice",
20,
421
],
[
"Rock",
"Fighting",
5,
422
],
[
"Rock",
"Ground",
5,
423
],
[
"Rock",
"Flying",
20,
424
],
[
"Rock",
"Bug",
20,
425
],
[
"Rock",
"Steel",
5,
426
],
[
"Ghost",
"Normal",
0,
427
],
[
"Ghost",
"Psychic",
20,
428
],
[
"Ghost",
"Dark",
5,
429
],
[
"Ghost",
"Steel",
5,
430
],
[
"Ghost",
"Ghost",
20,
431
],
[
"Dragon",
"Dragon",
20,
432
],
[
"Dragon",
"Steel",
5,
433
],
[
"Dark",
"Fighting",
5,
434
],
[
"Dark",
"Psychic",
20,
435
],
[
"Dark",
"Ghost",
20,
436
],
[
"Dark",
"Dark",
5,
437
],
[
"Dark",
"Steel",
5,
438
],
[
"Steel",
"Fire",
5,
439
],
[
"Steel",
"Water",
5,
440
],
[
"Steel",
"Electric",
5,
441
],
[
"Steel",
"Ice",
20,
442
],
[
"Steel",
"Rock",
20,
443
],
[
"Steel",
"Steel",
5,
444
]
],
"foresightOnly": [
[
"Normal",
"Ghost",
0,
446
],
[
"Fighting",
"Ghost",
0,
447
]
],
"foresightMarkerLine": 445
}src/battle_main.c#L329-L449// format: attacking type, defending type, damage multiplier
// the multiplier is a (decimal) fixed-point number:
…
TYPE_FORESIGHT, TYPE_FORESIGHT, TYPE_MUL_NO_EFFECT,
TYPE_NORMAL, TYPE_GHOST, TYPE_MUL_NO_EFFECT,
TYPE_FIGHTING, TYPE_GHOST, TYPE_MUL_NO_EFFECT,
TYPE_ENDTABLE, TYPE_ENDTABLE, TYPE_MUL_NO_EFFECTpokeemerald: decompilation of Pokémon Emerald · include/constants/pokemon.h#L5-L23 — type order used for `types` (constants that appear in at least one row)Checked by claude-agent, 2026-10-20 — read every row of src/battle_main.c L329–L449 and the type constants at the pinned commit; probes/pokemon-types/type-charts.mjs re-parses the array and diffs it against this valueCited by: Pokémon Crystal, Type effectiveness
Emerald keeps the Game Boy encoding, now named TYPE_MUL_*: 20 super effective, 10 normal, 5 not effective, and 0 no effect. pokeemerald/multiplier-encoding
Value
{
"kind": "multiplier-encoding",
"neutral": 10,
"super": 20,
"notVery": 5,
"none": 0
}include/battle_main.h#L31-L34#define TYPE_MUL_NO_EFFECT 0
#define TYPE_MUL_NOT_EFFECTIVE 5
#define TYPE_MUL_NORMAL 10
#define TYPE_MUL_SUPER_EFFECTIVE 20Checked by claude-agent, 2026-10-20 — read the defines and the table comment (battle_main.c L329–L334)Cited by: Pokémon Crystal, Type effectiveness
Emerald's table holds the same 110 rows as Crystal's, in the same order: no new type and no changed matchup. pokeemerald/chart-diff
Value
{
"kind": "chart-diff",
"from": "pokecrystal",
"newTypes": [],
"changed": []
}data/types/type_matchups.asm#L1-L118pokeemerald: decompilation of Pokémon Emerald · src/battle_main.c#L335-L449Type/Type chart · Type charts: Generations II-VThis matchup table is used from Generation II to Generation V.Checked by claude-agent, 2026-10-20 — the probe parses both tables, compares every cell and the row orderProbe: probes/pokemon-types/type-charts.mjsCited by: Pokémon Crystal, Pokémon Emerald, Type effectiveness
TYPE_MYSTERY (9), named "???", sits between the physical and special types and has no rows. pokeemerald/mystery-type
include/constants/pokemon.h#L15#define TYPE_MYSTERY 9pokeemerald: decompilation of Pokémon Emerald · src/battle_main.c#L462[TYPE_MYSTERY] = _("???"),Checked by claude-agent, 2026-10-20 — read the constants and the type-name table; the probe lists type constants with no rows (Mystery only)Probe: probes/pokemon-types/type-charts.mjsCited by: Type effectiveness
Before the type chart, Cmd_typecalc applies STAB as when either attacker type equals the move's type. pokeemerald/stab
About: Pokémon Emerald Same-type attack bonus
Value
{
"kind": "stab",
"form": "mul-div",
"mul": 15,
"div": 10
}src/battle_script_commands.c#L1368-L1373 // check stab
if (IS_BATTLER_OF_TYPE(gBattlerAttacker, moveType))
{
gBattleMoveDamage = gBattleMoveDamage * 15;
gBattleMoveDamage = gBattleMoveDamage / 10;
}pokeemerald: decompilation of Pokémon Emerald · include/battle.h#L471 — IS_BATTLER_OF_TYPE tests types[0] or types[1]Checked by claude-agent, 2026-10-20 — read Cmd_typecalc L1355–L1424For non-negative integers equals the Game Boy games' , so STAB's arithmetic did not change, only its form.
Cited by: Pokémon Crystal, Same-type attack bonus, Type effectiveness
For each row of the move's type, ModulateDmgByType runs once per distinct target type it matches: , raised from 0 to 1 unless the multiplier is 0. pokeemerald/type-step
Value
{
"kind": "type-step",
"div": 10,
"zero": "min1"
}src/battle_script_commands.c#L1321-L1325 gBattleMoveDamage = gBattleMoveDamage * multiplier / 10;
if (gBattleMoveDamage == 0 && multiplier != 0)
gBattleMoveDamage = 1;pokeemerald: decompilation of Pokémon Emerald · src/battle_script_commands.c#L1386-L1406 if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBattlerTarget].types[1] &&
gBattleMons[gBattlerTarget].types[0] != gBattleMons[gBattlerTarget].types[1])Checked by claude-agent, 2026-10-20 — read ModulateDmgByType and the loop in Cmd_typecalcCited by: Pokémon Crystal, Type effectiveness
The text comes from flags ModulateDmgByType sets per row: a 2× row cancels an earlier not-very-effective flag, a ½ row an earlier super-effective one, and ×0 sets "doesn't affect", clearing both. pokeemerald/effectiveness-message
Value
{
"kind": "message",
"rule": "flags"
}src/battle_script_commands.c#L1327-L1352 case TYPE_MUL_SUPER_EFFECTIVE:
if (gBattleMoves[gCurrentMove].power && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
{
if (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE)
gMoveResultFlags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE;
else
gMoveResultFlags |= MOVE_RESULT_SUPER_EFFECTIVE;
}Checked by claude-agent, 2026-10-20 — read the switch in ModulateDmgByTypeCited by: Pokémon Crystal, Pokémon Emerald, Type effectiveness
Against a Foresight target, the loop breaks at the TYPE_FORESIGHT row, skipping the Normal→Ghost and Fighting→Ghost immunities after it. pokeemerald/foresight
src/battle_script_commands.c#L1388-L1394 if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT)
{
if (gBattleMons[gBattlerTarget].status2 & STATUS2_FORESIGHT)
break;pokeemerald: decompilation of Pokémon Emerald · src/battle_main.c#L445-L447Checked by claude-agent, 2026-10-20 — read the loop and the table tailCited by: Type effectiveness
Struggle skips Cmd_typecalc entirely, so neither STAB nor the type chart touches it. pokeemerald/struggle-skips
src/battle_script_commands.c#L1360-L1364 if (gCurrentMove == MOVE_STRUGGLE)
{
gBattlescriptCurrInstr++;
return;
}Checked by claude-agent, 2026-10-20 — read the function entryCited by: Same-type attack bonus, Type effectiveness
Cmd_typecalc flags a Ground move against a Levitate target as missed and “doesn't affect”, and walks no type row. pokeemerald/levitate
src/battle_script_commands.c#L1375-L1384 if (gBattleMons[gBattlerTarget].ability == ABILITY_LEVITATE && moveType == TYPE_GROUND)
{
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
gMoveResultFlags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE);Checked by claude-agent, 2026-10-20 — read Cmd_typecalcCited by: Pokémon Emerald, Type effectiveness
After the rows, a Wonder Guard target makes a damaging move miss on the turn it attacks, unless the move carries the super-effective flag without the not-very-effective one. pokeemerald/wonder-guard
src/battle_script_commands.c#L1409-L1419 if (gBattleMons[gBattlerTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBattlerAttacker, gCurrentMove) == 2
&& (!(gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || ((gMoveResultFlags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)))
&& gBattleMoves[gCurrentMove].power)Checked by claude-agent, 2026-10-20 — read Cmd_typecalc; AttacksThisTurn's meaning (2 = attacks this turn, not a charge turn) taken from its name and not traced furtherCited by: Pokémon Emerald, Type effectiveness
Row order still matters: an Ice move against Water/Flying takes 3 damage to 1, then 2 (½ row at L369, 2× at L373). pokeemerald/truncation-order
src/battle_main.c#L369-L373 TYPE_ICE, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE,
…
TYPE_ICE, TYPE_FLYING, TYPE_MUL_SUPER_EFFECTIVE,Checked by claude-agent, 2026-10-20 — read the rows and ModulateDmgByType; the probe replays itProbe: probes/pokemon-types/type-charts.mjsCited by: Type effectiveness
Type still decides physical or special in Emerald, by its position relative to TYPE_MYSTERY. pokeemerald/physical-special-by-type
About: Pokémon Emerald Damage formula
T3 code-verifiedpokeemerald: decompilation of Pokémon Emerald ·include/battle.h#L466-L467#define IS_TYPE_PHYSICAL(moveType) (moveType < TYPE_MYSTERY)
#define IS_TYPE_SPECIAL(moveType) (moveType > TYPE_MYSTERY)Checked by claude-agent, 2026-10-20 — read the macros and their use in src/pokemon.c (L3232, L3287)Cited by: Damage formula, Type effectiveness
A plain damaging move runs critcalc, damagecalc (base damage), typecalc (STAB, then type rows), and then adjustnormaldamage (random factor). pokeemerald/damage-order
About: Pokémon Emerald Damage formula
T3 code-verifiedpokeemerald: decompilation of Pokémon Emerald ·data/battle_scripts_1.s#L249-L252 critcalc
damagecalc
typecalc
adjustnormaldamageChecked by claude-agent, 2026-10-20 — read BattleScript_EffectHit and Cmd_adjustnormaldamage (L1658–L1662)Unlike the Game Boy games, the accuracy check (accuracycheck, L244) comes before damage is computed.
Cited by: Damage formula, Type effectiveness
The random factor changes form: damage × (100 − rand % 16) / 100, i.e. 85–100 %, raised to 1 if that gives 0. pokeemerald/random-factor
About: Pokémon Emerald Damage formula
Value
[ 85, 100 ]
src/battle_script_commands.c#L1639-L1651 u16 randPercent = 100 - (rand % 16);
…
gBattleMoveDamage *= randPercent;
gBattleMoveDamage /= 100;Checked by claude-agent, 2026-10-20 — read ApplyRandomDmgMultiplierCited by: Damage formula, Type effectiveness