Item drop table
The rules that choose what, if anything, a defeated enemy leaves behind.
An item drop table decides what a defeated enemy leaves behind. A table lists the possible items, and something picks an entry: a counter, a random byte, or both. A chance or a cap decides whether anything drops at all. The Legend of Zelda picks the entry with a counter and the chance with a random byte1,2. Metroid picks both with one byte that steps once per frame3,4. A Link to the Past gives each of its seven prize packs its own counter, where Zelda’s groups share one kill cycle5,6. A pack drops half the time, and pack 4 always5.
Metroid Fusion turns a killed enemy into an X parasite whose color comes from a number built from the frame counter and a random value, against three weights in the enemy’s row7. The color sets the refill, 10 energy (yellow), 2 missiles (green), 500 energy and 100 missiles (red)8. The pick also follows need: a would-be green X turns yellow when missiles are full and energy isn’t7, where Metroid caps each room’s drops instead9.
- Kill cycleThe Legend of Zelda (1986). Four groups, a 10-step kill cycle, and streak bonuses.10,1,2,6,11,12,13,14,15,16
- Pack cycleThe Legend of Zelda: A Link to the Past (1991). Seven prize packs, each stepping through its own eight prizes.5
- Weighted, by needMetroid Fusion (2002). A killed enemy becomes an X parasite whose color, picked from 1024 by per-enemy weights, sets its refill.7,8
- Chance, then setThe Legend of Zelda: Oracle of Seasons and Oracle of Ages (2001). A per-enemy chance from 1 in 16 to always, then one of 32 entries; a drop Link can't use becomes none.17
- One rollMetroid (1986). An 8-entry table read by a frame-stepped byte, capped per room.3,18,9,19,20,21,22
#How it works
on a kill:
if the enemy never drops: nothing
entry = TABLE[enemy's group][selector] # selector: a counter or a random value
if a guarantee applies: entry = its item # streaks, retries
elif chance fails or cap reached: nothing
else: drop entry
#Implementations
#The Legend of Zelda (1986)
Zelda sorts monster types into four groups, and seven types never drop10. Each group has a row of ten items, and a kill cycle that advances with every kill picks the column1,6. A drop then needs the dead monster’s random byte to be under the group’s rate, 80, 152, 104, and 104 in 2562,2. Measured in the ROM over every case, the groups drop in 800, 1,520, 1,040, and 1,040 of 2,56014 cases14.
Two streak counters override the table. The 10th kill since Link was last hurt guarantees 5 rupees, or bombs if that kill was by bomb, and the 16th guarantees a fairy12,11. Any hit on Link zeroes both13.
#Metroid (1986)
Metroid’s selector is RandomNumber1, which gains 25 once per frame, so a drop depends on the frame the enemy dies4. Values below 16 drop nothing; the low 3 bits of the rest pick missiles, energy, or a 20-unit energy ball from an 8-entry table3,18. The 20-unit ball drops only for enemies that the area’s data allows, and the table’s comment calls it “No item”18.
Caps replace Zelda’s streaks. Each door re-rolls how many missiles and energy balls the next room may drop, and a drop that would pass its cap is lost9. In Tourian, a roll that would drop nothing instead resets the caps and rolls again21. Measured over all 256 values for one Brinstar enemy, the code gives 60 missiles, 90 energy balls, 90 $89 balls, and 16 nothing22,22.
#Compared
| The Legend of Zelda | Metroid | |
|---|---|---|
| Entries | 4 rows of 10, by monster group1 | 1 row of 8 for every enemy3 |
| Selector | a kill counter, 0–96 | a byte stepped by 25 each frame4 |
| Whether anything drops | random byte under a per-group rate2 | byte of 16 or more, and the room’s caps3,9 |
| Guarantees | 10th and 16th kill without being hurt12,11 | Tourian re-rolls until something drops21 |
| Per-enemy differences | group membership10 | one bit allows the 20-unit ball; one flag makes drops worth 3018,20 |
Games
| Game | Year | How | Note |
|---|---|---|---|
| The Legend of Zelda | 1986 | Kill cycle | four groups, a 10-step kill cycle, and streak bonuses |
| The Legend of Zelda: A Link to the Past | 1991 | Pack cycle | seven prize packs, each stepping through its own eight prizes |
| Metroid Fusion | 2002 | Weighted, by need | a killed enemy becomes an X parasite whose color, picked from 1024 by per-enemy weights, sets its refill |
| The Legend of Zelda: The Minish Cap | 2004 | Weighted, by need | per-monster weights, raised for hearts, bombs, arrows, and rupees Link lacks, and one roll |
| The Legend of Zelda: Oracle of Seasons and Oracle of Ages | 2001 | Chance, then set | a per-enemy chance from 1 in 16 to always, then one of 32 entries; a drop Link can't use becomes none |
| Metroid | 1986 | One roll | an 8-entry table read by a frame-stepped byte, capped per room |
Every claim about this mechanic, by game (23)
References
- ^ abcd
DropItemTableholds ten items for each group, and the kill cycle picks the column; group A's row is heart, rupee, heart, rupee, fairy, rupee, heart, heart, rupee, rupee.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
11057; ID's for items dropped by monsters. 11058; WorldKillCycle addresses the column. ⋮ 11060; Monsters are arranged in groups that determine the row. 11061; There are four rows. ⋮ 11063DropItemTable: 11064 .BYTE $22, $18, $22, $18, $23, $18, $22, $22 11065 .BYTE $18, $18, $0F, $18, $22, $18, $0F, $22 11066 .BYTE $21, $18, $18, $18, $22, $00, $18, $21 11067 .BYTE $18, $22, $00, $18, $00, $22, $22, $22 11068 .BYTE $23, $18, $22, $23, $22, $22, $22, $18
src/Z_04.asm lines 11057–11068 at 50a1c86 · upstream ↗ 11137 LDY $01 11138 LDA DropItemSetBaseOffsets, Y 11139 CLC 11140 ADC WorldKillCycle 11141 TAY 11142 LDA DropItemTable, Y 11143 STA $00 ; [00] Dropped item ID
src/Z_04.asm lines 11137–11143 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 4, as in drop-groups. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcdeOutside the special cases, a drop happens only when the dead monster's slot's byte of
Randomis below its group's rate:$50,$98,$68, and$68, or 80, 152, 104, and 104 in 256.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
11051; Top drop an item, a random value must be less than the 11052; element for the monster group. ⋮ 11054DropItemRates: 11055 .BYTE $50, $98, $68, $68
src/Z_04.asm lines 11051–11055 at 50a1c86 · upstream ↗ 11176@RandomlyCancel: 11177 ; If the random value >= drop item rate for the monster's group, 11178 ; then go destroy the monster. 11179 LDY $01 11180 LDA Random, X 11181 CMP DropItemRates, Y 11182 BCS @DestroyMonster
src/Z_04.asm lines 11176–11182 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 4, as in drop-groups. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcdeWhen an enemy dies, a
RandomNumber1below 16 drops nothing; otherwise its low 3 bits pick fromItemDropTbl, which holds a missile at 0 and 3, energy at 1, 4, and 6, and$89at 2, 5, and 7.Codenmikstas/metroid-disassembly · “Metroid (USA)”How we know
4575 LDA RandomNumber1 4576 CMP #$10 4577 BCC LDD5B 4578* AND #$07 4579 TAY 4580 LDA ItemDropTbl,y 4581 STA EnAnimFrame,x
Source_Files/Bank07.asm lines 4575–4581 at 4270d57 · upstream ↗ 4722;The following table determines what, if any, items an enemy will drop when it is killed. ⋮ 4724ItemDropTbl: 4725LDE35: .byte $80 ;Missile. 4726LDE36: .byte $81 ;Energy. 4727LDE37: .byte $89 ;No item. 4728LDE38: .byte $80 ;Missile. 4729LDE39: .byte $81 ;Energy. 4730LDE3A: .byte $89 ;No item. 4731LDE3B: .byte $81 ;Energy. 4732LDE3C: .byte $89 ;No item.
Source_Files/Bank07.asm lines 4722–4732 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7 $DCFC, the drop code; bank 7 $DE35, ItemDropTbl. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcThe main loop calls
RandomNumbersonce per frame, after the frame's work; it adds 5 toRandomNumber1five times, 25 in all, so the byte steps through all 256 values every 256 frames.Codenmikstas/metroid-disassembly · “Metroid (USA)”How we know
34RandomNumbers: ⋮ 37LC002: LDX #$05 ; 38LC004:* LDA RandomNumber1 ; 39LC006: CLC ; 40LC007: ADC #$05 ; 41LC009: STA RandomNumber1 ;2E is increased by #$19 every frame and ⋮ 46LC012: DEX ; 47LC013: BNE - ;
Source_Files/Bank07.asm lines 34–47 at 4270d57 · upstream ↗ 170WaitNMIEnd: ⋮ 176LC0D3:* JSR RandomNumbers ;($C000)Update pseudo random numbers. 177LC0D6: JMP MainLoop ;($C0BC)Jump to top of subroutine.
Source_Files/Bank07.asm lines 170–177 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7 $C000. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcA defeated monster's prize pack (1–7) gives a drop half the time, and pack 4 always. Each pack keeps its own counter that steps through 8 prizes in order; pack 1's row is heart, heart, heart, heart, green rupee, heart, heart, green rupee.Codespannerisms/usdasm
How we know
24136|06F9B2| JSL GetRandomNumber ⋮ 24138|06F9B6| PLY ⋮ 24140|06F9B7| AND.w PrizePackRarities,Y 24141|06F9BA| BNE .you_dont_get_a_drop ⋮ 24152|06F9C0| ORA.w $0FC7,Y ⋮ 24155|06F9C4| LDA.w $0FC7,Y 24156|06F9C7| INC A 24157|06F9C8| AND.b #$07 24158|06F9CA| STA.w $0FC7,Y ⋮ 24162|06F9CE| LDA.w PrizePackPrizes,Y
bank_06.asm lines 24107–24162 at bcdd96e · upstream ↗ 24276|06FA5C| db $01 ; pack 1 : 50% ⋮ 24279|06FA5F| db $00 ; pack 4 : 100%
bank_06.asm lines 24275–24283 at bcdd96e · upstream ↗ 24307.pack_1 24308|06FA72| db $D8 ; SPRITE D8 - heart ⋮ 24312|06FA76| db $D9 ; SPRITE D9 - green rupee
bank_06.asm lines 24305–24315 at bcdd96e · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abcdEach kill advances
WorldKillCyclefrom 0 to 9 and back to 0 before the drop is chosen, except kills of types$5D,$14, and$1C, which the comments call a Child Gel and a Red Keese.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
5457 ; Certain objects don't advance the world kill cycle. 5458 CMP #$5D 5459 BEQ @DropItem 5460 CMP #$14 ; Child Gel 5461 BEQ @DropItem 5462 CMP #$1C ; Red Keese 5463 BEQ @DropItem ⋮ 5465 ; Advance the world kill cycle (0 to 9). 5466 LDA WorldKillCycle 5467 CLC 5468 ADC #$01 5469 CMP #$0A ⋮
src/Z_07.asm lines 5457–5488 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 7 UpdateMetaObjectEnd, $FC95. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcWhen a dying sprite's countdown ends,
SpriteDyingsets its pose to 0x5B (the decompilers'SPRITE_POSE_TURNING_INTO_X) unless it is a secondary sprite, and an enemy's AI (Choot's, for one) runsXParasiteInitin that pose. The X it becomes takes its color from a number from 1 to 1024, made from the low 2 bits ofgSpriteRandomNumberand the 8-bit frame counter, against three weights in that sprite's row ofsPrimarySpriteStats: the top red-weight values give red and the next green-weight values green, each only when its weight is above 0, and everything left below the green bound gives yellow, whatever the yellow weight is, unless it is 0, which deletes the X instead. A would-be green X turns yellow when missiles are full and energy isn't, or Samus has no missiles yet; a would-be yellow X turns green when energy is full and missiles aren't. An X from a core X is green whengSpriteRandomNumberis below 5 or that energy test holds, and otherwise yellow; an X placed in a room is yellow. All of this applies only to an X whose sprite property isSSP_X_ABSORBABLE_BY_SAMUS: one markedSSP_X_UNABSORBABLE_BY_SAMUS, or the unnamedSSP_UNKNOWN_40, is always yellow, and any other property deletes the X.Codemetroidret/mfrevisedHow we know
561 case SSP_X_ABSORBABLE_BY_SAMUS: 562 if (type == X_PARASITE_TYPE_FROM_CORE_X) ⋮ 564 if (gSpriteRandomNumber < 5 || SpriteUtilCheckEnergyFullAndMissilesNotFull()) ⋮ 566 gCurrentSprite.pOam = sXParasiteOam_Green; 567 gCurrentSprite.samusCollision = SSC_GREEN_X_PARASITE; ⋮ 569 else ⋮ 571 gCurrentSprite.pOam = sXParasiteOam_Yellow;
src/x_parasite_util.c lines 561–572 at a6d6187 · upstream ↗ 575 else if (type == X_PARASITE_TYPE_FROM_SPRITE) ⋮ 577 // Calculate random number between 1 and 1024 inclusive 578 randomNumber = gSpriteRandomNumber & 3; 579 randomNumber <<= 8; 580 randomNumber |= gFrameCounter8Bit; 581 randomNumber++; ⋮ 583 yellowXThreshold = sPrimarySpriteStats[spriteId][4]; 584 greenXThreshold = sPrimarySpriteStats[spriteId][5]; 585 redXThreshold = sPrimarySpriteStats[spriteId][6]; ⋮ 589 redXThreshold = 1024 - redXThreshold; 590 if (randomNumber <= 1024 && randomNumber > redXThreshold) ⋮ 598 else ⋮
src/x_parasite_util.c lines 574–655 at a6d6187 · upstream ↗ 657 case SSP_X_UNABSORBABLE_BY_SAMUS: 658 gCurrentSprite.invincibilityStunFlashTimer &= 0x7f; 659 gCurrentSprite.pOam = sXParasiteOam_Yellow; ⋮ 661 break; ⋮ 663 case SSP_UNKNOWN_40: 664 gCurrentSprite.pOam = sXParasiteOam_Yellow; 665 gCurrentSprite.samusCollision = SSC_YELLOW_X_PARASITE; 666 break; ⋮ 668 default: 669 gCurrentSprite.status = 0;
src/x_parasite_util.c lines 657–669 at a6d6187 · upstream ↗ 509void SpriteDying(void) ⋮ 519 if (--gCurrentSprite.work1 == 0) ⋮ 521 if (gCurrentSprite.properties & SP_SECONDARY_SPRITE) ⋮ 523 gCurrentSprite.status = 0; ⋮ 525 else ⋮ 527 gCurrentSprite.pose = 0x5b;
src/x_parasite_util.c lines 509–530 at a6d6187 · upstream ↗ 328 case 0x57: 329 SpriteDyingInit(); 330 case 0x58: 331 SpriteDying(); 332 break; ⋮ 338 break; ⋮ 340 case 0x5b: 341 XParasiteInit(); 342 break;
src/sprites_AI/choot.c lines 328–342 at a6d6187 · upstream ↗ 477 SPRITE_POSE_TURNING_INTO_X = 0x5B,include/constants/sprite.h line 477 at a6d6187 · upstream ↗ 2746u8 SpriteUtilCheckEnergyFullAndMissilesNotFull(void) ⋮ 2748 if (gEquipment.currentEnergy == gEquipment.maxEnergy) ⋮ 2750 if (gEquipment.weaponsStatus & MBF_ANY_MISSILE && gEquipment.currentMissiles < gEquipment.maxMissiles) 2751 return TRUE; ⋮ 2762u8 SpriteUtilCheckMissilesFullAndEnergyNotFull(void) ⋮ 2764 if (!(gEquipment.weaponsStatus & MBF_ANY_MISSILE)) 2765 return TRUE; ⋮ 2767 if (gEquipment.currentMissiles == gEquipment.maxMissiles && gEquipment.currentEnergy < gEquipment.maxEnergy) 2768 return TRUE;
src/sprite_util.c lines 2746–2770 at a6d6187 · upstream ↗ 697 case PSPRITE_X_PARASITE_IN_ROOM: 698 case PSPRITE_X_PARASITE_IN_ROOM_PROXIMITY: ⋮ 704 XParasiteDetermineColor(X_PARASITE_TYPE_IN_ROOM, 0); 705 break; ⋮ 720 XParasiteDetermineColor(X_PARASITE_TYPE_FROM_CORE_X, 0); ⋮ 726 break; ⋮ 728 case PSPRITE_X_PARASITE: 729 case PSPRITE_X_PARASITE_AQUA_ZEBESIAN: 730 XParasiteSpawningInit(); 731 XParasiteDetermineColor(X_PARASITE_TYPE_FROM_SPRITE, gCurrentSprite.roomSlot); 732 break; ⋮ 734 default: ⋮
src/x_parasite_util.c lines 697–737 at a6d6187 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^ abTouching an absorbable X parasite runs
SamusAbsorbX, which refills by its color: a red X (SSC_RED_X_PARASITE) 500 energy, 100 missiles, and 10 power bombs; a green X 2 missiles; any other (yellow) X 10 energy.SpriteUtilRefillSamusadds missiles only once a missile flag is set and power bombs only once the power bomb flag is, and stops each at its maximum.Codemetroidret/mfHow we know
482void XParasiteGettingAbsorbedInit(void) ⋮ 497 SamusAbsorbX();
src/x_parasite_util.c lines 482–497 at a6d6187 · upstream ↗ 433void SamusAbsorbX(void) ⋮ 444 case SSP_X_ABSORBABLE_BY_SAMUS: 445 if (gCurrentSprite.samusCollision == SSC_RED_X_PARASITE) ⋮ 447 energy = 500; 448 missiles = 100; 449 powerBombs = 10; ⋮ 453 else if (gCurrentSprite.samusCollision == SSC_GREEN_X_PARASITE) ⋮ 455 energy = 0; 456 missiles = 2; 457 powerBombs = 0; ⋮ 461 else ⋮ 463 energy = 10; ⋮
src/x_parasite_util.c lines 433–470 at a6d6187 · upstream ↗ 2686void SpriteUtilRefillSamus(u16 energy, u16 missiles, u16 powerBombs) ⋮ 2688 gEquipment.currentEnergy += energy; ⋮ 2690 if (gEquipment.currentEnergy > gEquipment.maxEnergy) 2691 gEquipment.currentEnergy = gEquipment.maxEnergy; ⋮ 2693 if (gEquipment.weaponsStatus & MBF_ANY_MISSILE) ⋮ 2695 gEquipment.currentMissiles += missiles; ⋮ 2697 if (gEquipment.currentMissiles > gEquipment.maxMissiles) 2698 gEquipment.currentMissiles = gEquipment.maxMissiles; ⋮ 2701 if (gEquipment.weaponsStatus & MBF_POWER_BOMBS) ⋮ 2703 gEquipment.currentPowerBombs += powerBombs;
src/sprite_util.c lines 2686–2707 at a6d6187 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abcdEach door re-rolls the room's caps from
RandomNumber1, 0 to 15 missile drops and 64 to 94 energy drops, and zeroes the counts. A drop that would pass its cap is lost; one that passes the test adds to its count, even a$89roll that the enemy then can't drop.Codenmikstas/metroid-disassembly · “Metroid (USA)”revisedHow we know
1381L8B1B: STA CrntMslePickups ; 1382L8B1D: STA CrntEnrgyPickups ;Reset current missile and energy power-up counters. 1383L8B1F: LDA RandomNumber1 ; 1384L8B21: AND #$0F ;Randomly recalculate max missile pickups(16 max, 0 min). 1385L8B23: STA MaxMissilePickup ; 1386L8B25: ASL ; 1387L8B26: ORA #$40 ;*2 for energy pickups and set bit 6(128 max, 64 min). 1388L8B28: STA MaxEnergyPickup ;
Source_Files/Bank01.asm lines 1381–1388 at 4270d57 · upstream ↗ 4584 LDY MaxMissilePickup 4585 CPY CrntMslePickups 4586 BEQ LDD5B 4587 LDA MaxMissiles 4588 BEQ LDD5B 4589 INC CrntMslePickups ⋮ 4594 BEQ LDD5B 4595 INC CrntEnrgyPickups 4596 CMP #$89 4597 BNE -- 4598 LSR $00 4599 BCS --
Source_Files/Bank07.asm lines 4584–4599 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 1 $8B1B-$8B29, the reset in SamusEnterDoor; each area bank has its own copy; bank 7, the drop code. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Revised after a check by a second AI model, 2026-10-21: A withheld $89 drop still counts toward the cap.
- ^ abc
SetUpDroppedItemsorts a dead monster's type into one of four drop groups by three type lists, with every unlisted type in the fourth; seven types, among them the Gels, the Keese, and the Like Like, drop nothing.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
11030; Types of objects that do not drop items. ⋮ 11032NoDropMonsterTypes: 11033 .BYTE $5D, $14, $15, $1B, $1C, $1D, $17 ⋮ 11035DropItemMonsterTypes0: 11036 .BYTE $07, $08, $0E, $04, $0F, $23 ⋮ 11038DropItemMonsterTypes1: 11039 .BYTE $21, $22, $0D, $10, $13, $28, $2A, $27 11040 .BYTE $16 ⋮ 11042DropItemMonsterTypes2: 11043 .BYTE $09, $0A, $03, $01, $12, $06, $0B, $24 11044 .BYTE $30
src/Z_04.asm lines 11030–11044 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 4 $B01B, the lists, tables, and SetUpDroppedItem. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcWhen
WorldKillCount, the kills since Link was last hurt, equals 16 and the monster can drop items, the drop is a fairy, whatever its random byte.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
11145 ; If the global kill count = $10, set the dropped item to a fairy. 11146 LDA #$23 11147 LDY WorldKillCount 11148 CPY #$10 11149 BEQ @SetHelpItem
src/Z_04.asm lines 11145–11149 at 50a1c86 · upstream ↗ 5996HandleMonsterDied: 5997 ; Handle the monster dying. 5998 INC WorldKillCount
src/Z_01.asm lines 5996–5998 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 4, as in drop-groups. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcThe 10th kill since Link was last hurt brings a guaranteed drop of 5 rupees, or of bombs when that 10th kill was by bomb, and the count starts again from 0.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”
How we know
6000 ; Increase the help drop counter, if not at max ($A). 6001 LDA HelpDropCount 6002 CMP #$0A 6003 BCS @SetDyingMetastate 6004 INC HelpDropCount ⋮ 6006 ; If the help drop counter has reached the max, and damage type = bomb (8); 6007 ; then set [51] HelpDropValue in order to drop a bomb next time.
src/Z_01.asm lines 6000–6007 at 50a1c86 · upstream ↗ 11151 ; If help drop counter < $A, then use the dropped item ID as is. 11152 ; But there is a random chance that the item drop will be canceled. ⋮ 11157 ; Otherwise, the item will be guaranteed to be made. 11158 ; [51] HelpDropValue determines which kind: 11159 ; - 0: 5 rupees 11160 ; - other: bomb ⋮ 11172 STA HelpDropCount 11173 STA HelpDropValue
src/Z_04.asm lines 11151–11173 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 4, as in drop-groups. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abWhenever Link is hurt, the game zeroes
WorldKillCount,HelpDropCount, andHelpDropValue, the counters behind the fairy and the 10th-kill drops.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
5759@ResetHelp: 5760 ; Reset values used in special item drops. 5761 LDA #$00 5762 STA WorldKillCount 5763 STA HelpDropCount 5764 STA HelpDropValue
src/Z_01.asm lines 5759–5764 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 1, as in ring. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcCalled in Rev 1 for every group, kill-cycle column, and value of the random byte,
SetUpDroppedItemdrops in 800, 1,520, 1,040, and 1,040 of 2,560 cases for groups A to D, each the item its column names; it gives a fairy at a kill count of 16, and 5 rupees or bombs at a help count of 10.Verified“Legend of Zelda, The (USA) (Rev 1)” · aldonunez/zelda1-disassemblyHow we know
In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 4, the routine and tables the probe calls. We don't reproduce the bytes.
11138 LDA DropItemSetBaseOffsets, Y ⋮ 11140 ADC WorldKillCycle ⋮ 11142 LDA DropItemTable, Y ⋮ 11147 LDY WorldKillCount 11148 CPY #$10 ⋮ 11153 LDA HelpDropCount 11154 CMP #$0A ⋮ 11180 LDA Random, X 11181 CMP DropItemRates, Y 11182 BCS @DestroyMonster
src/Z_04.asm lines 11070–11201 at 50a1c86 · upstream ↗ Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Legend of Zelda, The (USA) (Rev 1) (SHA-1
4671517d72d0…). It fails if the result disagrees with the claim.The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.
Checked by a second AI model, 2026-10-21.
Checked by a second AI model, 2026-10-25.
- ^In
TakeItem, item$18is a rupee,$0Ffive rupees,$22a heart,$23a fairy,$21the clock, and$00four bombs; a heart restores 1 heart and a fairy 3.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”How we know
4318ItemIdToSlot: 4319 .BYTE $01, $00, $00, $00, $06, $05, $04, $04 4320 .BYTE $02, $02, $03, $0D, $09, $0C, $1B, $1C 4321 .BYTE $08, $0A, $0B, $0B, $0E, $0F, $10, $11 4322 .BYTE $16, $17, $18, $1A, $1F, $1D, $1E, $07 4323 .BYTE $07, $15, $19, $14 ⋮ 4341ItemIdToDescriptor: 4342 .BYTE $14, $21, $22, $23, $01, $01, $21, $22 4343 .BYTE $21, $22, $01, $01, $01, $01, $01, $15 4344 .BYTE $01, $01, $21, $22, $01, $01, $01, $01 4345 .BYTE $11, $11, $10, $01, $01, $01, $01, $11 4346 .BYTE $22, $01, $10, $12
src/Z_01.asm lines 4318–4346 at 50a1c86 · upstream ↗ 4540 CPY #$18 ; Heart container item slot 4541 BEQ @TakeHeartContainer 4542 CPY #$1C ; 5 Rupees item slot 4543 BEQ Take5Rupees 4544 CPY #$16 ; Rupee item slot 4545 BEQ @TakeRupee
src/Z_01.asm lines 4540–4545 at 50a1c86 · upstream ↗ 4651TakeHeartsNoSound: 4652 LDA $0A ; Move item value in [0A] to [01]. 4653 STA $01 ; [01] holds the number of hearts to add minus 1.
src/Z_01.asm lines 4651–4653 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 1 TakeItem through the heart routines, run from RAM at $7370. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^A dropped item lasts 255 decrements of its lifetime, one every other frame, about 510 frames, and Link can't take it until the 16th decrement, about 32 frames.Codealdonunez/zelda1-disassembly · “Legend of Zelda, The (USA) (Rev 1)”revised
How we know
11206UpdateItem: 11207 ; Every other frame, decrement the item lifetime. 11208 LDA FrameCounter 11209 LSR 11210 BCC :+ 11211 DEC Item_ObjItemLifetime, X ⋮ 11213 ; If lifetime reached 0, go destroy the object. 11214 LDA Item_ObjItemLifetime, X 11215 BEQ DestroyMonster_Bank4
src/Z_04.asm lines 11206–11215 at 50a1c86 · upstream ↗ 4417 ; [03A8][X] is used to count down the life of the item. 4418 LDA Item_ObjItemLifetime, X 4419 CMP #$F0 4420 BCS L6C28_Exit
src/Z_01.asm lines 4416–4420 at 50a1c86 · upstream ↗ In the cartridge (“Legend of Zelda, The (USA) (Rev 1)”): bank 4 UpdateItem, $B0FC. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Revised after a check by a second AI model, 2026-10-21: Pickup is blocked for 16 lifetime decrements, not 15.
- ^In both US releases a killed enemy's byte in
itemDropTablespicks a chance and a drop set, and two random values decide the drop. The first picks one bit of a 64-bit chance mask (computed, 1 in 16 to always); the second picks one of the set's 32 entries, which Seasons first maps through a Subrosia set when Link is in Subrosia. A drop Link can't use yet, such as bombs or seeds he hasn't found, becomes no drop. An Octorok drops something 24 times in 64; its set holds 16 hearts, 12 single rupees, and 4 five-rupee pieces.CodeStewmath/oracles-disasmHow we know
28 xor a 29 call decideItemDrop 30 jp z,partDelete 31 ld b,PART_ITEM_DROP
object_code/common/parts/enemyDestroyed.s lines 28–31 at 21c924a · upstream ↗ 761; Decides what an enemy will drop. ⋮ 766decideItemDrop_body: ⋮ 780 ld hl,itemDropTables 781 rst_addAToHl ⋮ 790 ld hl,itemDropProbabilityTable ⋮ 795 call getRandomNumber 796 and $3f 797 call checkFlag ⋮ 801 and $1f 802 ld hl,itemDropSetTable ⋮ 807 call getRandomNumber 808 and $1f ⋮
code/treasureAndDrops.s lines 761–811 at 21c924a · upstream ↗ 814; Checks whether an item drop of a given type can spawn. ⋮ 817; @param[out] c $ff if item cannot spawn (Link doesn't have it), otherwise the item itself ⋮ 819.ifdef ROM_SEASONS 820 ; different drop table for subrosia
code/treasureAndDrops.s lines 813–845 at 21c924a · upstream ↗ 896; Byte 1: Value to AND with that variable to check availability; if nonzero, the item 897; can drop. 898itemDropAvailabilityTable:
code/treasureAndDrops.s lines 894–920 at 21c924a · upstream ↗ 421wc608: ; $c608 422; This is always 1. Used as a dummy value in various places?
include/wram.s lines 421–423 at 21c924a · upstream ↗ 923; Each entry in this table is a bitset. A random bit is chosen. If the bit is 0, no item drops. 924itemDropProbabilityTable: ⋮ 934@probability0: 935@probability1: ⋮ 953@probability7:
code/treasureAndDrops.s lines 923–956 at 21c924a · upstream ↗ 1061itemDropSetE:code/treasureAndDrops.s lines 1061–1065 at 21c924a · upstream ↗ 1074; Bits 5-7: Index for itemDropProbabilityTable 1075; Bits 0-4: Index for itemDropSetTable 1076; Or it can be $ff for no item drop. 1077; Comments show changes in Seasons 1078itemDropTables: 1079.ifdef ROM_AGES
code/treasureAndDrops.s lines 1073–1081 at 21c924a · upstream ↗ 1098.elsecode/treasureAndDrops.s lines 1098–1100 at 21c924a · upstream ↗ 39.define ENEMY_OCTOROK $09constants/common/enemies.s line 39 at 21c924a · upstream ↗ 5 ITEM_DROP_FAIRY db ; $00 6 ITEM_DROP_HEART db ; $01 7 ITEM_DROP_1_RUPEE db ; $02 8 ITEM_DROP_5_RUPEES db ; $03
constants/common/itemDrops.s lines 4–8 at 21c924a · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abcdItem
$89drops only for an enemy whose byte in the area's table at$968Bhas bit 0 set, and Samus collects it as 20 units of energy; the table's comment calls it "No item".Codenmikstas/metroid-disassembly · “Metroid (USA)”How we know
4592* LDY MaxEnergyPickup 4593 CPY CrntEnrgyPickups 4594 BEQ LDD5B 4595 INC CrntEnrgyPickups 4596 CMP #$89 4597 BNE -- 4598 LSR $00 4599 BCS --
Source_Files/Bank07.asm lines 4592–4599 at 4270d57 · upstream ↗ 8534LF74B: ldy EnDataIndex,x 8535 lda $968B,y
Source_Files/Bank07.asm lines 8534–8535 at 4270d57 · upstream ↗ 8203 ldy #$00 8204 ldx #$03 8205 pla 8206 bne ++ 8207 dex 8208 pla 8209 cmp #$81 8210 bne + 8211 ldx #$00 ;Increase HealthHi by 0. 8212 ldy #$50 ;Increase HealthLo by 5. ⋮ 8215 sty HealthLoChange 8216 stx HealthHiChange
Source_Files/Bank07.asm lines 8203–8216 at 4270d57 · upstream ↗ 1878L968B: .byte $01, $01, $01, $00, $86, $04, $89, $80, $81, $00, $00, $00, $82, $00, $00, $00Source_Files/Bank01.asm line 1878 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7 $F483, the pickup code; bank 1 $968B, Brinstar's table. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^Until the first door, the caps on missile and energy drops are 39 when the game starts in Brinstar, because
SamusInitstores the mirroring value$27into them, or 47 ($2F) elsewhere.Codenmikstas/metroid-disassembly · “Metroid (USA)”How we know
1564 LDY #$27 1565 LDA InArea 1566 AND #$0F 1567 BEQ + ;Branch if Samus starting in Brinstar. 1568 LSR ScrollDir ;If not in Brinstar, change scroll direction from left 1569 LDY #$2F ;to down. and set PPU for horizontal mirroring. 1570 * STY MirrorCntrl ; 1571 STY MaxMissilePickup 1572 STY MaxEnergyPickup
Source_Files/Bank07.asm lines 1564–1572 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7 SamusInit, $C8D1. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abA small energy ball gives Samus 5 units and a
$89ball 20; a missile gives 2 missiles; an enemy whose data index carries the 30-unit flag gives 30 units or 30 missiles instead.Codenmikstas/metroid-disassembly · “Metroid (USA)”How we know
8203 ldy #$00 8204 ldx #$03 8205 pla 8206 bne ++ 8207 dex 8208 pla ⋮ 8210 bne + ⋮ 8220PickupMissile: 8221 lda #$02 8222 ldy EnDataIndex,x 8223 beq + 8224 lda #$1E
Source_Files/Bank07.asm lines 8203–8224 at 4270d57 · upstream ↗ 4566 JSR LF74B 4567 STA $00 4568 JSR $80B0 4569 AND #$20 4570 STA EnDataIndex,x
Source_Files/Bank07.asm lines 4566–4570 at 4270d57 · upstream ↗ 89L80B0: LDY EnDataIndex,X 90L80B3: LDA $977B,Y 91L80B6: ASL ;*2
Source_Files/Bank01.asm lines 89–91 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7 $F483, the pickup code. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcIn Tourian, enemies with data index 2 or 4 drop nothing, and any other kill that would drop nothing resets both caps to 1 and both counts to 0 and rolls the same
RandomNumber1again, skipping the test for 16.Codenmikstas/metroid-disassembly · “Metroid (USA)”How we know
4555LDCFC: LDA InArea 4556 CMP #$13 4557 BNE + 4558 LDA EnDataIndex,x 4559 CMP #$04 4560 BEQ +++++ 4561 CMP #$02 4562 BEQ +++++
Source_Files/Bank07.asm lines 4555–4562 at 4270d57 · upstream ↗ 4601LDD5B: ldx PageIndex 4602 lda InArea 4603 cmp #$13 4604 beq ++ 4605* jmp KillObject ;($FA18)Free enemy data slot. ⋮ 4607* lda RandomNumber1 4608 ldy #$00 4609 sty CrntEnrgyPickups 4610 sty CrntMslePickups 4611 iny 4612 sty MaxMissilePickup 4613 sty MaxEnergyPickup ⋮
Source_Files/Bank07.asm lines 4601–4614 at 4270d57 · upstream ↗ In the cartridge (“Metroid (USA)”): bank 7, the drop code. We don't reproduce the bytes.
Checked against the evidence by its author, an AI model, 2026-10-20.
Checked by a second AI model, 2026-10-21.
- ^ abcCalled in the ROM for all 256 values of
RandomNumber1, the drop code gives a Brinstar enemy of data index 0 60 missiles, 90 small energy balls, 90$89balls, and 16 nothing; index 3, whose byte in the tableLF74Breads ($968B+ data index, kept in$00) has bit 0 clear, gives 106 nothing and no$89.Verified“Metroid (USA)” · nmikstas/metroid-disassemblyrevisedHow we know
In the cartridge (“Metroid (USA)”): bank 7 $DCFC, the code the probe calls with Brinstar's bank mapped. We don't reproduce the bytes.
4566 JSR LF74B 4567 STA $00 ⋮ 4575 LDA RandomNumber1 4576 CMP #$10 4577 BCC LDD5B 4578* AND #$07 4579 TAY 4580 LDA ItemDropTbl,y ⋮ 4596 CMP #$89 4597 BNE -- 4598 LSR $00 4599 BCS --
Source_Files/Bank07.asm lines 4555–4614 at 4270d57 · upstream ↗ 8535 lda $968B,y 8536 rts
Source_Files/Bank07.asm lines 8534–8536 at 4270d57 · upstream ↗ Measured by a script in MesenCE 2.2.1 (build 4b8a196), on Metroid (USA) (SHA-1
2080059bea45…). It fails if the result disagrees with the claim.The numbers come from the run; its author, an AI model, checked the script measures what the claim says, 2026-10-25.
Checked by a second AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-25.
Sources
Code
- Núñez, Aldo. 2021. “zelda1-disassembly: A complete disassembly of The Legend of Zelda.” Commit 50a1c86. aldonunez/zelda1-disassembly @ 50a1c86 · licence, all uses
- n.d. “Legend of Zelda, The (USA) (Rev 1).” · licence, all uses
- nmikstas and Kent Hansen. 2025. “metroid-disassembly: Metroid software disassembly.” Commit 4270d57. nmikstas/metroid-disassembly @ 4270d57 · licence, all uses
- n.d. “Metroid (USA).” · licence, all uses
- (spannerisms), kan. 2026. “usdasm: A Link to the Past US Disassembly.” Commit bcdd96e. spannerisms/usdasm @ bcdd96e · licence, all uses
- metroidret contributors. 2026. “mf: a decompilation of Metroid Fusion (metroidret/mf).” Commit a6d6187. metroidret/mf @ a6d6187 · licence, all uses