Sage of Mirrors Posted June 4, 2012 Share Posted June 4, 2012 I've been looking into Luigi's Mansion recently. I've found out a few things, but that's just it- a few. Luigi's Mansion is so different from both SMS and TWW that most of the models and animations are in a different format. Now, Luigi's Mansion uses YAY0 (.szp) encoding on all of its files. The program ArcExtract can decode YAY0 and unzip whatever archive type LM uses, but a stand-alone YAY0 extractor I have doesn't seem to work, as it spits out some kind of file that looks nothing like an archive to me. Because of this issue, no custom files can be put into the game at this time. Just wanted to make that clear for everyone. Cutscenes and events are stored in root\Event. They're .szp files with the naming scheme "Eventxx," where x is the number of the file. There is Event01, Event02, Event03, ect. When unzipped using ArcExtract, there are typically two folders- "message" and "text." "message" contains a .csv file holding all the text for that cutscene, and "text" contains directions in a .txt file. Other files, however, can also be found in certain archives; these files, .cmn and .lig, are not contained in a folder and deal with camera movement and lighting, respectively. The .txt files are named for their event. Their structure is pretty simple, and thus they are somewhat easy to understand. Instructions are contained within < and >, while arguments are normally placed within ( and ). There are also at least two different ways to indicate a new section, which are the equal sign (=) and dashes (-). Almost all instructions are placed between the instructions <FRAMESTART> and <FRAMEEND>, which seem to denote different scenes. There are often instructions before <FRAMESTART>, however. Some of these are: <MENUOFF> Disables the ability to call up the pause menu. <FULLSCREEN> Disables the HUD. <FLAGON>(xx) Sets a flag, where xx is the flag number. <BGM>(xx) Sets background music, where xx is the music index. It's possible that this index is the sequence's index into the game's JaiarcS. <LUIGISTOP> This one is less clear, but it's likely that it disables movement, makes Luigi stop where he is, or both. <NECKOFF> I have no idea what this could be, but its possible that it could disable use of the vacuum. <NOWEAPON> Disables vacuum? It's only found once, at the start of the event where Luigi meets Prof. Egadd. Following <FRAMESTART>, there a multitude of different instructions. <ACTOR>"xxxxx" This is an essential one. x is the name, in ascii, of the actor it calls. Since there is nothing previously declaring actor names in the .txt, I assume that names are stored elsewhere. <ACTOR> is the root of a few other instructions, as well: <ALPHA>(xxx) Determines the visibility of actors. x is a number between 0 and 255. 0 is invisible and 255 is completely solid. This is probably used primarily for ghosts, though it could also be used for some cool effects. <MASKOFF> Disables... masking? A note in Japanese relating to <MASKOFF> references disabling a shadow; because ghosts normally make a pulsing light below them on the floor, this might be what it disables. <SHADOWOFF> Disables shadows. <COLOFF> Unknown. Maybe it disables collision? <POS>(xx)(yy)(zz) Assumedly moves an actor to the specified (x,y,z) coordinates. <ACT>"xxxxx" This is the most important instruction related to <ACTOR>. x is the name of an animation to be played in ASCII. <PATH>"xxxxx" Not currently known. Other instructions include: <WINDOW>(x)<COLOR>(y)<SPEAK>(z) Opens a text box, sets the background color and calls text to be displayed. It is currently unknown how the text is indexed. <CHOICE>"xxxxx"(y)"zzzzz"(a)<LISTEND> This is a bit complicated. It controls dialogue options, with x and z being names of the variables in ASCII. y and a are the text indexes of the options. There can be more than two variables. <ANYKEY> Found often after <WINDOW>. It probably tells the game to wait for the player to press a button before moving the text along. <CHECKFLAG>"xxxxx" This checks a flag, the name of which is in ASCII and goes in x. There can be multiple flags to be checked. <CASE>"xxxxx" Seems to have multiple uses. It works with <CHECKFLAG>, working like an "if, then" statement. In this use x is the flag that makes it run. It also works with <CHOICE>, where x is the name of the variable. <WAIT>(xx) Pauses the script for x amount of time. <RANDOMJMP>"xxxxx" Despite its name, this isn't random. It jumps to the <CASE> instruction specified in x. <CAMTARGET>"xxxxx"(yy) Moves the camera towards the actor in x. y is an unknown variable, but might have to do with the distance between the camera and the actor. <SE>(xx) Plays a sound effect. x is the index of the sound effect. <FLAGON>(xx) Turns the flag specified in x on. <FLAGOFF>(xx) Turns the flag specified in x off. <COUNTJMP>"xx" This instruction is ambiguous. x is a number, and there are often other numbers with it. It can be used with <CASE>. <WARP>(xx) Warps the player to another room specified in x. <GENON> It might be a flag that determines if you can capture a Portrait ghost. Note that, according to google translate, the word for "vacuum" in Japanese begins with the the letters "gen." <CLOSEWINDOW>(xx) Closes a window, obviously. x is unknown. <ALLSTART> Might have to do with ghosts. Specifically, the vacuumability of Portrait Ghosts. <HLIGHTON> Turns the flashlight... on? A Japanese note near this instruction references turning the flashlight off. <HLIGHTOFF> Turns the flashlight... off? <TIMEACTIVE> Unknown at the moment. <GCAMERA>"xxxxx" Calls a .cmn file, named in x. <GCPATHLIGHT>"xxxxx" Calls a .lig file, named in x. <LEVSE>(xx) More sound effects, but it's unknown why it has two instructions. So, for instance, a cutscene in which a golden puncher ghost talks to Luigi would look something like this: <MENUOFF> //Disable menu accessibility <NECKOFF> //Disable Vacuum accessibility <FULLSCREEN> //Disable HUD -------------------------------------- <FRAMESTART> //Start of the sequence <ACTOR>"demo_obake"<ALPHA>(180) //Sets Ghost's opacity <ACTOR>"demo_luigi"<ACT>"L_TDM01" //A Luigi animation (this one's a placeholder) <ACTOR>"demo_obake"<ACT>"H_TDM01" //A Ghost Animation (this one's a placeholder) <WINDOW>(0)<COLOR>(1)<SPEAK>(1) //Dialogue box <ANYKEY> //Wait for the player to press a button <WINDOW>(0)<COLOR>(1)<SPEAK>(2) //Another dialogue box <CHOICE>"scared"(1)"notscared"(2)"huh"(4)<LISTEND> //Start dialogue tree <ANYKEY> //Wait --- <CASE>"scared" //If the player chose the "scared" option... <WINDOW>(0)<COLOR>(1)<SPEAK>(6) //The ghost says something... <SE>(4) //Laughs... <WAIT>(5) //Waits... <ACTOR>"demo_obake"<ACT>"H_TDM01" //Starts to disappear... (animation not real) <ACTOR>"demo_obake"<ALPHA>(0) //And its opacity is set to 0 <NORMALSCREEN> //Returns HUD <MENUON> //Allows menu access <NECKON> //Allows Vacuum <FRAMEEND> //Ends scene <END> //Ends instructions Note this this could be horribly wrong, and would probably need to be revised if it were to actually be placed into the game. This game has a ton of secrets to unlock, but I feel confident that we will discover them in time. Link to comment Share on other sites More sharing options...
Sage of Mirrors Posted June 5, 2012 Author Share Posted June 5, 2012 I've been looking into how general objects are placed, and I believe that I've figured it out. While room models are stored in rootIwamotomap2, there is another file by the name of map2 rootMap. This .szp file contains many different files, including effect models available to the set of rooms and path files. However, there is also a set of files in the folder "jmp" all ending in -info. "enemyinfo," for example. There are a TON of these. The most notable, I assume, would be "enemyinfo," "characterinfo," "roominfo" and "furnitureinfo." characterinfo seems to deal with cutscene and event actors. The file for the main rooms of the mansion (since almost the entire mansion is considered one map) begins with a header 0x13C bytes long. I'm still looking into it at this time. There are many entries after the header. These entries are 0xB8 bytes long, and begin with the name of an archive in rootmodel. I'll use what I believe to be the first ghost in Event01 as an example. ASCII: demobak1........................----............................(null)..........................demo_obake.........................#..........................XbÂÅaHDV±ìÅ.éš....AÙš.... Hex: 64 65 6D 6F 62 61 6B 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2D 2D 2D 2D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 28 6E 75 6C 6C 29 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 65 6D 6F 5F 6F 62 61 6B 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 23 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 58 62 C2 C5 61 48 44 56 B1 EC C5 1F E9 9A 00 00 00 00 41 CD 99 9A 00 00 00 00 Here, the first few bytes in ASCII are "demobak1." We also see the text "(null)" and "demo_obake." demo_obake is the name used in the actor instruction for the first ghost; decompressing demobak1 reveals animations using the name scheme "y_tdmxx." Animations using this same scheme are used in <ACT> portions of <ACTOR> for demo_obake. Thus, demobak1 is the object name while demo_obake is the name used for events. More information to come. Link to comment Share on other sites More sharing options...
Recommended Posts