This is a response to a thread I found in the archives, here:
http://www.eqemulator.net/forums/showthread.php?t=15876
For my own purposes, I've been working on parsing some of the EQ files (mesh data mostly). It's kinda fun to try to figure them out, anyway I've made a bit of progress on the TER file beyond that listed in this thread, and figure I'd share it, in case anyone wanted to know. I will use the syntax of the original thread (C style), although I'm coding in Java myself. The salient points follow:
1) At this time there are 3 versions of the file format, with Header->version values of 1, 2, and 3.
2) After the Header is a section of Strings, and then a segment which the original thread was not able to figure out. I figured it out.

Here's how to parse it:
- Seek from the end of the header an additional Header->list_length bytes. This gets you at the start of the object list.
- The name list is a series of null terminated strings.
- In a loop for Header->object_count times, you will find:
Code:
struct ObjectHeader {
uint32 index; // A non-unique number assigned to the object entry. Unsure how to interpret at this time.
uint32 name_offset; // Name of the object, as offset from start of the name list. C convention uses null termination on Strings. (e.g. rockGrunge)
uint32 other_name_offset; // Another name offset (e.g. Opaque_MPLBump2UV.fx)
uint32 property_count; // Count of object properties to follow
}
- Following each ObjectHeader, in a loop for ObjectHeader->property_count, you will find:
Code:
struct ObjectProperty {
uint32 name_offset; // A name offset for the property name
uint32 type; // The type of the property
uint32 value; // The value of the property
}
- Based on the ObjectProperty->type, one interprets the ObjectProperty->value as a 'float' when 0, a name offset when 2, and an uint32 (RGBA value?) when 3.
At this time, outstanding items include:
- Why do ObjectHeader->index values repeat. I do note that they tend to start at 0 and work their way up 1 at a time, and then reset to 0 or 1, and continue the progression. Rinse/repeat.
- Sometimes there appears to be duplicate object entries out there. Perhaps this is related to the above point. There could be a higher level structure about this list of objects I'm not seeing.
- I've not noticed a difference between Version 1 and Version 2 files, but I've not looked hard yet.
- Version 3 files include additional data after the polygon list. I've not yet tried to figure out what it is.
For an example of the object data, I am able to extract the following information from the westkorlachb.eqg/ter_westkorlachb.ter file:
Code:
Object 0: FailsafeShader
Effect: Opaque_MPLBasic.fx
Properties:
e_TextureDiffuse02 = grid_standard.dds
Object 1: Material #1
Effect: Opaque_MPLBump2UV.fx
Properties:
e_TextureDiffuse02 = Di_korlach_cave_wall01.dds
e_TextureNormal02 = Di_korlach_cave_wall01_16n.dds
e_TextureCoverage02 = ab_WKB_bot_ov01.dds
e_fShininess00 = 12.0
Object 2: Material #2
Effect: Opaque_MaxWater.fx
Properties:
e_TextureDiffuse02 = rc_cavewater_c.dds
e_TextureNormal02 = rc_cavewater_n.dds
e_TextureEnvironment02 = ra_watertest_e_01.dds
e_fFresnelBias0 = 0.2
e_fFresnelPower0 = 8.0
e_fWaterColor13 = 0xff000a1c
e_fWaterColor23 = 0xff003a2b
e_fReflectionAmount0 = 0.2
e_fReflectionColor3 = 0xffffffff
e_fSlide1X0 = 0.02
e_fSlide1Y0 = 0.02
e_fSlide2X0 = 0.03
e_fSlide2Y0 = 0.03
Object 3: Material #3
Effect: Opaque_MPLBump2UV.fx
Properties:
e_TextureDiffuse02 = Di_korlach_cave_wall01.dds
e_TextureNormal02 = Di_korlach_cave_wall01_16n.dds
e_TextureCoverage02 = ab_WKB_top_ov01.dds
e_fShininess00 = 12.0
gus