WP&P
The
Winchester
Paston &
Portsmouth
Railroad
Corporation
WP&P RSD-15 #346

The Depot
Reskins RRtycoon Trainz
The Layout

How-To Guide

RRT3 Rolling Stock Modding

We Provide Pride!
The Sim
The Birds
The Rest

Based on the pioneering work in locomotive mods done by Kimmo Jaske (a.k.a. Bombardiere) and others who dissected the file structures in Railroad Tycoon 3, I have developed the following method of creating new rolling stock (freight and passenger cars) for use in the game. If you want to see and download some of my cars, then click here to see the cars I have created.

Jump to .3DP FILE EDITING...


EDIT: Current Modding Tools I recommend are - Image Editor = GIMP; Hex Editor = Tiny Hexer (mirkes.de); PK4 Unpacker = Game Extractor, Watto Studios; DDS Converter = DDSview (save as DXT-C3), or use User Skinning Tools to create PK4's in which a DDS is packed.
How To Reskin Cars - chart

To begin, you must BACKUP ANY FILES WHICH YOU WILL BE CHANGING. In most cases, this means only the .CTY file, as this method assumes that you are creating new assets for all the rest (based on copying and renaming the default game files). I created a "Backup" folder within my UserExtraContent folder, which contains a complete archive of all the types of files I use - basically I unpacked the PK4 files into similarly-named subfolders here.  You might prefer to store your backups elsewhere; it is probably better to NOT have them in UserExtraContent.

STEP 1: There is a .CTY file for each unique cargo in the game, kept in the DATA/CARGOTYPES/ folder. The easiest way to introduce a reskinned or new car is right here. Use a Hex Editor to get into this file and change it to refer to a different car type (which you will be creating), rather than the game's default. Refer to documentation by Pjay and Milo on the file structures to see what to edit and where. Aside from referencing a new car type here, you can also adjust the baseline price of the cargo as well as the cargo ID; there is also a byte used by the CargoModel to determine what kind of load to represent. That is, this is what tells a hopper to load up with coal or iron or bauxite, similarly for flatcars. For starters, though, leave all of this untouched aside from the reference to your new car type. Save right back to DATA/CARGOTYPES/ with the same filename.

STEP 2: This method assumes that you are creating a new car type based on a game default, such as creating an Iron Ore Hopper to carry iron, based on the default Hopper. Open the .CCT file for the default car, found in DATA/ENGINETYPES/, and save it using your new car type's name in the same folder. In this example, open the HOPPER.CCT file and do an immediate "Save As" to rename it IRONORE.CCT (you can give it any name you want, but shorter is better, because you will be typing it a lot in the next few steps!). I suggest saving before modifying so that you don't accidentally screw up the default - again, a BACKUP OF ALL .CCT FILES would be very prudent.

Once you have your new car's .CCT file begun, you can change it in a Hex Editor to refer to the new car's name. This reference tells the game engine which Car Bodies and Cargo Loads to look for. I recommend using the same [carname] prefix for all assets belonging to this car, although there might be ways to avoid redundancy by refering to some shared or default assets in some cases. A relatively recent computer can surely handle the redundant assets. As for my recommendation for [carname], I suggest the following:

HBAUX = H+BAUX = Hopper car for Bauxite
Use one letter for type, plus the first four letters of the specific cargo. Types would be:
A=Auto Carrier
B=Boxcar
C=Covered Hopper
D=Diner
F=Flatbed
H=Open Hopper
M=Mail
P=Passenger
R=Refrigerated Box Car
S=Stock Car
T=Tank Car
X=Caboose

STEP 3: Create .CAR and .CGO files for your new car in a manner similar to what you just did for the .CCT file. You can do this by copy+paste if you prefer, renaming the pasted files before you open them up in the Hex Editor. By default, the game uses a four-era structure, with an A, B, C, and D version of each car. These car models swap out in 1850, 1900, and 1950. However, these dates are not carved in stone! It is in the .CAR file where you can define different start and stop years for each era. Moreover, you can introduce additional eras (I use W, X, Y, and Z versions as transitional models, such that a W-era car comes between A and B, while Z comes after D) and thus end up with a car body that goes through more than four versions during the course of the game. Each era that you intend to use must have both a .CAR file and a .CGO file.

Again, refer to documentation by others to understand what gets changed in the file. The .CAR file is the "master index" of the graphical assets that will be displayed, as well as other things. Note that locomotives also have .CAR files; be sure to use a freight or express car's files as your template here. The segment of the file that gives the weight of the car appears to give 1/2 the weight, or the theoretical "empty" weight of the car. I am not sure that the game makes any use of this, since "empties" don't run on trains in the game, but I just set this to half the loaded weight. For cars like the Diner and Caboose, the weight given here is actually the total weight, since there is no .CGO file; these cars do not get loaded.

The .CGO file just gives the total loaded weight of the car. This can be altered; I am working on re-weighting the cars to make it such that heavy steam engines have a noticeable advantage after about 1930. My feeling is that the default game behavior makes articulated steam like the U.P. Big Boy almost always a losing proposition - you can run Mikados right up to 1950. By introducing some slightly heavier cars every few years, the average car weight will rise over time and begin to slow down that Mike... at least that is the theory!

The .CAR file will also refer to "CarSideView1.imb" for the 2D profile of the car that shows up in the train list interface. CarSideView is a collection of all the cars and locomotives in the game in one image file; the IMB file tells the interface where to crop for each unique car type. Editing this would be a major pain, so the far easier way to create the profile is to change this to refer instead to "[carname]A_Profile.IMB". In step 4, you will create the Profile IMB and DDS files that this refers to.

All files edited in Steps 2 and 3 get saved into the DATA/ENGINETYPES/ folder.

STEP 4: This is the real meat of your work, and likely to take a fair amount of time. The simplest thing is to gather all the .3DP assets you will need; simply copy+paste the ones you intend to use and rename them using your chosen [carname]. If you are doing a version of a Hopper, then you will need to copy all of the HOPA_*.3DP, HOPB_*.3DP, HOPC_*.3DP, and HOPD_*.3DP files, for instance. Feel free to mix-and-match, though; if you want to "promote" the D-era car body into the C-era, for instance, then you can just name the D assets as C assets. If you think the C-era boxcar shape looks more like a Reefer (I did!) then you can choose to use those 3DP files instead. It may be possible, in a manner similar to Bombardiere's work with locomotive modding, to mix-and-match Trucks with Car Bodies, but I have not done so yet. A reason for doing so might be if someone were to work on a European set of cars, many of which have single-axle trucks rather than the American 2-axle "bettendorf" trucks.

For the car skins, fire up your favorite image editor and have at it! You will need software that can at least read the DDS files that the game uses, though preferably one that can save the DDS file to a TGA or other format (and vice-versa). You need to preserve the Alpha Channel as you convert to whatever file type you will be working with in your editor; the Alpha Channel will tell the game engine that some pixels in the skin are fully transparent, others are fully opaque, and the rest are to be treated as if they glow at night. Keep this in mind while you work, and do what it takes to keep control over the alpha channel. You can use the alpha channel to change the car's shape in subtle ways, too, such as making all the zig-zags along the bottom of a boxcar's sill line. The Stock car is basically just a box car with alpha'ed space (transparency) between the slats - you can use the Stock car's 3DP files to represent a solid-walled boxcar or reefer (I have!).

To create a realistic-looking car, scour the internet for side-on images of the type of car you wish to represent. Photos of real cars are preferable, but often it is easier to locate photos of models, particularly from hobby manufacturers such as Atlas. Depending on what you find, you may need to do some perspective correction to get the car side photo to be truly rectangular. Once you do so, though, really all you have to do is paste in that car side into the "A" skin you are working on. Always work on the "A" skin; the game uses A,B,C,D,E, and sometimes F skins at smaller and smaller resolutions, swapping them out based on how far away the camera is zoomed. You can complete the A skin, then resize it and save as B, resize and save as C, etc. Alternately, you can feed the A skin into the UserSkinningTools provided with the Coast to Coast expansion, creating a dummy loco mod that uses that skin, and it will produce a PK4 file which, when unpacked, includes all of the A, B, C, etc. versions, saved as DDS files.

However, I prefer to do resizing manually, because you need to clean up the alpha channel between iterations! Otherwise, you end up with skins that glow around the edges at night time. This happens because the reduced-resolution versions of the skin end up with partially transparent pixels around the border between transparent and opaque areas. To overcome this, in the image editor I select all the fully transparent pixels, create a new layer which will underlay the original artwork, invert the selection (so that now I have a selection that includes all of the non-transparent pixels, including those half-opaque offenders), and then fill the selection with a solid black or dark grey color. In essence this is creating a silhouette of the non-transparent areas on a mostly-hidden layer, which has the effect of forcing the alpha channel to stark contrast (fully transparent or opaque). Of course, some cars like passenger cars have windows which are intended to glow at night - you will need to erase the silhouette from beneath those windows so that they remain partially transparent. As you resize, from 1024x1024 (A) to 512x512 (B) to 256x256 (C) etc., each time you should erase the silhouette layer and recreate it, otherwise the silhouette itself will develop a partially-transparent fringe.

Ultimately, you will need a set of A,B,C,D,E,F skins for each car model (of each era A,B,C,D, and more if you create them), saved as TGA or DDS files. The TGA's are easier to work with and I usually leave them at that, but if you use the UserSkinningTools then you'll end up with DDS files, which are smaller. Yes, this is a LOT of graphic art work! But after you've done a few, it gets easier and quicker.

For the 2D Profile icon that shows up in the train list, you can copy+paste a portion of your D-level skin into a file that is 32x128. I start with the CarSideView1.DDS file that comes with the game, and crop in to the type of car I am working on. This car will be shorter than 128 pixels, so just add transparent area as need to achieve this size - do not leave it at some odd value like 49x32! The DDS file format apparently expects dimensions in powers of 2, otherwise you get an oddly garbled icon when you make the conversion to DDS. The car should be all the way over to the left, with its wheels resting on the bottom of the image. Now, you can paste in the car side from your D-level skin, resizing it as necessary to match the icon. Pay attention to just how long, in pixels, the car icon actually is; this width must be entered into the .IMB file to tell the game what to crop that 128x32 image down to. When you open the .IMB file in a hex editor, you will see at the end of it a listing of coordinates, like "0 0 56 32". This is telling the game to use the rectangular portion between pixel 0,0 and pixel 56,32; in other words, crop in to a width of 56, height of 32. Just change the third coordinate to whatever width the icon really is.

All files in Steps 4 and 5 get saved into your DATA/USEREXTRACONTENT/ folder.

STEP 5: This step is not needed for all cars, but some cars do make use of a Cargo Icon or a Cargo Model. A Cargo Icon is like a decal of the type of load that the car is carrying, for instance a boxcar loaded with cotton will show the cotton icon on its side. If you don't want to see this icon (if it is obscuring your wonderful artwork), then you can try first to just eliminate the _CargoIcon1.3DP file. I know this works for passenger cars. Another option is to use a different source for the .3DP file, such as using the TankA_CargoIcon1.3DP for a boxcar. What this does is effectively locate the icon inside the body of the car, because the TankA body is skinnier than other cars.

Flatcars and Hoppers utilize the CargoModels to make them look different when they are carrying different loads, such as Iron and Coal in a hopper. The game selects the right CargoModel based not on the Cargo ID but rather another variable embedded in the .CTY, declared way back in Step 1, although I discovered that it actually uses that number plus one! In other words, if byte 32 of the CTY file = 03, then CargoModel04 will get used. Refer to the documentation by Pjay and Milo on this; it is rather arcane. But one possible use of this that I am envisioning is taking a stock car body (since it has a floor), using the alpha channel to erase the roof and half of the walls, skin it as a gondola, then fill it up with CargoModel10 (heaps of coal) or even CargoModel05 (coils of steel).



3DP FILE EDITING

Notes on the 3DP file structure compiled by PJay, as shared with Bombardiere (Kimmo Jaske) and WPandP (Michael Rountree), edited by Michael Rountree.

3DP files

4 bytes    :    "3DPF" = bytes: 51 68 80 70
4 bytes    :    04 00 01 00
4 bytes    :    "3DMD" - bytes: 51 68 77 68
4 bytes    :    int: number of instances
3*4 bytes    :    float: center X, Y, Z

[Editor's Note:  The Center point appears to be the nodal point which defines where this element connects to other elements; for a _Body.3dp it refers to the spot where it sits on the track, and for things like pistons or connecting rods it refers to connections to dependent elements.  If you get this wrong, you'll see weird behavior like a driving rod that loops around through space.  Also, I saw that changing the X-value on what amounts to the axle of a wheel does have an effect, even though the axle is basically a line in the X dimension; two wheels with the same center Y and Z values but different X values will rotate at differing speeds.  This may be due to absolute distance to centerline of track.]

INSTANCES / LIGHTS

INSTANCE
============
4 bytes    :    "INST" = bytes: 73 78 83 84
4 bytes    :    int: number of coordinates (or points)
4 bytes    :    int: number of triangles (or faces)
?*12 bytes: points (defined below)
?*76 bytes: faces (defined below)

[Editor's Note:  INST's are redundant in that they repeat points and faces, but with decreasing detail.  I have been editing only the first INST with success, but perhaps because my computer is fast enough to max all graphics settings; lesser rigs may depend on the simplified INST's.  It may be necessary to reduce an edited 3DP to just a single INST, unless you make the same changes to the corresponding points in all INST's.  If you do reduce to a single INST, then make note of it in the Readme, to the effect that this mod will tax the resources of lesser computers or possibly even induce game crash; I haven't seen this happen yet, but again it may just be because I've got a decent rig.]

LIGHT
============
4 bytes    :    "LGHT" - bytes: 76 71 72 84
4 bytes    :    int: number of lights

if number of lights = 1
--------------
12 bytes    :    int: 00 00 ... 00 00
4 bytes    :    float: 0.0 <=> 1.0
3*4 bytes    :    float: 0.0 <=> 1.0
3*4 bytes    :    float: -... <=> +... (X, Y, Z)

if number of lights = 2
--------------
4 bytes    :    int: 0
4 bytes    :    float: 6 <=> 46
4 bytes    :    float: 15 <=> 65
4 bytes    :    float: 0.0 <=> 1.0 (of 2.0)
3*4 bytes    :    float: 0.0 <=> 1.0
3*4 bytes    :    float: -... <=> +... (X, Y, Z)
3*4 bytes    :    float: -... <=> +... (X, Y, Z)

[Editor's Note:  I do not yet understand and have not attempted to mod the Lights of a model.  The glowing of lit windows, such as on a passenger car at night, is done through the alpha channel of the skin file, not in the 3DP file.]

POINTS / COORDINATES
=============
4 bytes    :    float: X value
4 bytes    :    float: Y value
4 bytes    :    float: Z value

[Editor's Note: Values are relative to origin (0,0,0) equal to center of the model at track height, for cars and engines at least.  +X is left side of train, -X is right side of train, +Y is caboose end of train, -Y is front end of train, +Z is above railhead, -Z is below track.  Units are not to any apparent scale, but rail gauge appears to be 6.25 units, so 1.0 unit = roughly 9 inches for American standard gauge.  Models appear to not be created to a uniform scale; the Pacific 4-6-2 for instance is gigantic compared to other steam engines.]

FACES / TRIANGLES
=============
3*4 bytes    :    int: Point number (according to order of points listed above)
3*4 bytes    :    float: normal vector in point 1 (X, Y, Z)
3*4 bytes    :    float: normal vector in point 2 (X, Y, Z)
3*4 bytes    :    float: normal vector in point 3 (X, Y, Z)
2*4 bytes    :    float: coordinate 1 in texture file (x, y) [range 0.0=left or top most pixel to 1.0=right or bottom pixel]
2*4 bytes    :    float: coordinate 2 in texture file (x, y) [range 0.0=left or top most pixel to 1.0=right or bottom pixel]
2*4 bytes    :    float: coordinate 3 in texture file (x, y) [range 0.0=left or top most pixel to 1.0=right or bottom pixel]
4 bytes    :    int: main direction (0=-x, 1=+x, 2=+y, 3=-y, 4=-z, 5=+z)

[Editor's Note:  I am unsure of the purpose behind the normal vectors and the main direction.  Whatever portion of the skin file you map onto the set of points will display to both sides, as if the normal was both ways all the time.  If you type in the coordinates in the wrong order, your skin will appear warped and turned on the model, but the easy way to correct this is just to list the points in a different order, in the first 12 bytes.  This may be necessary if you copy and paste the (x, y) coordinates from one source to another, as the source may have listed its points in a different order.  In other words, if AA - AB - AC looks funky the way you've defined it, don't bother retyping all those floating point X and Y values; just try AB - AA - AC and other permutations until it looks right.  Also, note that you do not have to use the triangles given in the source file... you can define a triangle between any three points!  This may be a way to get rid of a face that you don't want to see, or to create features that did not exist in the source.  An example might be a chain between the bell and the cab roof on an old steam engine:  this could be just a single triangle that goes between the center peak of the bell, to the center peak of the roof, with the third point somewhere near the midpoint down low between the rails.  In the skin file, draw the sagging chain with a lot of clear (alpha-masked) space around it, and map the coordinates with one end of the chain at the first point, the other end of the chain at the second, and the third point somewhere deep below the center of the chain.  Of course, to create a new triangle like this, you must give up one of the other triangles... unless you go back to the beginning of the file and change the number of points or faces or both.]

OTHER
=============
Other .3DP file first 8 bytes:
BE BA 00 00 68 01 00 00 => _anim.3dp
_Anim*.3dp => INST's in 3DMD files
_Light*.3dp => LGHT's in 3DMD files

[Editor's Note:  A decent hex editor, like "Tiny Hexer" from mirkes.de, will allow you to set the number of columns to view the file's contents, and when set to 12 columns then the long sections of X, Y, Z coordinates will line up such that all X's are in one column, etc.  This is helpful so that you can see which points belong together, as, for instance, the side of a boxcar will have the same value for X, two values for Y, and two values for Z.  To map out a _Body.3dp file takes patience, but can be done by changing one value to a ridiculous amount, such as setting the X-value to -30.  Save the file, making sure that you will be able to Undo after Save first, then load in the game.  The model will be warped at that point, you can it write down (i.e. "Point 0A = Cab Roof Front Right").  Most of the time, points are grouped together where they describe a given rectangle or even the full cylinder of a boiler, so you don't have to map every point.  Just find the major features, and of course you need to find all the points you intend to modify.

This is tedious for a complex model like a Steam Engine, but can be done.  It is much easier for lesser models, like Trucks or Bogies.  Bogies are just simple square faces (the roundness is achieved via alpha mask in the skin file), with four corners and a center of rotation, and two triangles defined.  To relocate a wheel, you'll edit the Y values for all five points by the same amount; changing the Y value moves a feature forward and back along the track.  "Tiny Hexer" has a Structure Viewer tool that can be set to show floating point (32-bit) values directly, and permit you to change that value by typing in the new decimal value.  With other hex editors, you may need to do some manual translation of values via another means]



created by Michael R. Rountree