class file specification

Started by Radical_Pi, June 13, 2009, 09:20:10 PM

Previous topic - Next topic
June 13, 2009, 09:20:10 PM Last Edit: June 14, 2009, 06:46:39 AM by The_Pi
I'm going to be spending a little while looking over the CLASS files (compiled ODFs and what macs edit in hex editing) to see if I can decode the format. If all goes well, I may be able to write a full class file editor for PC and release the source for a mac developer.

Please note that this post is in progress and I am currently editing it

All hex values will be in this format: bytebyte bytebyte ...(ASCII if applicable) ex. 5052 4f50(PROP)

Class header

NOTE: THE FOLLOWING SECTION IS NOT IN LVL FILES

un-lvled class files all begin with 7563 6662(ucfb). This is removed when the class file is added to an lvl and I believe it is just to verify a legal file for lvls.

immediately following the ucfb hex is the length of the file in reverse-byte order (little endian I believe, so I'll use that for the rest of the post). I believe this is a file integrity check before being put into the LVL file, as it does not appear in the lvl chunk.

NOTE: THE REST OF THIS IS IN THE LVL FILES

Next you should find a 4 byte type identifier. From what I've seen it is a hierarchical identifier for the ODF type (ex. a root object in the world such as a soldier is entc (entity class), the weapons it carries is wpnc (weapon class), and the bullets are ordc (ordinance class)). I believe this is only important for the ingame parser, which routes the ODF to different code based on the type (for example entc ODFs throw errors from Entity.cpp). This is most likely chosen by the bracketed section at the top of an ODF file (GameObjectClass translates to entc, WeaponClass translates to wpnc, and OrdinanceClass translates to ordc)

The next 4 bytes are a file length (little endian again), which operates the same as the one that doesn't appear in the LVL file. It is an offset starting from 4241 5345(BASE).

After the length, there is 4241 5345(BASE). This is the beginning of the actual ODF file, but I still consider it header for a small reason that I'll explain a bit later.

The next 4 bytes are just the length of the ClassLabel (see ODF files for what it is), in little endian again.

After the length of the ClassLabel is the actual label in ASCII. This follows the same rules as a PROP declaration for data length, except for it has a 4-byte type instead of 8-byte.

Next up is 5459 5045(TYPE). It is basically the same thing as the BASE declaration, except it has the ODF name without .odf in it. Since it has data that doesn't appear in the file, I still consider it and everything before it part of the header.

At this point the header ends and the actual data from the ODF file begins.

Class body

After the TYPE declaration, all you will find in the file is PROP declarations until you reach EOF or the next chunk. The format of a PROP declaration is as follows:

5052 4f50(PROP)
Then an 8 byte identifier of the ODF setting being set
Following the 8 bytes, the actual data appears
After the data, there are 1-4 NULL bytes

There are 2 rules that define the number of NULLs that appear after the data.
1) The length of the PROP declaration must be a multiple of 4
2) There must be at least 1 NULL after the data set.

So, the constant length PROP data is 12 bytes, a multiple of 4. After those 12 bytes is the data, which is an unknown length. If the length of the data is a multiple of 4, it will have 4 NULLs after it to match rule #2. If the length isn't divisible by 4, NULLs are added until it is divisible by 4.

Next up, the list of the 8 byte PROP IDs and their equivalent ODF options. I'm putting it in a separate file since this post would get way too long and there aren't spoiler tags

Download the list here
---------More coming soon--------

Viruses are like the New York Lottery. "Hey, you never know"

Have you been using Riley's .lvl reference as a guide?

Actually, I just looked at that, and he got it slightly wrong, since he didn't have the munge tools

the 8 byte ucfb+size header is not limited to just lvl files. I've looked at all of the mid-munge files (compiled but not lvled), and they all contain the header. What's more interesting is that model files for example (compiled msh) already contain the sub-chunks he talks about. In fact, all the files are in the chunked format already and could be passed of as LVL files. To me it looks like the ucfb.... is just a file integrity identifier and it confirms that it is valid for lvl inclusion.

All this makes me think that levelpack (lvl creator) just reads in the REQ file, checkes all the files stated for ucfb, then removes the header, shoves the files together, and slaps on the header on the new lvl file.

I think I might make an updated version of his format sometime, since it seems so simple to me now

btw, the file with everything is called "Never Gonna Give you up.txt" for now. I need to change it sometime

Viruses are like the New York Lottery. "Hey, you never know"