Native return value keeps changing



So every now and again after a client update, the native GetScreenCoordFromWorldCoord() flip flops its first return value. It’s a minor thing but I keep having to edit and restart my server after some client updates.

More specifically, the first return value is if the world coordinates are on the screen currently. This is the actual value which changes from true to false and back and forth.
I don’t know if there are multiple people that push client updates, possibly one of them has it backwards.

After the latest client update on 12/30, it is returning false when it should be returning true.


I doubt the developers can do anything about it if it’s native related. Anyway though, do you have a repro case with some example code that we could try?


I figured maybe the native.lua was getting updated or something because it’s always right after there’s a FiveM client update and only after an update so I think it has to do with that somehow.

And yeah, it’s used to display player IDs above them.

    while true do
	for id = 0, 32 do
	     if (NetworkIsPlayerActive(id) and GetPlayerPed(id) ~= GetPlayerPed(-1)) then
	          local tCoords = GetEntityCoords(GetPlayerPed(id), true)
		  DrawText3D(tCoords.x, tCoords.y, tCoords.z+1.0, "" .. GetPlayerServerId(id), 255, 255, 255, 255)

function DrawText3D(x, y, z, text, r, g, b, alpha)
    local onScreen, _x, _y = GetScreenCoordFromWorldCoord(x,y,z)

    if not onScreen then
        SetTextColour(r, g, b, alpha)

This is stripped down but should still work. As you can see, for it to work correctly, it needs to be if not onScreen and every once in a while after a client update, I’ll have to add or remove the not.
It was working fine yesterday with if onScreen and after today’s update I had to add not. Done this many times so I always know how to fix it.
Again, it’s minor but an annoyance when it identifies players.


a) it’s literally impossible for ‘an update’ to cause this to swap around
b) why are you using ‘getscreencoordfromworldcoord’ and not ‘setdraworigin’/‘cleardraworigin’?


…So it’s just a coincidence that for months, after almost every client update, and ONLY after client updates, I have to change my code? You’re saying there is absolutely no way? I’m not trying to attack FiveM, it’s such a minor thing, but I just don’t see how there’s no connection. It’s literally at a point where I see my FiveM downloading an update, and I just check to see if the IDs are swapped, and they usually are lol.

And I don’t see a huge reason why to SetDrawOrigin over the other. I’ll try it out and see how it is.
Wouldn’t SetDrawOrigin effect all drawn text that frame, like other UI? I haven’t used it but assume it would.


Could the issue be that there are two functions with the same name in natives_universal.lua?


--- World to relative screen coords
-- this world to screen will keep the text on screen. it will keep it in the screen pos
function Global.GetScreenCoordFromWorldCoord(worldX, worldY, worldZ)
     return _in(0xF9904D11F1ACBEC3, worldX, worldY, worldZ, _f, _f, _r)
Global.N_0xf9904d11f1acbec3 = Global.GetScreenCoordFromWorldCoord


-- Returns a boolean; whether or not the operation was successful. It will return false if the coordinates given are not visible to the rendering camera.
function Global.GetScreenCoordFromWorldCoord(worldX, worldY, worldZ)
     return _in(0x34E82F05DF2974F5, worldX, worldY, worldZ, _f, _f, _r)
Global.World3dToScreen2d = Global.GetScreenCoordFromWorldCoord

I haven’t tried testing them seperately, but I assume they are two different functions, since they were both created. I know the second is the one that works as expected, since it mentions returning false when not on screen. The first does not so I don’t know.


ah, that’s indeed more plausible, these probably end up in a random order on each codegen invocation because of Lua’s pointer indexing of tables.

can you confirm that the second one (0x34…) is meant to be the one in use typically?

not if using cleardraworigin after


I can confirm that (0x34…) is the one used typically. It used to be named _WORLD3D_TO_SCREEN2D while the other one is mainly used for more HUD based I believe.
Anyway that the first one, (0xF9) could be named to Global.GetScreenCoordFromWorldCoord2 or something like that to avoid confusion? It does come second in the Native Reference so it would make some sense.