Hey, I’ve found a pretty annoying bug in the JS client natives wrapper and the source of the bug.
Every float argument of natives is parsed with _fv function which add 0.0000001 to the value.
In most cases, it isn’t an issue, but if you want for example disable vehicle traffic with SetVehicleDensityMultiplierThisFrame(0.0) it will flash ghost vehicles because the multiplier argument value will be 0.0000001.
JS natives wrapper source code
function _fv(flt) {
return flt + 0.0000001;
}
...
global.SetVehicleDensityMultiplierThisFrame = function (multiplier) {
return _in(0x245a6883, 0xd966d537, _fv(multiplier));
};
i’m curious if the addition to _fv is to confirm it’s decimalized…
but i can’t fathom why parseInt() or parseFloat() weren’t used instead.
I look forward to finding out, i’ve begun devving in the JS engine as well and i’d hate all that work to go to bunk.
i just use this on any number if i want to do that…
function(n){return Number(n) === n && n % 1 !== 0};
but that’s just a band-aid.
if this extra amount affects our floats in the JS engine…that’s kinda big for JS nerds.
Is there some code standard that exists that we’d be breaching if we just passed it as it is and let us assume it’s an int unless it has decimal remainders?
Thanks for answering. if i can help fix this in any way, would be totally up for assisting. i’m no codemonkey, but i can throw some Visual studio around when i have to.
I checked the code you mentioned and understand the issue : if we set for example 1.0 as a float native parameter in JavaScript it’ll be dynamically converted to an integer value and the native will fail because it expect a float.
Can’t we use the _fv function to return a string if the value is an integer (example: if the value is 1 or 1.0 return ‘1.0’ string), then in the V8ScriptRuntime we add a test to treat text float values as float parameter ?
It adds more tests when calling natives, but we could keep float information from JS to C++
Example of modified _fv function
function _fv(flt) {
return Number.isInteger(flt) ? parseFloat(flt).toFixed(1) : flt
}
I tried to get a working C++ POC but I’m not good enough… The best answer I found is to test with a regex digit, minus and dot characters.
Good job guys. When I found this problem with the spawning parameters I created a simple lua package to handle the traffic. It’s good to know there is a workaround now for that problem. Anybody plan to create a pull request into the Fivem repository if this solution is tested properly?