I won’t pretend to understand the finer intricacies of C# & CFX, but from my understanding, we need to have the package files in the SLN/CS Project so we have the required references to actually write the code and compile it (duh). Once it is compiled, however, FXServer uses its own local copy of CitizenFX.Core.Server.dll
, located @ citizen\clr2\lib\mono\4.5
; by including our own copy (i.e. the Nuget copy), we cause a conflict, and thus a silent failure. Why this happens instead of one just taking priority over the other, I do not know. Someone more informed than I may be able to explain.
But tl;dr, CFX Nuget packages, make sure ‘Copy Local’ is always false.
Some other random fun C# FiveM tips that you didn’t ask for:
- Don’t create new LUA files in VS (editing existing ones is fine), it adds invisible characters that break the scripts upon loading in FiveM, and can be very difficult to track down.
- If you need JSON, don’t use the Nuget version of Newtonsoft, use this version.
- Again, I don’t fully understand why, but it’s something to do with the linked version being an older “Portable” version, vs. the Nuget version being too new, or something?
- If
Debug.Writeline
is giving you grief, make sure you have not importedSystem.Diagnostics
by accident. - A lot of Nuget packages won’t actually work due to FiveM sandboxing, so be prepared for that.
- That said, some do work, so before you write them off, make sure you have included their
.dll
files in your resource folder, and included them in your Manifest underfiles
.
- That said, some do work, so before you write them off, make sure you have included their
- C# has a resmon overhead. No it’s not a big deal, don’t let anyone tell you otherwise.
- When using event handlers, keep in mind you can only send “simple” types; you can’t send
struct
s for example. If you need to send “complex” data, I suggest JSON conversion on either end. - Shared Projects are your friend, use them if you can!
- The
Players
object on the server can be indexed with anint
or astring
, HOWEVER, if you index with astring
, it will attempt to match by player name. This is important because on thePlayer
class on the server, the.Handle
(aka the Server ID) returns a string. If for whatever reason you have stored a player’s handle and want to get their player object fromPlayers
later on, make sure to cast/parse it to anint
first!!
Just some random stuff that I’ve found catches out beginners + other ramblings.
Happy travels.