Important Message

You are browsing the archived Lancers Reactor forums. You cannot register or login.
The content may be outdated and links may not be functional.


To get the latest in Freelancer news, mods, modding and downloads, go to
The-Starport

Ships - Destructable Parts

The general place to discuss MOD''ing Freelancer!

Post Wed Jul 09, 2003 7:41 am

Ships - Destructable Parts

Has anyone successfully managed to make parts of a custom ship destructable? Initially i thought it looked fairly straightforward but i have been at it for quite a while now without success. Here is what i have worked out so far, if anyone could point out where i am going wrong that would be great.

Each part has several components :

1 - A .3db file - This is the shape of the part for use when it is blown off, not (as i originally thought) the shape of the part at all times. This also contains the location of the harpoint DpConnect which matches a harpoint on the ship for that part. Presumably the DpConnect and Dp'nameofpart ' (on ship) are for deciding what direction to blow the part in when it is destroyed.

2 - A .sur file - For detecting damage to the part
3 - Entries in the ships main .cmp file - There are two main nodes for each part :

a) An entry under 'Cmpnd' called Part_'nameofpart '_lod1 with 3 nodes :
Filename - Usually in the format 'nameofpart '_lod1xxxxxxxxxxxxxx.3db. Refers to name of second entry in .cmp file. Where the xxxxxxx number is the same for the hull and all the parts.
Index - 8 byte integer array. 'Root' is 0 other parts are numbered 1, 2, 3 etc
Object name - Object name 'nameofpart '_lod1. Matches object name in {Collison Group} entry in shiparch.ini.

b) An entry in the main tree the same as the entry for the main hull. It has the same name as Filename in the above entry. It contains the same nodes as the main hull entry :
Harpoints - Any Hps which are on the part
VMeshWire - ? Rarely more than 100 bytes for a part.
Multilevel - Information for different LODs. 1 VMeshRef for each level always 60 bytes.

4 - Entries in shiparch.ini - {Collision Group} has the stats for the part (hitpoints, type, explosion/debris type etc.) {Simple} Refers to the .3db file and .mat file for the part.

You can delete all the files in the ships directory (except for the main.cmp) and delete all the {Collision Group} and {Simple} entries in shiparch and the parts will still be on the ship when you load up. So the parts are present somewhere in the .cmp.

You can delete the 'Cmpnd' -> 'Part_'nameofpart '_lod1' -> Index entry, the 'nameofpart '_lod1xxxxxxxxxxxxxx.3db -> VMeshWire node and the 'Harpoints' node and the part is still there. This only leaves the 'Multilevel' node which is far too small to contain any decent info.

You can change the name of Part_'nameofpart '_lod1 to anything you like and the part still shows up.

You can change the Filename entry and as long as you make the same change to the name of 'nameofpart '_lod1xxxxxxxxxxxxxx.3db things are fine.

However if you change the Object entry the part disappears. So the object name is referring to the data for the part which must be contained in the main VMeshData node for the hull.

No matter what i do tho i cant seem to get a part to appear on a ship. I have tried defining a part of the ship as a different group. This increases the size of the VMeshData in the exported .cmp file so it is not simply ignoring the extra group. When the ship is in game this part does not appear. So then i added all the relevant entries to the .cmp using the object name i gave the group in milkshape (as the object name for Root is the hulls group name in milkshape this makes sense). No luck. I also tried adding the VMeshData for the part on its own as a separate node under VMeshLibrary again using the milkshape group name but this didnt work either.

I am really fed up. Once the part is registered in the .cmp and FL will show it the rest is a piece of cake. Anyone got this to work?

EDIT - I have just noticed one final place where the parts are referred to. There are two entries in a node in the .cmp file under 'Cmpnd'. The node is called 'Cons' and the subnodes are 'Fix' and 'Rev'. I had overlooked these assuming they were nothing of relevance. However 'Fix' contains the names of all the parts in the format 'Root....60bytes....Object name ....<112bytes'
The total is always 176 bytes regardless of the length of Object name . 'Rev' is similar but only contain references to the bay doors. Hopefully this is the key to it....

EDIT - The 'Fix' entry is the key to getting the parts to show up. I ripped the data from a game ship and replaced the name of one of the parts with the part i was trying to add to my ship. I then added a 'Cmpnd' -> 'Cons' -> 'Fix' entry to my ship and imported the edited data. When i loaded up the normal ship hull was there aswell as a second ship centred on the point where the component from the game ship would have been. The second hull had no Hps and behaved as a destructable part should. Now all that needs to be done is to work out how to get it to display the part in question instead of the whole bloody hull...

EDIT - Further to all this i have discovered that the reference to the actual structure of the part is contained within the data in the 'Fix' bit. If you change the Object name in both the 'Fix' entry and the 'Part_'nameofpart'_lod1' -> Object name entry the part will still appear as long as the object names match. Therefore the Object name name component of the 'Fix' entry is not relevant to what structure to show but is for FL to refer to later on.
Edited by - redeye on 09-07-2003 09:04:58

Edited by - redeye on 09-07-2003 09:48:28

Edited by - redeye on 09-07-2003 10:05:45

Post Wed Jul 09, 2003 2:14 pm

O.k. having investigated further and discovered the ancients scrolls handed down to us by HCl i understand things a bit better.

The Multilevel bit containing the 60 byte VMeshRef's turn out to be very important, after i dismissed them as being too small... The format is :


VMeshRef
{
dword 0x3c
dword VMeshID
word start_vert
word end_vert
word start_vert_reference
word end_vert_reference
word mesh_number
word number_of_meshes

float bounding_box[6 (minx, maxx, miny, maxy, minz, maxz)
float unknown[4
} = 60 bytes


As taken from HCls guide to the vmesh format. He says that the milkshape .cmp exporter provides these vmeshref chunks which is correct. Trouble is it only provides the VMeshRef for the first mesh. This VmeshRef consists of the header, MeshID, mesh number (01 00) and number of meshes (01 00) every other byte is 00. This works fine for the first mesh (no idea why) but if you try to do the same thing for a ship part it doesnt show at all. You can put in the VMeshRef data from the first mesh into your parts entry in the .cmp file and that works (this is how i was getting a second hull in the above post) however if you work out the VMeshID for your second mesh, and change the mesh number to 02 00 the second mesh does not show, even if you enter its VMeshRef in the entry for the hull.

The 'Fix' entry seems to be more involved with where the part is positioned on the ship. I had hoped the 60 bytes between Root and 'nameofpart ' were another VMeshRef but if they are they are in a different format. The x, y, z co-ordinates are located in the data after nameofpart ' in the 'Fix' entry.

As i am able to display a whole second hull with my current 'Fix' settings i assume these should be fine for displaying my ship component but it is possible i am overlooking something here.

I have tried putting in the start and end vertex numbers but that doesnt work. It will be alot more hassle to work out the start and end vert references but i will do that next and put them in. I have also tried a variety of bounding box values with no results. However i am not convinced that this will solve anything because the first mesh does fine with only a mesh number to guide it. The original game ships have full VMeshRefs for every component including the main hull with numbers for everything.

EDIT - O.k. a few final mumblings before i pass out from sleep deprivation... While the original ships do have full VMeshRef parts with bounding box etc. you can strip it right down to VMeshID, start and end vertex and mesh number + number of meshes and the parts still appear.
The start and end vertex numbers are different in the VMeshLibrary and in the VMeshRef. I dont see why.
Also if you edit the VMeshID for any part it disappears. This is a big mystery 'cause this is the only place the VMeshID seems to be. Once it is referenced FL should only refer to it as the full xxxxxx.3db way. There is definitely no mention of a VMeshID in the VMeshLibrary so why should changing it in the VMeshRef bugger things up?

Edited by - redeye on 09-07-2003 17:31:10

Post Thu Jul 10, 2003 3:20 am

If you find the key, let me know. That way, custom weapon models will also become possible. Currently i have some small projects regarding custom shield and missile models.

Post Thu Jul 10, 2003 4:23 am

I am totally stumped at the moment but am sure it is very close to being cracked. Where did HCl go anyway? I'm sure he would have this sorted in about 5 minutes.

I think i'm gonna work on making my 'second hull' destructable and figure out how to move it around the ship. Hopefully in doing that i will notice soemthing i've missed.

I have noticed one more thing. In the game ships all the VMeshID's are the same. That is for each level of detail. I was assuming i had to work out the VMeshID for my component and substitute that in. However if the VMeshID is the same for the main hull and all components in the game ship then presumably i should be using the same ones too.

If i alter the VMeshRef for the main hull entry so that it is the same but instead of starting at mesh 00 00 and there being 01 00 number_of_meshes it starts at 00 00 and there are 02 00 no._of_meshes then both meshes show. However the component is centred on the centre of the model instead of being where it was in the milkshape model. As usual tho things are not as simple as they should be. While you can set up a second hull by copying the hulls VMeshRef into the components you cannot display a second hull+centred component by copying the VMeshRef which displays both meshes into the components slot. Neither will the componet show if you use the VMeshID from the hull and specify start mesh 01 00 and 01 00 for number_of_meshes - even if you put in the correct start/end vertexes. Neither can any part of the hull+centred component twin mesh be removed by defining start and end vertexes.

The saga continues...

EDIT - O.k. incase anyone is reading this i should probably set a few things straight (again) cause i have made alot of spurious suggestions above. I am now very close to having this sorted. It is possible to have both meshes (ship + component) as your components mesh by simply using the main hull VMeshID, starting mesh = 0 and number_of_meshes = 2.

It is not possible tho to simply change starting mesh to 01 and no_of_meshes to 01 and only display the component. However i can now get parts of the component mesh to show by doing the above and setting the start and end vertex numbers (i though i had tried that but obviously had done something else wrong - too many windows not enough sleep...) As i said somewhere tho the start and end vertex numbers are not the same as the start and end vertex numbers in the VMeshData. Using these numbers results in only part of the component showing.

I'm sure it will be possible to work out the conversion using know start/end vertex numbers from the VMeshData and VMeshRef entries from game ships. Hell, if i cant do that i'll just try every combination of 4 bytes until the damn thing shows

EDIT - (again...) Once again i have overlooked something. Having looked at the start/end vertex numbers (VMeshData and VMeshRef) for the game ships components i spotted how to work out the start/end vertex numbers that go in VMeshRef from the VMeshData ones. In the VMeshData segment each component always has a starting vertex of 0 - no matter how many meshs it covers (in the model i was looking at the hull covered 3) the starting vertex was 0. If the component covered multiple meshes then the second meshes starting vertex was (previous mesh end vertex + 1). The VMeshData end vertex numbers for the final mesh in a component are always 1 less than the VMeshRef end vertex number, fairly simple. The start vertex number for any component is the sum of the end vertex numbers for all the components before it in VMeshData (based on the mesh_number order). Because all the components start at vertex 0 the sum of all the previous end vertex numbers gives you the total number of unique vertexes so far. The start/end vertex reference numbers work in a similar way. Start is total number of vertexes referenced by components before current one (triangles in all previous components * 3) and end is the actual number of vertexes referenced by that component. So heres a summary of how to work out VMeshRef start and end numbers from the VMeshData :

Start Vertex = Total of end vertex numbers (in VMeshRef) for all previous components
End Vertex = End Vertex number from final mesh of component + 1

Start_Vertex_Reference = Total of end_vertex_ref numbers (in VMeshRef) for all previous components
End_Vertex_Reference = Total number of vertexes references by all this componets meshes

Obviously this is an imperical method of working them out. This means it probably doesnt apply very well to custom ships because the meshes dont seem to work like that for exported VMeshData's. Instead of all starting with vertex 0 my meshes start with 0 for the first one then after that the starting vertex is the end vertex for the previous mesh + 1. Although this is quite possibly because of the way i built the ship.

Anyway that is a bit of a side issue. What i had overlooked was the start/end_vertex_reference numbers. Previously i had said that the game ship components could survive everything in their VMeshRef's being changed to 00. This is not true. Having tried alot of 4 byte combinations (o.k. not them all but enough) for my start and end vertex numbers and getting a variety of Hollywood style genetic mutations of my component appearing i figured i had missed something out. I went back and stripped down a game ship componets VMeshRef to just the header, VMeshID start/end vertex numbers, mesh_number and number_of_meshes. While at first glance the component appears fine a closer inspection reveals a similar genetic style mutation of the component. Adding the start/end_vertex_reference numbers restores the part back to normal.

So this seems to be the final stumbling block. I have the component appearing in game properly referenced as a seperable part of the ship. I have my eye on 3 floats in the 'Fix' segment that look very promising for locating the componet in x, y, z. The only obstacle is the bloody vertex_reference numbers which i have been avoiding looking at for ages because they seem to be a total nightmare

EDIT - Not much progress but i have it narrowed down to 2 bytes... Both the normal vertex and vertex_reference numbers (in a game ship) can have their end vertex number removed (i.e. replaced with 00 00) without affecting the components look. Hopefully this will also apply to custom components and now i only have to work out the start_vertex reference number and it should work.

Edited by - redeye on 10-07-2003 07:03:56

Edited by - redeye on 10-07-2003 09:40:57

Edited by - redeye on 11-07-2003 02:15:44

Post Fri Jul 11, 2003 3:20 am

I hope you find the key. I've been looking for it for quite a while but gave up and switched to standard weapons. Good luck.

Post Fri Jul 11, 2003 7:41 am

O.k. i have hit a major problem.

Summary so far is that i have a enough understanding of everything except the VMeshRef data segment. This is located in the ships .cmp file, each component has one and it is under the node 'name_of_part '_lod1xxxxxxxx.3db -> Multilevel -> LevelX -> VMeshPart -> VMeshRef.

The format is as above post. HCl says the .cmp exporter creates this section, which is true. However it only creates one relating to the first mesh in the model (first group as defined in milkshape). As i have found out from stripping down the data in game ship .cmp's VMeshRef segments the only data required to correctly display the part on the ship is :

VMeshID
Start Vertex Number
Start Vertex_Reference
Mesh_Number
Number_Of_Meshes

As the .cmp exporter only ever provides a VMeshRef for mesh_number 00 the start_vertex and start_vertex_reference numbers are always both 00.

For the game ships start_vertex/start_vertex_reference are always just the total of all preceding meshes vertexes/referenced vertexes. However as i have discovered simply applying this method to custom parts does not work. While putting in start_vertex worked out this way means the component is displayed in a distorted fashion (as are game ship components if you remove the start_vertex_reference number) putting in the start_vertex_reference number does not correct this distortion (as it does for game ships). I had assumed this was a minor problem to do with the way the vertexes are differently ordered in game/custom ships.

So i went 'back to basics'. I created 2 squares - 4 vertexes and 2 triangles each and put them in the game as a ship. As usual the first group (the 'hull') showed fine. Once the correct starting vertex (04) for the second square (the 'component') was entered it displayed but was distorted - instead of the two faces sharing one of the corners they seemed to be using the corresponding corner from the other square. I proceeded to enter in every value for start_vertex_reference from 00 to 1F. Some of them gave different distortions, some of them made the whole square/component disappear but none of them correctly displayed the square. The theoretical correct value - 06 - made the component disappear as did all values greater than 06. I repeated the experiment with 2 pyramids. This time there were 24 total referenced vertexes and the start_vertex_reference number should have been 0C. Again not a single value from 00 to 1F made it appear properly. Again the theoretically correct number - 0C - made it disappear completely as did all higher values than this. Very high values make the whole computer reset on loading.

The basic result of this is that there is something else missing. Simply working out the correct start_vertex_reference number is not gonna solve things because the brute force experiments above have told me that there is no value for this that will correctly display the mesh/component. This leads me down the road of wondering if the VMeshData segment exported with the .cmp exporter is outputting the vertex data in a way that is consistent with separate parts. It was never designed to so it is quite possible there is something not right about it. Or it is possible the way i have ordered/placed the vertexes in MS is wrong. Maybe the separate meshes need to share a vertex etc.

I am now going to analyze a game ships .cmp file and try to see what is different from the custom .cmp.

Post Fri Jul 11, 2003 9:37 am

I have frigging cracked it!!!

As i type this i have a ship in dock with a fin floating slightly above it. The fin is defined properly as a separate object in the .cmp. I am about to give it a .sur file and test its destructability out in space. I will post a proper tutorial when i have worked out all the remaining things but for anyone who has been able to follow my above ramblings here is the final piece of the puzzle :

Having discovered that no value of start_vertex_reference could propely display a simple component i figured there could be something wrong in the VMeshData segment that was buggering things up.

After investigating the game ships .cmp files i spotted the major difference between a game and milkshape exported cmp. The milkshape .cmp exporter gives the start vertex for any second mesh as the actual number of the vertex (in the list at the end of VMeshData) it then gives the end vertex as the number of the last vertex used. However each mesh in a games .cmp file has 0 as the start vertex (actaully not the start of each mesh, only the starting mesh for each component, but thats a side issue) and end vertex is simply the number of vertexs it reads. So i replaceced my components start vertex with 00 00 and changed end_vertex to the number of vertexes in the component (in the VMeshData chunk). To be on the safe side i also added 1 to the end vertex number on the main hulls mesh header becuase instead of this number meaning end vertex is actually means 'once you have started, read x vertexes'. Any set of numbers defined by 0 - x actually contains x+1 numbers.

Then i opened up the VMeshRef sections for both. The hulls VMeshRef was fine but i checked it had start_vertex / vertex_reference as 00 00, start_mesh as 00 and number_of_meshes as 01. Then i added start_vertex as the actual number of the starting vertex in the data segment i.e. the old start_vertex value in the VMeshData segment. The start_vertex_reference number again is the actual number of the start_vertex_reference looking at them all sequentially as they are referred to in the VMeshData segment - it is the total of all the numbers of vertexes that have been referenced in previous meshes, so in this case it was exactly the same as the number of vertexes referenced value for mesh no. 00 in its header in the VMeshData segment.

Worked first time. Now i can finally sleep

EDIT - My smugness is short lived. I have hit another snag and this time i dont see any obvious way around it. After i was testing the destructable component i could only get it to blow up if it got missiled. Turns out the .sur file for the component is not involved in it blowing up, it is probably to detect damage on it after it has blown off but before it is reduced to dust. Same for the .3db file for components. Neither are the Dp'name_of_part' or DpConnect harpoint necessary for parts to blow. I still couldnt get my component to take laser fire tho.

I swapped the kusari dragon's main .sur file for the eagles one. Now none of the parts on the dragon would blow off. I swapped it for a few other .sur files to the same effect. Therefore the ships main .sur file is directly involved in getting components to destruct. As no one understands the .sur files it is going to be a major obstacle. Hopefully some sort of workaround will show itself.

EDIT - Workaround found. Cant be bothered thinking why it works, but replacing the Cmpnd -> Cons -> Fix segment with the relevant section from the ship whose .sur file i stole and then renaming my component so its object name matches one of the original object names makes the component destructable. There are 3 floats in each components section in the Fix segment which seem to describe the components point of origin (Fix segment = 'Root'...60bytes...'name_of_part_lod1'....<112bytes) . They are byte numbers 129-140 where the 'R' of root is byte number 1 for each component. As my mesh was already mapped on the overall model to be in the right place, i set these 3 values to be 0 (as a 32 bit IEEE single) and the component appears in the correct location.

Edited by - redeye on 11-07-2003 12:51:24

Edited by - redeye on 11-07-2003 13:58:15

Post Sat Jul 12, 2003 8:57 am

Coolies. Alot of people will be pleased.

Is it just me? Or does our good buddy Trent look every so slightly like a certain beloved.....Battlestar Galactica rouge.

Post Sun Jul 13, 2003 3:21 am

I've tried to follow it but i'm a bit lost. Hope that the tutorial won't be too confusing. Oh well. Maybe someone will crack the sur file in the not too distant future and find out how to make them.

Post Sun Jul 13, 2003 3:43 am

Dont worry about trying to follow that ramble, i will post a proper tutorial when i have worked out the last few bits. I have nearly completed a version of the Battleaxe from Tachyon with 5 destructable parts. It all works fine expect that at the moment the parts dont take enough damage. I have to set their hitpoints to <50 (on an 800 hp ship) or they barely ever blow up. This would be fine except they take missile damage as normal so with them all set at 50 it looks good and the parts are destroyed in good relation to the ships hull damage but if you get hit by a class 1 missile all the parts are destroyed.

As i am using the eagles .sur file i had assumed the parts would take damage at the same rate as the eagles parts which have hps in the thousands. I tried using the original 'Fix' segment from the eagle (i have to edit the x, y, z origin for the components - if the parts are positioned in your milkshape model as you want it to appear in space you must set the x,y,z to 0, 0, 0 and then all the parts are in the same relative location as they were in milkshape) but this makes no difference. The only thing that leaves as the difference between the eagles components and mine are their co-ordinates in the VMeshData segment. I have just edited the model so that all the components are far closer to the origin - based on my hunch that the location of the component in the model is somehow connected to the damage it takes in the sur file.

Once i have that sorted i will upload the ship, a tutorial is pretty useless without an example. Having a .cmp with the nodes for parts will save alot of hassle aswell. I have asked if anyone is willing to rewrite the .cmp exporter but no luck so far. At the moment there is alot of tedious manual editing of VMesh segments which could easily be eliminated by an updated exporter.

Post Sun Jul 13, 2003 4:43 pm

Its not really neccessary to have the parts with such low armor in comparison to the main body. A balance of 1/5th ratio of the total health per part depending on the vulnerability of the parts might be a good standard to take. That way, if a missile hits you, you won't lose everything.

On a side note, do you think this method can be used to create custom turrets? Its a long shot but its better than nothing.

Post Sun Jul 13, 2003 5:01 pm

I have upped the armour on the components to a couple of hundred. This is enough so that they do get destroyed but dont all blow off when a missile hits you.

I have taken a brief look at the weapons .cmp files. As far as i can see they are set up exactly the same as the ships with a base part then a barrel part. However they also have an entry under Cmpnd -> Cons -> Rev. It is very similar to the 'Fix' entry for ship components so i dont imagine it will be too hard to steal/modify it to display custom guns.

More work is needed on the Cmpnd -> Cons nodes, they are the only part of this (excepting the .sur files) that i dont fully understand.

Tutorial is nearly finished, i'll post it tomorrow.

Post Sun Jul 13, 2003 8:01 pm

Thanks a lot, you just upped the ante for every ship made in the future :p

Incredible work!

Post Mon Jul 14, 2003 2:59 am

Finally, my Javelin cruiser and her smaller sisters will be able to mount the weapons i had designed for them.

Post Tue Jul 15, 2003 1:22 pm

I have posted a proper tutorial on this. It is here.

It looks intimidating but once you have got your head round it things get alot easier

Return to Freelancer General Editing Forum