Welcome to Open Carnage

A resource for Halo Custom Edition and MCC modding, with unique means of rewarding content creation and support. Have a wander to see why we're worth the time! - EST. 2012


Textures - S3dpak Format Spec

Posted (edited)


    Hello! My name is Zatarita! Today, we look at Texture files found inside of S3dpaks. On the Xbox release of CEA. The S3dpak is the primary file type used for storing game asset data. This means for the Xbox version the S3dpaks had to contain the textures used by the assets in scene. There are a few different files that work together to allow the engine to load and index textures when needed. For example TexturesMips64, and TexturesInfo. For more information on these the appendix. Depending on when you read this, there may be dedicated pages explaining them and how they work together.  By the time you are done reading this tutorial. You should feel confident in your ability to navigate through a texture file. I will also show you a few techniques to extract the textures manually from the file; given you ever find your self with the need to do so. 

    One thing to keep in mind is there are two different flavors of Texture. The ones in the pac_stream.s3dpak are different from the ones inside of the level s3dpaks. I'm assuming it was done this was so that s3dpak could stream the texture pre-formatted right into memory without any other processing. These streamed textures use the same format number as the non-streamed variants ( 0x6 ) inside the s3dpaks. So there is no easy way to tell which texture type you have without inspecting the data. These style textures are not going to be covered as I sadly don't have enough time at the moment, and requires a more nuanced explanation. I will cover these textures in their own post to give them the needed attention they require. 

    I will periodically review this post to add updated information as new discoveries are made; however, all information present here is correct to my current understanding. Some things may be proven incorrect. 



    The Texture file utilizes a common system used by a lot of different saber files. Each 'structure' of data is assigned a sentinel value. Following this sentinel value is the end of block pointer. This end of block pointer points to the start of the next sentinel value. Everything in-between is data that belongs to the structure of data. The "structure" can be anything, sometimes even just one property of the data. For example, we can see in the picture above the sentinel "0F 00" in blue with the end of block value "0A 00 00 00" following it in pink. The value "0F 00" in this context denotes that the data is a signature. In green we can see the value of the data "TCIP" which denotes that the superseding data should be interpreted as texture data. Following this we have "02 01" and another end of block value. With an understanding of the sentinel system; I can explain the data in relationship to that system. It will make more sense.


  1. F0 00 - Signature ("TCIP")
  2. 02 01 - Dimensions Width, Height, Depth, Faces (0x400, 0x400, 0x1, 0x1)
  3. F2 00 - Format (0xC)
  4. F9 00 - Mipmap Count (0x1)
  5. FF 00 - Pixel Data ( ... )
  6. 01 00 - End Of Data (     )


Additional Reading


While this is not required for the understanding of the Textures format. It might assist with better understanding other aspects of the engine. The TexturesMip64 follows the same exact format. Not only that the PC version uses a variant of the format for their Ipak entries as well. The primary difference between the two versions is the PC version does not have End of Block values. They are instead nulled out with FF FF FF FF. If we compare the two of them side by side, we can see they're identical besides this change:

unknown.png   unknown.png
Xbox Textures format (left)   vs   PC Ipak Entry (right)         

A side effect of this is the PC version has to have extra metadata to tell the engine the size of the data ( since there is no end of block value like in the xbox version ) and because of this ( I assume ) the Imeta was born. For more information on this see the ipak/imeta and TexturesMip64 references in the appendix. ( If they've been made yet )



    Formatting follows a similar system to the other files like TexturesInfo, TexturesMips64, and the Ipak. I have laid out on a table the supported textures for the Saber engine. Out of all of the options, only a handful are used by MCC, and they are highlighted in green. This table can be used to reference which format number is which dds format. As seen above in pink, the format of that texture  is 0xC. Which corresponds to the value OXT1 on the table. For more information on the table see TexturesInfo in appendix.




    Now we get to the fun part. We're going to use the information we extracted from the data above to extract a DDS file from the Texture. For this we're going to need a few prerequisites. RawTex will help us generate us a DDS header for our data. Also, In order for rawtex to show us a preview it requires texconv to be installed in the same directory as rawtex. Once we've done this we can open rawtex, and drag a texture into the window.


One thing to know about rawtex is it doesn't care for mipmaps or extra faces. This might be A WAY to do it, but it's not the best. The most optimal way is to generate an appropriate dds header from the raw data.




    Briefly I will go over the UI. On the top left there is a textbox labeled 0xOFFSET which is how we tell rawtex where to find the pixel data. On the column to the left, and row on the top, there are height and width selection options, Plus text boxes where you can manually type it in. Also, on the column on the left, we have a few options for format. Following this is the "Try and Convert" button. There are a few other things; however, for our purposes this should be enough. The best way to figure it out is to play around with it. It's one of my go-to "Reverse Engineers Toolkit" items. 

    Moving on, we're going to extract a texture using the above information. I grabbed a random texture and dragged it into a newly opened rawtex window. When we do that, we see this beautiful creation. We have to update the information to the correct properties using the data from the hex. The important data is the height, width, and format. For my case the data is 256, 256, OXT1. Once the correct values are inputted. We are shown the texture, and a .png copy of the texture is saved to the same directory as the original file once you click "Try and Convert".

unknown.png    unknown.png




    The xbox version of the game utilizes s3dpaks as it's primary format for storing data. Because of this, they need to be able to support textures which can be utilized by assets on scene. They manage this with the "Textures" format. There are a few variants to the Texture format, and in this tutorial I introduced you to the non-streamed variant. In this brief spec I attempted to present to you enough information about the format to be able to navigate it's contents with some level of confidence. Thank you again for stopping in.

Currently I'm unsure if there is a tool out there that can extract from Xbox s3dpaks; however, in the s3dpak specification I go over how you can manually extract data if needed. It's not too complicated.





ipak / imeta


Edited by Zatarita


S3dpak - format - Imeta/ipak - format - Fmeta - format


H2a-inflate - SuP

Share this post

Link to post
Share on other sites


Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.