Callbacks

A long time ago, I used to program in PAWN (the language used in SAMP (GTA San Andreas Online)), and now that I’m learning LUA/FiveM, it’s been quite an experience for me. The way the threading system works is something I’ve never seen before—it’s impressive!

My question is: In PAWN, everything had Callbacks, like OnPlayerConnect, OnPlayerEnterVehicle, OnPlayerSpawn, OnPlayerKillOtherPlayer, etc.

Maybe I misspelled some Callbacks lol, but you get the idea. When I searched to see if there was an OnPlayerEnterVehicle callback here in FiveM, I realized it didn’t exist. So I went to check how many callbacks there are, and to my surprise, there are very few. Then I looked into how FiveM programmers identify client actions, and I saw they use checks (like IsPedInAnyVehicle) combined with Citizen.Wait(0). From what I understand, this means it constantly checks if the player is in a vehicle, while all the other codes (resources) are also executing AT THE SAME TIME…

So basically, while this check is constantly running, other checks are also running tick by tick (all the time), and it literally blows my mind lol.

Having multiple checks running tick by tick (Citizen.Wait(0))—doesn’t that risk crashing the client-side if done on the client-side, or crashing the server-side if done on the server-side?

How do you deal with this here? It scares me to think that one resource could overwrite the actions of another resource. For example:

[resource1]

client.lua:

some random codes....
Citizen.Wait(0)
IsPedShooting if yes SetPedMoney - 1

[resource2]

client.lua:

some random codes....
Citizen.Wait(0)
IsPedShooting if yes SetPedMoney + 1000

Just two examples of resources running tick by tick, with the imminent risk of one overwriting the actions of the other and causing a huge mess in the players’ economy. Of course, in the example above, it would be possible to create fixes and work around the problem, but I imagine that in more complex cases, this could become a disaster!

Don’t get me wrong—I know that PAWN/SAMP is prehistoric compared to LUA/FiveM. I’m using these examples because I genuinely want to learn how to deal with this using good practices and prevent my code from turning into an almost impossible mess to fix in the future.

The original bit about callbacks, CFX provides the “baseevents” resource with the FXServer. This resource handles a bit of the information you are looking for, running these checks already and firing events for other resources to handle (many developers ignore baseevents and internalize the functionality though). As for the order of operations, I believe that CFX has managed to create an environment that the server owner gets to determine order of operation by setting the start order of the resources, but all actions would complete, so in your example, when the player fired their weapon, they would gain a total of 999 money, every time. Finally… as to the not having a mess to deal with in the future, just keeping track of what resources actually do what functionality, and not putting in a bunch of garbage you aren’t sure what it does fully.

https://docs.fivem.net/docs/resources/baseevents/

This actually does exist: CEventNetworkPlayerEnteredVehicle
Check here for a list of game events: Game events - Cfx.re Docs
And this thread: Some Game Events and how to use them

Yes, bad practice. If you have some sort functionality that is not covered by events, it makes sense to have a single resource that checks multiple things in a loop and triggers an event when it actually happens (e.g. check out the baseevents resource). This way you only have one resource with a loop.

Not really, no. At least I do not know of any limit. You can definitely have hundreds of threads running. Of course they should be optimized but you get the point.

I have not yet dabbled in any sort of anticheat stuff, however the rule is relatively simple: “Never trust the client”. If you can then do everything on the server. Especially critical things like money/inventory etc.

Just don’t do stuff like that :upside_down_face:
In your case both resources would be running at the same time, so money would be +999 in the end (again, do stuff like that on server side).

Soo… SA:MP did the exact same thing in the backend, it’s just that Kalcor never wanted you to see any of it which is why we had all those callbacks back in the day (which lead to some ghoulish 50k+ lines gamemodes all crampted into one .pwn file).

But you can definetely recreate them using a “library”-style resource, and event handles / triggers.
@Kiminaze 's links are good for low-level events that GTA V triggers in their backend, and Jimmy’s baseevents is a good example of a library resource that a lot of servers still use.

Which is exactly why people are creating resources that tackle only specific needs. You will have one resource for core gameplay (keep track of player stats, update those stats and then send those stats to other resources that might need them), one resource for missions, one for factions, one for keeping track of player-owned vehicles, etc etc.

Also, and this is something that you didn’t have to worry in SA:MP, but you have to now, scripts are separated into 2 categories: client and server. (also shared, which means that both the client and the server load the same initial file, but they are not connected).
A client will only be able to download and interact with the client scripts, which means that you can keep all the scary stats logic server-side, and only send the client whatever data they really need.

Clients shouldn’t be able to dictate how much money they have. Keep that in mind when writing your resources, and you won’t have to worry about resources colliding with each other (at least… not worry that much)

LOL, that definitely can happen if you blindly download resources from the forum and not look into what they actually do (which, a surprising number of server owners do!)