Level editing tutorial (Not 56k friendly)

Discussion in 'Engineering & Reverse Engineering' started by Dude, Mar 10, 2009.

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

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    Dude's sadx level editing tutorial.

    I apologize in advance for the image situation in this tutorial - if anyone can make the images smaller without sacrificing the ability to read the numbers, feel free to downsample them for me. You can also view this tutorial off the board on my website

    In this tutorial I will explain how to create a semi-original level layout for sonic adventure dx pc, using 3d studio max and a hex editor. The first thing you will need to do is isolate the area in the game you want to manipulate. For this tutorial, this quick rip of Emerald Coast part 1 (download here) will suffice for learning the basics (a word of warning: this rip is far from accurate, and shouldn't be used for anything other than this tutorial. I'll make a better rip later).

    Also, when working with 3d models imported from sadx, make sure you leave the 'rotate model' option unchecked in your obj import and export plugin. This will cause the viewports to be inaccurate, but our x,y,z coordinates will be accurate for object placement because of this.

    After ripping the desired data using sadx, navigate to the section of the level you'd like to change, for this example, we will be moving the island immediately after the first loop as pictured here:

    [​IMG]

    Now, using the top (back) view, lets select the island's parts. Notice the island is cut into 15 objects, as seen here:

    [​IMG]

    Now, lets move and rotate those pieces like so:

    [​IMG]

    ok, now that we've moved the island's geometry, we'll have to start updating the collision and rendering data. Its tedious and alot of work, but it is all necessary for the edits to show up properly ingame. To keep myself from accidentally moving other pieces of the level, I've frozen everything except for our island. Deselect everything, and then select the dark green part of the island that makes up the tip.

    [​IMG]

    Notice that it is named "objgroup12202980_22" This tells us important information about where to find its data in sonic.exe. To make it easier to remember, lets rename it to "Island1_12202980". Now unfortunately, the level ripper doesn't properly import pivot information, and since we've moved the island, that data would be obsolete anyways, so go over to the hierarchy tab with the tip of the island selected and click the button that says "affect pivot only" and then click "center to object", then turn off "affect pivot only". This helps us establish where the center of the object is, which we'll need for the rendering and collision data. Keep this piece of the island selected (make sure only one part of the island is selected), and go to "file -> export selected". Select "alias-wavefront OBJ" for the file format, and then save the file as "Island1.obj" in the same directory your OBJ2VT.exe program is. Uncheck "rotate model", and make sure the 'scale' field is at 1.0.

    Drag Island1.obj onto OBJ2VT.exe, and when prompted, press any key. A new file called out.vt will appear in the directory. This is our vertex tree, and it is full of raw vertex data in a format that sadx will happily accept. Now we need to figure out where it goes. Our object name contains the numbers "12202980", and this is the decimal offset in sonic.exe where the main data for our island object goes. Open sonic.exe in hex workshop. Press "ctrl+g" to bring up the goto box, and enter those numbers. Make sure the radio button for 'dec' is selected.

    [​IMG]

    press enter, and it should take you to this location

    [​IMG]

    The first 4 bytes I have selected are flags that determine wether or not the model can be transformed by sonic.exe ingame, pay it no mind for now. Go over 4 bytes to where it says "B8 33 FA 00" This is a pointer to the ATTACH structure of the model (outlined in sanik's notes). The attach structure is useful to us for 2 reasons:

    - it points to the vertex data, which we need to replace with the contents of out.vt

    - and it contains data telling the game where the object can be seen from.

    [​IMG]

    If you look down in the data inspector, you'll see "16397240"; this is how "B8 33 FA 00" translates into a long integer (4 byte whole number). This number tells us where the aforementioned ATTACH structure resides in the game's ram, NOT where it resides in sonic.exe. To find where we need to go in sonic.exe, we will have to do some subtraction. We take the value "16397240" and subtract it from the pointer key "0x400000" (hex), or "4194304" (dec). 16397240 - 4194304 = 12202936. Use ctrl+g again, and this time enter "12202936". It should take you here:

    [​IMG]

    We're not far from where we started, the difference between the OBJ struct and the ATTACH struct is always marginal, but this isn't always the case. Sometimes the game likes to play tricks, so always do your pointer math. Anyways, now that we're at the ATTACH structure, lets take a look around:

    [​IMG]

    the data inspector reveals that our vertex pointer is "16394360", which after the key comes out to be 12200056. use ctrl+g again, and after you've arrived at "12200056", open out.vt

    [​IMG]

    Selecting everything in out.vt reveals it to contain a total of 0x5a0 (hex) bytes. Copy the contents of out.vt, then go back to "12200056" in sonic.exe. Click select block, and when the box comes up, enter 0x5a0, making sure the 'hex' radio button is selected.

    [​IMG]

    Press enter, and then paste. If any byte shifting occured, you messed up. Don't save just yet, go back to the ATTACH structure.

    [​IMG]

    go to the object center, and select the first 4 bytes. Now go back to 3dsmax and select the x origin of the object.

    [​IMG]

    copy this number, then run back to hex workshop and paste that number into the data inspector under the 'float' entry.

    [​IMG]

    repeat this with the y and z coordinates, until your attach struct looks like this:

    [​IMG]

    We're almost done with the attach struct, but we need one last piece of data to tell the game how big our island piece is. Go back into 3d studio, and create a new sphere at the same origin point as your island piece. Expand its radius using the radius handle (not the scale tool) until the sphere barely encompasses all of the island.

    [​IMG]

    copy this value, and paste it into the the last remaining entry (object radius), and your attach struct should look like this:

    [​IMG]

    you're almost there! If you were to save sonic.exe now, your object would appear exactly as it is supposed to, but you would fall through any part that wasn't in the same area as before. Select the rendering data you added to the ATTACH struct and paste it into a new file, like here:

    [​IMG]

    Now we have to find some data that we can't find from the OBJ or ATTACH structs - the COL struct. To find the col struct we go back to our original numbers ("Island1_12202980" if you forgot), and instead of subtracting our key, this time we ADD it. 1220298 + 4194304 = 16397284. Now this number we just got isn't actually going to tell us anything, because we already are at the place it is telling us to go. So instead of going to 5414602, we find it by pressing ctrl+f. Set the type to '32 bit unsigned long', and then paste '16397284' into the value box. If hex workshop asks you to continue again at the beginning of the file, say ok. It should find a result at 11101328 (dec). We are roughy halfway through the COL struct.

    [​IMG]

    As a general rule, col structs where the object is meant to be visible end in 80. We can use this to find the whole struct, as pictured here:

    [​IMG]

    Select the first 0x10 bytes of the struct and replace them with the radius data you entered into the ATTACH struct earlier, like so:

    [​IMG]

    Now save your sonic.exe as EmeraldCoast.exe, and run it. Upon loading emerald coast and going to the loop, you should see this:

    [​IMG]

    Its a little low, but shouldn't it be right where we placed it? Not quite, you see there are some coordinates in the OBJ struct that move the model an additional distance - this is for objects that are used more than once, or possibly for other reasons. Remember how the OBJ struct had an attach pointer? Well right after that are 3 more floats that tell the game how far from the vertex data to render the object. In this case, we'll need to zero out this data. Open your EmeraldCoast.exe in hex workshop again, and use ctrl+g to go to 12202980. Here we find the offending value (-23.0)

    [​IMG]

    zero out that number, save and re-load. You should get this:

    [​IMG]

    Now thats more like it! You'll notice you still can't move past the old barriers though. We've moved them in 3d studio but not in sonic.exe. You have two options here:

    - get rid of them altogether by making their mesh total in the attach struct 0
    - move them using the process above to match their new location.

    Anyways, repeat the process for all 15 of the level pieces if you so desire. It will help you to take notes so you can quickly jump to any OBJ, ATTACH, COL, or VERTEX struct you need to in case you need to change something. My list entries for this island are below:

    Code (Text):
    1. Emerald Coast Edits:
    2.  
    3. Island1_12202980
    4. attach struct - 12202936
    5. vertex struct - 12200056
    6. col struct - 11101328
    7.  
    8. Island1_Caustics_12718652
    9. attach struct - 12718608
    10. vertex struct - 12717168
    11. col struct - 11114540
    12.  
    13. Island1_Waves_12744884
    14. attach struct - 12744840
    15. vertex struct - 12743880
    16. col struct - 11115152
    17.  
    18. Island2_12211512
    19. attach struct - 12211468
    20. vertex struct - 12208176
    21. col struct - 11101364
    22.  
    23. Island2_Caustics_12721692
    24. attach struct - 12721648
    25. vertex struct - 12719920
    26. col struct - 11114576
    27.  
    28. Island2_Waves1_12746960
    29. attach struct - 12746916
    30. vertex struct - 12746216
    31. col struct - 11115224
    32.  
    33. Island2_waves2_12745940
    34. attach struct - 12745896
    35. vertex struct - 12745176
    36. col struct - 11115188
    37.  
    38. Island3_12222040
    39. attach struct - 12221996
    40. vertex struct - 12220048
    41. col struct - 11101436
    42.  
    43. Island3_sand_12217228
    44. attach struct - 12217184
    45. vertex struct - 12214880
    46. col struct - 11101400
    47.  
    48. island4_12226328
    49. attach struct - 12226284
    50. vertex struct - 12224144
    51. col struct - 11101472
    52.  
    53. island4 shadow_12697132
    54. attach struct - 12697088
    55. vertex struct - 12696752
    56. col struct - 11114180
    57.  
    58. island5_12643760
    59. attach struct - 12643716
    60. vertex struct - 12639752
    61. col struct - 11113676
    62.  
    63. island3_wall_12633620
    64. attach struct - 12633576
    65. vertex struct - 12632904
    66. col struct - 11113640
    67.  
    68. island6_12646608
    69. attach struct - 12646564
    70. vertex struct - 12645432
    71. col struct - 11113712
    and lo, a level was changed:

    [​IMG]

    Its alot of work, and it took me roughly an hour. I kind of cheated (I used one sphere data for all of the ATTACH and COL structs, because I accidentally corrupted the exe while working, and had to restore a backup), but it works ingame. You can download my finished 3dsmax file here. And if you get lost, or need help figuring out what data does what, you can download my EmeraldCoast.exe, and use Hex workshop to do a file compare on the original executable vs. this one. As you've no doubt noticed, the camera is now totally out of whack with the level. For now, just use free cam. I'll do a camera file tutorial sooner or later.

    -Dude
     
  2. Enzo Aquarius

    Enzo Aquarius

    20% Cooler. Member
    1,420
    0
    0
    Canada, eh.
    Sonic TV Scripts, Sonic Comic Wiki Work
    Brilliant! I may not mess around with SADX, but this was a neat read. The steps are well done and the pictures really supplement the text, making it quite easy to understand. If you weren't a tech member already, I would've recommended you get the status. :)
     
  3. Wow, I didn't think I'd see an actual guide out. Hex isn't my friend, but from what I do understand it seems pretty straightforward.


    Also, your windows theme...burns my eyes X_x
     
  4. Hinchy

    Hinchy

    Up And Down And All Around Oldbie
    1,952
    19
    18
    Lafayette, LA, USA
    I want to make a fangame before I die
  5. Maxd

    Maxd

    Member
    661
    0
    0
    Alabama
    Mixin'
    Any chance that this tutorial could be applied to Sonic Adventure, so we could play our modifications on real hardware (I.e. Dreamcast) if we kept the levels within hardware capability?
     
  6. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash
    Yes, the principles are all exactly the same, the only difference is that you use 0xC900000 as your pointer key instead of 0x400000.
     
  7. Maxd

    Maxd

    Member
    661
    0
    0
    Alabama
    Mixin'
    Very cool. I might look into this further some time later down the road...
     
  8. Hayate

    Hayate

    Tech Member
    I appreciate the work you've put into this, but please stop telling people to use decimal. Why convert a hex number into decimal, use a calculator to subtract the decimal version of 0x4000000 from it and then convert back into hex when you could change the sole digit yourself and avoid all those conversions?
     
  9. Dude

    Dude

    Tech Member
    3,138
    0
    16
    Southbridge, MA
    Random VR/AR trash

    Because the object ripper uses decimal offsets and it is the object ripper's output that tells you where things are. you only have to convert the key to decimal once. First thing I do when editing is convert the key to decimal then store it in calc's memory. From there out, its all decimal.
     
  10. Shadic

    Shadic

    Member
    1,230
    3
    18
    Olympia, WA
    Home improvement eternal
    3D level editing is so complex. I will be overjoyed the day that a program comes out that does all the Hex for us.

    Cool tutorial.. Even if all it did was inspire me to not make SADX levels. :P
     
Thread Status:
Not open for further replies.