-
Notifications
You must be signed in to change notification settings - Fork 93
Add a New Booster Pack
This tutorial will explain how to add a new booster pack to the game. This guide refers to the new booster pack as Genesis, but you can use whatever name you like. Some versions of poketcg will have different function labels. While this guide will focus on the current disassembly, labels from other repositories will occasionally be noted (primarily poketcg_v2).
- Creating the Necessary Graphics Files
- Editing the Remaining Data Files
- Updating the Card Album
- Defining All of the New Constants
- Awarding the Booster Pack to the Player
To start things off, go to src/gfx/booster_packs. Create a copy of the laboratory1.png
file, and name it genesis1.png
. Then, create a copy of laboratory2.png
, and name it genesis2.png
. Since this is merely a tutorial, we won't be going further than that, but if you wish to design your own graphic, feel free to edit the files in your preferred image editing program (e.g. Asesprite, GIMP, Paint.NET, etc.).
When you eventually make
the rom file, RGBDS will detect these new .png files and convert them to .2bpp files which will later be stored within the rom.
The next file will be added to src/data/maps/tiles/dimensions. This time, create a copy of laboratory.dimensions
, and name it genesis.dimensions
. Technically, all of the booster pack images have the same dimensions, so there's no need to edit this file.
Moving on, go to src/data/maps/tiles/cgb, and create a copy of laboratory.bin
with the name genesis.bin
. Feel free to edit this and any of the other .bin files that we will be creating.
Just like with the .2bpp files from the first instruction, RGBDS will create both genesis.bgmap
and genesis.bgmap.lz
when you compile the rom. You can also ignore any *.match` files; they ensure that the repository's data is identical to what exists in the original game, which is irrelevant since we're modifying the original game.
If your game still supports the original Game Boy (DMG), then you'll also need to create a copy of laboratory.bin
in src/data/maps/tiles/gb, again renaming it genesis.bin
.
And if your game still supports the Super Game Boy, then you'll need to create one last binary file with the relevant palette information in src/data/sgb_data, so copy laboratory_booster_pals.bin
and name the new file genesis_booster_pals.bin
.
We now need to add a few lines to src/engine/sgb.asm so that the corresponding .lz file will be included when we build the rom.
SGBData_LaboratoryBooster:
dw $20 ; length
INCBIN "data/sgb_data/laboratory_booster_pals.bin.lz"
+SGBData_GenesisBooster:
+ dw $20 ; length
+ INCBIN "data/sgb_data/genesis_booster_pals.bin.lz"
+
SGBData_PlayerPortraitPals:
Let's do the same with the rest of the files that we just added to the repository. Open src/gfx.asm and add the following to any SECTION that has the requisite space.
Genesis1Gfx::
dw 96
INCBIN "gfx/booster_packs/genesis1.2bpp"
Genesis2Gfx::
dw 86
INCBIN "gfx/booster_packs/genesis2.2bpp"
GenesisTilemap::
INCBIN "data/maps/tiles/dimensions/genesis.dimensions"
dw NULL
db FALSE ; cgb mode
INCBIN "data/maps/tiles/gb/genesis.bin.lz"
GenesisCGBTilemap::
INCBIN "data/maps/tiles/dimensions/genesis.dimensions"
dw NULL
db TRUE ; cgb mode
INCBIN "data/maps/tiles/cgb/genesis.bgmap.lz"
The final task will be to add this new information to the tilemap and tileset tables.
First, add another 2 entries to Tilemaps
in src/engine/gfx/tilemaps.asm.
Tilemaps:
...
tilemap CopyrightCGBTilemap, TILESET_COPYRIGHT ; TILEMAP_COPYRIGHT_CGB
tilemap NintendoTilemap, TILESET_NINTENDO ; TILEMAP_NINTENDO
tilemap CompaniesTilemap, TILESET_COMPANIES ; TILEMAP_COMPANIES
+ tilemap GenesisTilemap, TILESET_GENESIS_1 ; TILEMAP_GENESIS
+ tilemap GenesisCGBTilemap, TILESET_GENESIS_2 ; TILEMAP_GENESIS_CGB
assert_table_length NUM_TILEMAPS
And then, add the corresponding entries to Tilesets
in src/engine/gfx/tilesets.asm
Tilesets:
...
tileset JessicaGfx, 36 ; TILESET_JESSICA
tileset StephanieGfx, 36 ; TILESET_STEPHANIE
tileset AaronGfx, 36 ; TILESET_AARON
+ tileset Genesis1Gfx, 96 ; TILESET_GENESIS_1
+ tileset Genesis2Gfx, 86 ; TILESET_GENESIS_2
assert_table_length NUM_TILESETS
The main booster pack data can be found at src/data/booster_packs.asm. First, we need to define the rarity distribution, located at the top of the file. As always, you can adjust these ratios however you wish, but for this tutorial, we'll simply copy the distribution used for Laboratory, namely 0 Energy cards, 6 Common cards, 3 Uncommon cards and 1 Rare card.
BoosterSetRarityAmountsTable:
; db energies, commons, uncommons, rares
; commons + uncommons + rares needs to be equal to 10 minus the number of energy cards
; defined in the pack's data below; otherwise, the number of cards in the pack won't be 10.
db 1, 5, 3, 1 ; COLOSSEUM
db 1, 5, 3, 1 ; EVOLUTION
db 0, 6, 3, 1 ; MYSTERY
db 0, 6, 3, 1 ; LABORATORY
+ db 0, 6, 3, 1 ; GENESIS
The rest of the file is comprised of specialized variants for each of the booster packs, each with its own card type ratios. For the purposes of this tutorial, we'll simply add a single "Neutral" variant for the new booster pack, but you can create however many you feel is appropriate. Most of the other booster packs have a different version for each of the Pokémon types/Card Clubs. You can insert the new booster variant(s) anywhere in src/data/booster_packs.asm, but we'll just place this one at the end of the file.
BoosterPack_RandomEnergies::
...
db 0 ; Colorless Type Chance
db 0 ; Trainer Card Chance
db 0 ; Energy Card Chance
+BoosterPack_GenesisNeutral::
+ booster_set GENESIS ; booster pack set
+ dw NULL ; energy or energy generation function
+
+; Card Type Chances
+ db 20 ; Grass Type Chance
+ db 20 ; Fire Type Chance
+ db 20 ; Water Type Chance
+ db 20 ; Lightning Type Chance
+ db 20 ; Fighting Type Chance
+ db 20 ; Psychic Type Chance
+ db 20 ; Colorless Type Chance
+ db 20 ; Trainer Card Chance
+ db 0 ; Energy Card Chance
+
We now need to reference the data that was just created. Open src/engine/booster_packs.asm, and scroll down to BoosterDataJumpTable
. Add an entry for the neutral variant that we defined during the previous step. If you created additional variants, then you'll need to add entries for them as well.
BoosterDataJumptable:
...
dw BoosterPack_EnergyWaterFighting
dw BoosterPack_EnergyGrassPsychic
dw BoosterPack_RandomEnergies
+ dw BoosterPack_GenesisNeutral
assert_table_length NUM_BOOSTERS
Next, open src/engine/menus/give_booster_pack.asm, and add a similar entry to BoosterTypes
, using the same order from BoosterDataJumpTable
.
BoosterTypes:
...
db BOOSTER_COLOSSEUM ; BOOSTER_ENERGY_WATER_FIGHTING
db BOOSTER_COLOSSEUM ; BOOSTER_ENERGY_GRASS_PSYCHIC
db BOOSTER_COLOSSEUM ; BOOSTER_ENERGY_RANDOM
+ db BOOSTER_GENESIS ; BOOSTER_GENESIS_NEUTRAL
assert_table_length NUM_BOOSTERS
We should also put another entry at the end of BoosterScenesAndNameTexts
in the same file. Technically, GenesisBoosterText
doesn't yet exist, but we'll create it at the end of the next step with the other new texts. If you're using poketcg_v2, you should replace GenesisBoosterText
with GenesisName
.
BoosterScenesAndNameTexts
...
db SCENE_LABORATORY_BOOSTER, SCENE_LABORATORY_BOOSTER
tx LaboratoryBoosterText
+
+ db SCENE_GENESIS_BOOSTER, SCENE_GENESIS_BOOSTER
+ tx GenesisBoosterText
_PauseMenu_Exit:
ret
More data pertaining to the booster pack scenes can be found in src/data/scenes.asm. First, add an entry to ScenePointers
.
ScenePointers:
...
dw Scene_Copyright
dw Scene_JapaneseTitleScreen2
dw Scene_ColorPalette
+ dw Scene_GenesisBooster
assert_table_length NUM_SCENES
Then, define that scene at the end of the file. The palettes were simply copied from Scene_LaboratoryBooster
; however, if you designed your own booster pack graphic during Step 1, then you can change PALETTE_104 to whatever palette the new graphic uses. If it's a custom palette, you'll first need to define that somewhere and then add an entry to Palettes
in src/data/palette_pointers.asm.
Scene_JapaneseTitleScreen2:
dw NULL
dw NULL
db PALETTE_109, PALETTE_100, $00
db TILEMAP_JAPANESE_TITLE_SCREEN_2, TILEMAP_JAPANESE_TITLE_SCREEN_2_CGB, $01, $00
db $00
+Scene_GenesisBooster:
+ dw SGBData_GenesisBooster
+ dw NULL
+ db PALETTE_108, PALETTE_104, $01
+ db TILEMAP_GENESIS, TILEMAP_GENESIS_CGB, $80, $00
+ db SPRITE_BOOSTER_PACK_OAM
+ db PALETTE_117, PALETTE_117, $00
+ db $ff, SPRITE_ANIM_189, $00, $00
+ dw $00
+
Finally, none of the previous information matters if there aren't any cards in the Genesis set. We can assign some of the cards in the game to the new booster pack by editing src/data/cards.asm. The following example will show how to move the Bulbasaur card from the Evolution set to the Genesis set, but you can edit whichever cards you want. Just be sure to adjust the total number of cards in the set during Step 4 to match the number of cards that were assigned to the new booster. It's also a good idea to have at least as many cards in the set as there are in the booster pack. For this example, that means putting at least 6 Common cards, 3 Uncommon cards and 1 Rare card in the Genesis set.
BulbasaurCard:
db TYPE_PKMN_GRASS ; type
gfx BulbasaurCardGfx ; gfx
tx BulbasaurName ; name
db CIRCLE ; rarity
- db EVOLUTION | NONE ; sets
+ db GENESIS | NONE ; sets
db BULBASAUR
db 40 ; hp
db BASIC ; stage
dw NONE ; pre-evo name
It's also important that we include the new booster pack in the Card Album, which can be accessed from the PC menu. There's a lot to edit, but fortunately it's all contained inside the one file: src/engine/menus/card_album.asm.
To start things off, go to CreateCardSetListAndInitListCoords
, and add another section before the one for Laboratory.
.GetEntryPrefix
push af
cp CARD_SET_PROMOTIONAL
- jr nz, .laboratory
+ jr nz, .genesis
lb de, TX_FULLWIDTH3, "FW3_P"
jr .got_prefix
+.genesis
+ cp CARD_SET_GENESIS
+ jr nz, .laboratory
+ lb de, TX_FULLWIDTH3, "FW3_E"
+ jr .got_prefix
.laboratory
cp CARD_SET_LABORATORY
jr nz, .mystery
...
If you're using poketcg_v2 or if you simply copied the commit for preventing header text from being overwritten, then you'll also need to add another entry to BoosterNamesTextIDTable
, which is located just below .GetEntryPrefix
.
Still in the same file, find the CardAlbum
function and scroll down to .BoosterPackMenuParams
(.SetSelectionMenuParams
in poketcg_v2 and .MenuParameters
in Pokémon TCG Neo). We'll be increasing the number of menu items that are displayed as well as the spacing between them. Removing the double spacing is a simple workaround that should suffice for now. A better solution would be to have the items be scrollable, but that requires a bit more work. It will probably be added to the tutorial eventually.
.BoosterPackMenuParams:
db 3, 3 ; cursor x, cursor y
- db 2 ; y displacement between items
+ db 1 ; y displacement between items
- db 5 ; number of items
+ db 6 ; number of items
db SYM_CURSOR_R ; cursor tile number
db SYM_SPACE ; tile behind cursor
dw NULL ; function pointer if non-0
Scroll down even further to .PrintCardCount
to set up the card album header for the new booster. (This edit isn't necessary in poketcg_v2.)
.PrintCardCount
...
; print the total number of cards that are in the Card Set
ld a, [wSelectedCardSet]
cp CARD_SET_PROMOTIONAL
- jr nz, .check_laboratory
+ jr nz, .check_genesis
; promotional
ldtx hl, Item5PromotionalCardText
ld e, NUM_CARDS_PROMOTIONAL - 2 ; minus the phantom cards
ld a, [wOwnedPhantomCardFlags]
bit VENUSAUR_OWNED_PHANTOM_F, a
jr z, .check_owns_mew
inc e
.check_owns_mew
bit MEW_OWNED_PHANTOM_F, a
jr z, .has_card_set_count
inc e
jr .has_card_set_count
+.check_genesis
+ cp CARD_SET_GENESIS
+ jr nz, .check_laboratory
+ ldtx hl, Item6GenesisText
+ ld e, NUM_CARDS_GENESIS
+ jr .has_card_set_count
.check_laboratory
cp CARD_SET_LABORATORY
jr nz, .check_mystery
...
When the player doesn't have any Promotional Cards, the game replaces that menu option with a series of dashes. Since the coordinates of the menu items were changed, we need to update the printing coordinates for EmptyPromotionalCardText
. This is handled in the same function under .draw_box
(.skip_clear_screen
in Pokémon TCG Neo), near the end of the file. (This edit also isn't necessary in poketcg_v2.)
...
; still has no promotional, print empty Card Set name
ld a, TRUE
ld [wUnavailableAlbumCardSets + CARD_SET_PROMOTIONAL], a
- ld e, 11
+ ld e, 8
ld d, 5
call InitTextPrinting
ldtx hl, EmptyPromotionalCardText
call ProcessTextFromID
...
The last thing to edit in src/engine/menus/card_album.asm is the list of menu data located at the end of the file, still within the CardAlbum
function. More specifically, the print coordinates for each of the booster pack names needs to be updated now that the menu items are single-spaced; there's also one more entry since we added another booster pack. (Note that the coordinates are different in poketcg_v2 and will need to be adjusted.)
.BoosterPacksMenuData
textitem 7, 1, BoosterPackTitleText
textitem 5, 3, Item1ColosseumText
- textitem 5, 5, Item2EvolutionText
- textitem 5, 7, Item3MysteryText
- textitem 5, 9, Item4LaboratoryText
- textitem 5, 11, Item5PromotionalCardText
+ textitem 5, 4, Item2EvolutionText
+ textitem 5, 5, Item3MysteryText
+ textitem 5, 6, Item4LaboratoryText
+ textitem 5, 7, Item5GenesisText
+ textitem 5, 8, Item6PromotionalCardText
db $ff
Before we move on to the next step, we'll need to edit some of the game's text data to comply with our recent changes. All of the text files are stored in src/text.
First, we'll open src/text/text2.asm, and update Item5PromotionalCardText
.
-Item5PromotionalCardText:
- text " 5. Promotional Cards"
+Item6PromotionalCardText:
+ text " 6. Promotional Cards"
done
Add the following 2 texts to any of the text files. You can either replace an unused text or add it to any of the files with extra space. (check here for a tutorial on adding new texts).
Item5GenesisText:
text "5. Genesis"
done
GenesisBoosterText:
text "Genesis"
done
Finally, open src/text/text_offsets.asm and update the pointers. The final 2 lines should be inserted in the same order as the actual texts; if you edited unused texts, then replace those labels.
- textpointer Item5PromotionalCardText
+ textpointer Item6PromotionalCardText
...
+ textpointer Item5GenesisText
+ textpointer GenesisBoosterText
If you're using poketcg_v2, you should replace both instances of GenesisBoosterText
in the above examples with GenesisName
and also create a 3rd text with the following contents. Remember to update text_offsets.asm as well.
GenesisText:
textfw "Genesis"
done
We're not quite done. We must define all of the new constants that were referenced during the previous steps.
First, go to src/constants/booster_constants.asm, and add a constant for the new pack after the one for Laboratory:
const_def
const BOOSTER_COLOSSEUM ; $00
const BOOSTER_EVOLUTION ; $01
const BOOSTER_MYSTERY ; $02
const BOOSTER_LABORATORY ; $03
+ const BOOSTER_GENESIS ; $04
const_def
const BOOSTER_COLOSSEUM_NEUTRAL ; $00
const BOOSTER_COLOSSEUM_GRASS ; $01
...
In the following section of the same file, you will see a list with each of the variants for every booster pack. If you recall, we only added the one "Neutral" variant earlier in the tutorial, but remember to add a constant for each of the variants that you decided to make during Step 2.
...
const BOOSTER_ENERGY_WATER_FIGHTING ; $1a
const BOOSTER_ENERGY_GRASS_PSYCHIC ; $1b
const BOOSTER_ENERGY_RANDOM ; $1c
+ const BOOSTER_GENESIS_NEUTRAL ; $1d
DEF NUM_BOOSTERS EQU const_value
DEF NO_BOOSTER EQU $ff
Next, go to src/constants/card_data_constants.asm, and update the set 1 constants by adding entries for the new booster pack. Make sure you put the new booster pack between CARD_SET_LABORATORY and CARD_SET_PROMOTIONAL, rather than at the end of each of the lists.
; card set constants (set 1)
const_def
const CARD_SET_COLOSSEUM ; $0
const CARD_SET_EVOLUTION ; $1
const CARD_SET_MYSTERY ; $2
const CARD_SET_LABORATORY ; $3
+ const CARD_SET_GENESIS ; $4
const CARD_SET_PROMOTIONAL ; $5
const CARD_SET_ENERGY ; $6
DEF NUM_CARD_SETS EQU const_value – 1
; CARD_DATA_SET constants (set 1)
DEF COLOSSEUM EQU CARD_SET_COLOSSEUM << 4
DEF EVOLUTION EQU CARD_SET_EVOLUTION << 4
DEF MYSTERY EQU CARD_SET_MYSTERY << 4
DEF LABORATORY EQU CARD_SET_LABORATORY << 4
+ DEF GENESIS EQU CARD_SET_GENESIS << 4
DEF PROMOTIONAL EQU CARD_SET_PROMOTIONAL << 4
DEF ENERGY EQU CARD_SET_ENERGY << 4
The next constant will need to be added to src/constants/menu_constants.asm. We'll be defining the total number of cards that the new booster pack will contain. For this example, let's assume that the new booster pack will contain only 10 cards. The absolute maximum number of cards that a booster pack can contain is defined in wram as 60 cards, but you should be able to use as many as 80 cards without running into any problems. Note that in poketcg_v2, these constants were deleted, and the information was moved to CardAlbum.CardSetTotals
in src/engine/menus/card_album.asm, as it was never referenced outside of that file/function.
DEF NUM_CARDS_COLOSSEUM EQU 56
DEF NUM_CARDS_EVOLUTION EQU 50
DEF NUM_CARDS_MYSTERY EQU 51
DEF NUM_CARDS_LABORATORY EQU 51
+ DEF NUM_CARDS_GENESIS EQU 10
DEF NUM_CARDS_PROMOTIONAL EQU 20
Another will need to be added to src/constants/scene_constants.asm.
...
const SCENE_COPYRIGHT ; $19
const SCENE_JAPANESE_TITLE_SCREEN_2_COPY ; $1a
const SCENE_COLOR_PALETTE ; $1b
+ const SCENE_GENESIS_BOOSTER ; $1c
DEF NUM_SCENES EQU const_value
The final constants are related to the graphics that we added at the beginning of the tutorial. That includes 2 more tilemaps in src/constants/tilemap_constants.asm...
...
const TILEMAP_COPYRIGHT ; $66
const TILEMAP_COPYRIGHT_CGB ; $67
const TILEMAP_NINTENDO ; $68
const TILEMAP_COMPANIES ; $69
+ const TILEMAP_GENESIS ; $6a
+ const TILEMAP_GENESIS_CGB ; $6b
DEF NUM_TILEMAPS EQU const_value
...and 2 more tilesets in src/constants/tileset_constants.asm.
...diff
const TILESET_JESSICA ; $54
const TILESET_STEPHANIE ; $55
const TILESET_AARON ; $56
+ const TILESET_GENESIS_1 ; $57
+ const TILESET_GENESIS_2 ; $58
DEF NUM_TILESETS EQU const_value
The new booster pack is now in the game, but there isn't yet a way for the player to obtain it. In the original game, the primary way to acquire cards is to defeat NPC duelists, as each duelist can reward up to 3 booster packs upon defeat.
For now, let's simply change Water Club Member Sara's 2nd pack to the neutral variant of the new Genesis booster. Open src/scripts/water_club.asm, scroll down to Script_BeatSara
, and edit the following line.
Script_BeatSara:
start_script
max_out_event_value EVENT_BEAT_SARA
print_npc_text SaraPlayerWon1Text
- give_booster_packs BOOSTER_COLOSSEUM_WATER, BOOSTER_COLOSSEUM_WATER, NO_BOOSTER
+ give_booster_packs BOOSTER_COLOSSEUM_WATER, BOOSTER_GENESIS_NEUTRAL, NO_BOOSTER
print_npc_text SaraPlayerWon2Text
quit_script_fully
You'll end up using the same constants regardless of how the booster pack is rewarded. For example, you could also switch the booster pack that Dr. Mason gives you alongside his initial e-mail by making the following change to PCMailBoosterPacks
in src/engine/menus/mail.asm.
PCMailBoosterPacks:
table_width 2, PCMailBoosterPacks
db $00, $00 ; unused
- db BOOSTER_COLOSSEUM_NEUTRAL, $00 ; mail 1
+ db BOOSTER_GENESIS_NEUTRAL, $00 ; mail 1
db BOOSTER_LABORATORY_PSYCHIC, $00 ; mail 2
db BOOSTER_EVOLUTION_GRASS, $00 ; mail 3