Skip to Content

C# Scripting Basics

While Lua and JavaScript are the most common languages for FiveM development, C# (C Sharp) offers strong typing, compiled performance, and access to the rich .NET ecosystem. This guide covers the basics of setting up and writing C# resources.

Prerequisites

To develop in C#, you need:

Project Setup

1. Create a Class Library

  1. Open Visual Studio.
  2. Create a new project.
  3. Select Class Library (.NET Framework). Note: Do not choose .NET Core or .NET 5/6+.
  4. Name your project (e.g., MyResource.Client or MyResource.Server).

2. Add References

You need to reference the FiveM client and server assemblies.

  1. Right-click References in the Solution Explorer -> Add Reference.
  2. Browse to your FiveM Application Data folder (e.g., %localappdata%\FiveM\FiveM.app).
  3. Navigate to citizen\clr2\lib\mono\4.5.
  4. Select:

3. Build Output

Configure your project to output the compiled .dll files to a folder inside your server’s resources directory.

Basic Resource Structure

A C# resource typically has two projects in one solution: one for Client and one for Server.

fxmanifest.lua

You still need an fxmanifest.lua to define the resource and load the assemblies.

fx_version 'cerulean' game 'gta5' files { 'MyResource.Client.net.dll', 'MyResource.Server.net.dll' } client_script 'MyResource.Client.net.dll' server_script 'MyResource.Server.net.dll'

Writing Code

In C#, scripts inherit from BaseScript.

Client Script Example (Client/Main.cs)

using System; using System.Threading.Tasks; using CitizenFX.Core; using static CitizenFX.Core.Native.API; namespace MyResource.Client { public class Main : BaseScript { public Main() { // Event Handlers EventHandlers["onClientResourceStart"] += new Action<string>(OnClientResourceStart); // Register a command RegisterCommand("hello_csharp", new Action<int, List<object>, string>((source, args, raw) => { TriggerEvent("chat:addMessage", new { color = new[] { 255, 0, 0 }, args = new[] { "[C#]", "Hello from C# Client!" } }); }), false); } private void OnClientResourceStart(string resourceName) { if (GetCurrentResourceName() != resourceName) return; Debug.WriteLine($"The resource {resourceName} has started on the client."); } } }

Server Script Example (Server/Main.cs)

using System; using CitizenFX.Core; namespace MyResource.Server { public class Main : BaseScript { public Main() { EventHandlers["onResourceStart"] += new Action<string>(OnResourceStart); } private void OnResourceStart(string resourceName) { if (GetCurrentResourceName() != resourceName) return; Debug.WriteLine($"The resource {resourceName} has started on the server."); } } }

Events and Networking

Triggering Events

// Client to Server TriggerServerEvent("myResource:serverEvent", "arg1", 123); // Server to Client Player player = Players[source]; player.TriggerEvent("myResource:clientEvent", "data");

Handling Events

public Main() { EventHandlers["myResource:serverEvent"] += new Action<Player, string, int>(OnServerEvent); } private void OnServerEvent([FromSource] Player player, string arg1, int arg2) { Debug.WriteLine($"Received from {player.Name}: {arg1}, {arg2}"); }

Using Natives

Access FiveM natives via the CitizenFX.Core.Native.API static class.

// Example: Spawning a vehicle int vehicleHash = GetHashKey("adder"); RequestModel((uint)vehicleHash); while (!HasModelLoaded((uint)vehicleHash)) await Delay(0); int vehicle = CreateVehicle((uint)vehicleHash, x, y, z, heading, true, false);

Benefits of C#

Troubleshooting