FYI: FiveM and RedM support raw .ymap/.ytyp files

For a while now, you’ve been able to use XML-format .ytyp/.ymap files in FiveM and RedM, without doing a conversion between XML and PSO/RSC format: just make sure the .xml file is just named mh1_01.ymap without any extra extension, and it should be parsed and used fine.

Note that these are loaded using the game parser, so this may behave differently in some ways from CodeWalker/OpenIV’s parsers.

Routing buckets: split game state

Server versions from pipeline ID 3245 and above have added a ‘routing bucket’ functionality, which is similar in concept to the ‘dimension’ or ‘virtual world’ functionality seen in prior non-Rockstar GTA network implementations.

For those unaware or lazy to search, one can assign a player or entity to a routing bucket, and they will only see entities (and players) that belong to the same routing bucket. In addition to that, each routing bucket will have its own ‘world grid’ for determining population owners, so even if you have population enabled, you’ll notice nothing unusual at all when using routing buckets.

Example use cases include:

  • Multi-mode servers where you want to have different games go on without affecting other games
  • Session/party systems
  • ‘Character screen’ being instanced differently from gameplay going on

Example use cases do explicitly not include interiors. Interiors should be using the traditional ‘conceal’ native functions, or the future support for 3D-scoped routing policy, which will also allow specifying any ‘instanced’ zone for MMO-style servers so a server can have a map area ‘dedicated’ to a player/party on a mission but still be able to see everything going on outside that zone.

See the linked timestamp in this GTA Online trailer to see why interiors should not be handled using this support in GTA V, where this was fine in GTA3 series titles because they did not have any interiors looking outwards.

The natives to use are as follows:

Note that these natives require OneSync to be ‘on’, not set to ‘legacy’ mode, and at this time might still route game events such as explosions and projectiles – this will be fixed in a near-future server version, as will support for sending network events to a specific routing bucket only.

CitizenFX C# templates are fixed

Since the earlier release of the CitizenFX C# templates, people have reported that certain built-in language types did not work, leading to vague errors such as '' is not a type supported by the compiler or such.

It took a while, but these should be fixed as of version 0.2.2 of the C# templates/SDK/framework packages, and these should now be usable for writing client code with compile-time checks for APIs available to the client-side subset framework.

A quick note about OneSync server-side persistence

Starting at server build 2689 (unless backed out in a later build), when using OneSync, there’s a few differences regarding entity lifetime compared to before.

  • Entities that are owned by a script (not marked as no-longer-needed, or re-assigned as mission entity) will now be able to be in an ‘unowned’ state in which the server is the owner of the entity. This happens when no player is having the entity in scope (as in – the entity is out of range of any player), and this state ends when it goes in scope for a player.
  • Script ownership is now correctly synced across the board. No longer does the owning script ID vanish when an entity migrates or is recreated. This should fix a lot of cases of mission entities getting deleted anyway.
  • Faraway entities are no longer controlled by their original owner. This means that any entity that would be out of scope will be culled and migrated/disowned. It might lead to a small number of script compatibility issues, but in return a lot of cases of unenterable vehicles (because the owner is too far and doesn’t know you) especially with Infinity/Beyond modes should be fixed.
  • Entities that aren’t owned by a script get reassigned and, when impossible, culled when out of scope. This is a difference from the old behavior where this was up to the game behavior of the owning client. Typically, the owning client would have cleaned up non-script entities early anyway, so this should not be a significant difference.

In addition to these changes, a number of improvements to ‘entity RPC’ are planned to allow for more robust server-side entity creation/initial configuration of entities by taking advantage of this ‘unowned entity’ state, resolving a large number of issues with current server-side CREATE_VEHICLE/… calls.

Try the new CitizenFX C# templates for FiveM

We’ve recently published the CitizenFX.Templates package on NuGet, which includes a nice template for making a fully C#-based resource using the latest recommendations. The docs will be updated whenever more people confirm this works and report some feedback as to this, but for now here’s the steps to set it up:

dotnet new -i CitizenFX.Templates
mkdir MyResource
cd MyResource
dotnet new cfx-resource

You’ll find helpful instructions afterwards in the generated README.md.

Uploading photos from in-game to the Cfx.re Gallery

Recent builds of FiveM have added backing functionality to the photo gallery feature in the pause menu. This guide shows how to upload your photos to the Cfx.re Snapmatic section on the forums.

  1. Make sure you have a photo camera resource that uses photo commands to save a gallery photo. An example resource would e.g. be Xinerki’s ‘Cellphone Camera‘ resource, instructions for which can be found in the topic.
  2. Sign in and link your Cfx.re forum account in the main menu of FiveM.
  3. Go to the pause menu in a server (or a local game), and go to Gallery, and press Enter/A.
  4. Select a photo to upload, assuming you have a few. You can also press Enter/A to view/confirm and change the title.
  5. Press the ‘Upload to Social Club’ button as marked in the bottom of the screen.
  6. Say ‘Yes’.
  7. Wait a while.
  8. You’ll see your image uploaded on the forums!

Using the new console key bindings

You’re able to define keyboard bindings in a new way, as originally detailed in the 2018 design document “Configuration & Input – Redesigned“.

Here’s a sample snippet of a simple ‘hands up’ binding:

local handsUp = false

CreateThread(function()
    while true do
        Wait(0)

        if handsUp then
            TaskHandsUp(PlayerPedId(), 250, PlayerPedId(), -1, true)
        end
    end
end)

RegisterCommand('+handsup', function()
    handsUp = true
end, false)

RegisterCommand('-handsup', function()
    handsUp = false
end, false)

RegisterKeyMapping('+handsup', 'Hands Up', 'keyboard', 'i')
RegisterKeyMapping('say hi', 'Say hi', 'keyboard', 'o')
User-editable bindings.

These bindings will be editable by the user in the ‘key bindings’ option (only 1 binding per command yet, no secondary binding), and depending on user demand we’ll add a helper for computing the right hashes to use with ~INPUT_~-style display as well for help hints and similar.

In addition to that, a plethora of new console commands are added to the client F8 console, an example is below:

// bind a key to toggle the safe zone to an offscreen size and back
bind KEYBOARD F3 "+vstr hideHud showHud"
seta "hideHud" "profile_safezoneSize 500"
seta "showHud" "profile_safezoneSize 7"

// list all bindings
bind

// bind for a specific resource (similar to RegisterKeyMapping)
rbind runcode keyboard o "say hi"

// unbind
unbind keyboard f3

// set the volume way above the usual max
profile_sfxVolume 50

// ear rape?
profile_sfxVolume 9000

// toggle a variable
toggle strmem

// toggle a variable between two values
toggle con_miniConChannels * minicon:*

// see cmdlist to view all new and existing variables and commands

… and the fxd:/fivem.cfg (%appdata%\citizenfx) file contains a lot of additional user settings now in a readable format.

Optimizing resource downloads using a caching proxy

Server builds starting at pipeline ID 1679 added the ability to configure the fileServer field used for resource downloading using a set of commands:

# Set the file server for the specified resource regex.
# The URL should *not* end with a slash.
fileserver_add ".*" "http://10.10.0.1/files"

# Remove the file server associated with a resource regex.
fileserver_remove ".*"

# List all registered file server patterns.
fileserver_list

# Old command, but **required** to not get corrupted cache entries.
adhesive_cdnKey "someSecurePassphrase"

There’s currently no cache invalidation logic based on hashes (this’ll need yet another server update due to the file server not ignoring query strings + a client update), so make sure to clear your proxy’s cache before you modify/restart a resource.

Here’s an example NGINX configuration for setting this up (but you should, for example, run this behind yet another proxy which offers HTTP/2 over TLS, or otherwise set this up properly – we’re expecting the community to provide fleshed-out examples on the forums):

default.template

proxy_cache_path /srv/cache levels=1:2 keys_zone=assets:48m max_size=10g ;
log_format asset '$remote_addr - [$time_local] "$request" $status $body_bytes_sent $upstream_cache_status';

server {
        listen 80;

        location /files/ {
                access_log /dev/stdout asset;
                add_header X-Cache-Status $upstream_cache_status;
                proxy_cache_lock on;
                proxy_pass $REMOTE$request_uri;
                proxy_cache assets;
                proxy_cache_valid 1y;
                proxy_cache_key $request_uri$is_args$args;
        }
}

Dockerfile

FROM nginx:alpine
COPY default.template /etc/nginx/conf.d/default.template
CMD sh -c "envsubst \"`env | awk -F = '{printf \" \\\\$%s\", $1}'`\" < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"

Start command

docker build -t fxproxy .
docker run -d --name=fxproxy -e REMOTE=http://10.10.0.2:30120 -p 80:80 -v $PWD/cache:/srv/cache fxproxy

OneSync: intercepting game events (such as explosions)

The latest version of the server (1543+) added support for parsing and preventing routing of game events. This currently only supports parsing CExplosionEvent, but this might be a fairly useful one to prevent routing of ‘excessive’ explosions, or explosions that are ‘too close’ to a player and not of the correct weapon type.

Here’s an example:

-- SERVER script, requires OneSync!
AddEventHandler('explosionEvent', function(sender, ev)
    print(GetPlayerName(sender), json.encode(ev))
end)

This’ll show JSON data similar to the following:

{"explosionType":0,"isAudible":true,"posX":742.84313964844,"cameraShake":1.0,"isInvisible":true,"ownerNetId":0,"posY":-1808.2889404297,"damageScale":1.0,"posZ":33.105224609375}

If you want to, say, make an explosion-free zone:

AddEventHandler('explosionEvent', function(sender, ev)
    if ev.posX > 2000.0 and ev.posY > 2000.0 and ev.posX < 3000.0 and ev.posY < 3000.0 then
        CancelEvent()
    end
end)

This can be used in a variety of ways – rate limiting, automatic warning/kicking, disabling routing of bad explosions, etc.

Two new experimental OneSync variables

In the latest Windows server release (1504 or higher), two experimental variables have been added to help troubleshooting problematic behavior and offer a ‘workaround’ for common problems.

onesync_distanceCullVehicles true

This console variable (set it in your config, or in the console at runtime) will lead to player-occupied vehicles also being subject to distance culling – that is, they won’t exist if a player is more than n units away from the entity.

Enabling the variable might help with game performance (FPS), and should help with bandwidth concerns as well as ‘texture loss’/’city bug’ streaming issues caused by loading larger amounts of custom addon player vehicles than usual.

Cons are that player-occupied vehicles will not be known to client scripts unless another player is nearby enough. This might affect ‘teleport into player’s vehicle’ scripts, for instance.

onesync_forceMigration true

This one forces any entity which has not received any clone sync updates for over x seconds to be migrated to any other nearby player. While it doesn’t fix the underlying cause for ‘ghost vehicle/ped’ migration failures, it should make them less painful and not require kicking the alleged owner anymore.

There should not be too many cons, but it’s disabled by default lest it crash players when it’s triggered, or worse.