Running a full RAGE:MP C# gamemode
SYNC MP runs unmodified RAGE:MP C# gamemodes — the same GTANetworkAPI (NAPI.*, : Script,
[Command], [ServerEvent], [RemoteEvent], [RemoteProc]) surface, loaded by the same loader
flow. A large production gamemode (hundreds of scripts, MySQL + Redis, thousands of events) boots on
SYNC MP with no source changes.
How it works
Your server's C# backend (Bootstrapper.dll, next to the server exe under dotnet/runtime/) is a
faithful re-implementation of RAGE:MP's GTANetworkAPI bridge. The public API is identical; only the
native layer (Rage.*) is re-pointed from RAGE:MP's native server onto the SYNC MP engine.
When a C# resource loads, the loader:
- Loads
<resource>/<meta.xml → script src>(e.g.bin/Debug/netcoreapp3.1/YourGamemode.dll). AnyBootstrapperreference in the resource resolves to the server's ownBootstrapper.dll. - Detects your custom entity classes — if you declare
class ExtPlayer : Player,class ExtColShape : ColShape, etc., every entity SYNC MP creates is instantiated as your subclass, so(ExtColShape) NAPI.ColShape.CreateCylinderColShape(...)casts succeed (RAGE:MP 1:1). - Instantiates every
: Scriptclass and registers its[Command]/[ServerEvent]/[RemoteEvent]/[RemoteProc]members — same counts and order as RAGE:MP. - Fires
Event.ResourceStartexactly once per resource.
A main-thread task pump drives NAPI.Task.Run / NAPI.Task.WaitForMainThread every server
tick, exactly like RAGE:MP's game loop — so scheduled/delayed work runs on the main thread.
Running your server
SYNC MP is a drop-in for ragemp-server.exe. Point the server's working directory at your RAGE:MP
server root so the gamemode's relative file reads (settings/, json/, dotnet/resources/) and
AppDomain.BaseDirectory resolve the same way:
:: from your RAGE:MP server root
D:\path\to\sync-mp\altv-server.exe
conf.json is read in RAGE:MP format (bind, port, maxplayers, gamemode,
"csharp": "enabled"). With C# enabled, every folder under dotnet/resources/ is auto-discovered
and loaded — no resource list needed.
A successful boot mirrors RAGE:MP line-for-line, e.g.:
loaded 350 commands(s)
loaded 123 server events(s)
loaded 620 remote event(s)
Accounts loaded. Characters loaded. Fractions loaded. Organizations loaded.
Loaded 1627 houses. Loaded 1627 garages. Vehicles are loaded (19)
Server is ready to accept connections
Native bridge coverage & the safety net
The Rage.* native surface is wired to the SYNC MP engine incrementally. Any native not yet
wired is auto-defaulted to a no-op that returns default, instead of throwing — so an
unimplemented function degrades to "does nothing" rather than aborting the handler that called it.
On boot the server logs how many delegates were defaulted, e.g.:
[csharp] Rage native bridge: 144 unbound delegate(s) defaulted to no-op (safety net)
Fully wired today: chat, events/RPC (server↔client), player lifecycle/health/armour/weapons,
entity position/velocity/model/dimension/heading, vehicles (engine/lock/health/color/mod/neon/…),
world time/weather, colshapes, blips, markers, text-label creation, IPLs, run-native-on-client,
entity shared data / server data (SetSharedData/GetSharedData/Has/Reset — server-side,
per-entity, all types), and world data. Client propagation of entity shared data and some
per-entity property setters are still being wired; until then those calls are safe no-ops.
The resource-load console output is RAGE:MP-exact — -> Starting <res> resource..,
loading scripts.. found N script(s), instantiating <Type>.. per class, loaded N commands/server events/remote events, loading exported functions.. found N, -> Resource <res> started!,
Started! Waiting for connections.. — so a boot looks the same as it did under ragemp-server.exe.
Known limitations (in progress)
- Some entity property setters (e.g.
TextLabel.Text, entity shared-data broadcast) are safe no-ops until wired end-to-end to client streaming. - A gamemode that relies on an unwired native won't crash, but that specific effect won't appear yet. Check the boot log for the residual exceptions — anything gamemode-side (bad DB row, data cast) reproduces identically on RAGE:MP.