don't click here

Sonic 06's "standard.lub" file

Discussion in 'Engineering & Reverse Engineering' started by Sable, Nov 17, 2018.

  1. Sable

    Sable

    Member
    70
    8
    8
    So over at the Lost Legacy Discord we've caught wind of an LUB file that's apparently not possible to decompile without heavy editing, as it allegedly contains non-LUA data that the XEX needs for the game to run. It seems to be an absolutely massive file - from what we can see, it might hold relevant data to Super forms, the Rainbow gem, homing attack delay/flips, and tons of other stuff that was cut from the final game.

    Problem is that none of us can find exactly where said non-LUA data is in the file, to strip it and create a normal LUB. Here's the link - if this isn't okay, feel free to obliterate me :v: Attempting to decompile it using ShadowLag's 06 SDK leads to a massive file that loops a conditional after a certain point - and luadec just straight up doesn't work. So, if anyone wants to take a crack at it... Yeah.
     
  2. biggestsonicfan

    biggestsonicfan

    Model2wannaB Tech Member
    1,608
    408
    63
    ALWAYS Sonic the Fighters
    What about the PS3 executable?
     
  3. if I remember correctly the PS3 uses (mostly) the same files. I'm sure it's the same with PS3 only code bolted onto the front of it. The game is an alpha at best.

    As far as Standard.lub, it's not the only lua that can't be decompiled. There's a few others. Of course this extends beyond my knowledge but if someone wants to have a crack at it
     
  4. Lostgame

    Lostgame

    producer/turnablist. homebrew dev. cosplayer. Oldbie
    4,134
    58
    28
    Toronto, ON
    The O.I.C.
    >> the game is an alpha at best

    Hehe, you can say that again. ;)
     
  5. Strike

    Strike

    Member
    5
    0
    0
    Bumping this. Please, if anyone has an idea of how to get around this, share it.
     
  6. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    Bumping? Seriously?
     
  7. Strike

    Strike

    Member
    5
    0
    0
    Maybe if someone cared enough to respond?
     
  8. Pokepunch

    Pokepunch

    Member
    84
    0
    6
    UK
    A Sonic 2 Hack
    Maybe if someone knew enough about this to respond they would?
     
  9. HyperBE32

    HyperBE32

    Blast Processing Member
    23
    0
    1
    Cheshire, England
    Marathon
    The reason standard.lub can't be decoded is because Sonic '06 SDK for some reason has trouble decoding the embedded for loop in the file, which is strange because I'm pretty sure there are other LUB files in the game that use the same for loops. Ironically, after reaching the loop, it'll just repeat the contents of the file infinitely until it finishes 'decoding' to the file's intended size.

    Both the Xbox 360 and PlayStation 3 use an identical file structure. The only differences being the xenon folder has been renamed to 'ps3' for obvious reasons. The only code I've come across in other files around Sonic '06 that suggests differences between both versions is in cache.arc, but it only changes how things are rendered to accommodate for how differently the game needs to be rendered on both systems. The PlayStation 3 also uses ATRAC 3 audio, rather than the Xbox's XMA format, again for obvious reasons.
     
  10. Yes, so PS3 only changes bolted onto it :v:. I don't recall off the top of my head, but I think I've ran into a few files getting into an infinite loop. So the assumption is that it isn't a standard "version" of lua?
     
  11. HyperBE32

    HyperBE32

    Blast Processing Member
    23
    0
    1
    Cheshire, England
    Marathon
    Some speculate that some LUB files contain more than just text data, but I doubt that'd result in the SDK refusing to decode for loops. =P
     
  12. So then why the infinite loop then? Not so standard if lua decompilers can't read it
     
  13. HyperBE32

    HyperBE32

    Blast Processing Member
    23
    0
    1
    Cheshire, England
    Marathon
    It's not that they can't read it, they're perfectly capable of doing so. It just has trouble getting past the for loop, which is the purpose of this thread, because we literally have no idea why it refuses. There could be many reasons for why, such as; an unsupported Lua version, miscellaneous data stored in the file interfering with the decoding process, etc.
     
  14. HyperBE32

    HyperBE32

    Blast Processing Member
    23
    0
    1
    Cheshire, England
    Marathon
    After so long of not knowing exactly what was in this file, I came across a pre-decompiled version of it on GitHub and it works perfectly fine when used in-game.

    Contents:
    Code (Text):
    1. ActionStage.Start = inherits_from(State)
    2. function ActionStage.Start.constructor(_ARG_0_)
    3.   Game.Log("construct ActionStage.Start")
    4. end
    5. function ActionStage.Start.Main(_ARG_0_, _ARG_1_)
    6.   Game.Log("Start:Main")
    7.   if _ARG_1_.titleHud ~= nil then
    8.     _ARG_1_.titleHud:ProcessMessage("HudHide")
    9.   end
    10.   if _ARG_1_.bgm ~= nil then
    11.     Game.PlayBGM(_ARG_1_.bgm)
    12.   end
    13.   _ARG_1_:ChangeState("playing")
    14. end
    15. ActionStage.Retry = inherits_from(State)
    16. function ActionStage.Retry.constructor(_ARG_0_)
    17.   Game.Log("construct ActionStage.Retry")
    18. end
    19. function ActionStage.Retry.Main(_ARG_0_, _ARG_1_)
    20.   Game.Sleep(1.5)
    21.   Game.Retry()
    22.   Game.Sleep(0)
    23.   _ARG_1_:ChangeState("playing")
    24. end
    25. ActionStage.Playing = inherits_from(State)
    26. function ActionStage.Playing.Main(_ARG_0_, _ARG_1_)
    27.   _ARG_1_:StartPlaying()
    28.   if _ARG_1_.mainHud ~= nil then
    29.     _ARG_1_.mainHud:ProcessMessage("HudSetPlayerCount", {
    30.       value = _ARG_1_:GetLife()
    31.     })
    32.     while true do
    33.       Game.Sleep(10)
    34.     end
    35.   end
    36. end
    37. function ActionStage.Playing.PlayerDies(_ARG_0_, _ARG_1_)
    38.   if _ARG_1_._life > 0 then
    39.     _ARG_1_._life = _ARG_1_._life - 1
    40.     Game.Log("miss!!")
    41.     _ARG_1_:ChangeState("retry")
    42.   else
    43.     _ARG_1_:ChangeState("gameover")
    44.   end
    45. end
    46. ActionStage.Clear = inherits_from(State)
    47. function ActionStage.Clear.Main(_ARG_0_, _ARG_1_)
    48.   Game.Log("Clear:Main")
    49.   _ARG_1_:ControlPause(false)
    50.   CreateTask("missioncompleted")
    51.   Game.PlayBGM("clear")
    52.   if _ARG_1_.mainHud ~= nil then
    53.     _ARG_1_.mainHud:ProcessMessage("HudHide")
    54.   end
    55.   Game.Sleep(5)
    56.   _ARG_1_.notify = false
    57.  
    58.   -- For loop reconstructed
    59.   for r = 1, 4 do
    60.     if ({
    61.       stage = _ARG_1_.result_name,
    62.       score = _ARG_1_:GetScore(),
    63.       time = _ARG_1_:GetPlayTime(),
    64.       ring = _ARG_1_:GetRingCount(),
    65.       timeBonus = _ARG_1_:CalcTimeBonus(),
    66.       rank = r,
    67.       totalScore = self.score + self.timeBonus,
    68.     }).totalScore > _ARG_1_:GetRankTable()[r] then
    69.       break
    70.     end
    71.   end
    72.  
    73.   while _ARG_1_.notify == false do
    74.     Game.Sleep(0)
    75.   end
    76.   Game.End()
    77. end
    78. function ActionStage.Clear.HudNotify(_ARG_0_, _ARG_1_, _ARG_2_)
    79.   Game.Log("notify")
    80.   _ARG_1_.notify = true
    81. end
    82. ActionStage.GameOver = inherits_from(State)
    83. function ActionStage.GameOver.Main(_ARG_0_, _ARG_1_)
    84.   Game.Log("GameOver:Main")
    85.   Game.Sleep(5)
    86.   Game.End()
    87. end
     
  15. Chris Highwind

    Chris Highwind

    Member
    2,100
    16
    18
    Statesville, NC
    Slacking
    Am I the only one that finds this disappointing? All it seems to do is determine what happens when a stage begins, when you lose a life or game over, and when a stage is cleared.
     
  16. HyperBE32

    HyperBE32

    Blast Processing Member
    23
    0
    1
    Cheshire, England
    Marathon
    I wasn't expecting much from a 3KB file, to be honest. :v: