How to Utilize Unused Level Slots in Sonic 2

Discussion in 'Tutorials Archive' started by Pacca, Mar 8, 2015.

Thread Status:
Not open for further replies.
  1. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    This guide will teach you how to add new Zones to Sonic 2, using the leftover blank level slots that were wiped and removed during development. Although this mainly applies to the completely blank slots (IDs 1, 3, and 9), this can also be applied to partially restore Wood Zone (ID 2), and Hidden Palace Zone (ID 8 ), provided you add the right files from the S2 betas. Keep in mind that this was made with the Xenowhirl Disassembly in mind, but it should be easy to apply to the Github one, too, provided you know what you're doing.

    What you will need:

    • Sonlvl (used to generate important files)
    • Art, Block, Chunk, and Palette Files for your new level (Not necessary, these can also be generated by Sonlvl, but will be blank if done that way)

    Step 1: Choose a  level Slot

    This is pretty easy, choose which level slot you want. Again, if you want to implement Wood Zone or Hidden Palace, use slot 2 or 8, respectively. Otherwise, just choose one of the three unused level slots at random; they're all the same. Keep in mind that both Hidden Palace and Wood Zone have extra palette cycles and other data defined for them, so be careful if you choose to add a new zone on top of them.

    Step 2: Adding your Zones Files

    If you feel advanced enough and want to make your own level completely from scratch, without actually starting from predefined files, then ignore this step; they will be generated later. Otherwise, pull your art tiles, blocks, chunks, and palette files from LevelConvertor or one of the existing Sonic 2 levels and put them in the following locations, and make sure each file is named after your new Zones abbreviation (for example, if your new zone is "Radical Highway Zone", your abbreviation would be "RHZ").

    Art files go in "art/kosinski"

    Blocks go in "mappings/16x16"

    Chunks go in "mappings/128x128"

    Palettes go in "art/palettes"

    Again, be sure they all have the same name, which is your Zones abbreviation.

    Step 3: Editing Main Level Load Blocks

    Search for "LevelArtPointers:". This will bring you to the "Main Level Load Block" list, which is a bunch of entries defining the PLCs, art, and mappings for every zone. It should look something like this:


    LevelArtPointers:
    levartptrs 4, 5, 4, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 0 ; EHZ ; EMERALD HILL ZONE
    levartptrs 6, 7, 5, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 1 ; LEV1 ; LEVEL 1 (UNUSED)
    levartptrs 8, 9, 6, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 2 ; LEV2 ; LEVEL 2 (UNUSED)
    levartptrs $A, $B, 7, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 3 ; LEV3 ; LEVEL 3 (UNUSED)
    levartptrs $C, $D, 8, ArtKos_MTZ, BM16_MTZ, BM128_MTZ ; 4 ; MTZ ; METROPOLIS ZONE ACTS 1 & 2
    levartptrs $C, $D, 8, ArtKos_MTZ, BM16_MTZ, BM128_MTZ ; 5 ; MTZ3 ; METROPOLIS ZONE ACT 3
    levartptrs $10,$11, $A, ArtKos_SCZ, BM16_WFZ, BM128_WFZ ; 6 ; WFZ ; WING FORTRESS ZONE
    levartptrs $12,$13, $B, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 7 ; HTZ ; HILL TOP ZONE
    levartptrs $14,$15, $C, BM16_OOZ, BM16_OOZ, BM16_OOZ ; 8 ; HPZ ; HIDDEN PALACE ZONE (UNUSED)
    levartptrs $16,$17, $D, ArtKos_EHZ, BM16_EHZ, BM128_EHZ ; 9 ; LEV9 ; LEVEL 9 (UNUSED)
    levartptrs $18,$19, $E, ArtKos_OOZ, BM16_OOZ, BM128_OOZ ; $A ; OOZ ; OIL OCEAN ZONE
    levartptrs $1A,$1B, $F, ArtKos_MCZ, BM16_MCZ, BM128_MCZ ; $B ; MCZ ; MYSTIC CAVE ZONE
    levartptrs $1C,$1D,$10, ArtKos_CNZ, BM16_CNZ, BM128_CNZ ; $C ; CNZ ; CASINO NIGHT ZONE
    levartptrs $1E,$1F,$11, ArtKos_CPZ, BM16_CPZ, BM128_CPZ ; $D ; CPZ ; CHEMICAL PLANT ZONE
    levartptrs $20,$21,$12, ArtKos_CPZ, BM16_CPZ, BM128_CPZ ; $E ; DEZ ; DEATH EGG ZONE
    levartptrs $22,$23,$13, ArtKos_ARZ, BM16_ARZ, BM128_ARZ ; $F ; ARZ ; AQUATIC RUIN ZONE
    levartptrs $24,$25,$14, ArtKos_SCZ, BM16_WFZ, BM128_WFZ ; $10 ; SCZ ; SKY CHASE ZONE
    ; ---------------------------------------------------------------------------
    ; END Art_Ptrs_Array[17]


    As you can see, there are 5 unused slots, almost all of which have been set to reuse Emerald Hill Zones data (except Hidden Palace, which references Oil Oceans 16X16 mappings as it's art and chunks, for some reason). Next to each pointer is it's level ID, the same one you picked beforehand. Just replace the "EHZs" in each slot you want to fix with the abbreviation for your new Zone. If you want to add hidden palace, though, just replace it's line with this:


        levartptrs $14,$15, $C, ArtKoz_HPZ, BM16_HPZ, BM128_HPZ;   8; HPZ; HIDDEN PALACE ZONE

    Step 4: Defining your Zones artwork, blocks, and chunks

    Search for "BM128_WFZ:". Below that, add this (be sure to replace every instance of "MyLevel" with your levels abbreviation)


    ;-----------------------------------------------------------------------------------
    ; MyLevel 16x16 block mappings (kosinski compression)
    BM16_MyLevel: BINCLUDE "mappings/16x16/MyLevel.bin"
    ;-----------------------------------------------------------------------------------
    ; MyLevel main level patterns (kosinski compression)
    ArtKoz_MyLevel: BINCLUDE "art/kosinski/MyLevel.bin"
    ;-----------------------------------------------------------------------------------
    ; MyLevel 128x128 block mappings (kosinski compression)
    BM128_MyLevel: BINCLUDE "mappings/128x128/MyLevel.bin"
    ;-----------------------------------------------------------------------------------

    Now all the entries we add in "Main Level Load Block" will point to the data for our zone, which we added in step 2.

    Step 5: Adding Palette Data

    We still have to add one of our new files in, though; our palettes. Search for "PalPointers:". You should see a huge list of every palette in the game, including level palettes. add a line after "palptr Pal_UNK7,  Normal_palette, $1F" and add this:


    palptr Pal_MyLevel, Normal_palette_line2, $17

    after that is the list of actual palette files, which is where we need to make this palette pointer point to. Add this at the end of the second list:


    Pal_MyLevel: BINCLUDE "art/palettes/MyLevel.bin" ; MyLevel Palette

    then, go back to "Main Level Load Block" and change the third number to the index number of your new pallete (if this is the first new palette your adding, then it should be "$28". If you've already added new palletes, then just add the number of new palettes you added to the number, and it should work).

    Step 6: Defining Act Layouts

    Search for "Off_Level:". You should see yet another giant list of pointers. Now, things are a bit more confusing; these lists (at list in the Xenowhirl Disasm) aren't labeled by zone, but by how far they are in the list. Since these lists define data for each act, and not the whole zone, they're twice as long, so if you multiply the level ID you chose by two, you should be able to find your level in here. If the level you chose isn't Hidden Palace, it should look something like this:


    dc.w Level_EHZ1-Off_Level; #
    dc.w Level_EHZ1-Off_Level; #

    Replace it with something like this:


    dc.w Level_MyLevel_1-Off_Level; #
    dc.w Level_MyLevel_2-Off_Level; #

    Then, search for "Level_HTZ2:". Below that; add this:


    ;---------------------------------------------------------------------------------------
    ; MyLevel act 1 level layout (Kosinski compression)
    Level_MyLevel_1: BINCLUDE "level/layout/MyLevel_Layout1.bin"
    ;---------------------------------------------------------------------------------------
    ; MyLevel act 2 level layout (Kosinski compression)
    Level_MyLevel_2: BINCLUDE "level/layout/MyLevel_Layout2.bin"
    ;---------------------------------------------------------------------------------------


    Step 7: Adding Object Layouts

    Search for "Off_Objects:". You should see a pointer list for the objects in each act; thankfully, this list does have comments pointing out each level ID. Search for the two pointers in the list relating to your level. You should see something like this:


    dc.w Objects_Null3 - Off_Objects ; # $##
    dc.w Objects_Null3 - Off_Objects ; #

    Replace that with this:


    dc.w Objects_MyLevel_1 - Off_Objects ; # $##
    dc.w Objects_MyLevel_2 - Off_Objects ; #

    Then, after "        BINCLUDE    "level/objects/Null_6.bin"", add this:


    Objects_MyLevel_1: BINCLUDE "level/objects/MyLevel_1.bin"
    Objects_MyLevel_2: BINCLUDE "level/objects/MyLevel_2.bin"

    Step 8: Defining level Collision

    One of the most important parts of any zone is its' collision; without it, Sonic will fall through the floor! You will have to fix it manually in your level editor of choice, but this allows you to define it for your zone. Search for "Off_ColP:". Go to the line for your level slot, it should look something like this:


    dc.l Off_Level ; #

    Replace it with this:


    dc.l ColP_MyLevel ; #

    Immediately below that list is another, for the second collision layer. Just replace the corresponding line (which should look about the same as the first), with this:


    dc.l ColS_MyLevel ; #

    Now search for "ColS_WFZSCZ:". After that, add this:


    ;---------------------------------------------------------------------------------------
    ; MyLevel primary 16x16 collision index (Kosinski compression)
    MyLevel: BINCLUDE "collision/MyLevel1.bin"
    ;---------------------------------------------------------------------------------------
    ; WFZ/SCZ secondary 16x16 collision index (Kosinski compression)
    MyLevel: BINCLUDE "collision/MyLevel2.bin"
    ;---------------------------------------------------------------------------------------

    Step 9: Generating Files with SonLVL

    Make sure your SonLVL ini files are setup with your disassembly. Then, create a new file (if you haven't already) called "SonLVL.user.ini" right next to your old SonLVL ini file. Then, open it with a text editor. Add this:


    [MyLevel Zone Act 1]
    tiles=../art/kosinski/MyLevel.bin
    blocks=../mappings/16x16/MyLevel.bin
    chunks=../mappings/128x128/MyLevel.bin
    layout=../level/layout/MyLevel_Layout1.bin
    objects=../level/objects/MyLevel_1.bin
    rings=../level/rings/MyLevel_1.bin
    palette=../art/palettes/SonicAndTails.bin:0:0:16|../art/palettes/MyLevel.bin:0:16:48
    colind1=../collision/MyLevel1.bin
    colind2=../collision/MyLevel2.bin
    [MyLevel Act 2]
    tiles=../art/kosinski/MyLevel.bin
    blocks=../mappings/16x16/MyLevel.bin
    chunks=../mappings/128x128/MyLevel.bin
    layout=../level/layout/MyLevel_Layout2.bin
    objects=../level/objects/MyLevel_2.bin
    rings=../level/rings/MyLevel_2.bin
    palette=../art/palettes/SonicAndTails.bin:0:0:16|../art/palettes/MyLevel.bin:0:16:48
    colind1=../collision/MyLevel1.bin
    colind2=../collision/MyLevel2.bin

    Now save it and open "SonLVL.ini" with SonLVL. In the levels section, your new zone should appear. First, open up act 1, then save it. Then open act 2 and save it. You've now defined a new level!

    Step 10: Adding it to the game

    There are multiple guides for changing the level order and the level select, so I'm not going tell you how here. Just look it up; there's lots of info online and in the disassembly to help you. If you really need to see it right away, use the Cheat Code: "FE10:0X0Y", where X is your levels ID number and Y is the act you want to see, minus 1.

    And your done! Add collision and layouts in your level editor of choice, and enjoy your new level :3

    P.S. It is very possible to continue defining new zones with this, provided you still have available slots. Once you run out, I believe another guide somewhere on Sonic Retro can help you out, which I'm sure you can find if you truely need extra level slots.
     
    Last edited by a moderator: Mar 8, 2015
    AkumaYin likes this.
  2. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    Actually, the recommended way to add levels to SonLVL's INI is to create a file named "SonLVL.user.ini" and add the extra levels there. SonLVL will read them with the regular levels, and they won't get overwritten if you update the INI files.
     
  3. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    Wow! The things you've done with SonLVL never seize to amaze me! The guide has been updated!
     
Thread Status:
Not open for further replies.