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
- Open Visual Studio.
- Create a new project.
- Select Class Library (.NET Framework). Note: Do not choose .NET Core or .NET 5/6+.
- Name your project (e.g.,
MyResource.ClientorMyResource.Server).
2. Add References
You need to reference the FiveM client and server assemblies.
- Right-click References in the Solution Explorer -> Add Reference.
- Browse to your FiveM Application Data folder (e.g.,
%localappdata%\FiveM\FiveM.app). - Navigate to
citizen\clr2\lib\mono\4.5. - 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