I like railroading games because they have a certain amount of simulation in them and railroading is an interesting topic to me.
My idea was to add much more realistic train handling to my game. The existing games all have one fatal flaw; they do not handle empty train cars. The train cars, or rolling stock, magically appear then you need them and disappear when you don’t need them. Having to handle empty cars would be a nice touch.
In addition to handling empty cars, my intention has been to handle these other things too:
- Cars on the track but not connected to a locomotive. This is required if empty cars are to be handled.
- More realistic loading and unloading of cars. A locomotive might drop off cars and pick them up a day later after they have been loaded.
- Multiple locomotives on a train to handle steep hills.
I don’t intend to describe all aspects of the project here. What I have working is an experimental program that lets me do some of the train and car handling. Here is a video of a train, as it works now, moving in various ways:
|Launch in external player|
This is a long video but demonstrates how the train game might work. The locomotive is given instructions about the various waypoints along the route. Beyond those waypoints and the actions that the train must complete at each waypoint, there are no other movement instructions. The code, and thus the imaginary locomotive, figures out where to accelerate, where to decelerate, where to change tracks, where to change directions, and where to stop to couple or uncouple cars. If given a waypoint that tells the train to pick up cars, the train will move towards the waypoint and will slow appropriately to couple with any cars it finds after that. The train would then accelerate in the right direction along the right path to the next waypoint.
Some of the coding challenges were related to path finding. I wrote about this in an earlier blog entry.
Another coding challenge was in designing data structures that were simple enough to manage yet provide enough information to let a train move on the track network. The most obvious issue is that a train might be occupying multiple segments of track and may even cross a track switch (one track splits into two or more) and the train must be simulated and drawn correctly. Experimentation yielded working code although I always had it in my mind that there must be an easier way to handle this.
One interesting thing that I implemented was a choice cache mechanism described in detail in this blog post. The important thing there was to keep a record of the choices that the code makes while moving a train so that the train can be drawn on the correct track segments without having to know the location of every car in the train. Managing every car separately would make it difficult to move the train because curves can cause the cars to change how far apart they are on the track while they keep the same distance apart coupler-to-coupler.
More on this subject can be found by simply searching for “train” on this blog.
Linear vs. curved distance on curves. Note that the distance along the curve is not the same as the straight line distance between the two points of contact with the track.
Another coding subject that was an issue is how should the code let the user draw the track and how can the mouse input be interpreted so that the data structures, and therefore the train code, know which direction is which when the train comes to a track switch. Although keeping track of the nodes where the track splits into a different number of segments is easy, keeping track of the segments so that the train does not make a 180 degree turn at a branch point is essential to a realistic train game. The drawing code to handle the input and the storage of the data was complex so that the train code for moving around the track is not.
I may revisit this project but creating a real game of this complexity is well beyond the scope of a home project.