Sync/Replicate ForceEngineAudio() on vehicles

Would it be possible to get this: ForceVehicleEngineAudio - FiveM Natives @ Cfx.re Docs into replication carried onto other clients? Currently any vehicle that leaves scope and comes back in loses its effect, leading to non-performant solutions:

RegisterNetEvent("engine:sound")
AddEventHandler("engine:sound", function(name,plate)
    if vehicle_sounds[plate] == nil then
        vehicle_sounds[plate] = {}
    end
    vehicle_sounds[plate].plate = plate
    vehicle_sounds[plate].name = name
end)

Citizen.CreateThread(function()
    while true do
        local mycoords = GetEntityCoords(PlayerPedId())
        for k,v in pairs(GetGamePool('CVehicle')) do
            if #(mycoords - GetEntityCoords(v, false)) < 50 then
                local plate = string.gsub(GetVehicleNumberPlateText(v), "%s+", "")
                if vehicle_sounds[plate] ~= nil and vehicle_sounds[plate].plate ~= nil and plate == vehicle_sounds[plate].plate and vehicle_sounds[plate].current ~= vehicle_sounds[plate].name then
                    ForceVehicleEngineAudio(v,vehicle_sounds[plate].name)
                    vehicle_sounds[plate].current = vehicle_sounds[plate].name
                end
            end
        end
        Wait(2000)
    end
end)

Snippet from: Resolved | Vehicle Engine Sounds - #4 by Smokiiee

If it is weird R* stuff or not possible thats fine I can use the above to sync. But I just thought it could be done in the replication of the entity.

1 Like

Yeah, if you just use weird stuff and events instead of network object IDs, of course it won’t be ‘performant’.

How about just state bags and state bag change handlers even instead of this weird mess? :roll_eyes:

Well this was just one example of how to achieve it. I have not implemented a solution yet so I have not written my own besides testing the above.

So the most performant way I can imagine this working without the replication taking place in the base client is to check every vehicle that enters scope for a statebag that has this engine tag and apply it.

The native has to be applied every time the vehicle exits and re-enters scope still though.

I think expected behavior would be to set the data on the vehicle and it gets replicated to other clients like any visual or performance mods.

Like I said, if its stupid say so and I will implement the above method for us, but figured it wouldn’t hurt to ask.

I said ‘state bag change handler’. Not ‘check every vehicle that enters scope’.

See AddStateBagChangeHandler - FiveM Natives @ Cfx.re Docs.

Perhaps, but this is such low priority that I’m suggesting an alternate method that’s not as ‘non-performant’ as the code you posted as unless you or someone else who actually needs it implements and PRs it, this won’t be added as a base feature any time soon.

Again, we don’t have infinite time to research and add every little suggestion especially if there’s already the ability to do something via code and you’re the only one asking so far, and there is barely any framework yet for compatibly adding additional sync data to data nodes so this is a very risky feature (and therefore the easiest way to implement this in platform code would be to do the exact same I’m suggesting you to do via script).

1 Like

Perfect, thanks.

For those looking for the solution D_B talked about above I made this code and tested it:

AddStateBagChangeHandler('engineSound' --[[key filter]], nil --[[bag filter]], function(bagName, key, value, _unused, replicated)
    Wait(0) -- I added this wait as sometimes it seems like the statebag event is called before replication is done fully on the client (still testing and this is not 100%)
    if not value then return end
    local entNet = tonumber(bagName:gsub('entity:', ''), 10)
    local vehicle = NetworkGetEntityFromNetworkId(entNet)
    if vehicle and vehicle ~= 0 then
        ForceVehicleEngineAudio(vehicle, value)
    end
end)

This assumes you set a statebag of the engine audio string. It MUST be replicated and I set the statebag on the serverside.

Basically this will fire every time a vehicle with the statebag engineSound enters your scope.

2 Likes

Maybe you could provide the code snippet from the server side? How you set the statebag? I’ve never used statebags and have no clue how to work with them

https://docs.fivem.net/docs/scripting-manual/networking/state-bags/