Burnsies HideoutDocsBurnsie.Common

Safe Natives — SafeNatives and CrowdNatives

Anything outside the verified RPH managed surface is a raw game native, called by hash. A wrong hash or changed signature normally means a crashed plugin — or a crashed game. Burnsie.Common.Natives fences every such call:

  • Every native the library touches is called by a pinned hash (confirmed against alloc8or's natives.json).
  • The first failure of a native logs once and disables that native for the rest of the session. Subsequent calls return defaults silently.
  • Nothing here ever throws. A bad native degrades one effect instead of taking the scene or the plugin down.

Set the logger once at plugin startup so failures are reported:

SafeNatives.Log = log;
CrowdNatives.Log = log;

All calls must run on a GameFiber. Ped/entity parameters are null- and Exists()-guarded inside the wrappers.

SafeNatives — general-purpose natives

Feedback & effects

SafeNatives.PlayFrontendSound("ERROR", "HUD_FRONTEND_DEFAULT_SOUNDSET"); // or use FrontendSounds
SafeNatives.AnimPostFxPlay("DeathFailMPIn", 0, looped: true);  // full-screen effect; 0 = until stopped
SafeNatives.AnimPostFxStop("DeathFailMPIn");
SafeNatives.AnimPostFxStopAll();                                // teardown safety
SafeNatives.ShakeGameplayCam("JOLT_SHAKE", 0.4f);
SafeNatives.StopGameplayCamShaking();
SafeNatives.PadShake(durationMs: 400, frequency: 200);          // controller rumble (freq 0–255)
SafeNatives.StopPadShake();
SafeNatives.FlashMinimap();                                     // one flash, activation emphasis

Ped state & tasks

SafeNatives.ApplyPedDamagePack(ped, "SCR_Torture", 0f, 1f);  // visible damage
SafeNatives.ResetPedVisibleDamage(ped);                      // revive path
SafeNatives.SetPedToRagdoll(ped, 3000);                      // limp ragdoll; re-call to hold down
SafeNatives.ClearPedTasks(ped);                              // graceful
SafeNatives.ClearPedTasksImmediately(ped);                   // instant (stands up out of ragdoll)
SafeNatives.TaskPlayAnim(ped, dict, anim, flag: 1);          // flag 1 = loop until cleared
SafeNatives.TaskFollowNavMeshToCoord(ped, target, moveBlend: 2f, targetRadius: 1.5f); // 1=walk 2=run
SafeNatives.TaskTurnPedToFaceEntity(ped, target, 2000);
SafeNatives.TaskLeaveVehicle(ped, vehicle);
bool inVeh = SafeNatives.IsPedInAnyVehicle(ped);
int type = SafeNatives.GetPedType(ped);                      // 6=cop, 20=medic, 21=firefighter; -1 unavailable

Animation dictionaries stream asynchronously — request, poll, release:

SafeNatives.RequestAnimDict(dict);
while (!SafeNatives.IsAnimDictLoaded(dict)) GameFiber.Sleep(50);   // add a deadline
SafeNatives.TaskPlayAnim(ped, dict, anim, 1);
// later: SafeNatives.RemoveAnimDict(dict);

Player & death-flow control

RPH 1.124's managed Game.DisableAutomaticRespawn / Game.FadeScreenOutOnDeath throw NotImplementedException at runtime (observed in the field) — these natives are the working path for custom death handling:

bool ok = SafeNatives.PauseDeathArrestRestart(true);  // dead player stays where they fell
SafeNatives.SetFadeOutAfterDeath(false);
SafeNatives.ResurrectLocalPlayer(position, heading);   // standard revive (works in SP)
SafeNatives.SetEntityInvincible(entity, true);         // ALWAYS pair with (entity, false)
SafeNatives.SetTimeScale(1.0f);                        // cancels death slow-mo
SafeNatives.SetPlayerDamageResistance(player, 0.5f);   // sets weapon AND melee modifiers
bool faded = SafeNatives.IsScreenFadedOut();
SafeNatives.DoScreenFadeIn(800);

Two contracts to respect:

  • PauseDeathArrestRestart returns false when the native is unavailable. If you build death handling on top, honor that return — arming halfway leaves vanilla respawn running underneath yours.
  • There is no getter for these states: restore game defaults (restart running, fade-out on) at teardown rather than a cached value.

Input

bool typing = SafeNatives.IsOnScreenKeyboardActive();  // used by Keybind suppression
SafeNatives.SetPlayerControl(player, false);           // lock movement input for scripted
                                                       // scenes (camera stays free).
                                                       // ALWAYS pair with (player, true) on
                                                       // EVERY exit path — a stuck lock is
                                                       // a soft-lock. First consumer:
                                                       // PanicButton's CPR patient pose.

CrowdNatives — crowd/scene control natives

Same fence, same rules; used by the Crowd engine and available to your scenes directly.

// Density suppression — these are PER-FRAME natives; call every tick while suppressing:
CrowdNatives.SuppressPedDensityThisFrame(0.1f);
CrowdNatives.SuppressScenarioDensityThisFrame(0.1f);
CrowdNatives.SuppressVehicleDensityThisFrame(0.1f);

// Scene preparation:
CrowdNatives.ClearAreaOfPeds(position, radius: 40f);            // one-time clear
int areaId = CrowdNatives.AddScenarioBlockingArea(min, max);    // stop ambient scenario spawns
CrowdNatives.RemoveScenarioBlockingArea(areaId);                // per-scene cleanup (id 0 = no-op)
CrowdNatives.RemoveAllScenarioBlockingAreas();                  // LAST-RESORT unload sweep only —
                                                                // removes other plugins' areas too

// Fire:
int fireId = CrowdNatives.StartScriptFire(position, maxChildren: 10, gasFire: false);
CrowdNatives.StopFireInRange(position, radius: 30f);
// maxChildren clamps to 0–25; respect the game's global 128-fire cap.

// Ped behavior:
CrowdNatives.StartScenarioInPlace(ped, "WORLD_HUMAN_STAND_MOBILE"); // idle crowd texture
CrowdNatives.WanderInArea(ped, center, radius: 10f);
CrowdNatives.SmartFleePed(ped, fleeFrom, safeDistance: 60f, fleeTimeMs: -1);
CrowdNatives.SetFleeAttributes(ped, CrowdNatives.FleeAttributeForceCower, true);
CrowdNatives.SetCombatAttribute(ped, 17, true);                 // 17 = always flee
CrowdNatives.StandGuard(cop, position, heading);                // cordon post

// Environment:
CrowdNatives.SetArtificialLights(on: false);   // blackout. Wrapper negates the native's
                                               // inverted parameter, so call sites read honestly.
CrowdNatives.SetRoadsInArea(min, max, false);  // reroute ambient traffic around a scene
CrowdNatives.SetRoadsInArea(min, max, true);   // ALWAYS restore on teardown

Rules

  • Prefer the RPH managed API when it exists and works; the fence is for everything else.
  • Restore what you set: invincibility off, time scale 1.0, roads re-enabled, lights on, post-effects stopped — on every exit path.
  • Per-scene resources (scenario blocking areas) are removed by id, never with the global sweep, so you never touch other plugins' state.
  • A default-value return can mean either "the native said no" or "the native is disabled". Where the difference matters, the wrapper returns bool success — check it.