Back to Main Page

This was an idea posted on GTAForums that I decided to investigate.


Glowing Brake Discs - Red Hot Action

During my rounds of GTAForums, I stumbled across a thread about Red Hot Brake Discs. The idea seemed interesting and had the potential to be another addition to GVE and VEP... so challenge accepted!

If anyone has read the Driver Information System page, you will have seen the parts about the door markers. This seemed like a prime candidate to adapt that system for something wheel based. So I quickly put together the code that got me the bone positions of the wheels and immediately ran into the scripter's worst nightmare... addon vehicle modders.

By rights, I should have been able to use the hub_lf, hub_rf etc... bones but of course, that would have required addons to use those bones properly... never going to happen. So I opted for the wheel bones and that proved equally as risky. I had to choose one, so wheel bones it was. I got the location of each bone and to move the effect into a visible area, I added a .025f offset, or -.025f depending on which side of the vehicle they were on.

Note: Under consideration is the ability to specify vehicles in the ini file with offsets so that any really troublesome vehicles can be manually adjusted to be perfect.

So that got me the markers in roughly the right place and then I turned the front wheels. There were two problems with the front wheels.

1) They turned when you steered.
2) The amount they turned was slightly different to the amount of steering that was being applied.

The solution to number 1 was something I had dealt with in my CCTV watcher mod and that was rotating an offset around a base object that was also rotating. The front wheels turned on a car that was also turning.

The solution I had used was a Quaternion.Euler function, that would rotate a position around a rotation. I was lucky to have found that because that's the kind of thing I could take days to think about and then still not have something that worked.

Number 2 is something I have taken a shortcut with for now, it actually rotates 80% of the steering angle, which seems to work okay for the outer wheel but the inner wheel is going to be different, so that's something I will have to come back to.

Update: Number 2 turned out to be a pain in the backside. I hadn't taken into account the steering lock ratio, which I now have but like real cars, when you turn left or right, the inner and outer wheels turn by different amounts. So it was a case of "Which of these numbers will modify the angle by the right amount to make things work?". That now seems to be fixed... fingers crossed.

Further Update: Number 2 isn't fixed... what a complete pain this is, there seems to be no consistency in the turn amount. I must be missing a value somewhere but I just don't know what. Sometimes, the consequences of being a broken person are far-reaching, having no info sources makes things doubly-difficult. :(

So I had the markers, they all tracked the wheels, so now it was time to create the effect. This was basically a case of modifying the red, green and alpha values to simulate heat build-up in the discs. The heat is built up based on the speed you are travelling and the amount of brake pressure being applied. That's probably an overly simplistic way to do it but it seems to work. Sometimes, simple things just work and simple things cost very little in processing power, so it's good when they do work.

So zero heat = 0 Alpha = 0 Red level. As the heat increases, so do the Alpha and Red levels, which probably seems obvious. Alpha is clamped at 192, in the hope of allowing the texture behind to still appear visible to a small extent.

But then there's the Green level, which I wanted a bit more control over, that's a level I call overheat. Overheat is a level that starts to kick in as the discs hit 33% of their maximum heat level and it's based on the accumulation of that final 66% of heat. But to ensure the discs don't go into blazing yellow, they're restricted to build up at half-rate and clamped at half-maximum value.

Here's a more graphical view of how it works... this doesn't quite convey the actual colour process as it appears ingame but it gives you the idea.

Once you stop braking, the brakes cool down based on elapsed time and Alpha, Red and Green levels decrease accordingly.

This is a short video of how the effect looks in a replay around the airfield with 3 Acura NSX cars. Even though the processing is based on simple number manipulation, it seems to work well.


As you can probably guess from this, I have already built this into VEP so that any cars sent to it during LCA replays are able to display the effects. The player vehicle functions will be moved into GVE once I am happy that things are stable. If performance shows signs of suffering, I have code in place that will detect which side the car is being viewed from and will only display the effect on the wheels on that side. The effect is small though, so it might be okay as it is.

An issue did pop up today with the different sized wheels and the effect size. So I added some code to get the wheel dimensions and to scale the effect based on the rim size. This will work independent from front to rear, to cater for any vehicles with bigger rear wheels.

So that's another rapid development cycle for something that has reaped big rewards in the mods I use. It just shows, even the smallest ideas that nobody else cares about, are always worth time investing in them.

Update: I decided to add an adjustment mode to this to combat the wheel issues. It's a simple mode that just lets you move the effect forwards and backwards from the wheel and allows you to scale the effect. It then saves those settings to an ini file that is read by GVE and VEP, so that it can adjust any vehicles that get used. Simple enough but as you can see from this image, it makes all the difference. The top view is before adjustment, the bottom view is after.

Update: Well once again I asked a question for some info and once again, I was met with a wall of silence. I was missing a vital piece of the puzzle to fix the front wheel brake discs and I couldn't find it, so I asked for help. It seems no matter how much help I give out, there is always zero help in return from the "community".

I actually did find it with the help of my Offset Watcher mod, which dumps a real-time updating hex dump of selectable memory locations onto the screen. So now the brake discs perfectly align with the front wheels, which is extremely satisfying.

Funny really, I was asked if this mod was going to see the public light of day. Every time I write a mod, I always ask myself that and then after I have tried to get help, I remind myself that it isn't. This was the 4th personal request mod I have created since I stopped public modding, I still provide answers, I still provide solutions and the GTA V Modding community still provides a reason for me to have nothing to do with it. And it's a pity, because this mod is so much better in the game, than it is on the crappy videos I produce. People could have been creating videos with these mods and instead, they're left to just watch them.

I am genuinely proud of the mods I create and share, I wonder if there are people genuinely proud of the irreperable damage they have done to the GTA V modding scene? I sometimes think there are.

Update: Turns out my jubilation was premature about finding the missing vehicle property and after another day of watching endless screens of values, without even a hint of knowing if I am in the right place, I am sorely tempted to just quit. I have spent the day dumping 6000+ line data files that weigh in just short of 100KB and nowhere does this steerWheelMult value even appear as a value that matches what is written in vehicles.meta. I even created something blatantly obvious, .345678 in the meta file and that value was nowhere in the data I dumped. But if there does seem to be a matching value, it isn't there in another car, which means it was just a coincidental match.

What is really intriguing is the one source I can usually rely on to get accurate info like this, is also wrong. So at least the value is not just eluding me, the other person's code always returns 1, which is of course, incorrect.

So the solution to this problem turned out to be another parameter in the DAS (Disc Adjustment System) config files. You can now set the simulated steerWheelMult value with gamepad inputs and they get saved for both GVE and VEP to use when required. Is it ideal? No. Does it work? Yes and at this point in time, that is all that matters.

Update: Out of sheer curiosity, I decided to do an experiment to see how this worked with props. So I created the effect as a prop with an emissive texture and got it working.


The first half of this video shows the main vehicle using the props for the effect, the second half uses the markers. Whilst the props look nice and bright and glowing, there is also an obvious problem. Prop alpha levels go from 0 - 255, like markers... however, they only change every 20%. That means that instead of 256 levels of alpha, you get 5, which isn't very good.

So that's the prop option out of the window then... right? Well no... but here's the thing, why should I care?

The actual solution is pretty simple, I create multiple versions of the prop, with the alpha level of the texture reduced by a fixed percentage. I then create a version of the prop with each texture on them and flip between props. So for example, if I created a 4% reduction in texture alpha for 5 frames, that would give me 5 levels of texture alpha for each level of prop alpha. As you switch to the next level of prop alpha, you go back to the first prop at full texture alpha, that has now been reduced by 20% by the prop and is at the next natural step in the alpha reduction process. I can already detect which side of the vehicle you're on, so it only requres 2 * number of prop variations to get a more smooth-looking effect.

This might make that explanation clearer...

But to go back to my question, given the attitude I keep facing, why should I even think about it? The answer of course is easy... and it's simply the fact that it's what creative people do. Every challenge is worth taking on, because every challenge teaches you something new and expands your knowledge. And who knows, I am teetering so close to the edge these days, maybe someone can offer an incentive for me to let them have this. Who am I kidding... not going to happen.

Update: I should have known better... the prop idea failed miserably. The prop switching works perfectly but the alpha levels in the textures seem to get overridden by the Prop alpha level. So even though each prop has a different alpha level for its own texture, all 5 are shown the same. Ah well... nothing like going out on a failure.

NOTE: The cooling process is deliberately being run slowly, to give me chance to see the prop states changing.


Update 8/4/2019: I was given a line of code today, that should have sorted out the steering angle problem on the front brake discs, this is the code I was given:

float mult = *(float*)(ext.GetWheelsPtr(gV.Vehicle) + 0xCC);

That's C++ code, so I obviously had to convert it to C#

I already have a function that returns the wheelPtr, which was written by CamxxCore, so I know that works. So in my mind, all I needed to do was this:

byte[] bytes = new byte[4];
Marshal.Copy(wheelPtr + 0xCC, bytes, 0, 4);
return BitConverter.ToSingle(bytes, 0);

That's the way CamxxCore wrote the float-getting code, so I know that method works. I also use that on all of the other functions in my vehicle extensions classes, so I know that definitely works. But this returns completely the wrong value in this instance and I have no idea why. For example, it should return a value between 0f and 1f but if I get in the Ubermacht Oracle XS, it returns 3.9f... which is definitely wrong.

For the record, I really struggle to understand any code that uses this kind of thing:- *(float*), I really just don't get it at all. I can read and read and read and I still don't get it. Some things just don't sink-in like they should and this is one of them. So I don't actually know what the first line of that code is actually returning, which is probably why I am returning the wrong thing. I mean, my assumption is that it is returning a float value from the address being pointed to by the rest of that line. I even tried the method used in SHVDN to read a float from memory but it returned the same incorrect value.

I mean, it seems like in the old Z80 days where you had:

ld hl, a - which would load the register-pair HL with the value of A

ld (hl), a - which would load the address being pointed to by HL with the value of A

Oddly enough, it's a line that is accepted in (almost) its existing state in C# but that also returns the same incorrect value. The line I actually tried was:

float mult = *(float*)(wheelPtr + 0xCC);

wheelPtr is returned prior to that line being called and that line is called inside an unsafe{} block.

So if anyone is reading this and you can see what I am doing wrong, could you please drop a comment on one of my videos. I won't turn it into a conversation, because I know that's not a good thing with me. I will simply "Like" the comment and say "Thank You" and that can be that. I just don't understand my mistake and there isn't any way for me to find out what that mistake is.

Update 09-04-2019: For a change, I actually have some success. After being given another memory address (in place of the one above for the steering multiplier), I then proceeded to write a whole collection of incorrect code to use it. Because there is so much I don't really understand with memory handling, my method is basically... think of every possible way I might be able to do it and then try them all until one works. And in this instance, none of them did.

Then I realised that the answer was right in front of me all the time, in another function. Once I had that bit of code corrected, the right value was returned from the function I wrote to get it. So that allows me to strip a stored value from the config file and can remove one value from the adjustment mode as well. It does place that value at the mercy of any game updates but I don't think that's going to be something I will have to deal with soon anyway.

So my final comment on this page is going to be a massive thank you to ikt, for providing the code that let me finally put this steering problem to bed.