Skip to Content
ScriptingC# Scripting Basics

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:

  • Visual Studio 2022 (Community Edition is free) or VS Code with the C# Dev Kit extension.
  • .NET Framework 4.5.2 (FiveM uses a mono runtime compatible with this version).
  • Basic knowledge of C# syntax and Object-Oriented Programming (OOP).

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:
    • CitizenFX.Core.dll (Required for both Client and Server)
    • CitizenFX.Core.Client.dll (For Client scripts only)
    • CitizenFX.Core.Server.dll (For Server scripts only)

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#

  • Async/Await: Native support for asynchronous programming makes handling delays and API calls cleaner.
  • Type Safety: Catch errors at compile time rather than runtime.
  • Performance: Generally faster execution for complex logic compared to interpreted languages.

Troubleshooting

  • FileNotFoundException: Ensure all referenced DLLs are in the resource folder or properly referenced in fxmanifest.lua.
  • Runtime Errors: Check the server console (F8) for stack traces. C# stack traces are usually very detailed.
Last updated on