-
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 will refer 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).
- Defining All of the New Constants
- Creating the Necessary Graphics Files
- Editing the Remaining Data Files
- Updating the Card Album
- Awarding the Booster Pack to the Player
Before we begin modifying any of the data or engine files, we should establish all of the constants that will be used throughout this tutorial. A lot of important information is organized into a series of numerical IDs, and these IDs are given labels to help us make sense of this information when we encounter them throughout the disassembly.
Let's start with the obvious constants. Begin by opening src/constants/booster_constants.asm, and add a constant for the new booster 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. For the purposes of this tutorial, we'll just add a single "Neutral" variant for the new booster pack at the end of the list, 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.
...
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 card set will contain. For this example, let's assume that it will contain only 10 cards, which is essentially the minimum amount since that's how many cards a booster pack contains. The absolute maximum number of cards that a card set 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 constant will need to be added to src/constants/scene_constants.asm as well. This is for the small cutscene that plays after the player receives a booster pack.
...
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 will be added in the following step. That includes 2 more tilemaps (DMG and CGB) 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.
...
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
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.).
RGBDS won't be able to use these .png files, but when it comes time to build the game, rgbgfx will use them to generate .2bpp files, which can then be stored within the rom file.
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 it and the .bin file from the next instruction using Tilemap Studio.
Just like with the .2bpp files from the first instruction, both genesis.bgmap
and genesis.bgmap.lz
will be generated upon compiling 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
. You can edit this file as well, but I don't know of any specific program that will make the process easier.
Now, we'll 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. If none exist, you'll need to add a new SECTION (e.g. Gfx 13) and then assign it to a rom bank in src/layout.link.
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
Unsurprisingly, 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. If you recall, we only decided to add the one "Neutral" variant for this tutorial, but remember to define any other variants that were assigned constants during Step 1. 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. (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
We'll have to make a quick detour before we resume editing the rest of the data files since GenesisBoosterText
doesn't yet exist. All of the game's text is located in src/text. You can either replace an unused text or add it to any of the text files that isn't full.
You may want to look at the Add New Text tutorial if you're still unfamiliar with the process. (If you're using poketcg_v2, make sure to again replace all instances of GenesisBoosterText
with GenesisName
.)
GenesisBoosterText:
text "Genesis"
done
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 2, 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 that the number of cards assigned to your new booster pack matches the set total that was recorded during Step 1, and you should also note that it's a good idea to have at least as many cards in the set as there are in a booster pack. For this tutorial, that means that we need to assign 10 cards to the new Genesis set: 6 Commons, 3 Uncommons and 1 Rare.
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
Moving on, it's 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
+ ldtx hl, Item6PromotionalCardText
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, Item5GenesisText
+ 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; although, there are a couple of other changes that will need to be made. You should add another entry under .CardSetTotals
between the ones for CARD_SET_LABORATORY and CARD_SET_PROMOTIONAL (assuming you didn't already do so during Step 1). You should also add another entry under .SetNames
for GenesisName
, this time between LaboratoryName
and PromotionalName
.
...
; 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. First, we'll open src/text/text2.asm, and update Item5PromotionalCardText
.
-Item5PromotionalCardText:
- text " 5. Promotional Cards"
+Item6PromotionalCardText:
+ text " 6. Promotional Cards"
done
You'll also need to open src/text/text_offsets.asm and rename the label for its pointer.
- textpointer Item5PromotionalCardText
+ textpointer Item6PromotionalCardText
Plus, we referenced another text that doesn't yet exist. Again, you can either replace an unused text or add it to any of the text files that isn't full, and you can reference the Add New Text tutorial if you're still unfamiliar with the process.
Item5GenesisText:
text "5. Genesis"
done
If you're using poketcg_v2, then you'll have to define GenesisText
from BoosterNamesTextIDTable
too. It's identical to GenesisBoosterText
/GenesisName
, except that its contents are printed using fullwidth text (8x8 pixel characters) instead of halfwidth text (4x8 pixel characters).
GenesisText:
textfw "Genesis"
done
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