In DPPt and SuMo/USUM, the music for most areas of the overworld changes during the night, helping with the immersion in the game. In the original GSC, the only music that changes during the night is the [Johto Wild Battle](https://youtu.be/VGuuR0kQIgg) theme, [to a slower and "softer" theme](https://youtu.be/NlG-uj4GMnQ) (not even HGSS ported this music over). In this tutorial, we'll extrapolate the changes applied to that music to every overworld theme in the game, and implement a system that changes the music automatically during the night. We'll also add a new night version of the Kanto Wild Battle theme. ## Contents 1. [Understanding how the Johto Wild Battle Night version is programmed](#1-Understanding-how-the-Johto-Wild-Battle-Night-version-is-programmed) 2. [Adding a new Night version](#2-Adding-a-new-night-version) 3. [Adding the code that switches the music at night](#3-Adding-the-code-that-switches-the-music-at-night) 4. [Adding the rest of the music](#4-Adding-the-rest-of-the-music) 5. [Adding softer drumkits](#5-Adding-softer-drumkits) 6. [Adding a custom wave](#6-Adding-a-custom-wave) 7. [Adding the Kanto Wild Battle Night theme](#7-Adding-the-kanto-wild-battle-night-theme) 8. [Extra: Support for evening](#8-Support-for-evening) ## 1. Understanding how the Johto Wild Battle Night version is programmed You can skip this section, since knowing about how the original night song is programmed isn't necessary to the rest of the tutorial. But if you're curious about how the original night music is programmed or the music engine in general, this is a good way to get started. If you open the `johtowildbattlenight.asm` file, which contains this particular music, you'll immediately notice it's only 29 lines long, way too short to contain the entire song. This is because, unlike the Night versions in the later gens, this one reuses almost the entire code of the regular Day version. The file pretty much only contains the header defining the different channels (in this case, the Noise channel isn't used) and almost immediately calls the main loop of the Day version for each channel (as defined by the last command in each channel, `sound_loop`). In short, the differences between **the Day and Night version isn't the notes themselves, but the way they are played**. Here are the main differences between the two versions: * **Tempo:** The tempo of the song, as defined by the `tempo` command, is higher in the Night version (107 as opposed to 104). Note that the `tempo` command works in reverse to BPM: the higher it is, the slower the song plays. * **Duty Cycle:** The duty cycle of Channel 2 (which contains the melody) is always $3 (corresponds to a pulse of 75%) in the Day version, but is changed to $2 (corresponds to a pulse of 50%) for the main loop of the Night version. This gives a softer feel to the music. * **Channel 3 Waveform:** Unlike Channels 1 and 2, the third channel is programmable and can produce different waveforms from the restrictive "pulse" from the other two channels. The Gen 2 games use 10 different waveforms for their music, can be found in the `wave_samples.asm` file; some of these are close to a sine wave, making them very "soft", while others have more complex shapes and are much "sharper". The Night version of the Johto Wild Battle switches the wave sample $4 (which is relatively sharp) for wave sample $1, which is much softer. Apart from these changes, we're also going to make a small change to the Noise channel for the music which uses it: define new, lower noise notes to make the music even softer. ## 2. Adding a new Night version As an example, we'll add the Night version of New Bark Town into the game. [Here's a link to the file containing the original song, plus the night version at the bottom](https://pastebin.com/vhA3P0Xy), with the transformations we have covered earlier. Note that this file uses the depreciated music commands, but the file should still work fine in more recent versions of pokecrystal. Adding a new night version music to the game works exactly the same way as adding any other new song; [there's already a tutorial for that](https://github.com/pret/pokecrystal/wiki/Add-a-new-music-song), and the process here is mostly the same. Add the music pointer `Music_NewBarkTownNight` to the `music_pointers.asm` file and the new music constant `MUSIC_NEW_BARK_TOWN_NIGHT`. There's a slight caveat though: Instead of adding the Night version in a separate file like explained in sections 2 and 4 of the other tutorial, **you need to replace the entire original song with this new file**. There are two reasons for this: first, since the Night version reutilizes much of the same code as the Day version, both separate files would need to be in the same section; otherwise, the game wouldn't compile (if you noticed, both versions of the Johto Wild Battle are in the same section in the `audio.asm` file, although they are in separate files); second, the code of the original song was altered, essentially creating more subroutines that can be called as needed by the new Night version and thus reducing the need for redundant code. But don't worry, the original song will play in exactly the same way as before. However, if you try to compile the game, make will give you this error: `error: layout.link(156): Sections would extend past the end of ROMX`. The reason for this is because the music sections are very well compacted, which makes it difficult to add even a couple of new bytes corresponding to the new songs without overfilling a bank. A way to solve this is moving the altered song to a brand new section: Edit **audio.asm:** ```diff SECTION "Songs 1", ROMX ... INCLUDE "audio/music/championbattle.asm" INCLUDE "audio/music/ssaqua.asm" -INCLUDE "audio/music/newbarktown.asm" INCLUDE "audio/music/goldenrodcity.asm" ... +SECTION "Altered Songs", ROMX +INCLUDE "audio/music/newbarktown.asm" ``` Now it should work, and the new night version should be in the game! You can use it like any other song in the game, for example adding it to a specific map in New Bark Town. But the objective is to play this version only during the night, and in all maps that play the New Bark Town song. ## 3. Adding the code that switches the music at night The way we are going to make the game switch the music at night is by "hijacking" the code that loads the music into the wram. But first, we need a way to tell the game what are the "pairs" of songs we want to switch between. We are going to do that through a table. First, create the file **home/audionighttable.asm**: ```diff +NightMusicTable: +night_music: MACRO + db \1, \2 +ENDM + night_music MUSIC_NEW_BARK_TOWN, MUSIC_NEW_BARK_TOWN_NIGHT + db -1 ; end ``` Then include it in **home.asm** ```diff INCLUDE "home/sprite_anims.asm" INCLUDE "home/audio.asm" +INCLUDE "home/audionighttable.asm" INCLUDE "home/mobile.asm" ``` This file contains a table with two constants on each row: the first column has the Day version of a song, and the second column contains the Night version of the same song. On its own, this table doesn't do anything. We need the code to *actually* change the music when it's night. For that, we'll create a new function. Edit **home/map.asm**, adding this code at the end (thanks to [ISSOtm](https://github.com/ISSOtm) for helping with this code): ```diff +ChangeMusicIfNight:: + ld a, [wTimeOfDay] + cp NITE_F + ret nz + ld hl, NightMusicTable +.loop + ld a, [hli] + cp -1 + ret z + cp c + ld a, [hli] + jr nz, .loop + ld c, a + ret ``` What this function does is first see if the time of day is night (`cp NITE_F`); if not, we return to where we were before. If the time of day is night, the table we created earlier is loaded and the constants in the first column are sequentially compared to the constant in `c` until we reach the end of the table. If there's a match, `c` is updated with the constant on the same row and the second column of the table. Now, we just need to do a small edit on the same **home/map.asm** file to actually call this function: ```diff GetMapMusic:: push hl push bc ld de, MAP_MUSIC call GetMapField ld a, c cp MUSIC_MAHOGANY_MART jr z, .mahoganymart bit RADIO_TOWER_MUSIC_F, c jr nz, .radiotower farcall Function8b342 + call ChangeMusicIfNight ld e, c ld d, 0 .done pop bc pop hl ret ``` And that's it! The Night version of New Bark Town should now play during the night whenever that particular song is loaded! However, there's still a couple of small oversights that need to be fixed. The first one you might not even notice during gameplay: when the game reloads the overworld music after a battle or when the game is restarted, for example, it does it by loading the constant directly from the wram. This means that, if the time of day changes mid-battle, the map music won't actually be changed until the map itself is changed. This is very easy to fix. Edit **home/audio.asm**: ```diff RestartMapMusic:: push hl push de push bc push af ld de, MUSIC_NONE call PlayMusic call DelayFrame ld a, [wMapMusic] + ld c, a + call ChangeMusicIfNight + ld e, c - ld e, a ld d, 0 call PlayMusic pop af pop bc pop de pop hl ret ``` Here we're just loading the current map music from the wram to `c` and checking if it needs to be changed using the same function as before. The second problem is a bit more tricky to fix. There are two special cases of maps that have their music change throughout the game: the Radio Tower in Goldenrod City and the small shop in Mahogany Town, both of which have their music change to the Team Rocket themes during the respective story sequences, and back to the normal town music when they are defeated. This is done through a series of checks in the `GetMapMusic` function, which we've already changed a while earlier. Because of the way this code is done, the music won't actually switch at night with the current code. To fix this issue, we need to change the logic of these checks. Edit **home/map.asm**: ```diff GetMapMusic:: push hl push bc ld de, MAP_MUSIC call GetMapField ld a, c cp MUSIC_MAHOGANY_MART jr z, .mahoganymart cp MUSIC_RADIO_TOWER jr z, .radiotower farcall Function8b342 +.done call ChangeMusicIfNight ld e, c ld d, 0 -.done pop bc pop hl ret .radiotower ld a, [wStatusFlags2] bit STATUSFLAGS2_ROCKETS_IN_RADIO_TOWER_F, a jr z, .clearedradiotower - ld de, MUSIC_ROCKET_OVERTURE + ld c, MUSIC_ROCKET_OVERTURE jr .done .clearedradiotower - ld de, MUSIC_GOLDENROD_CITY + ld c, MUSIC_GOLDENROD_CITY jr .done .mahoganymart ld a, [wStatusFlags2] bit STATUSFLAGS2_ROCKETS_IN_MAHOGANY_F, a jr z, .clearedmahogany - ld de, MUSIC_ROCKET_HIDEOUT + ld c, MUSIC_ROCKET_HIDEOUT jr .done .clearedmahogany - ld de, MUSIC_CHERRYGROVE_CITY + ld c, MUSIC_CHERRYGROVE_CITY jr .done ``` What we are doing here is essentially changing the register where these checks place the music constant in, be it the Rocket version or the normal version. In the original code, they put the constant in `de`, which is what is needed for the next functions, but the new code to switch the music at night changes the constant at `c`, which is where `GetMapField` puts it. Luckily, there's already code that changes the register of the music constant (the `ld e, c` / `ld d, 0` lines), so we simply need to anticipate where those checks jump to in the base code (the `.done`) by three lines and thus reuse that bit of code. ## 4. Adding the rest of the music The rest of the asm files for all overworld music of Gen 2 are in the files below: * [Azalea Town](https://pastebin.com/XjgQCb8i) * [Celadon City](https://pastebin.com/yWTPm3JP) * [Cherrygrove City](https://pastebin.com/cvqGKuZL) * [Ecruteak City](https://pastebin.com/wkaqEK5s) * [Goldenrod City](https://pastebin.com/gcYmZWRx) * [Lavender Town](https://pastebin.com/2eKU2GBr) * [Route 1](https://pastebin.com/HWSA7ANT) * [Route 3](https://pastebin.com/DFMV24yh) * [Route 12](https://pastebin.com/prD56yYV) * [Route 26](https://pastebin.com/BqSZhHme) * [Route 29](https://pastebin.com/SkHuzUcr) * [Route 30](https://pastebin.com/cQJVpiwr) * [Route 36](https://pastebin.com/uC6hEkJn) * [Route 37](https://pastebin.com/b39aVyFg) * [Route 42 / Lake of Rage](https://pastebin.com/eePvSnV9) * [Violet City](https://pastebin.com/E1gXs888) And the updated night conversion table below: ```diff NightMusicTable: night_music: MACRO db \1, \2 ;\1 - original song ;\2 - night song ENDM night_music MUSIC_NEW_BARK_TOWN, MUSIC_NEW_BARK_TOWN_NIGHT + night_music MUSIC_ROUTE_29, MUSIC_ROUTE_29_NIGHT + night_music MUSIC_CHERRYGROVE_CITY, MUSIC_CHERRYGROVE_CITY_NIGHT + night_music MUSIC_ROUTE_30, MUSIC_ROUTE_30_NIGHT + night_music MUSIC_VIOLET_CITY, MUSIC_VIOLET_CITY_NIGHT + night_music MUSIC_AZALEA_TOWN, MUSIC_AZALEA_TOWN_NIGHT + night_music MUSIC_ROUTE_32, MUSIC_ROUTE_32_NIGHT + night_music MUSIC_GOLDENROD_CITY, MUSIC_GOLDENROD_CITY_NIGHT + night_music MUSIC_ECRUTEAK_CITY, MUSIC_ECRUTEAK_CITY_NIGHT + night_music MUSIC_ROUTE_38, MUSIC_ROUTE_38_NIGHT + night_music MUSIC_LAKE_OF_RAGE, MUSIC_LAKE_OF_RAGE_NIGHT + night_music MUSIC_ROUTE_26, MUSIC_ROUTE_26_NIGHT + night_music MUSIC_VIRIDIAN_CITY, MUSIC_VIRIDIAN_CITY_NIGHT + night_music MUSIC_ROUTE_3, MUSIC_ROUTE_3_NIGHT + night_music MUSIC_ROUTE_12, MUSIC_ROUTE_12_NIGHT + night_music MUSIC_CELADON_CITY, MUSIC_CELADON_CITY_NIGHT + night_music MUSIC_VERMILION_CITY, MUSIC_VERMILION_CITY_NIGHT + night_music MUSIC_PALLET_TOWN, MUSIC_PALLET_TOWN_NIGHT + night_music MUSIC_ROUTE_1, MUSIC_ROUTE_1_NIGHT + night_music MUSIC_LAVENDER_TOWN, MUSIC_LAVENDER_TOWN_NIGHT db -1 ; end ``` Of course, you can use this same code to add any new pairs of Day/Night music by adding a new line. If you try to add all the songs in at the same time, the game will compile and work fine; however, a few songs might sound a bit weird. This because we still have to define the lower noise notes and the respective drumkits. Likewise, although the game will compile, the Viridian City music uses a custom wave, which will also have to be included; if you don't include this, the song will sound weird as well. ## 5. Adding softer drumkits First, we need to define these new drumkits. Edit **audio/drumkits.asm**: ```diff Drumkits: dw Drumkit0 dw Drumkit1 dw Drumkit2 dw Drumkit3 dw Drumkit4 dw Drumkit5 + dw Drumkit0S + dw Drumkit1S + dw Drumkit_Empty + dw Drumkit3S ... +Drumkit0S: ;6 + dw Drum00 + dw Snare2 + dw Snare3 + dw Snare4 + dw Snare4_Soft + dw Drum05 + dw Triangle1_Soft + dw Triangle2_Soft + dw HiHat1_Soft + dw Snare5_Soft + dw Snare6_Soft + dw Snare7_Soft + dw HiHat1 +Drumkit1S: ;7 + dw Drum00 + dw HiHat1_Soft + dw Snare5_Soft + dw Snare6_Soft + dw Snare7_Soft + dw HiHat2_Soft + dw HiHat3_Soft + dw Snare8_Soft + dw Triangle3_Soft + dw Triangle4_Soft + dw Snare9_Soft + dw Snare10_Soft + dw Snare11_Soft +Drumkit_Empty: ;8 +Drumkit3S: ; 9 + dw Drum00 + dw Snare12_Soft + dw Snare13_Soft + dw Snare14_Soft + dw Kick1_Soft + dw Triangle5_Soft + dw Snare5_Soft + dw Drum27_Soft + dw Drum28_Soft + dw Drum29_Soft + dw Snare9_Soft + dw Kick2_Soft + dw Crash2_Soft ``` And add the new "softer" noise notes at the end of the same **drumkits.asm** file: ```diff +;Softer Noise Notes + +Snare12_Soft: + noise C#, 1, $81, $33 + endchannel + +Snare13_Soft: + noise C#, 1, $41, $32 + endchannel + +Snare14_Soft: + noise C#, 1, $71, $31 + endchannel + +Kick1_Soft: + noise C#, 1, $78, $6b + noise C#, 1, $61, $00 + endchannel + +Triangle5_Soft: + noise D_, 1, $81, $18 + endchannel + +Drum27_Soft: + noise C#, 8, $82, $10 + endchannel + +Drum28_Soft: + noise D_, 4, $81, $00 + noise D_, 4, $11, $00 + endchannel + +Drum29_Soft: + noise D_, 4, $81, $11 + noise D_, 4, $11, $00 + endchannel + +Snare4_Soft: + noise C#, 1, $71, $33 + endchannel + +Snare5_Soft: + noise C#, 1, $72, $23 + endchannel + +Snare6_Soft: + noise C#, 1, $72, $25 + endchannel + +Snare7_Soft: + noise C#, 1, $72, $26 + endchannel + +Snare8_Soft: + noise C#, 1, $92, $50 + endchannel + +Snare9_Soft: + noise C#, 1, $81, $22 + endchannel + +Snare10_Soft: + noise C#, 1, $61, $22 + endchannel + +Snare11_Soft: + noise C#, 1, $51, $22 + endchannel + +Kick2_Soft: + noise C#, 1, $98, $6b + noise C#, 1, $61, $00 + endchannel + +Crash2_Soft: + noise C#, 1, $74, $12 + endchannel + +Triangle1_Soft: + noise C#, 1, $61, $2a + endchannel + +Triangle2_Soft: + noise C#, 2, $31, $2b + noise C#, 1, $51, $2a + endchannel + +Triangle3_Soft: + noise C#, 1, $91, $18 + noise C#, 1, $21, $33 + endchannel + +Triangle4_Soft: + noise C#, 3, $81, $28 + noise C#, 1, $61, $18 + endchannel + +HiHat1_Soft: + noise C#, 1, $71, $10 + endchannel + +HiHat2_Soft: + noise C#, 1, $91, $10 + endchannel + +HiHat3_Soft: + noise C#, 1, $92, $11 + endchannel ``` You may notice the `Drumkit_Empty` on the list of drumkits. This is used to keep the offset between the normal and the softer versions of the drumkit 6 spaces apart (so drumkit $6 is the softer version of drumkit $0, drumkit $7 is the softer version of drumkit $1, etc); no song in the vanilla game uses drumkit $2, so we don't need to define this lower version. This isn't really necessary but this helps in case you need to add in a new Night version of your own. ## 6. Adding a custom wave For the Viridian City nighttime version to sound correct, we'll need to add in a new wave. This is very easy to do. **Edit wave_samples.asm:** ```diff WaveSamples: ; These are streams of 32 nybbles (4-bit values) used as wave patterns. ; Plot them as a line chart to see the wave's shape. dn 0, 2, 4, 6, 8, 10, 12, 14, 15, 15, 15, 14, 14, 13, 13, 12, 12, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 3, 2, 2, 1, 1 ;0 dn 0, 2, 4, 6, 8, 10, 12, 14, 14, 15, 15, 15, 15, 14, 14, 14, 13, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 1, 1 ;1 dn 1, 3, 6, 9, 11, 13, 14, 14, 14, 14, 15, 15, 15, 15, 14, 13, 13, 14, 15, 15, 15, 15, 14, 14, 14, 14, 13, 11, 9, 6, 3, 1 ;2 dn 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 15, 14, 13, 14, 15, 15, 14, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ;3 dn 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 14, 15, 7, 7, 15, 14, 14, 13, 12, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0 ;4 dn 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 2, 2, 1, 1, 15, 15, 14, 14, 12, 12, 10, 10, 8, 8, 10, 10, 12, 12, 14, 14 ;5 dn 0, 2, 4, 6, 8, 10, 12, 14, 12, 11, 10, 9, 8, 7, 6, 5, 15, 15, 15, 14, 14, 13, 13, 12, 4, 4, 3, 3, 2, 2, 1, 1 ;6 dn 12, 0, 10, 9, 8, 7, 15, 5, 15, 15, 15, 14, 14, 13, 13, 12, 4, 4, 3, 3, 2, 2, 15, 1, 0, 2, 4, 6, 8, 10, 12, 14 ;7 dn 4, 4, 3, 3, 2, 2, 1, 15, 0, 0, 4, 6, 8, 10, 12, 14, 15, 8, 15, 14, 14, 13, 13, 12, 12, 11, 10, 9, 8, 7, 6, 5 ;8 dn 1, 1, 0, 0, 0, 0, 0, 8, 0, 0, 1, 3, 5, 7, 9, 10, 11, 4, 11, 10, 10, 9, 9, 8, 8, 7, 6, 5, 4, 3, 2, 1 ;9 + dn 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 11, 11, 12, 12, 13, 7, 7, 13, 12, 12, 11, 11, 9, 8, 7, 6, 6, 5, 4, 4, 3, 2 ;A ``` This new wave is a "softer" version of wave $4. The music is already pulling the wave from index A, so unless you have any extra custom waves, there shouldn't be an issue. ## 7. Adding the Kanto Wild Battle Night theme Adding the Kanto Wild Battle theme works just like any other Night song. Replace the original song with [this file](https://pastebin.com/p19WcKbx) and add a new `Music_KantoWildBattleNight` pointer and `MUSIC_KANTO_WILD_BATTLE_NIGHT` constant. However, to actually make it load in-game, we need to add new code to switch the music at night, just like with the Johto Wild Battle Night. Edit **start_battle.asm:** ```diff .kantowild ld de, MUSIC_KANTO_WILD_BATTLE + ld a, [wTimeOfDay] + cp NITE_F + jr nz, .done + ld de, MUSIC_KANTO_WILD_BATTLE_NIGHT jr .done ``` And with this final edit, we have all our night versions in and a system to switch any overworld music at night. One final note: you might have noticed there's no file for Route 2, the remixed version of the theme for Viridian Forest in the original RBY. This is because I figured most people would prefer restoring the Viridian Forest map and use that song there, which would turn it into a dungeon and therefore would be no need to switch the song at night. I'll leave the conversion to a night version of this song as an exercise to the reader if you really need it ;) ## 8. Support for evening If you followed Rangi's tutorial for [adding evening as the fourth time of day](https://github.com/pret/pokecrystal/wiki/Make-evening-the-fourth-time-of-day), you might want the night versions to play in the new evening period. This is very easy to do. Edit **home/map.asm**: ```diff ChangeMusicIfNight:: ld a, [wTimeOfDay] cp NITE_F - ret nz + ret c ... ``` And edit **start_battle.asm**: ```diff .kantowild ;same comparison for Kanto - integrate in the other comparison? ld de, MUSIC_KANTO_WILD_BATTLE ld a, [wTimeOfDay] cp NITE_F - jr nz + jr c, .done ; not NITE_F or EVE_F ld de, MUSIC_KANTO_WILD_BATTLE_NIGHT jr .done ``` Here we are simply changing the checks for when to use the night music to include every time of day over `NITE_F`, which includes `EVE_F`.