C# General client/server question

Hi guys.

I’m starting to develop a server in C# and discovered that certain essential classes/functions are only available on client side. For example the “CitizenFX.Core.Vehicle” class is only available on client, that means I can’t work with vehicles on server side, does it? But why would you create a vehicle on a single client? Is it synced across clients and how do I take control over it on the server side?

Same thing applies for the player’s ped (CitizenFX.Core.Game.PlayerPed on client side), how could I possibly manage all player peds on server side?

Greetings

You gotta change all that client side and it will sync across the rest, I mean pretty easy to test just spawn in a car on a client and you will see it appears on all clients :slight_smile: I also thought about creating everything in c# but the NUI stuff is so much work it’s killing. Goodluck tho D:

I’m writing a lot of C# and I’m not running into any issues with it. What exactly do you wish to “manage”? If you could give us some examples, we’d be able to list the responsibilities of both the server and client. That should give you an idea of what to make.

Depending on what you want to do, you can generate an event that is sent to the server, from which you can then distribute it to all other players. For convenience, you would even be able to create your own functions that take care of this for you.

1 Like

I want to create zones and let players conquer them. It just doesn’t seem right to not know the players position on server side (as the CitixenFX.Core.Player class doesn’t contain a .Position property on server side) and let the client manage the zone conquering all by itself. I know, I have to sync the zones anyway, but I’m talking about the players position management (is inside a zone->starts conquering, for example) especially.

Another question now that somebody experienced appeared:

  • How to use the CitixenFX.Core.Vehicle class and whats it purpose? I was told to use “CitixenFX.Core.Native.API.CreateVehicle” to create a new vehicle, which I have to admit got me confused.

I can help you out by giving you two ideas:

  1. Let the detection of entering/leaving zones happen by the client, so you keep the heavy processing on the client side. As soon as the player enters the zone, send an event to the server with the player position & zone, and let the server validate & start the capture. Make sure you save the state server-sided, so you can do additional validation (what happens when 24 players enter the zone?).
  2. Send the player position to the server every second or so, and cache them server-sided. You can then apply additional checks when the server receives a new position. This would include entering a zone and starting a capture.

Now, I’m not so sure why you would actually want the server to do a lot of things. The power of client-side scripts is that you don’t need the processing power on the server, which makes hosting a server relatively easy and cheap. Of course it’s good to validate, but resources are actually obfuscated to some level when downloaded to the client. Don’t over-engineer your resources to prevent tampering, as FiveM already handles a great portion of that.

The API namespace actually contains most of the logic. The Core.Vehicle and Core.Player classes you mentioned are merely wrappers that internally call the methods inside the API namespace. It’s a bit hard to understand at first, but looking at the source code has really helped me out. You can find the classes in the GitHub Repo.

Creating vehicles is done using the World.CreateVehicle method in case you’d like to stick to the CitizenFX.Core namespace. Example:

var vehicleModel = new Model(ModelHash.Infernus);
if (!vehicleModel.IsLoaded)
    await vehicleModel.Request(3000); // for when you stream resources.
var vehicle = await World.CreateVehicle(vehicleModel, new Vector3(0f, 0f, 0f), 0f);

Note: I didn’t test the code, but you get the gist of it.

Thank you, I understand things a lot better know due to your great explanation! :slight_smile:

I have to admit that there’s still another question. World.CreateVehicle is the only legit function to spawn a synced vehicle, right?

int id = await API.CreateVehicle(_modelHash, position, heading, true, false);
API.CreateRandomPedAsDriver(id);

Because this isn’t working and I don’t get why.
The vehicle is created, the ped isn’t spawning. Is API.CreateVehicle okay to do this anyway? The wiki says it returns a “handle” as an integer, do I get something wrong here?

Thank you for your time, sir!

Not sure if 5 days is considered old but I’ll reply anyway.
On topic:
I personally never used World.CreateVehicle. I use the function you posted (API.CreateVehicle) but you must know that the handle it returns is client specific. The handle of the same vehicle will be different for each client. So you will need to work with the NetID instead. For a normal use case I think you should probably just use World.CreateVehicle. The only reason I am working with NetIDs is because I’m trying to make vehicles server-sided. My project is currently showing some promise I might release it to the public if I’m happy with it.

1 Like