Marking a vehicle as ‘player vehicle’ for game code

A recent finding from the forums is that the GTA game code checks for the presence of a decorator named player_vehicle on entities to enable/disable certain behavior for player-driven vehicles (e.g. personal vehicles?).

Among other things, this includes:

  • Radio emitters for the radio station the car is playing
  • Some special behavior for entering the vehicle via a door (i.e. the ‘enter vehicle’ key)

Example code

-- somewhere *once* during initialization
DecorRegister("Player_Vehicle", 3)

-- on a vehicle
if DecorIsRegisteredAsType("Player_Vehicle", 3) then
    DecorSetInt(vehicle, "Player_Vehicle", -1)
end

Making a console key bind wait between commands

Someone recently asked in a chat room if it were possible to delay executing multiple different commands when using the bind command in the F8 console to make custom key binds.

This is, of course, entirely possible using a variant of the wait command taken from Quake:

# this will run 'say hello', wait 1.5 second (1500 milliseconds), and run 'e wave'
bind keyboard F11 "say hello; wait 1500; e wave"

Quick note on using built-in ACL/security

Ever since the built-in ACL system exists (add_ace and similar), it has somehow not seen people use it to its full potential, often adding dependencies on ‘frameworks’ to resources solely in order to check if a player is currently on a particular ‘job’ in said ‘framework’.

A lesser-known feature of the ACL system is the ability to have its configuration defined at runtime (in fact, there’s no persistence layer at all – the expectation has been for the community to build one), allowing you to do stuff as follows for example:

# server.cfg, required for access to ExecuteCommand
add_ace resource.myframework command.add_principal allow
add_ace resource.myframework command.remove_principal allow
// server-side code in myframework
on('myframework:jobAssigned', (source, job) => {
    ExecuteCommand(`add_principal "player.${source}" "job.${job}"`);
});

on('playerDropped', () => {
    const source = source;
    for (const job of myfw.getPlayerJobs(source)) {
        ExecuteCommand(`remove_principal "player.${source}" "job.${job}"`);
    }
});

… and then a resource that one would want to add a job check to – or a chat mode’s seObject, or an existing resource – can just check for the job.mechanic privilege using native commands such as IsPlayerAceAllowed, without taking a dependency on myframework or any of its inner workings.

Using modified scenario files on FiveM

A forum post has been written detailing how to use modified scenarios on FiveM servers. The gist of the post is as follows:

However, what should work is registering a replacement scenario point manifest:

  1. take sp_manifest.#mt from update:/%platform%/levels/gta5/ from 1604 if you use it! if you use the 2189 one on 1604 you’ll crash with ERR_STR_PACK_2 as island scenarios don’t exist!, (contents of, as XML)
  2. specify it as data file:
    file 'sp_manifest.ymt'
    -- SCENARIO_POINTS_FILE may work, too
    data_file 'SCENARIO_POINTS_OVERRIDE_FILE' 'sp_manifest.ymt'
    
  3. edit it:
    <Item type="CScenarioPointRegionDef">
      <Name>compcache:/test_ymt/countryside_ne</Name> <!-- apparently VFSRagePackfile doesn't support RSC registration, so we use `compcache` instead of `resources` here -->
      <AABB>
       <min x="577.9417" y="-2190.842" z="1.645161" />
       <max x="2970.658" y="6642.504" z="355.7393" />
      </AABB>
    </Item>
    
  4. make sure file 'countryside_ne.ymt' is in your resource’s stream/ folder
  5. yay!

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!