Technical Documentation: citizenfx/fivem
βΉοΈ Provenance: Multi-Tier Ingestion Β· CodeWiki Reference
Overview (README.md)
FiveM & RedM
This repository contains the code for the Cfx projects, among which are the following:
- FiveM, a dual-purpose (SP/MP) modification framework for the PC version of Grand Theft Auto V Legacy as released by Rockstar Games.
- RedM, a modification framework for the PC version of Red Dead Redemption 2 as released by Rockstar Games.
- FXServer, the server component for FiveM and RedM.
FiveM and RedM allow the creator community to host and operate large-scale community servers. Creators build their own game modes and content in a variety of scripting languages, giving players fully customized experiences to jump into.
Getting started
To play, download the launcher from the FiveM or RedM website.
To contribute to FiveM or RedM, follow the documentation in docs/.
To run your own server, get started with server hosting for FiveM or RedM.
License
Use of this software is subject to the Rockstar Games Creator Platform License Agreement, except for specific files that are licensed under the GNU Library General Public License.
Full details are in the LICENSE file, and third-party components are listed in THIRD_PARTY_NOTICES.
README (`docs/README.md`)
Cfx.re Developer Documentation
This directory contains developer documentation for the Cfx.re projects.
Building (`docs/building.md`)
Building the Cfx codebase
Generate solution
To build FiveM, RedM or FXServer on Windows you need the following dependencies:
Visual Studio 2022 (Community edition or higher) including the following:
- Workloads
- .NET desktop development
- Desktop development with C++
- Windows application development
- Individual components
- .NET Framework 4.6 targeting pack
- Windows 11 SDK (10.0.22000.0)
You can install these workloads by going to "Tools" -> "Get Tools and Features..." -> Check the checkboxes -> Click "Modify" in the bottom right corner.
- Workloads
PowerShell 7 or higher.
Python 3.8 or higher with the
pylauncher installed.MSYS2 at
C:\msys64\which is where the installer places it.
Then, execute the following commands in a cmd.exe shell to set up the build environment:
git clone https://github.com/citizenfx/fivem.git -c core.symlinks=true
cd fivem
git submodule update --jobs=16 --init
:: if you're using Python 3.12 or higher make sure you install the setuptools package
pip install setuptools
:: downloads the right Chrome version for 64-bit projects
fxd get-chrome
:: build bindings of game natives.
prebuild
:: or -game server/-game rdr3
fxd gen -game five
fxd vs -game fiveSet up data files for `five`
After building the FiveM client, you should be having files such as /code/bin/five/debug/v8.dll exist automatically. Manual copying is no longer required.
Symlink game-storage directory (optional)
The code\bin\five\debug\data\game-storage directory can get quite large and is equivalent to the %LocalAppData%\FiveM\FiveM.app\data\game-storage directory, so you should use a symlink to save disk space.
If you don't know how to do that, here's how:
- Navigate to
code\bin\five\debugin yourfivemsource repository. - Make a new
datadirectory if it doesn't already exist. - Delete the
game-storagefolder indataif it already exists. - Hold Shift, right click empty space while in
code\bin\five\debug\data, and select "Open PowerShell window here". - Type in the following commands:text
cmd mklink /d game-storage "%localappdata%\FiveM\FiveM.app\data\game-storage" - You should now see a
game-storagefolder insidecode\bin\five\debug\data.
Known issues
Game starts but all I see is the main menu background, my cursor and (when I press F8) a console!
This directory is probably missing:
/code/bin/five/debug/citizen/ui.UI building might have failed, but you can copy this directory
%LocalAppData%/FiveM/FiveM.app/citizen/uifrom your main installation of FiveM.Windows error code 126, or some issues with other DLLs.
It's possible that you accidentally missed a step or skipped a file that should have been copied. Start this section over from scratch; do not pass go, do not collect Β£200.
Windows error code 127.
Add an antivirus exclusion for the repository, try rebuilding, and see if it works this time.
error CS0234: The type or namespace name 'API' does not exist in the namespace 'CitizenFX.Core.Native' (are you missing an assembly reference?)
error CS0246: The type or namespace name 'Hash' could not be found (are you missing a using directive or an assembly reference?)
fxd genran beforeprebuild. Close the solution, re-runfxd genand then reopen & build the solution again.
Layout (`docs/layout.md`)
Source code layout for the Cfx codebase
The CitizenFX codebase is a vast set of multiple components, many of which having nested README.md files explaining
their purpose further in the codebase.
This document is a general guideline towards these directories.
Root
- code/: Core native project code, and the root of the native build.
- data/: Runtime data for the projects to use.
- ext/: Extra supporting projects, generally either standalone or otherwise only depending on files/data in
ext/ itself. - vendor/: Submodules for project dependencies.
Vendor Chromium Mojo Docs Basics (`vendor/chromium/mojo/docs/basics.md`)
Mojo Basics
This document aims to provide a brief overview of the different concepts in Mojo
and how they work together. For more details about more complex and/or
Chrome-specific Mojo use cases, please consult Intro to Mojo & Services.
[TOC]
Interfaces
Mojo provides a C++-like interface definition language for defining
interfaces for making interprocess calls (IPCs):
module math.mojom;
interface Math {
// Adds two int32s and returns the result as an int64 (to avoid
// overflow issues).
Add(int32 x, int32 y) => (int64 sum);
};Interfaces are built using the mojom (or mojom_component) GN
template:
mojom("mojom") {
sources = ["math.mojom"]
}This will generate C++ (and optionally, Java and JavaScript) interfaces. Writing
code to handle IPCs is a simple matter of implementing the generated interface:
class MathImpl : public math::mojom::Math {
public:
explicit MathImpl(mojo::PendingReceiver<math::mojom::Math> receiver)
: receiver_(this, std::move(receiver)) {}
// math::mojom::Math overrides:
// Note: AddCallback is a type alias for base::OnceCallback<void(int64_t)>.
// The parameters to the callback are the reply parameters specified in the
// Mojo IDL method definition. This is part of the boilerplate generated by
// Mojo: invoking |reply| will send a reply to the caller.
void Add(int32_t x, int32_t y, AddCallback reply) override {
// Note: Mojo always returns results via callback. While it is possible to
// make a sync IPC which blocks on the reply, the handler will always return
// the result via callback.
std::move(reply).Run(static_cast<int64_t>(x) + y);
}
private:
// Wraps a message pipe endpoint that receives incoming messages. See the
// message pipes section below for more information.
mojo::Receiver<math::mojom::Math> receiver_;
};Note: the build process also generates proxy classes (e.g. MathProxy) which
encapsulate the details of making the actual cross-process call. These are
used internally and are an implementation detail that can typically be ignored.
Message Pipes
Interfaces are layered on top of low-level message pipes. Each
message pipe has two bidirectional endpoints. The Mojo bindings enforce
additional conventions on top of message pipes, where one endpoint is the
sender/caller, represented as:
// Wraps a message pipe endpoint for making remote calls. May only be used on
// the sequence where the mojo::Remote was bound.
mojo::Remote<math::mojom::Math> remote_math = ...;And the other endpoint is the receiving/callee, represented as:
// Usually a class member. Wraps a message pipe endpoint that receives incoming
// messages. Routes and dispatches IPCs to the handlerβtypically |this|βon the
// sequence where the mojo::Receiver was bound.
mojo::Receiver<math::mojom::Math> receiver_;This allows limited bidirectional communication. For one interface, the sender
(A) may make any number of calls to the receiver (B). (B) may send a single
reply for each call from (A). More expressive APIs are often implemented as a
pair of interfaces (with two underlying message pipes), allowing calls to be
made in either direction between (A) and (B).
Message pipe endpoints are typically created using one of:
mojo::Remote::BindNewPipeAndPassReceiver
Used when the sender/caller creates the endpoints. One endpoint is retained for
itself to send IPCs, and the other endpoint is returned as an unboundmojo::PendingReceiver<T> for the receiver/callee to bind to amojo::Receiver<T>.
mojo::Remote<math::mojom::Math> remote_math;
// BindNewPipeAndPassReceiver() returns a
// mojo::PendingReceiver<math::mojom::Math>. This may be bound to a
// mojo::Receiver<math::mojom::Math> to handle calls received from
// |remote_math|.
LaunchAndBindRemoteMath(remote_math.BindNewPipeAndPassReceiver());
// |remote_math| may be immediately used. The Add() call will be buffered by the
// receiving end and dispatched when mojo::PendingReceiver<math::mojom::Math> is
// bound to a mojo::Receiver<math::mojom::Math>.
remote_math->Add(2, 2, base::BindOnce(...));mojo::Receiver::BindNewPipeAndPassRemote
Used when the receiver/callee creates the endpoints. One endpoint is retained
for itself to receive IPCs, and the other endpoint is returned as an unboundmojo::PendingRemote<T> for the sender/callee to bind to a mojo::Remote<T>.
class MathImpl : public math::mojom::MathImpl {
// ...addition to the previous MathImpl definition...
mojo::PendingRemote<math::mojom::Math> GetRemoteMath() {
// BindNewPipeAndPassRemote() returns a
// `mojo::PendingRemote<math::mojom::Math>`. This may be bound to a
// `mojo::Remote<math::mojom::Math> which can be used to send IPCs that will
// be handled by |this|.
return receiver_.BindNewPipeAndPassRemote();
}
};mojo::PendingRemote::InitWithNewPipeAndPassReceiver
Less common, but similar to mojo::Remote<T>::BindNewPipeAndPassReceiver().
Typically used by broker code that needs to hand off a mojo::PendingRemote<T>
to the sender/caller side and hand off a mojo::PendingReceiver<T> to the
receiver/callee side.
mojo::Remote/mojo::Receiver and mojo::PendingRemote/mojo::PendingReceiver
Both mojo::Remote<T> and mojo::Receiver<T> have a corresponding unbound
version: this allows either endpoint to be passed between sequences in the same
process or even between processes over IPC.
mojo::Remote<math::mojom::MathImpl> remote = ...;
// |pending_remote| is movable and may be passed around. While unbound, the
// endpoint cannot be used to send IPCs. The pending remote may be passed to
// the mojo::Remote<T> constructor or mojo::Remote<T>::Bind() to rebind the
// endpoint.
mojo::PendingRemote<math::mojom::MathImpl> pending_remote = remote.Unbind();mojo::Receiver<math::mojom::MathImpl> receiver = ...;
// |pending_receiver| is movable and may be passed around. While unbound,
// received IPCs are buffered and not processed. The pending receiver may be
// passed to the mojo::Receiver<T> constructor or mojo::Receiver<T>::Bind() to
// rebind the endpoint.
mojo::PendingReceiver<math::mojom::MathImpl> pending_receiver = receiver.Unbind();--- METRICS ---
- Files Extracted: 5
- Estimated Token Budget: ~3369 tokens
- Canonical Reference: https://codewiki.google/github.com/citizenfx/fivem