Creating Levels in Sonic Heroes
From Sonic Retro
|SCHG: Sonic Heroes|
(Original guide by igorseabra4)
First of all, you should come here and download the latest version of Heroes Power Plant (I'll just refer to it as HPP from now on). Get Magic.TXD as well, as we're gonna need that to edit TXD texture archives. For model editing, we're gonna use 3ds Max, although it's possible to use other model editors as well, 3ds Max is reccomended due to being easy to export different parts of the model to separate files (which we're gonna need to do). Heroes Mod Loader will be used to load the levels for testing and playing ingame, and HeroesONE is optional but necessary if you're porting objects between levels.
In the PC version of Sonic Heroes, level models are multiple BSP files located inside ONE archives; their visibility data in the level's s*_blk.bin file. Both are located in the dvdroot folder. The collision model is a CL file in the dvdroot/collisions folder. HPP can handle editing of those. Textures are located in a TXD archive, which we'll edit with Magic.TXD.
If this is your first time creating a level for this game, it's a good idea to first extract and take a look at the original levels, to see stuff like their size, shape, how they're laid out etc. HPP can export level models and collision models in OBJ format, but it can't load all BSPs; some of them you'll have to rip with File:Bsp2objv021sonic.zip (included in the HPP download) after extracting the raw data from the original ONE. Magic.TXD can rip the textures.
Since the console versions of Sonic Heroes use the same file types for most files and do accept .BSPs from the PC version, you can create custom levels for the PC or any of them, as long as you remember to save the .TXD in the correct version (Magic.TXD allows you to choose either PC, GameCube, Xbox or PlayStation2). However, data located in the EXE such as start positions can't be modified in those as there's no mod loader for these versions.
Setting Up a Mod
First of all, we're going to set up a mod folder for your work. Your stage is going to use the Generic Stage Injection Mod to replace start positions and splines at runtime by the Mod Loader, without need to edit the game's EXE. None of the game's original files will be replaced during this, but even so, it's reccomended you back all of them up just in case you mess something up or something goes wrong.
Notice the HPP package has a folder called Generic Stage Injection Mod DLLs. You'll find two DLLs named main.dll inside Development and Release folders. As quoted straight from the readme.txt file also located here:
These two Mod Loader mod main.dll files contain custom start position and spline injection mods which are loaded from the Config.cc file generated by HPP.
The difference between them is that the DLL in the Development folder contains additional code for re-replacing the mod files while the game is running; this means you can edit the files and see the changes ingame in real time (the files are replaced again every time you quit a stage). The DLL in the Release folder doesn't have this function, and the stage is injected into the game only once, since the players are not going to edit the files. While making your levels, use the Development DLL; when releasing them, use the Release DLL. Each DLL will output a different message to the Mod Loader log, so you can know which one you're currently using.
Note that, in the Development DLL, splines are injected only once, so to see changes in them you must quit the game and open it again. Start positions and all other files will be replaced with the game running.
With that in mind, browse to your Heroes Mod Loader folder and take a look into "Mod-Loader-Mods". Create a new folder here and name it whatever you want to. Then, create a text file named Mod.ini and place it in this folder (you can copy one from another mod if you're lazy) and edit it to fill it with your mod's info. Copy your Development main.dll here as well (or the Release one, if that's what you want). Now create a new folder called "root" here and another one called "dvdroot" under root (you can mimic this from other mods). If you want to, right now you can also create a "collisions" and a "textures" folder under dvdroot so you won't have to do it later.
Open up HPP and you'll see a black screen. Press F1 to show the Viewport Config window, which shows some information about what's being drawn. This window also has a bunch of text explaning how to use the program and I really reccomend you to read it as I'm not gonna explain here. Open the Mod Loader Config Editor window and create a new file. In the Level Flag box, choose which level you want your custom one to replace; this is an important step as some objects will only work in the level slots they originally belonged to (such as frogs) and pinball table and bingo slide collision also only works in slots which originally had them. So once you've picked a level that suits your desires, save the file as Config.cc (other names won't work) in your mod folder. A "Splines" folder with a file named 0.obj should also pop up, leave that there for now.
Your mod should be set up and will show up in the Mod Loader for enabling. If you try it now, since there are no new files, all you're gonna get ingame is the original level but you'll start at the 0, 0, 0 position and there will be no splines.
For more information, see Model Format.
I assume you already have a model of a level you want to import in 3ds Max right now.
Chunks are the game's way of splitting a level into multiple parts, so only a some of them will show up at a time. Each chunk has a number and is made up of multiple BSP files, if your curiosity made you open one of the game's original ONEs you should have noticed that. This is how a BSP is named:
SLL_MM_NN.BSP (or STG instead of S)
LL is the level number, MM is the material setting identifier and NN is the chunk number. Check the Level List page to see your level's number (in the File Names and Data list). That will also tell you whether your files start with S or STG.
For the game to know which chunk to display at a given time, the camera must be inside boundaries set in the s*_blk.bin file, which we'll discuss soon; if the last part of the name is ommited (SLL_MM.BSP) the file will always be displayed (this is used for some levels' skyboxes).
The files also have different MM material settings. They will set how the model is rendered. For a complete list of what you can use, see Material Flags. These are some of them:
- ON - Normal
- ONS - Normal, shadow casting
- ONW - Normal, no culling
- ONWS - Normal, no culling, shadow casting
- DN - Skybox
- PN - Normal, alpha testing
- PNS - Normal, alpha testing, shadow casting
- PNW - Normal, alpha testing, no culling
- PNWS - Normal, alpha testing, shadow casting, no culling
- DA - Skybox, alpha material
- AFN - Alpha material
- AFNS - Alpha material, shadow casting
- K - Additive alpha
- KW - Additive alpha, no culling
Importing Your Models
In 3ds Max, you should split your models into meshes so that each mesh will be converted into one BSP file. You can first split the model into multiple by chunk, then split each chunk into the different components of it: floors should be in their own mesh (ONS) as they recieve shadows and walls (ON) don't. Parts of the model with textures with alpha testing should have the PN in their name, textures with normal alpha should have the AFN in their name, the skybox will be DN, effects such as water and glow will be K and so on. You can name your meshes the same name of their BSP so you won't have trouble renaming them later. A file name for the floor models of the third chunk in Seaside Hill would be S01_ONS_03.BSP, a name for a model with alpha textures for the fourth chunk in Casino Park would be STG05_AFN_04.BSP. Note that you can use the shaders from the original stages as well (such as animated water and blue roads from the city levels). Just take a look at the texture name in the original TXD and name your texture accordingly.
There's a maximum of 65535 vertices and triangles per BSP, but each one shouldn't be even close to that (as HeroesModelTool will add extra vertices to fix UV coordinates and vertex colors). Each resulting BSP shouldn't be much bigger than around 400 kb or the game will crash; if that happens, when importing, HPP will warn you of that. In that case, split your files into even more chunks.
Export each mesh to a separate OBJ or DAE file (remember to use Y axis = up). The model must use triangular faces, contain vertex positions and texture coordinates. Vertex normals are ignored as the game doesn't use them, and for DAE, vertex colors are supported (Heroes uses vertex colors extensively for shading and shadows on the models). Texture names will be the same ones of the textures you're using in 3ds Max. Their names cannot contain spaces. This addon for 3ds Max can automatically export each model to a separate file just as we need.
Now, import your models using HPP's Level Editor. Double-click the files to rename them if needed, then save. Take a look into your original game's dvdroot folder. If there's a s(tg)LL_h.one file for your level, then that should be your ONE file name; if there isn't, save it as s(tg)LL.one. Save it inside your mod's root\dvdroot folder (in your mod's folder), don't replace any of the original files. Saving a ONE file takes quite a bit of time, the program might hang up for up to one minute.
Since you have no visibility file set up yet, nothing will initially show up; disable the Render By Chunk checkbox in the Viewport Config (or the H shortcut key) to disable per-chunk rendering. If you did everything correctly, your models should show up in HPP.
Except they probably have no textures if you haven't set that up yet. To set up textures for HPP, create a new folder with the same name of your ONE (without the extension) under HPP's Resources folder (there's an example s01 folder there). Place your textures in PNG format in that folder and HPP will be able to render your level with textures once you save or reload the ONE. This obviously won't add your textures to the game, as for that they must be put in the TXD archive.
For more information, see Visibility Editing.
Ingame, each chunk is rendered if the camera is inside the visibility boundaries defined in the _blk.bin file. The level editor in HPP includes a visibility editor, where you can add chunks, set the number that they refer to, edit their maximums and minimums and see the chunk boundaries displayed in the viewport (disabled by default, check Chunk Boxes in the Viewport Config or press B to toggle that). You can verify that the chunks are rendered in the proper locations by disabling Render By Chunk and checking them out in HPP. When you're happy with your visibility layout, save the file as s(tg)LL_blk.bin in your mod's root\dvdroot folder along with the ONE. From now on, when opening the ONE in the Level Editor, the visibility file will be loaded as well.
If you run your game with the mod enabled now, you'll probably be able to see the custom models, except they have no textures since we didn't add that yet. Also, you have no start position and the collision is still the original level's. It's a good idea to test it now, because if the game crashes, that probably means one of your BSP files is too big (the game doesn't crash if you have an invalid BSP or visibility file, only if it's valid but too big).
We'll be using Magic.TXD for the textures.
The TXD files for level textures are located in dvdroot/textures. You'll probably figure out by now the name of your level's. Copy the original TXD from your game to your mod's root\dvdroot\textures folder and open it in Magic.TXD.
Use Edit->Add or the Insert shortcut key or just drag your new textures into the list to add them to the file. Each texture should have mipmaps and be DXT1 compressed, except for textures with alpha (you can manipulate those settings in Magic.TXD by pressing M with the texture selected; just take a look the format the original textures use and try to mimic it).
Save and make sure the version of the TXD is correct (it should be Sonic Heroes PC, or GameCube or PlayStation 2 if you're editing those versions). Don't delete the original textures from the file unless you're sure of what you're doing (some levels will crash without certain textures). Remember this file contains textures for both level and object models. If your model uses the same textures from the game that are already in the file (such as shaders) you obviously don't need to add them a second time. You should test your level again now and it should render correctly.
For more information, see Collision Format.
First, you must create a collision model. You should start from your level's original model, but get rid of details such as plants that are not supposed to be touchable. You can also add invisible geometry to it. Replace stairs with ramps. Make sure the model is as simple as possible. Split it into multiple meshes, as this division will be kept in the file. This model has a maximum size of 65535 vertices and/or triangles. Export it as OBJ and import it with HPP's Collision Editor window. Save it in the mod's root\dvdroot\collisions folder (it's named s(tg)LL.cl).
Notice there are a few settings in the collision editor: depth level, power flag and flip normals. If you're just a regular stage modder and have zero idea how Sonic Heroes internally handles collision, just leave them as they are (depth level at 5 and power flag at 0xD). If you want to, you can set the depth level to auto. This will usually result in your collision quadtree's depth level being from 8 to 10. This means the game will take less CPU to check for collisions and will run better (at a higher resolution, no framerate drops) on lower-end computers, which is your goal (you want people to play your level even if they have bad PCs) (if you set your depth level to 1 or 2, even if you have a nice PC your game will lag terribly). But custom collision files with high depth levels are known to make the game crash at random spots while running (we have no idea why) and that's why we can just leave it at 5 for now, as it won't crash and won't make your game lag unless you have a computer with terrible specs. If it works, why bother? As for the power flag, it defines a few numbers that are added to the quadtree's settings, we don't know much about what it does. Most of the original files leave it at 0xD so that's what we do.
Once your model is imported and saved, you can check Show Collision or use the X shortcut to display it. The file's quadtree can be displayed as well if Show QuadTree is checked, although there's not too much need for this except maybe for debugging purposes. If you test your model and notice collision is buggy in some parts (such as floor clipping), it's probably because some of your meshes have too many triangles. Try simplifying the mesh, and if you absolutely can't, split it into 2 or more.
When creating your collision model, you must name your meshes so they represent different parts of the level. Append an underscore _ and one of the following letters to set the collision type for that mesh:
- nothing - normal floor collision
- _a - Water collision (for _wt.cl).
- _b - Bingo slide.
- _i - Invisible wall. No noticeable difference from normal wall.
- _k - Protection barrier. It's a wall that is only solid as long as you are touching the ground.
- _l - Slippery wall. It's a wall that has an angle, so you'll slip out of it. You'd be able to walk on it if it was normal floor collision.
- _p - Pinball table.
- _s - Stairs. Model should be a slope, but your character will stand upright on top of it (if you make a steep slope with this flag, you'll be reminded of Sonic 4)
- _t - Triangle jumpable wall.
- _w - Wall. You can't walk or run on top of it.
- _x - Death collision (for _xx.cl)
Note that the bingo and pinball types will only work in levels which originally had them. The difference between them is that you accelerate much faster and have more control on slides than tables.
If you want to experiment a bit, you can also set the flags manually. Export the collision from one of the original CL files to OBJ, import it in 3ds Max and take a look at how meshes are named. You can append the same type of formatting (_WWXXYYZZ, 4 bytes) and the flags will be that. You can play with flags that have not been documented yet with this.
sewer56lol's Collision Library
sewer56lol has worked on a tool and library for handling CL files. Its collision generator can be considered superior to HPP's for a few technical reasons. You can get the source here.
The project README contains instructions on how to operate the tool and use the library in your own programs if desired.
Death Zones and Water
CL files that have _xx or _wt appended to their names contain collision for death and water boundaries, respectively. You can import them with HPP, make sure all models have _a or _x to their names as specified above. When importing, make sure Flip Normals is checked as these files use reversed normals; they'll show up upside down and you'll have to disable culling to see them right side up. These files are a bit problematic and are known not to work ingame for unknown reasons. This is still being worked on. Maybe sewer56lol's collision tool will handle those files better than HPP.
HPP's Layout Editor window can open and edit layout data; Heroes SET ID Table Editor (which is included in the HPP package) can be used to change object availability for use on certain stages. Object layouts are contained in s(tg)**_p**.bin for each level and team; save them to your root\dvdroot folder. Once you open a layout file in the editor, it should be pretty straightforward; just place objects wherever you want. You can click to select them, move them, rotate, set misc. settings, see a preview of them as a small cube (some objects such as springs and triggers even show up with a different model). Please read the Object Editing and Object Porting pages for all the info on this.
To do: this section
Start Positions and Splines
For more information, see EXE Editing.
You can set start, ending (victory animation) and bragging (for the start of multiplayer levels) positions in HPP's Mod Loader Config Editor. These will be saved to the Config.cc file. For starting and ending positions, the only thing that shouldn't be self-explanatory is the hold time; it's the time you spend running before you gain control of the characters. It only applies to a Running start mode. Get the coordinates from the object layout editor for convenience.
As for splines, you can import those in the Spline Editor window. It is reliant on the Mod Loader Config Editor to display and import splines (that's why it will only show up if you have a config file open). When creating a new Config.cc file, if there are no splines present, a default one of type null is created (the Generic Stage Injection Mod doesn't know how to load zero splines, so it must have at least one). You can delete this default spline after importing at least one custom one.
When importing a new OBJ file, make sure the only thing in the file is the spline; all the program will do is read all the vertices in order and create the new spline with them. There are 3 types of splines: autoloops, rails and ball paths. Ball paths are those tubes used in Casino Park and BINGO Highway (it's them in those Power Plant (level, not program) green spheres as well). You can pick one for each spline (setting it to null will make the spline do nothing, this is useful if you want to disable it without deleting it). The splines can be seen in the view if the option is checked; remember to save.
If for some reason you wish to leave the splines of the original level intact instead of importing your own, you can do that by opening Config.cc in a text editor and removing the line that starts with "PUSH_INSTRUCTION_POINTER". Then, you can delete the Splines folder and its contents, as that line is what makes the Generic Stage Injection Mod load your custom splines. You have to do this again every time you save in HPP.
Note that not all levels have spline pointers, meaning you can't add or replace splines for them. The levels which currently have documented ones are the 14 main action stages, Test Level, Egg Albatross and Robot Storm. None of the other bosses, Sea Gate or Multiplayer levels have them yet.
If you wish to extract and take a look at the original game's splines and start positions, Heroes Tweaker (an EXE editor tool which is not updated anymore) lets you open Tsonic_win.exe and do that. It can export the splines as OBJ.
Custom Mod DLL
The Generic Stage Injection Mod, although it has the useful features of replacing start positions and splines from your Config.cc and Splines folder (and mid-game file swapping with the Development version of the mod), can't do much more than that. If you want to edit stuff such as bobsleds, Team Chaotix's mission goals, the amount of items you must collect in their missions, the amount of minutes you have for Team Sonic's Extra mission, the ranking requirements (A, B, C, D ranks) for each team, you must create your own mod DLL, and for that you must know at least the basics of programming in C# with Microsoft Visual Studio. Not only that, you can also add your own code to the game, such as the custom coded mid-level music change implemented in the Emerald Coast stage mod. More details on this will be added later, for know if you want to know more about this, you can ask on our Heroes Hacking Central server on Discord.
Lighting data in s**_light.bin files. We don't know their format yet, but we do know they contain multiple light data entries. They are applied to characters and objects only (it's not environmental lighting). The main entry is applied all the time, and each of the other entries is applied by trigger objects.
Music is located in looping ADX files in the bgm folder. If the music's not looped, it won't start again after ending.
You can add all of those files to your root\dvdroot folder (or subfolders) and they will be replaced by the Mod Loader.