FivePD API

Getting started

This documentation assumes you're already familiar with programming in C# to some extent.

Before anything else, make sure you have the following installed:

  • FiveM
  • .NET 7.0 SDK or newer (download from here)
  • (Recommended) JetBrains Rider or Visual Studio

Start a new project

1. Create the Project

Create a new Class Library project in your IDE.

2. Edit the .csproj File

Next, edit your project's .csproj file to ensure it's compatible with the FiveM server runtime.

In the Solution Explorer, right-click on your project and select Edit -> Edit 'YourProjectName.csproj'.
In the Solution Explorer, right-click on your project and select Edit Project File.

Replace the content of the file with the following. We are changing the TargetFramework to netstandard2.0 for compatibility with the FiveM server. We also recommend setting the LangVersion to 11 or higher to use modern C# features.

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <LangVersion>11</LangVersion>
    </PropertyGroup>

</Project>

3. Add Dependencies

Your project needs two key dependencies:

  • CitizenFX.Core.Server: Install the latest version from NuGet. This package provides the necessary FiveM server APIs.
  • FivePD.Server.API: Add a reference to the FivePD.Server.net.dll file, which is located in your FivePD installation at fivepd/Libraries/FivePD.Server/. This gives you access to the FivePD-specific APIs.

4. Create Your Addon Logic

You can create different types of addons. The most common are Extensions and Callouts.

An addon can contain multiple extensions and callouts within the same project.

An IExtension is used for creating custom logic that is not a callout, such as new commands or integrations.

  • Create a new class that implements the IExtension interface.
  • Implement the required OnStarted() and OnStopped() methods.
using FivePD.Server.API;
using FivePD.Server.Interfaces;

namespace MyAwesomeAddon;

public class MyAwesomeExtension : IExtension
{
    private readonly IAddonLoggerService _logger;

    public MyAwesomeExtension(IAddonLoggerService logger)
    {
        this._logger = logger;
    }

    public Task OnStarted()
    {
        this._logger.Information("MyAwesomeExtension has been started!");
        return Task.CompletedTask;
    }

    public Task OnStopped()
    {
        this._logger.Information("MyAwesomeExtension has been stopped!");
        return Task.CompletedTask;
    }
}

A Callout is a dispatchable mission for players.

  • Create a new class that inherits from the Callout base class.
  • Implement the required methods to define the callout's behavior.
using System.Collections.Generic;
using System.Threading.Tasks;
using CitizenFX.Core;
using FivePD.Server.API;
using FivePD.Server.EntityWrappers;
using FivePD.Server.Interfaces.Addons;
using FivePD.Server.Models;
using FivePD.Common.Enums;

namespace MyAwesomeAddon;

public class MyAwesomeCallout : Callout
{
    private readonly IAddonLoggerService _logger;

    public MyAwesomeCallout(IAddonLoggerService logger)
    {
        this._logger = logger;
    }

    public override Task<CalloutSetupProperties> Setup()
    {
        return Task.FromResult(new CalloutSetupProperties
        {
            Title = "Sample Callout Title",
            Description = "A brief description of the callout.",
            ActivityRadius = 20f,
            Priority = FPriority.Code3,
            Location = new Vector3(723.24f, -148.43f, 50.49f),
        });
    }

    public override Task<bool> CanBeDispatched()
    {
        return Task.FromResult(true);
    }

    public override Task OnDispatched(List<Unit> units)
    {
        this._logger.Information($"OnDispatched - {units.Count} units");
        return Task.CompletedTask;
    }

    public override Task OnUnitAssigned(Unit unit)
    {
        this._logger.Information($"OnUnitAssigned - {unit.Callsign}");
        return Task.CompletedTask;
    }

    public override Task OnAccepted(Unit unit)
    {
        this._logger.Information($"OnAccepted - {unit.Callsign}");
        return Task.CompletedTask;
    }

    public override Task OnCompleted()
    {
        this._logger.Information("OnCompleted");
        return Task.CompletedTask;
    }

    public override Task OnPlayerEnteredInActivityZone(FPlayer player)
    {
        this._logger.Information($"OnPlayerEnteredInActivityZone: {player.GetUnderlyingPlayer().Name}");
        return Task.CompletedTask;
    }
}

5. Build and Deploy the Addon

FivePD addons do not require the .net.dll extension that standard FiveM resources use. Your compiled file should be named MyAwesomeAddon.dll, not MyAwesomeAddon.net.dll.

  • Build your solution in Release mode.
  • Navigate to your FivePD installation directory, then to fivepd/Libraries/Addons.
  • Create a new folder for your addon (e.g., MyAwesomeAddon).
  • Copy the compiled MyAwesomeAddon.dll from your project's bin/Release/netstandard2.0 folder into the new directory.

6. Configure the Addon Metadata

This file can be either JSON or YAML. Learn more in the File Types documentation.

Create a metadata.yaml file inside your addon's folder (MyAwesomeAddon). This file tells FivePD how to load your addon. For more details, see the Configure Your Addon page.

FriendlyName: My Awesome Addon
Version: 100
FriendlyVersion: 1.0.0
Author: Your Name
Assemblies:
  - MyAwesomeAddon.dll

7. Final Step

Start or restart the FivePD resource. If you have done everything correctly, you should see the following message in the server console: Registering addon "My Awesome Addon" version 1.0.0