Skip to content

Effects and physics ​

Effects are reversible leases, not permanent game patches. Calls that create, move, acquire, or release them require a managed callback. All resources are owned by the plugin and tied to the current session and player generation. They are invalidated on unload, error cleanup, disconnect, death, or respawn.

Effect leases ​

samp.effects.acquire(name, options) ​

Returns an Effect Handle with release(). Releasing is idempotent. options.priority is an optional integer from -1000 to 1000, default 0. A plugin may own at most 64 effects.

player.physics_flags ​

Requires game.physics.override.

lua
local lease = samp.effects.acquire("player.physics_flags", {
    priority = 50,
    usesCollision = true,
    collidable = true,
    disableCollisionForce = false,
    applyGravity = true,
    onSolidSurface = true,
    isStanding = true,
    wasStanding = true
})

Every flag is optional, but at least one must be present and every provided value must be boolean. Each flag is resolved independently: higher priority wins; equal priority uses the older lease. Omitting a flag leaves it uncontrolled by that lease.

player.collision_filter ​

Requires game.physics.override. API 1.1 supports the same reversible collision-filter surface described below.

lua
local lease = samp.effects.acquire("player.collision_filter", {
    priority = 0,
    mode = "only_surface",
    surface = surface
})

The surface must be a current Local Surface Handle owned by the same plugin. The local player then collides only with that surface under this policy.

Grouped release ​

samp.effects.group(handles) ​

Accepts a non-empty array of up to 64 current, unique Effect Handles owned by the plugin. Returns a group { release = function }. Calling release() releases all members and is idempotent. Creating a group does not transfer or duplicate ownership; individual handles may still be released first.

Local surfaces ​

samp.physics.create_surface(options) ​

Requires game.physics.override and an available local player.

lua
local surface = samp.physics.create_surface({
    position = { x = 0, y = 0, z = 10 }
})

position is required. x and y must be finite within -2500..2500; z must be finite within -100000..100000. A plugin may own at most 16 surfaces.

The returned Local Surface Handle provides:

MethodPhaseContract
surface:is_valid()anyReturns boolean and is safe after invalidation.
surface:set_position(vector)managedUses the same coordinate limits and returns nothing.
surface:release()managedIdempotent; returns nothing.

Do not persist a surface or lease Handle. Recreate required resources after the next player.spawned event.

Camera follow ​

samp.effects.acquire("camera.follow", options) ​

Requires the high-risk game.camera.control permission and a current game.entity.read permission for the streamed remote player being followed. The target must be a current remote-player Entity Handle:

lua
local target = samp.entity.get("player", playerId, streamGeneration)
if target and target:is_valid() then
    local lease = samp.effects.acquire("camera.follow", {
        target = target,
        priority = 100
    })
end

The effect is managed and the returned lease is released when it is released explicitly, the plugin unloads or trips its error fuse, the target streams out, the player generation changes, the session changes, or the camera resets. The runtime stores the target's session and stream generation, not a native pointer; an entity reused with a new generation is never silently rebound.