C# Debug.WriteLine not working in server code, works in client

Classic GIF - Classic - Discover & Share GIFs

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 imported System.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 under files.
  • 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 structs 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 an int or a string, HOWEVER, if you index with a string, it will attempt to match by player name. This is important because on the Player 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 from Players later on, make sure to cast/parse it to an int first!!

Just some random stuff that I’ve found catches out beginners + other ramblings.

Happy travels.

2 Likes