Sonic Mania: Hacking Discussion

Discussion in 'Engineering & Reverse Engineering' started by Chimera, Aug 29, 2017.

  1. GerbilSoft

    GerbilSoft

    RickRotate'd. Administrator
    2,893
    24
    18
    USA
    rom-properties
    Obfuscation. If it was swapped on 32-bit boundaries, that might make slightly more sense due to endianness, but on nybble boundaries, obfuscation is the only reasonable explanation.
     
  2. flarn2006

    flarn2006

    Member
    274
    3
    18
    SA2 Cheat Table
    Obfuscation? For what purpose?
     
  3. McAleeCh

    McAleeCh

    Oldbie
    998
    22
    18
    After poking through the list of object names some more, I've figured out which go with which for all the remaining badniks which are used in-game and have added them to the wiki. The only one I still can't identify is the unused CPZ pond-skater badnik - it's a functional object, so one of the names must correspond to it, but I'm damned if I can figure out which! = P

    Don't suppose anyone's found where the debug mode object lists are defined? The object appears on Chemical Plant Zone's debug list, so having a list of exactly which object names are the ones used in that list would narrow things down a lot if it's possible to find.
     
  4. jman2050

    jman2050

    Teh Sonik Haker Tech Member
    633
    0
    16
    Alright here goes, the (almost) complete SceneX.bin format. Assuming I didn't make any mistakes of course.

    Dunno how similar it is to any previous versions of level data in earlier Retro Sonic iterations as I never explored any of that. Quick summary is that the level format seems to describe three specific things. 1) The per-scanline scrolling data for every individual level plane, 2) An array of 16x16 tile references, essentially the meat of the level data, and 3) A full object instance definition list. The first two are about what you'd expect, but the third is interesting in that it's a lot more flexible than what a Genesis Sonic hacker would be familiar with. There's no insight here on how objects actually function, though I do have some ideas having poked around the code, these are strictly how they're defined and loaded for each individual Scene file.

    Apologies for formatting issues, taking notes readable by anyone other than myself is not really my forte. And of course figuring out the unknown variables would be welcome.

    Code (Text):
    1. Sonic Mania Level Format
    2. NOTE: All WORDs and DWORDS are little endian unless otherwise noted. At least that's what I remember, someone should double check.
    3.  
    4. DWORD- 'SCN' - Magic
    5. BYTE*16 - Probably an editor-only header, it's completely skipped over
    6. BYTE - Size of upcoming data - 1
    7. <variable length>BYTES - See above. This is also ignored by the game itself.
    8.  
    9. BYTE - Skipped over, ignore
    10. BYTE - Number of specified planes
    11. For each plane sequentially:
    12.     WORD - Size of upcoming string
    13.     <variable length>BYTE - Plane string
    14.     BYTE - ???
    15.     BYTE - ???
    16.     WORD - Width of plane in tiles
    17.     WORD - Height of plane in tiles
    18.     WORD - ???
    19.     WORD - ???
    20.     WORD - Number of entries in the subsequent array of structs which describe different scrolling speed parameters that are then used by the plane's first compressed array
    21.     [SCROLL-ARRAY]:
    22.         WORD - X scrolling camera-relative speed ( 0x100 = 1 pixel )
    23.         WORD - X Automatic scrolling speed ( 0x100 = 1 pixel )
    24.         BYTE - ???
    25.         BYTE - ???
    26.     Compressed chunk x 2 - Both work together to form level data information. Compression is bog standard zlib.
    27.         DWORD  - Size of upcoming compressed chunk. The value is read and then that number of bytes is then read and decompressed into level data.
    28.             DWORD (NOTE: big endian) - Size of uncompressed data
    29.             <remaining bytes> - Compressed chunk
    30.     (First chunk is an array of size [plane height in pixels] bytes. Each entry is an index to the scrolling information described in [SCROLL-ARRAY] and corresponds exactly to
    31.     each line of pixels in the plane.
    32.     Second chunk is an array of size [plane height in tiles * plane width in tiles] WORDs. Each entry is a 16x16 tile reference.
    33.     Known format of 16x16 tile references:
    34.         ???? YXTT TTTT TTTT
    35.         Y - Flip tile on Y axis
    36.         X - Flip tile on X axis
    37.         T - Tile index, see 16x16Tiles.gif for sequential tiles
    38.         ? - This might be similar to Sonic 3's format which describes the solidity of this specific tile for each of the 2 collision planes. I am suspicious though, as it appears
    39.             that both collision planes are in fact be completely decoupled from each other, which would free up two of these remaining bits or something else. Regardless, my
    40.             speculation is that bits 15/14 describe solidity in this manner )
    41.    
    42. BYTE - Counter for number of defined objects. Objects are loaded by a combination of GameConfig.bin and StageConfig.bin and unlike the Genesis games, this level format iterates on a
    43.        per-definition basis, instantiating all objects of a particular type at once. The convenience of this is that optional arguments are declared per-object which are then given
    44.        definitions in each instance of the object as needed, as will become clear below.
    45. For each object definition sequentially:       
    46.     DWORD * 4 - Object ID string hash
    47.     BYTE - Number of arguments. Will always at least read one argument if instances are defined even if 0. The first argument is always positional data, optional arguments are described
    48.            after this byte in a header.
    49.     IF ARGS > 1, for each argument above 1:
    50.         DWORD*4 - Argument identifier ID string hash
    51.         BYTE - Type of argument, values 0-B (see below)
    52.     BYTE - Number of instances of this object. Can be 0
    53.         Argument 1 (always for each instance):
    54.             WORD  - Object Instance Table index
    55.             DWORD  - X position 16:16 precision
    56.             DWORD  - Y position 16:16 precision
    57.         Arguments past 1 are variable size depending on the type of argument as signified in the header:
    58.             <CASE 0, 3>:
    59.                 BYTE - value of argument
    60.             <CASE 1, 4>:
    61.                 WORD - value of argument
    62.             <CASE 2, 5, 6, 7, B>:
    63.                 DWORD - value of argument
    64.             <CASE 8>:
    65.                 WORD - Count of upcoming array of WORDS for object to reference.
    66.                 <variable length>WORDs - Array of WORDs
    67.             <CASE 9>:
    68.                 DWORD*2 - two DWORDs comprised 2 values of this argument. Likely for positional data
    69.             <CASE A>:
    70.                 DWORD - value of argument? The ASM is somewhat different from case 2 but as far as I can tell it does exactly the same thing. Investigate
    71.                         further, my x86 proficiency is suspect at best.
    72.        
    73.    
    74.  

    I did make a quick and dirty tool that rips the level data and makes full-size PNGs of each individual level plane but it's very barebones and very slow. I might upload it if someone wants but I'm positive you guys can do better than me as far as tools go.
     
  5. EyeKey

    EyeKey

    Member
    29
    0
    0
    Nice job. An interesting point is that the serialization of the static object files is very similar to the serialization of the arguments here. It uses the same type numbers. But in the static object files it loads it as a stream to the memory (+ a bit that marks if you just want to skip that field and not fill it, the default value of everything is zero).
    I think that the best way to describe it is that the static object file is the static attributes, and in the scene it loads the instance attributes.


    And about the level to PNG, I did the exact same tool as you, I posted it yesterday, few pages back.

    EDIT: Something interesting from the code the loads the static object: You can only fill types 0-6 in the static object, all the other types you can only skip, but in some of them it skips more in the memory than it reads when it initialize the same type in the scene, for example for 0xa it skips 24 bytes.
     
  6. TuxKnux

    TuxKnux

    Member
    3
    0
    0
    Its name in the game files is Sweep.
     
  7. BaconFace

    BaconFace

    DrTapeworm Member
    38
    0
    0
    congrats to E-03 Sweep for being the first modern(ish) character to be officially backported to the classic series, despite being unused!

    also of interest is that in the object list posted a few pages ago, i noticed a lot of names of Sonic 1 badniks that appeared in Scrap Brain are in there (Bomb, Orbinaut, Caterkiller) so maybe they were actually serious about bringing it back before opting for MMZ instead, though it's just as likely that they were just leftovers that never got cleaned out.
     
  8. Rageguy

    Rageguy

    Member
    9
    0
    0
    [​IMG]

    Really wish model replacing was possible, just did this for fun. :v:
     
  9. Shaddy the guy

    Shaddy the guy

    Spend the police budget on femboy hooters Member
    394
    23
    18
    Beaverton OR
    Thinga Comic
    Hey, game's only just come out on PC, wait and see what might happen.


    (probably nothing, but you never know)
     
  10. Master Emerald

    Master Emerald

    A green crystal Member
    It actually dates back to Sonic CD
     
  11. SystemsReady

    SystemsReady

    I Have No Idea What I'm Doing At Any Given Moment Member
    422
    67
    28
    The Twin Cities
    trying to not fall asleep while writing Selenium tests
    Egg....Reverie....

    Maybe it's because I'm sick as a dog right now, but does anyone else think that the zone name could further hint that the level was supposed to have ALL the HBHs? As a "Reverie" is a party basically.....
     
  12. EyeKey

    EyeKey

    Member
    29
    0
    0
    Well the format is very simple, mainly list of faces and color for each faces. I can do a script that does it, but the issue will be animations. you will have to use the same faces, and only move the veriticies, and hope that the faces are exported to the file in the same order.
     
  13. Rageguy

    Rageguy

    Member
    9
    0
    0
    I'd have to use the pre-existing sonic mesh though, correct?


    edit: I've also been working on some more things here and there..

    [​IMG]

    i may or may not continue
     
  14. McAleeCh

    McAleeCh

    Oldbie
    998
    22
    18
    Thanks for the info both of you - much appreciated! Have updated the wiki to add this information, meaning we now have names identified for all enemies and bosses! Not finished adding enemies to the template just yet as most that are left need their sprites assembling accurately before I can add them in, but I've added all their names to the relevant Zone pages in the meantime. Very interesting that the team reimagined an Adventure-era enemy for inclusion in this game, even if it was cut in the end!
    Thanks for the reminder - I'd looked for this name in the object list originally as I'd assumed it was intended to be a verison of this badnik. From the name/design, it's definitely intended to be Sweep, but you're right that the size/functionality seems based on Amenbo. Have added a reference to the Mania section of Sweep's wiki article noting this similarity.
     
  15. LoneDevil

    LoneDevil

    READ BERSERK Member
    134
    13
    18
    Texas
    Hot damn that metal model, Last two things he needs is jogging/running (only for mach 1 and 2) and rolling frames.
     
  16. EyeKey

    EyeKey

    Member
    29
    0
    0
    What do you mean? You won't have to use the preexisting model. But the way that the meshes are stored is that there is list of faces, which is just indexes of vertices, and than there is array of those vertices per frame.
    I am not really familiar with 3d programs so I don't know if there a simple way to export something like that. The faces need to be consistent between the frames.
     
  17. Rageguy

    Rageguy

    Member
    9
    0
    0

    As far as faces being consistent, I'm sure they would be considering the mesh used for each frame would have the same amount of faces as the previous one.
    But as far as setting up arrays and having the indexes of vertices, I've got no clue how I would get that set up.
     
  18. Dark Sonic

    Dark Sonic

    Member
    12,639
    224
    43
    Working on my art!
    Looks like we got ourselves a new patch. I wonder what it changed/fix (they said it fixed a soft lock glitch that occurred when fighting the Titanic Monarch boss with all the Chaos Emeralds in No Save mode, but they also vaguely implied it fixed other things too)
     
  19. TrackerTD

    TrackerTD

    Dragon Land is Screaming! Member
    Well at any rate, the mod loader doesn't seem to be loading my mods anymore, so unless I cocked something up it seems something's changed on that front.
     
  20. MainMemory

    MainMemory

    Have no fear...Amy Rose is here! Tech Member
    4,412
    67
    28
    SonLVL
    I was expecting the game to get updated eventually, but not quite this soon. Almost makes me think I should wait for things to settle down. But I put too much time into this yesterday to just give up. I'm going to disassemble the game AGAIN and find everything I need AGAIN and release a new version of the mod loader for the new version of Mania.