So, before I go crazy from tedious work on more physics modifications, I want to determine and implement (haven't started on any of this) some simple things that would make .eng and .wag set up easier. I'm curious if any of this sounds useful for other workflows (I know I'm pretty much on my own when it comes to complete replacements of .eng and .wag files), or if there are any ideas in a similar vein that I haven't considered.
Automatic Model Centering: I am tired of checking for and calculating the offset to re-center shape files, so I'd like to bypass the need to use the whole CentreOfGravity thing to re-center models exported with the wrong origin by providing a parameter to automatically re-center the rail vehicle 3D model. Eg: ORTSCenterShapeZ() could read the 3D model data, check the min and max Z values, then calculate the required offset for the min and max to be equidistant from the origin, and set CentreOfGravity Z to that value automatically (without the 1-meter limit currently imposed on CoG.Z). The data is there, so why should I ever waste time running that calculation myself? Another advantage of this approach (and many other ideas in this post) is that it dynamically updates when the 3D model changes, which might be useful if the author actually fixes their stuff and centers the model. I specifically mention centering the shape on the Z axis because that's most useful, centering the shape in the X and Y directions could be done but probably wouldn't do anything useful.
(Before anyone responds "just get the shape right the first time" I don't make shapes, it is far too late for that, there's stuff coming out even now that makes these sorts of mistakes. It's far easier to fix in post than expect everyone to both pay attention to the models they make today and fix the thousands of models they have made over the last 20 years. This post is also a case of "only tool
Automatic Bounding Box Size: To get correct coupler spacing, I always find myself opening up shape files, checking the model length, subtracting off the coupler overlap I want, and manually typing that in the Size() parameter. This is another thing that would be trivial to automate and save me some time. Something such as ORTSAutoSize( 0m, 0m, -0.18m ) could determine the Z dimension (length) of the 3D model, subtract 18 cm from it (this is the coupler spacing I use, I know others are different), then use that value as the model length. The X and Y dimensions of the model would be calculated from the 3D data, but then with no offset added. This would not only ensure the length is correct for coupler spacing, but also ensure that the width and height are at least sensible for calculating the aerodynamic drag of the vehicle, when many MSTS things have nonsense entered for width and height (wagons that aren't rectangles should still have their area specified manually).
Manual Offsets: Find a model that's sitting in the rails or floating above them? That can be solved by shape file editing, but shape file editing is not fun and that only fixes the problem on your computer (again, it is too late to "just get the 3D model correct" there is brand new content coming out with the wheels clipping into the rails); if you want to fix the problem for other people you have to tell them to shape file edit and you immediately lose the interest of most people. Instead, this is something that could be done entirely at runtime inside of OR. Think of something like ORTSOffsetShape( 0m, 0.02m, 0m ) to move a shape up by 2 cm (but with no change to left/right or forward/backward position) because the wheels clip the rails. Due to the way things work under the hood, I think this would also work for offsetting shape components. Bogie in the wrong place? (this would be one very messed up 3D model!) Then maybe ORTSOffsetShape( "BOGIE1", 0m, 0m, -0.2m ) can do the trick.
Model Scaling: There are some particularly baffling cases out there of models, or at least sub objects of models, having completely wrong scaling. Or maybe you want to know what a GEVO would look like on narrow gauge. Again, this would be convenient to solve at the .eng/.wag level instead of editing the shape file. ORTSScaleShape( 0.637, 0.637, 0.637 ) could scale down the entire model (width, height, and length) to 63.7% of original-enough to convert from standard gauge to 3ft gauge. I know I have some models where the bogies are too narrow and the wheels don't align with the track, so ORTSScaleShape( "BOGIE1", 1.2, 1, 1 ) could make the bogie 20% wider without messing up the height or length.
Texture Overrides: How many copies of the same 3D model, just with different texture names specified, do you think you have in your trainset? It could be far more efficient, and easier to set up (again, shape file editing causes a lot of people to tune out), if just one shape file could be used by multiple pieces of rolling stock with the textures specified in a text file. Under the hood, it's not too difficult to intercept the list of textures read from the shape file and sneakily replace it with something else. Something along the lines of ORTSTextureOverride( "BNSF_777_a.ace, BNSF_778_a.dds", "BNSF_777_b.ace, BNSF_778_b.dds" ) could replace the textures for BNSF 777 with those for 778, effectively reskinning the shape without any editing needed. Or perhaps more generically ORTSTextureOverride( "0, BNSF_778_a.dds", "1, BNSF_778_b.dds" ) where 0 and 1 are the index of the texture based on the order of textures in the shape file (this would reduce the risk of typos breaking the texture mapping). Of course, many reskins also involve freight animations so something similar would go into ORTSFreightAnims as well.
I know there are sometimes changes other than textures that might require shape file editing (like changing the material for part of the model to allow transparency), those should also get something that can be done in the .eng or .wag so shape file editing isn't needed at all. If it's not obvious, shape file editing is not something users should have to do in 2024.
Automatic Davis Calculation: Except for some specialty equipment or when using a resistance calculation other than the Davis method, Open Rails receives all the information needed to calculate resistance using the Davis method. I've used quite a bit of time and space setting up resistance numbers (I have entire folders that are just files with resistance numbers) when for the most part I just want the Davis resistance of a boring old boxcar. So, if the user fails to specify resistance values (of course, if the user does enter data like they should, use that), we should at least attempt to generate some reasonable replacement based on the type, weight, number of axles, ORTSBearingType, ORTSDavisDragConstant, ORTSFrontalArea, and so on-think of doing what Fcalc does but doing it automatically upon loading the game. For comparison, the current fallback for missing resistance data is incredibly limited and seems to only consider the weight of the vehicle-probably just a last resort.
Parametric Include Files: My equipment tends to be built out of many include files, allowing things to be assembled piece by piece (can make a locomotive have no dynamic brakes by simply not including the dynamic brake include statement without affecting anything else) which is flexible but the result is an .eng file with too many include statements for anyone but me to understand and far too many .inc files in the common folder to sift through and find what I need. It would be nice if one include file could do more than just one specific configuration, so one of my more exotic ideas is to allow include files to be provided parameters that can tell the include file to read or skip certain lines. The idea here is that include("GP38-2_Physics.inc") could provide the default state for a typical GP38-2, easy enough for someone to add on to an MSTS model without knowing every last detail, while the exact same file could provide much more specificity when used as something like include("GP38-2_Physics.inc", "NoDynamicBrake, ExtraCapacityFuelTank, BlombergM, WBGCompressor"), which would modify the default configuration to have no dynamic brakes, the optional larger fuel tank, relevant adjustments for the Blomberg M bogie, and the big 6 cylinder WBG compressor. Normally each option on the configuration would require a separate include file (this is what I do for dynamic brakes), taking the questionable route of overriding a token by including it again later in the file (I find this works ok ish for the fuel tank capacity), or just giving up and not offering the choice (I don't have the option for the WBG compressor as I understand it's not exactly common). By allowing one file (as opposed to dozens of files) to govern many different design variations, it's easier to make an engine/wagon file as fewer include statements are needed, the common folder gets cleaner as fewer individual .inc files are needed (in theory), and it's easier to account for the various configurations of the real model of locomotive/wagon.
That said, this is the one thing I'm less sure about the technical details of. Include files are already a strange system, anything could happen if more is added in.
Anyway, those are just the things I've already thought of to make .eng and .wag creation easier and that I feel I can implement in a sensible amount of time (I'm hoping to save time in the future, after all!) This is coming from the perspective of someone using MSTS 3D models and rewriting the .eng/.wag from scratch, but I'm sure different perspectives (devs working from their own 3D models, those adding onto existing .eng/.wag instead of starting over, someone who just wants to add reskins without editing things) make for different priorities, so I'm open to other ideas for automating or simplifying these processes.