Back to Main Page

It wasn't until the Kitsune Trains animation project that I actually realised there were train engineer mods that let you drive the trains. The trains in GTA 5 are uninspiring blocks of polygons that do very little that makes you want to watch them... under normal circumstances.

The animated steam trains shifted that outlook, suddenly they were doing things that were interesting and that made me consider this mod during development of the KT script.

I made some changes to the KT script just prior to release, that let me have access to the cinematic camera control. I was using it for one of the sounds (can't remember if it was the bell or the horn) but it was always at the back of my mind to create this camera mod.

However, given the issues caused by the release of the KT script, I now have no plans to make this a publicly available mod.

I am not going to elaborate any further than that. This page isn't anything to do with Kitsune Trains, so...

Progress on this mod will be slow, guaranteed. Drinking levels have increased, that means the ability to think clearly for extended periods of time has decreased measurably. It doesn't matter though, it will take as long as it takes... if it gets finished at all.

Page 2

Cinematic Train Camera - Trainspotting in Style

This will be the development page for the Cinematic Train Camera mod I plan to create.

Initial Proof of Concept video for this mod.


This videos shows an absolute minimal level of camera logic. There is no advanced functionality of any kind, it picks a spot, places a camera then either follows the train or doesn't... that's it. The fully functional mod will have a number of zoom modes, tracking modes, motion modes etc... to pick from, just like the cameras in LCA. The difference is that in LCA you manually chose the camera type, here it will be dynamic.

The mod may or may not get finished, it's being driven by anger right now and as that dwindles to indifference, the mod may grind to a halt.

Oh... and if anyone is wondering why comments and Like/Dislike counts are turned off on that video, it's quite simple... it's potentially going to cause anger and I'm just not interested in hearing it.

Basic Camera Placement:

The base position for the camera is a point ahead of (or behind) the train based on the train's current speed and direction of travel. The point is always on the actual route as an interpolated point between two track nodes, giving me scope to search in all directions from the centre of the track for a suitable place for the camera. I know which direction that piece of track is heading in by taking the direction from one node to the next, meaning I can look directly left or right for obstructions. The variations in camera types will alter how this location search will be conducted.

I could have opted for the same system as the OnFoot Cinematic Camera used but I wanted to experiment with a more spontaneous system, instead of a system that is constantly tracking points. This may be a bad move, only time will tell.

There is some erratic placement being caused by the calculations used to predict the ahead point. I think this is because the point the game uses to change between track nodes isn't based on any measurable factors. It's actually right at the front of the train and not at the train's origin, which I wasn't expecting but that does explain the odd movement the trains go through when going round bends. I think the train is placed at that frontal point and then the rotation points the back end at the rear point. But I am reading the track node value from memory rather than using my own node tracking system this time, thanks to a memory pattern I saw in some code online. This is why I am at the mercy of when the game changes track node values.

But this frontal point is not based on the model maximum.Y dimensions, so I can't get a matching value to calculate from. As a result, threre is some juddering with the final calculated position but it's still in the right area, so it shouldn't be a major problem. I have equivalent code which searches for a position to the rear of the train for if/when the train is reversing.

Of course there is also an option of using the KT script to provide info for this mod to use. The KT script stores the current track node in a decorator in each train that mod handles. It could also store the track and interpolation factor between nodes as decorator values as well. If I want to make it compatible with any game versions I am running that use vanilla trains, then I have to be able to work without that data, so there's probably not much point in adding it.

Starting Point:

As it stands at the moment, there is the initial update function that creates everything seen in this video, along with a bunch of diagnostic info if debug mode is turned on. I am now creating a second update function that I can switch to and that will use the full implementation of the CinematicCamera class, which will handle all camera functionality. As that class expands, then so will what the mod is capable of. But it means I can switch to different states of the mod through a setting in the ini file, which will control which update function gets called.

Update 30th May: The first issue I decided to deal with was tunnels. For obvious reasons, tunnels are problematic and they impose severe restrictions on both camera placement and camera types. Trains register being inside a tunnel with one of the memory values, plus the track nodes store that information as the node being an "Underground Track" node. but the camera doesn't use any of that information, so it relies on the _ARE_COORDS_COLLIDING_WITH_EXTERIOR Native to determine if it is inside an interior.

Once it detects being inside an interior, it calls a specific camera placement function to determine the limitations imposed. It fires two rays, one to each side from 1m above the track node position. This tells it how far it is from the track to the tunnel walls on either side. It will then use the furthest distance, subtract 25cm from that and use that as the camera position. This should ensure that you are always getting the most distance between the camera and the train, to give the best view. This all seems to work fine during initial testing.

Update: Well the native I was using is proving to be unreliable in some areas of the map for some reason. The name has been revised to IS_COLLISION_MARKED_OUTSIDE on one of the NativeDB sites, which means it probably doesn't do what I thought it did. GET_INTERIOR_AT_COORDS will return an interior ID from a position but it doesn't care if you're inside or outside the interior, so that's no use.

I can't use the vanilla trains1.dat file, because that's broken. There are areas inside tunnels marked as overground track, there's an area on a bridge near Slab City that marked as underground track. If they didn't screw up so much of their data, then it would be usable... but this is Rockstar, screwing up data seems to be their specialty.

I really don't want to have to resort to the "Determine if it's an interior by firing raycasts in all directions and seeing if they all hit something" method, because I know for a fact that there are areas that would trigger a false positive on that as well.

I just tried GET_INTERIOR_FROM_COLLISION and that has the problem in the image below. It seems that colliding with the rails prevents it from detecting the interior. FYR: The number is the interior ID.

Okay... so I thought "Well surely the ground must always return the correct value from that collision related native", so when I set a new camera, I get the Ground Z at that location, then pass that as a new Vector3(cameraPos.X, cameraPos.Y, GroundZ) to the IS_COLLISION_MARKED_OUTSIDE Native. First pass through the problem tunnel went okay but it's clearly something I am going to have to keep an eye on.

Sheesh, less than 5 minutes later and from inside the tunnel in La Mesa, the camera gets positioned somewhere near N.O.O.S.E Headquarters, so I guess that doesn't work either. F*ck!!!

Turns out my cross-country camera error was caused by me underestimating the potential width of a tunnel. Pushing the Raycast distance out to 20m seems to have eradicated that problem. I am already starting to get the impression that this mod is going to present some challenging scenarios to deal with though.

Update: nope, the problem still seems to exist in tunnels, this obviously needs more work. I have pushed out the width checking to 30m, just in case there are some rare scenarios that are being caught out.

I have also implemented a system where if the train isn't in view when a camera switches in a tunnel, it always points at the train. If it is in view, there is a 50/50 chance that the camera won't point at the train.

On a positive note, I am really liking what I am seeing with the views that are being produced so far. I normally play with real-time enabled, so that the days last longer but I turned it off for a while to watch the transition into evening. The result is a bit like AutoSnap, you get one-time shots of a certain train position, with a certain camera position, with certain lighting... even with the vanilla freight train some of the shots are pretty awesome. Once I add in the additional camera options, this should be really cool to watch. It just goes to show, sometimes anger leads to things that stop you from feeling quite so angry... and the Vodka helps as well of course.

I am also curious as to whether the animals run from the train or the player, so I am going to switch on the "everyone ignores player" option in Simple Trainer while you are riding the train to see if the animals stop getting spooked. Hmmm, they do seem less prone to run when that option is turned on, so I might include that in the camera activation code, or maybe even when you get into a train.

I think I am going to call it a day for today anyway, it feels like progress has been made, so things are not too bad. Funny, I was sat watching the trains and thought "Hey I know, I'll release a crappy basic version for free that does nothing and then a Patreon version that does everything". Then I realised how stupid that sounded and decided to stick with my original plan of just releasing screenshots and videos of the mod instead. :P

Oh, one other thing I did implement was the camera switching with the view controls, so I can now switch to a new camera view by flicking those controls, like the normal cinematic camera for vehicles.

Update 31st May: No real progress so far today because of the bugs and crashes in other mods that have surfaced during testing. Maybe something will happen later... Actually, that isn't completely true because I did have to impose another look-ahead limit because the UP4014 was so long that it was causing the mod to look too far ahead for the length of time a camera stays active.

23:30... loaded up Visual Studio several times today, looked at the code and then closed it again. Definitely a "not happening" day.

Update 1st June: Another day of nothing so far. I thought this might have kept me interested based on past experience with camera mods but it's just not happening.

22:10... loaded VS once today, added 4 lines of irrelevant code, closed it again. Looks like KT did way more damage than I first thought. This is all going to provide an interesting twist in my therapist meeting on Thursday.

Just shows though, 30th May had lots happening and then all motivation disappears instantly. Vodka intake is high as well but it's doing nothing.

Update 2nd June: Another day... a different story. Quite a lot happened with the mod today.

Zooming cameras are now working, including the auto-zoom cameras seen in LCA which calculates the FOV based on the target distance from the camera.

Rising and Falling cameras are now working with the same interpolated Cubic easing as seen in LCA.

Camera shake based on FOV is also implemented for any zooming cameras.

There's still a lot of checking code missing to make sure cameras don't get put inside objects or under mountains. There's also no checking code added to switch cameras for any other reason that the timer running down but adding all the motion and zooming code adds quite a lot to how it all looks, so it's positive additions.

It's going to remain a more slow-paced cinematic experience because like my on-foot camera, the attraction I find with that is it gives you more time to watch the surroundings. Even though you have a main focus, I think what is going on around makes them so much more convincing and entertaining. I was going to put a small montage together but at 15 seconds for each cinematic shot, you soon run into the problem that you have enough interesting clips for 10 minutes of video but that feels like too much to put in a video. I can't imagine any videos I create from this are going to be popular either, so I will probably just post occasional screengrabs that show interesting moments.

Update: Made some fairly major changes to the camera position code which has definitely improved things. It should put an end to camera-inside-things hopefully.

Added a video as well because why not.


Update 3rd June: Added some code that will generate a +/- 10 degree Y-rotation on the camera if the Zoom and Motion modes are set to Fixed. It just makes the static camera a bit more interesting.

I discovered today that the J10RailroadEngineer mod interferes with the Vehicle Enter/Exit control to such an extent, I cannot detect it being pressed using either IsControlJustPressed or IsDisabledControlJustPressed. I'm not sure what the mod author was thinking when they made that decision but it made disabling the cinematic camera when you exit a vehicle a far more convoluted process than it needed to be. You also can't enter another vehicle when a train is close by, which can be really annoying if you have stopped a train next to another vehicle.

I have to add some code next that stops repeated use of the same camera type. I got three rising cameras in a row tonight and it doesn't feel right when it does that. Switching camera views by input seems to have broken for some reason as well, so I need to find why that has happened.

Trivia: The main train line in the game is 18.44188215 Miles (29.6793325 Km) long, which at 30Mph will take you 36 minutes to travel round. Given the 15 second timer for camera changes in this mod, that means you will see 144 camera changes during a full circuit of the line.

I wouldn't like to think how many changes I have watched during testing of this camera, I used to walk the streets for several hours a day during testing of the on-foot camera, I am not at that stage with this but at least an hour a day is spent just watching trains to see how changes are happening. And at least Emily gets to sit down testing this mod, which I am sure sure is appreciative of.

Update 4th June: Added more code to further refine the camera choice to avoid repeated use of the same motion or zoom types. Also did some work to restructure the camera choice code to try and optimise that in case more types need to be added. Later I will try and add the high-orbit cam, which in theory shouldn't be a problem but it will demand code to check for a blocked view in case it switches to high-orbit and then the train goes into a tunnel. This is effectively the block timer I added to the on-foot cinematic camera.

My mind also keeps pondering the idea of attached cameras but they weren't very well implemented in LCA. They really need to have some kind of damper system attached but that involves maths that I am unfamiliar with. There also isn't much to attach cameras to on trains, the bone hierarchy is pretty limited.

But it's slow and steady progress that is so far, still yielding positive results.

Update: Aaaarrgggghhh!!! I keep getting random issues in the tunnel in La Mesa where the camera appears to be outside the tunnel but i couldn't think why it was happening. So I decided to check in Brokewalker to see if there was some missing collision in the walls... turns out it was an even bigger problem...

There is no wall for the Raycast to detect, so the camera just gets placed down that tunnel. I presume that tunnel is an interior and because the player is so far away, it doesn't get loaded. But the main issue is that I need to be able to detect when I hit those tunnels so the camera doesn't get placed so far down them.

I can't check for a different interior than what the train is in because the tunnels are not one single interior, so the camera could quite feasibly be in a different interior just because it is further along the track... although I could detect if the interior is different to the origin point on the track. But that still leaves me having to decide on the distance from the track to set the camera point, which is even more of a problem when that tunnel is on the left side.

Just realised when running some diagnostics that the tunnel is never on the left side because trains only go through that tunnel on the left track. So if the right side check doesn't hit anything, I know I have hit a tunnel and can set a fixed value that I know will be a usable distance from the track. That seems to work during tests as the camera is now placed inside the same tunnel.

But once again the Rockstar F*CKUP comes back to screw things up. I am sat in the tunnel, the train is stopped, the interior detection says "You're outside" but the position is reporting an interior ID of 49154.

I can't say "Well if the detection says you're outside but the interior ID isn't 0 then you must be inside" because if I was outside that interior, it would stil report that ID because the Native isn't actually saying "Get the interior at this coord", it's saying "Get the interior near this coord".

I can't use a timer to check if the interior check has failed for a short period of time, because that breaks when the train is stopped.

I also can't use the values stored in the node type value in the trains1.dat file, because that isn't reliable either.

And then a light-bulb went on... I take the origin position and check that, I also take origin + (2 * forward) and origin - (2 * forward) and check those. If any of those returns true, then I set the CamIsInInterior to true. Doing a very slow 1Mph movement, one of those always reported being in an interior and all it needs is for one to be returning true. If any other area causes a problem that gets past that, I can always push the outer checks further out. I could use the next and previous track node positions but given how the nodes are sometimes widely spread, that might trigger a troublesome false positive.

I have seriously had it with this shit now. I spend all that time getting a solution that works, I drive down the tunnel and suddenly the camera is outside. Is it because of another interior/exterior problem you might ask? No, I would answer, it's because some dumb f*****g dipsh*t claiming to be an artist decided "Meh, who needs collision anyway".

That whole section marked in red has no collision, so if you cast a ray at it, it hits nothing. If it hits nothing, it thinks the tunnel is wider than it really is and puts the camera outside.

This is what it looks like inside the tunnel. The three red spheres are the interior checks and all return true. The blue line has a hit sphere on the end, the green line does not.

And those rays are being cast with IntersectOptions.Everything, so it's not as if something could be slipping by undetected. How do these people get or keep a job?

Update: Several hours later... I tried using capsules instead of rays and that worked in the La Mesa tunnel but failed in the tunnel near Slab City. So after trying various options, what I ended up with is a ray test 1m above the track, with the IntersectOptions just set to Map to avoid it detecting the plants in the middle of the track. I would say that has solved the problem but it takes so damned long to test every tunnel, there is no guarantee it does solve it.

It's at times like this when I realise that trying to get any sense of enjoyment out of modding is just no longer possible. It becomes just a sense of accomplishment, because you overcame the hurdles a bunch of incompetent asshats placed in your way. If anyone ever tries to tell me that Rockstar tests what it creates, I will call them a liar. Shit like this doesn't get past testers, unless the testers are as crap at their jobs as the creators... or are told to let it pass by overpaid asshats pretending to be middle management. I suspect overpaid asshats pretending to be middle management is something Rockstar is full of, amongst other things that go with "full of".

The only redeeming factor of this is fortunately the important one and that is its ability to throw up some awesome cinematic shots. If it failed at that, I think I would just give it up as a bad job.

Update 5th June: Another location in the La Mesa tunnel caused a screw up so that meant another revision to the tunnel code.

Orbital camera is now in, using both modes for camera position. Following Mode attaches the camera to the train and orbits around it, Fixed Mode orbits around the projected camera origin point. Both modes point the camera at the train. I am not convinced about this camera type though, so it is subject to revision or complete removal.

Another tunnel problem now, in the one just past the point the railtrack crosses the road after passing NOOSE HQ. At this point, I am about ready to just disable the camera in tunnels completely. Just noticed actually the screenshot above is at the entrance to that very tunnel.

Update: Made some slight changes to Orbital mode, it has its moments so it's probably going to stay. Added a timer that counts up if the projected camera point and the train are in an interior for Orbital mode. The timer hitting two seconds will cause a camera switch. The reason for both checks is that if the train is on its way out of the tunnel, there is no reason to switch views, so it is more to catch the train going into a tunnel where it might not emerge for a long while.

I think I am going to impose a more strict width limit in tunnels and that should help the camera avoid being placed in nasty tight nooks and crannies that cause problems. I mean my philosophy with this mod is "I don't care if it's a bad shot because it might evolve into a good one". So you might get the camera behind a rock or a wall but when the train comes into clear view, it could turn out to be a great shot. So while I was pretty vigilant with the view being blocked in my on-foot cam, this one is the opposite. I am giving things chance to develop... seems to work well so far. I seem to be spending hours watching the trains and I don't really see that many bad positions.

One thing that is annoying me is the train lights in the orbit mode, in some instances they keep turning off and on and I am not sure why. It might be a LOD thing, so I might try increasing the LOD multiplier for the train, see if that makes any difference.

I think it might be time to start a Page 2, this first page is quite long now.