Can I export vertex coordinates, normals and UV mapping to a specific format?

Ok, have made a start on the guide. So far I’ve just set up a .blend with all the bits and pieces imported. Zip is attached.

The locomotive itself is on Layer 1. The tender is on Layer 6, simply because it also has its body origin set at 0, 0, 0 in the hex, so if put on Layer 1 it would overlap the locomotive.

On layer 11, I’ve left the locomotive at its default location and shunted the tender back by +46.43115 on the Y axis, which is where it sits in the game. This is where the front length point of the tender coincides with the rear length point of the locomotive.

Just to see what happened I tried importing all the .3dp’s for the light files, and it turns out the script will do this. It’s a bit funny on results, so I had to manually correct the positions of some of the vertices, but that’s not worth worrying about IMO. It’s only meant to import mesh anyway, and really other things should probably be done by manually adding empties.

Same goes for the track points and length points.

Anyway, lights 1, 2 and 3 are ones that each have a point glow and a spotlight beam, so they have two vertices each. These lights are the main headlights, or running lights. Lights 4, 5 and 6 are single point lights that are for instrument and firebox lighting inside the cab. These only have one vertex each.

I also threw in empties to show the attachment points of all other components. I’ll make a start on bookmarked screenshots of the files tonight.

PS: Be warned that the model doesn’t come with the proper Darth Vader paint job. They got a bit fanciful. :smiley:

By the way, do you happen to use HexEditorNeo for hex jobs? If you do, I can provide you with complete bookmark files for the hex, if you like. Otherwise I’ll just give you screenshots and notes.

Attachments

Class_01_complete_import.zip (656 KB)

Here’s the rest of it. All the actual game files that are related to the model, along with screenshots and notes.

Let me know if you want any more information.

Attachments

Class01_files_and_screenshots.zip (1.27 MB)

Thanks, I’ll check it out! I just downloaded that Hex Editor, but I think I already understand the file structures well enough. I usually use HxD, which is very simplistic but I like it nonetheless.

Two more questions: what are imb files? And how is the original folder structure? (3dp, lco and car files all in the same folder? or like in the zip folder, a 3D and an EngineType folder?)

If you don’t normally use Neo don’t worry about it. You need a paid version to do the custom bookmarking anyway. I picked it up the Standard version while back when the exchange rate was in my favour. Free version is useless.

I found HxD was a PITA to use. This one seems very good: http://www.hexedit.com/index.html

If I was after a freebie, I’d give that a go. My 2c.

Anyway, imb files are just for calling the profile icons for the in-game menus (ie: little side views of your trains, etc). They’re not relevant to .3dp importing/export tricks.

Original folder structure is as I have it in the second zip. You have the root RT3 folder, then main Data folder inside that.

EngineTypes on the next level down holds all the .car and .lco files, while 3D holds all the .3dp’s and skins.

By default, all of the .3dp’s and skin images (for all assets) are packed into big PK4’s (glorified zips) with one for .3dp’s and another for skins. I named folders after the PK4 names to hold the extracted files. In a default installation they’d just be rt3_3DPF.pk4 and rt3_3DDSF.pk4.

The game doesn’t require individual folders for each asset. It just pulls the files based on the name. I can screenshot the folder structure if it helps make things clearer.

The screenshots were just thrown into the corresponding folders to keep them handy.

ETA: By the way, although I get why you want to understand the folder structure anyway, you don’t actually have to worry about it for the purposes of this script. Anyone who wants to work on a model is going to have to extract files from the PK4’s anyway, and do some other trickery as well, before they can get a model running in the game.

We’ve got all that sorted already, so you can just assume people will grab whatever files they require, and put them in whatever custom folders suit the job. You can pretty much use any folder structure you want. Once the model is sorted, people can just pack them up for the game again. No problem.

I’ll assume the user unpacked the necessary files from pk4.

I’m thinking about to support .car and .3dp on import. If it’s a .3dp, it will load just that (single part, multiple LODs). If the user selects a .car file, I can guess the path to all the .3dp files that belong to that loco or tender (glob for basename*.3dp). I could import all the .car and .lco data as scene properties for convenience. A default material can be created and the DDS/TGA texture assigned to the model - I’m not sure if the script should try to do that in case of a single .3dp import.

What do you think about importing a set of 3dp files “as scene”? It would actually not be any different from the current script, except that the current scene would be renamed to the basename. The basename could be stripped off the filenames and the part name alone assigned as name for objects/meshes. One would import the loco as one scene, and the tender as another.

Could lights be imported as Blender lamps? I’m not sure if the default light properties can be used to represent the required information.

Should all LODs of a 3dp file be parented to their attachment point empty? Moving the attachment point would move all LODs.

On export, there could be multiple modes: single 3dp, lco / car only, multiple 3dps + car + lco (maybe each with a checkbox?). Not sure if you need an option to include/exclude layers for LODs. Would you want to use layers to organize components, without affecting LOD export? If so, should there be some convention which layers will end up as which LOD? (e.g. first 3 layers for LOD 1, 4-6 for 2nd etc.?)

I guess two checkboxes would be handy to export visible and/or selected objects only. There will be some corner cases however: if you want to export a single 3dp, and nothing is selected / visible, what should it do? What if only some objects of a group are visible/selected?

Because Blender groups can be n:m, maybe it’s better to create a new “group” property? I could add some operators to make it similar to Blender groups (some key combo to add selected objects to group). If an object had already a group, it would be replaced by the new group name, so it stays 1:n. Another way, if parenting to the attachment empties is okay with you, could be to iterate over all empties and use their names as part name, and export their child meshes as 3dp each. Corner cases: parent -> child -> grandchild - how to handle that? One or multiple meshes of a LOD not assigned to any group - should it be ignored entirely in this case?

Also, should the body’s attachment point be actually represented as empty, or should the world origin (0,0,0) be used and no empty imported to that location? If a group misses an attachment point empty, shall the object origin be used as location?

Honestly, I would not worry about the .lco or .car files for this script. Nobody is going to care about them for the purposes of modelling, for the simple reason that they’re just not relevant to modelling.

It’s pointless having things like availability dates, weights, etc, imported as scene properties. Introducing them into the equation is just unnecessary complication. They are often changed later anyway if in-game testing shows they need some tweaking for overall game balance compared to other assets, and the tweaking is done by direct manual editing of the .car files. It takes longer to stop and restart the game than it does to edit the .car file.

You don’t need the generic base name of the files if you can just use the actual file name, which is how people will want things named in the .blend anyway.

Rather than messing around with importing .lco and .car files, it would make much more sense to support things like Light, LengthPoint and TrackPoint files if you’re looking for an extra coding challenge.

What do you think about importing a set of 3dp files “as scene”? It would actually not be any different from the current script, except that the current scene would be renamed to the basename. The basename could be stripped off the filenames and the part name alone assigned as name for objects/meshes. One would import the loco as one scene, and the tender as another.
I wouldn’t worry about the base name at all. There’s no need to. IMO it’s just a distraction.

I still think the best option is to just use the entire file name for every imported object. If you strip the base name from files you will end up with objects that have the same name, which means instead of having it named as a loco or tender body (for example) you will just be stuck with Body and Body.001. This is not as clear and is going to be a PITA.

Also, it’s rather handy to be able to set the loco and tender together on another layer, by simply duplicating them and shunting the duplicate tender back before transferring them to the new layer. This is just handy for getting an overall look at the entire unit. Introducing separate scenes into this is IMO another unnecessary complication. What I do is just import loco and tender to different layers. No scenes required.

Bear in mind that you are not coding for Blender experts. It may sound heretical, but the less they have to learn about Blender, the more likely they are to use your code.

Could lights be imported as Blender lamps? I’m not sure if the default light properties can be used to represent the required information.
That’s an interesting thought and I can see the sense of it.

To get it to make sense, I think you would have to use a directional light (probably a spot) for the light files which have a directional beam and a point light for the others. It would be possible to make the script distinguish between the two, based on the file structure. You’d also want to add an empty at the aim point for the directional beam, and have the light aiming at that. You’d have to name the empty for clarity as well (Light1_AimPoint for example).

If you’re going to get into coding for lights, it’d also be cool to pull the light’s colour from the .3dp. It’s set as RGB, as floats. So this hex translates to an RGB code of 1, 0.9569, 0.4549 (or 255, 244, 116 in the other format):

00 00 80 3F 66 F7 74 3F A7 E8 E8 3E

Getting all of this data imported and exported cleanly is going to require a fair amount of extra code, if I’m not mistaken, for a job which is pretty simple manually.

Should all LODs of a 3dp file be parented to their attachment point empty? Moving the attachment point would move all LODs.
Offhand I’d say no. I can see that creating as many problems as it could potentially solve. For example, when live testing a model and figuring out the best truck attachment point (which is always a bit of a trial and error process) you want to be able to move the attachment point without affecting the truck’s location.

On export, there could be multiple modes: single 3dp, lco / car only, multiple 3dps + car + lco (maybe each with a checkbox?). Not sure if you need an option to include/exclude layers for LODs. Would you want to use layers to organize components, without affecting LOD export? If so, should there be some convention which layers will end up as which LOD? (e.g. first 3 layers for LOD 1, 4-6 for 2nd etc.?)
I’ve already given an opinion on .lco and .car files being mixed up in this. :smiley:

And yes, I find having the LOD’s on layers to be the clearest and most intuitive way of doing it. It allows you to work on each LOD without having to worry about what is hidden and what isn’t. The models have up to five LOD’s, which works well with the way the layers are blocked together in Blender’s GUI. What I do is put the loco LOD’s across the top row of layers in the first block, with the tender LOD’s on the second row. Then, if I want an overall view, I’ll duplicate loco and tender LOD’s to the top row of the second block. I’d be using that as the convention.

By the way, yesterday I revamped the .blend to add all the LOD’s on the layers I usually use. If you want a copy of that, let me know.

I guess two checkboxes would be handy to export visible and/or selected objects only. There will be some corner cases however: if you want to export a single 3dp, and nothing is selected / visible, what should it do? What if only some objects of a group are visible/selected?
I wouldn’t worry about that too much. If there’s something they don’t want exported they can shunt it off to an unused layer, or even just delete it before exporting. If the file is full of old WIP crud that wont be exported, they can always keep a backup copy of that and just clean up the export file anyway.

Because Blender groups can be n:m, maybe it’s better to create a new “group” property?
You’ve lost me there. What’s n:m?

I could add some operators to make it similar to Blender groups (some key combo to add selected objects to group). If an object had already a group, it would be replaced by the new group name, so it stays 1:n. Another way, if parenting to the attachment empties is okay with you, could be to iterate over all empties and use their names as part name, and export their child meshes as 3dp each. Corner cases: parent -> child -> grandchild - how to handle that? One or multiple meshes of a LOD not assigned to any group - should it be ignored entirely in this case?
I’d forget the corner cases and just make people follow a clearly defined convention. You can include error messages like “Hey stupid, don’t do that!”.

Also, should the body’s attachment point be actually represented as empty, or should the world origin (0,0,0) be used and no empty imported to that location? If a group misses an attachment point empty, shall the object origin be used as location?
I think an empty for the body would be good, just for consistency.

For missing attachment points it won’t be possible to get a solution that works in all cases. Centroid would work for wheels, but would give hilarious results for umpteen other things. Probably, if you need a fallback, using the body/world origin would be the best option. That way at least all values are zero, which makes figuring out distances to the right location fairly simple.

Past a certain point I think you can just make people get their shit together if they want a good result. :wink:

PS: By the way, are you aiming to make a complete GUI for RT3 modelling, so that no idiot ever has to look at any hex anywhere? My initial thoughts were to just write the minimum amount of code necessary to handle the really gnarly stuff (namely import/export) and leave everything else to be done manually.

The way I see it, the less code there is the more maintainable it’ll be for future Blender versions. The other point is that even if you do try to make things idiot-proof, a sufficiently talented idiot will still screw it up.

Right, I didn’t think of that. Multiple scenes wouldn’t help, since bpy.data is shared among all scen

How about this: layers 1-5 for up to five LODs for loco, and layers 11-15 for up to 5 LODs for tender. The rest could be ignored. Or maybe every layer group of five layers for up to five LODs and 4 arbitrary components (e.g. group 1: loco, group 2: tender, group 3: wheels, group 4: everything else, like lights). To ignore objects, one would need to hide them or move them to another scene (possibly ignore if no group is set as well).

I think that’s possible. It requires a driver however to make a working AimPoint:
spotlight_trackto_and_driver.blend (81.2 KB)
It’s complicated to set up, there should probably be a button to create an empty and a lamp with constraint and driver…

That should be simple to do.

Is it really necessary to duplicate? I mean, couldn’t you put the loco on one layer, and the tender on another, but arranged to look in Blender how they will look ingame (non-overlapping), and have the tender’s attachment point at the right location? The absolute vertex coordinates of the tender shouldn’t matter, because the engine will use the attachment point to position the tender, doesn’t it?
Well, I might be a bit confused here… In other games, they usually declare their attachment points in the parental object, not the children. So maybe the tender needs to be placed around the world origin, but it could be faked with another empty, to which all tender parts could be parented.

I borrowed that from database modelling / entity relationship diagrams. The following is true for Blender groups: a group can contain multiple objects, and an object can be contained in multiple groups. It’s a many-to-many relationship. https://en.wikipedia.org/wiki/Many-to-many_(data_model)

Well yeah, supporting LCO and CAR seems fairy simple compared to the complexity of how import and export of meshes is supposed to work. I actually wrote the main bits for that already, because I needed something simple while I watched Burn Notice :wink:

Ok, well if it’s getting complicated it may be a good idea to not worry about it. In this context, having spotlights and stuff is really only Blender eye candy anyway, and people would have to frig around with the settings so the lights weren’t a nuisance for modelling and skinning. It’d be fine to just throw in two empties: one for the light origin and one for the aim point. That’s really all that’s needed. Then the export script can just use the empties to set the coordinates in the exported light file.

Is it really necessary to duplicate? I mean, couldn’t you put the loco on one layer, and the tender on another, but arranged to look in Blender how they will look ingame (non-overlapping), and have the tender’s attachment point at the right location? The absolute vertex coordinates of the tender shouldn’t matter, because the engine will use the attachment point to position the tender, doesn’t it?
Well, I might be a bit confused here… In other games, they usually declare their attachment points in the parental object, not the children. So maybe the tender needs to be placed around the world origin, but it could be faked with another empty, to which all tender parts could be parented.
I only duplicate them and move the duplicates when I want to see both at once on the same layer. This is just handy sometimes for checking out the overall look, or to do a screenshot of the complete unit. It’s not something that’s required for actual modelling.

I borrowed that from database modelling / entity relationship diagrams. The following is true for Blender groups: a group can contain multiple objects, and an object can be contained in multiple groups. It’s a many-to-many relationship. https://en.wikipedia.org/wiki/Many-to-many_(data_model)
Ok, gotcha.

Well yeah, supporting LCO and CAR seems fairy simple compared to the complexity of how import and export of meshes is supposed to work. I actually wrote the main bits for that already, because I needed something simple while I watched Burn Notice :wink:
Ok, so the plan is that they can enter all the years and weights, etc in Blender via a custom gui, then just export everything including .lco and .car? If you feel like writing that just for fun, I don’t think anyone will argue.

If you want to go to town on it you could try doing the .imb files as well. If you get really bored I can throw even more complexity at you. Have I told you about .cgo and .cct and .cty files yet? :smiley:

(That’s all stuff related to express, freight, or industry assets. You’d have to be really bored.)

People are likely to want to use this stuff to model buildings, and express or freight cars, not just locomotives. The cargo cars have extra files, and the buildings don’t have .car or .lco files but do have others, so this could all get quite complicated. This is another reason why I was originally thinking of just sticking to importing and exporting the basics, but if you’re really up for it…

Anyway, here’s the revamped .blend with all the LOD’s in it.

Attachments

Class_01_all_LODs.zip (707 KB)

I only duplicate them and move the duplicates when I want to see both at once on the same layer. This is just handy sometimes for checking out the overall look, or to do a screenshot of the complete unit. .

But couldn’t you just activate both layers?

Have I told you about .cgo and .cct and .cty files yet?

Heh, no. I think I’m fine with CAR, LCO and 3DP for now :wink:

I wonder if they auto-generated the very low-poly LODs, because they look really broken… but I guess they are only used when you can barely see the model anyway.

Can you provide me a another screenshot for the file structure of lights?

How would I figure out which two empties make up a light if we were to use empties?

Do you or the game care what chars are used as padding? 0xCD appears to be used as fill char, but not sure why they do that at all if it’s really just padding (eg. after 0x00 in a string).

Yes, I can do that, but that means having the tender I’ll actually be modelling shunted out of its proper location. I prefer to just shunt duplicates to another layer. It only take few seconds.

Heh, no. I think I’m fine with CAR, LCO and 3DP for now :wink:
What I’m getting at is that you’ll still have to allow for people wanting to use the script for models which don’t have .lco or .car. If it just goes ahead and exports and imports cleanly anyway, no problem. It’ll need to be able to cope with that situation though.

I wonder if they auto-generated the very low-poly LODs, because they look really broken… but I guess they are only used when you can barely see the model anyway.
Yup. In gameplay you don’t notice, amazingly enough. This particular one is a bit unusual though. Most of them keep some of the main planes intact. This is the first one I’ve seen where it all breaks down into tris with gaps. I only noticed it yesterday when I manually hauled out all the LOD’s.

Can you provide me a another screenshot for the file structure of lights?
Yup. I’ll whip up a bunch of them for all the actual lights for this model.

How would I figure out which two empties make up a light if we were to use empties?
Would have to be named or grouped to suit I suppose.

Do you or the game care what chars are used as padding? 0xCD appears to be used as fill char, but not sure why they do that at all if it’s really just padding (eg. after 0x00 in a string).
I don’t think it matters. The important thing is the 00 end stop. Anything after that is never read by the game engine, until you get to the next declaration at the predetermined byte count. I have seen files which have garbage in the padding and they still work.

Ok, screenshots of all the light files for this model.


Had an idea about the double lights. I figure the singles are easy (one empty for point glow origin) but the doubles are a bit more of a nuisance. However, there’s no reason why all the extra bits in the doubles couldn’t be standardised.

They’re only used for headlights anyway, and they all have the same colour in practice. They also have the same beam angles, beam distances, etc. So, all it would need is to spit out presets for all of the extras. As long as it takes the light origin from the empty, there’s no need for custom settings anywhere.

The single lights get used for a variety of things, often in different sizes and colours. If it’s more convenient they could just be standardised too. People could tweak colour and size in the hex later.

Hey, we haz bugs! :smiley:

I was just revamping a model and did an export of the finished product with the new script. It aint right. There are two problems.

1/ Bytes 32 >> 39 inclusive, which should contain the number of verts and tris, are being set to all zeroes.

2/ Bytes 39, 592 >> 60,303 inclusive are just full of zeroes.

I’ve zipped up the file and attached it so you can have a look.

The import side of the new script seems fine, and I can always export with the old script for the moment, so there’s no huge drama here. Just go over it when you have time. Cheers.

Attachments

AutoPlant_Upgrade1_LOD_1.zip (81 KB)

Aha! Figured it out. It was the empties I was using. Apparently having any empties anywhere in the .blend, even if they’re not on the layer I’m exporting from, will screw up the exported .3dp.

I would have thought they were safe to keep since they’re not actually mesh AFAIK, and since they weren’t on the layer I was exporting from anyway. Seems I was wrong about that.

I stripped the .blend down to just the actual mesh I wanted to export, with one LOD per layer, and that will export just fine. Verts and tris counts are up where they should be, and no massive blocks of zeroes anywhere in the hex. It’s all good. :yes:

This could be a problem if we want to use empties for other purposes and keep them when exporting. If you want examples to test I can give you the two .blends for the relevant model (with and without empties).

I’m only seeing zeroes 32-39? Empties shouldn’t matter, the script skips everything that isn’t a mesh… were you in edit mode when you ran the export?

No, I was definitely in object mode. And 39, 592 > 60,303 are definitely zeroes in the file I attached. I’m using decimal offsets by the way, not hex offsets. Hex offsets do my head in. I’ll start using hex offsets when I grow an extra six fingers. :wink:

Ok, so if it wasn’t treating the empties as mesh then it must have been the layers. I had the LOD’s on separate layers and was exporting one at a time when I got the file that was borked.

Will the current script try to export everything on every layer, even if they’re hidden, and bork things, or is it meant to be able to handle that?

By “handle that” I mean “only export the active layer”.

What I read was 592-60303, and missed the 39. It’s indeed all zeroes. I think I see the problem, I’m pretty sure I effed up the logic in the exporter. It doesn’t handle multiple meshes correctly and there is a leftover from an earlier version… I’ll have to rewrite it. Layers are currently not handled, every mesh will be processed.

I gave the group stuff some more thought, and here’s a new idea: groups (as in components, as in 3dp files) could be defined via name convention / object names. One group could be:

Class01L_Body.1A (layer/lod 1, mesh 1)
Class01L_Body.2A (layer/lod 2, mesh 1)
Class01L_Body.3A (layer/lod 3, mesh 1)
Class01L_Body.1B (layer/lod 1, mesh 2)
Class01L_Body.2B (layer/lod 2, mesh 2)
Class01L_Body.3B (layer/lod 3, mesh 2)
Class01L_Body.attach (empty for attachment point)

The separator char would be a period in this example, and what you type after that wouldn’t matter to the script. It would take the part before the period of every object and consider that a group (Class01L_Body).

It has some nice properties: Every object can only be part of one “group” (1:n) and you name your objects anyway. No extra property to store the group name would be needed (and be assigned). It could even be extended to LODs to decouple it from layers (to avoid objects being able to live on multiple layers). On import, only a single mesh per group would be imported (multiple meshes of the same group are “merged” during export). If the attachment point is not equal to (0,0,0), an empty can be created with group name + “.attach” or something like that. On export, the first empty in a group would be used as attachment point, or the origin of one or multiple objects in the group if there’s no empty in the group. Someone who doesn’t know all this, would still be able to get something out of Blender, even though it would be a 3dp file per mesh and object origins as attachment points.

Ok, so it was my balls up with having multiple meshes on multiple layers that threw the script. I can still get good exports from the current script by temporarily deleting other layers, or by splitting the LOD’s out to their own files once things are ready for export, so things are workable for the moment anyway. :slight_smile:

The naming convention idea is a good one. My only concern is that a period is not the most visible of characters and I’d be inclined to use some thing a bit more in your face. For instance, standard server practice for automatic backups of edited PHP files is to put a tilde in front of the file name. This is good because it’s not a character that ever gets used for anything else, and it’s obvious to anyone at a glance, and it already has precedent as a symbol for “don’t process this stuff”. So we could use a tilde here too:

Class01L_Body~1A (layer/lod 1, mesh 1)
Class01L_Body~2A (layer/lod 2, mesh 1)
Class01L_Body~3A (layer/lod 3, mesh 1)
Class01L_Body~1B (layer/lod 1, mesh 2)
Class01L_Body~2B (layer/lod 2, mesh 2)
Class01L_Body~3B (layer/lod 3, mesh 2)
Class01L_Body~attach (empty for attachment point)

Or any other suitable symbol would work if you don’t like a tilde. # or @ would be fine too.

I’m not worried about only having a single mesh imported. This is inevitably going to be the case when importing existing default models for purposes of modification. No way around that. For custom models that have been built in Bender I’m assuming the .blend will be available, so no problem there.

If there’s no empty set in the group I’d be inclined to just set the origin to all zeroes. It will work for all Body files anyway, so is a good fallback in that respect. It won’t work for many other components, but still has the advantage that it’s clear and non-confusing. If something misbehaves when loaded into the game, a quick check at the top of the hex will show you a row of zeroes where you know they shouldn’t be, so the problem will be immediately obvious. This is better than having to run the hex through a converter to get numbers you can read, then having to check those against the model, then realising that you forgot the attachment point. Saves screwing around. :wink:

By the way, if you want to see some results for your work here are a couple of small projects I’ve knocked over already.

First one is a 2-6-4T suburban tank engine, which was done by revamping the mesh of the game’s default Prussian P8 while keeping the original skin. This was a quick and easy replacement for another existing model, which was supposed to be a 2-6-4T but looked like nothing you would ever want to see on your railway. :eek:

The new one isn’t any particular locomotive (neither was the old one) but has the general style and feel of similar engines of the period, and generally looks the part. People seem to like it.



The second project, which I just finished yesterday, was fixing a problem with the default PopTop model for a car factory. This factory can be upgraded, and the upgrade mesh was about 60% outside the factory footprint. The result was that it overlapped neighbouring buildings, which looked a pretty stupid and has bugged people for years.

So, I went through the mesh and sorted it out so it’s now all inside the factory footprint. Again, same skin as the original. Just fixed the mesh. This is a project I never would have been game to tackle back when we had to do it all by manually editing the hex. It would have taken literally months and driven anyone insane. Now it’s easy and fun.


Nice work! So the model was simply misplaced? Or did the place the same model twice and overlapping to fake a larger factory premise?

What do you think of the following naming convention:

Foobar~1~1
Foobar~1~2
Foobar~2~1

Two tildes make it easier to read. I think it makes sense to let the first number indicate the LOD and the second to be whatever you want (not necessarily numbers) to make distinct names in case you want to keep multiple meshes and empties in your blend, but want them to become a single 3dp. The sequence “number” can be left out if there’s only a single mesh and the attachment point is supposed to be (0,0,0) - LOD before sequence number therefore. If the LOD number is also left out (no tilde, or something invalid after it) I would default to LOD1, so that people who don’t know the convention can export everything as LOD1.

Corner case: the empty for the attachment point. It doesn’t belong to a LOD, thus the name would be Foobar~attach?! Or Foobar~~baz? The following would also work:

Foobar (mesh; no LOD, thus LOD1; no sequence number, instead of Foobar~1~something)
Foobar~AttachmentPoint (empty)

Regarding LCO/CAR: for locos it makes a lot of sense to store data about the loco, but what about the tenders? Do they have both files just like locos? Why I’m asking is because I wonder if all the properties stored in these files occur multiple times for a complete unit (loco+tender+x) and would thus require a collection to store them in a single blender at the scene level.

It was misplaced. Whoever did it had made a nice model, but forgotten about the available footprint size. I had to delete quite a bit of mesh and move some of the rest (along with some lights and some animations) to get it to all fit. I would have just changed the X and Y values for the footprint to suit the original model, but unfortunately that’s one of the odd bits that is hidden in obfuscated source code, so revamping the model was the only way of doing it.

Anyway, double tilde is fine by me. Nice and clear. I usually name things as LOD1 etc just so I don’t mistake it for anything else when I’m half asleep. As idiot-proof as possible is a good thing. So with your idea I’d be inclined to use:

Foobar~LOD1~Some_component.

I don’t think you need to worry too much about fallbacks for models with one LOD or whatever. I’d make people include the whole syntax in all cases, just to keep them in good habits. It’ll be a little bit more typing sometimes, but it will always be clear. The fewer options you give them, the fewer cock-ups it’s likely to result in (humans are like that). :smiley:

So for something simple, like a wheel, which only has one LOD and no sub-components I think Foobar~LOD1 would be good, with the second tilde and the second name after it being optional. The script would only read up to whatever was after the first tilde, and stop reading either when the text ends or it sees another tilde.

Attachment points could be done as Foobar~AttachmentPoint. Can’t see anything wrong with that. It makes it obvious what the thing does. I like obvious.

Locomotives are the only units that have .lco files. Tenders don’t have .lco files but they do have .car files.

Cargo cars (freight or express) have a range of files: .car, .cct, .cgo and .cty. This is where things can get complicated.

Buildings have another range of files: .bca and bty - but no .car or .lco - and sometimes anim3dp and Anim.3dp (which are two different types of animation files).

I realise you probably don’t want to get into catering for all of these, and there’s no need to anyway as the hex is pretty simple to do manually. I’m just letting you know what else is in the game’s coding, in case you need to provide fallbacks for missing stuff.

I’ve attached some old .txt files, which have notes someone else made on the content of various game files. These notes are a bit rough in spots, but will give you the general idea if you’re curious about the other files.

Attachments

PJay’s Stuff.zip (7.54 KB)