---@meta -- SDK 2 language-server declarations. Not executed at runtime. ---@alias Vec3 number[] ---@alias Quat number[] xyzw ---@class DeformationOptions ---@field yield_speed? number contact impulse/body mass threshold, m/s (default 2) ---@field compliance? number metres per m/s above yield (default 0.045) ---@field radius? number impact region metres (default 1.2) ---@field max_displacement? number cumulative offset limit metres (default 0.55) ---@field max_step? number per-impact crush metres (default 0.22) ---@field cooldown? number minimum update interval seconds (default 0.10) ---@field resolution? integer[] XYZ lattice counts, default {9,5,17}; <=2048 total ---@class BodyDesc ---@field deformation? DeformationOptions ---@field shape {type:'box'|'sphere'|'capsule'|'convex'|'mesh', half_extents?:Vec3, radius?:number, half_height?:number, points?:Vec3[], path?:string, object?:string} ---@field body_type 'dynamic'|'kinematic'|'static' ---@field mass? number ---@field position? Vec3 ---@field heading? number ---@field friction? number ---@field ccd? boolean ---@field sensor? boolean ---@field membership? integer ---@field filter? integer ---@field center_of_mass? Vec3 body-local COM (weight transfer under corner loads) ---@field collider_offset? Vec3 chassis-local collider translation (legacy vehicle.json) ---@field inertia_half_extents? Vec3 optional inertia box; with COM sets MassProperties ---@field linear_damping? number default 0.08 ---@field angular_damping? number default 0.5 ---@class SpringRayOpts ---@field local_origin Vec3 ---@field local_direction? Vec3 default {0,-1,0} ---@field rest_length number ---@field max_travel? number ---@field contact_radius? number ---@field stiffness number ---@field compression? number ---@field relaxation? number ---@field damping? number alias for compression/relaxation ---@field max_force? number ---@field dt number ---@class SpringRayHit ---@field in_contact boolean ---@field point Vec3 ---@field normal Vec3 ---@field hard_point Vec3 ---@field direction_ws Vec3 ---@field suspension_length number ---@field load number ---@field relative_velocity number ---@class BodySnapshot ---@field player_overlapping boolean Enabled native local board/skater volumes touching this body; includes sensors. Solid contact margin 0.025m; sensors require intersection. Updated each fixed callback, false while suspended/attached. Geometric query only; collision masks do not suppress it. ---@field position Vec3 ---@field rotation Quat ---@field linvel Vec3 ---@field angvel Vec3 ---@field force Vec3 last sdk.physics.force this tick (zeros if none); Rapier user forces are cleared each tick ---@field torque Vec3 last sdk.physics.torque this tick ---@field mass number ---@field speed number |linvel| ---@class PlayerSnapshot ---@field landed_trick_base string Engine-authored base label identifier (not localized), captured with landing_seq ---@field landed_spin_degrees integer Signed body rotation from the settled scorer; excludes board shuvit rotation ---@field landed_clean boolean Quality captured at the confirmed landing ---@field landed_sketchy boolean Sketchy quality captured at the confirmed landing ---@field suspended boolean local or remote simulation/visibility suspension ---@field id? string ---@field local? boolean ---@field name? string display name from the multiplayer menu ---@field position Vec3 ---@field velocity Vec3 ---@field angvel Vec3 ---@field forward Vec3 ---@field heading number ---@field rotation Quat ---@field speed number ---@field on_board boolean ---@field state integer ---@field category integer ---@field filtered integer ---@field mode string ground|air|grind|offboard|offboard_air|bail|teleport ---@field grind string|nil ---@field bailing boolean ---@field trick string HUD trick name; empty when idle ---@field trick_seq integer increments each newly announced trick; NOT a landing ---@field landing_seq integer monotonic confirmed, banked on-board sequence counter ---@field landed_trick string last confirmed landing label; persists until another landing ---@field bail_seq integer monotonic wipeout-entry counter ---@field new_trick boolean true for the announce frame ---@field modified_trick boolean ---@field close_tricks boolean ---@field sequence boolean combo/line still live ---@field score number ---@field line number ---@field multiplier number ---@field line_time number ---@field clean boolean ---@field sketchy boolean ---@field switch boolean ---@field fakie boolean ---@field nollie boolean ---@field intents table ---@class ContactEvent ---@field a string|nil body key or `"ground"` when the other side is owned ---@field b string|nil body key or `"ground"` ---@field started boolean true on pair begin, false on end ---@class TouchingPair ---@field a string|nil body key or `"ground"` ---@field b string|nil body key or `"ground"` ---@class PadSnapshot ---@field buttons integer XInput button bits ---@field triggers number[] LT, RT in 0..1 ---@field left number[] stick XY ---@field right number[] stick XY ---@class NetworkInfo ---@field active boolean ---@field local_id string ---@field is_host boolean ---@field host_id string ---@field players string[] ---@field states table>> mod_id → peer_id → key → value ---@field status string ---@class SDKSnapshot ---@field player PlayerSnapshot ---@field skaters table ---@field map {name:string, generation:integer} ---@field tick integer ---@field keys table ---@field actions number[] ---@field pad PadSnapshot ---@field paused boolean ---@field replay boolean ---@field camera? {position:Vec3} ---@field attach? {body:string, owner:string} ---@field physics {bodies:table, contacts:ContactEvent[], touching:TouchingPair[]} ---@field network? NetworkInfo ---@class ModCallbacks ---@field on_load? fun() ---@field on_unload? fun() ---@field on_ui_update? fun(event:{dt:number,paused:boolean}) runs while paused; does not advance simulation timers (menus >= 2) ---@field on_update? fun(event:{dt:number}) ---@field on_fixed_update? fun(event:{dt:number}) ---@field on_settings? fun(event:{key:string,value:any}) ---@field on_event? fun(event:{name:string}) sdk = { api_version = 2, ---@type string mod_id = "", ---@type table settings = {}, ---@type SDKSnapshot snapshot = {}, physics = {}, graphics = {}, player = {}, camera = {}, input = {}, ui = {}, net = {}, assets = {}, time = { elapsed = 0 }, } ---@param text string function sdk.log(text) end ---@param path string ---@return string function sdk.read_text(path) end ---@param path string package-relative .glb ---@return {nodes:string[], meshes:string[]} function sdk.assets.objects(path) end ---@param key string ---@param body BodyDesc function sdk.physics.spawn(key, body) end ---@param key string function sdk.physics.remove(key) end ---@param key string ---@param opts {shape:{type:'mesh'|'convex', path?:string, object?:string, points?:Vec3[]}, position?:Vec3, friction?:number} function sdk.physics.add_collider(key, opts) end ---@param key string ---@param force Vec3 ---@param point? Vec3 function sdk.physics.force(key, force, point) end ---@param key string ---@param impulse Vec3 ---@param point? Vec3 function sdk.physics.impulse(key, impulse, point) end ---@param key string ---@param torque Vec3 function sdk.physics.torque(key, torque) end ---@param key string ---@param torque Vec3 function sdk.physics.torque_impulse(key, torque) end ---@param origin Vec3 ---@param direction Vec3 ---@param opts? {max_distance?:number, filter?:'all'|'ground', exclude?:string[]} ---@return {body:string|nil, point:Vec3, normal:Vec3, toi:number}|nil function sdk.physics.raycast(origin, direction, opts) end ---@param key string ---@param point Vec3 ---@return Vec3|nil function sdk.physics.velocity_at(key, point) end ---@param key string ---@param point Vec3 ---@param direction Vec3 ---@return number|nil function sdk.physics.effective_inv_mass(key, point, direction) end ---@param key string ---@param opts SpringRayOpts ---@return SpringRayHit|nil function sdk.physics.spring_ray(key, opts) end ---@param key string ---@param local_accel Vec3 ---@param dt? number ---@return Vec3|nil function sdk.physics.local_ang_accel_impulse(key, local_accel, dt) end ---@param key string ---@param linvel Vec3 function sdk.physics.set_linvel(key, linvel) end ---@param key string ---@param angvel Vec3 function sdk.physics.set_angvel(key, angvel) end ---@param key string ---@param position Vec3 ---@param rotation Quat function sdk.physics.set_pose(key, position, rotation) end ---@param key string ---@param joint {body_a:string, body_b:string, anchor_a:Vec3, anchor_b:Vec3, axis?:Vec3, limits?:[number,number], contacts_enabled?:boolean} function sdk.physics.revolute(key, joint) end ---@param key string ---@param joint {body_a:string, body_b:string, anchor_a?:Vec3, anchor_b?:Vec3, axis?:Vec3, limits?:[number,number], contacts_enabled?:boolean} function sdk.physics.prismatic(key, joint) end ---@param key string ---@param motor {mode:'velocity', target_velocity:number, factor?:number, max_force?:number}|{mode:'position', target_position:number, stiffness:number, damping:number, max_force?:number} function sdk.physics.joint_motor(key, motor) end ---@param key string ---@param spring {position?:number, target_position?:number, stiffness:number, damping:number, max_force?:number} function sdk.physics.joint_spring(key, spring) end ---@param key string function sdk.physics.remove_joint(key) end ---@param key string ---@return BodySnapshot|nil function sdk.physics.read(key) end ---@return ContactEvent[] edge events from the previous Rapier step function sdk.physics.contacts() end ---@return TouchingPair[] pairs in contact after the previous Rapier step (`ground` included) function sdk.physics.touching() end ---@param key string ---@param opts {path?:string, body?:string, position?:Vec3, rotation?:Quat, scale?:Vec3, color?:Vec3, visible?:boolean, opacity?:number} -- opts.deform_nodes: optional string[] of GLB scene node names whose meshes follow the bound body deformation. function sdk.graphics.mesh(key, opts) end ---@param key string function sdk.graphics.remove(key) end ---@param key string ---@param visible boolean function sdk.graphics.set_visible(key, visible) end ---@class MeshBufferOpts ---@field body? string ---@field position? Vec3 body-local when bound, world when unbound ---@field rotation? Quat ---@field scale? Vec3 ---@field blend? boolean default true ---@field unlit? boolean default true ---@field visible? boolean default true ---@field depth_bias? number decal bias, default 0 ---@field texture? string mod-relative PNG path, e.g. textures/skid_tread.png ---@field capture? string named camera capture; mutually exclusive with texture ---@field tint? Vec3 material tint, default white ---@class MeshBufferWrite ---@field positions Vec3[] ---@field normals? Vec3[] ---@field colors? number[][] per-vertex RGBA (packed flat by the runtime) ---@field uvs? number[][] ---@field indices integer[] 0-based triangle indices ---@class LightOpts ---@field kind? "point"|"spot" ---@field body? string ---@field position? Vec3 ---@field offset? Vec3 ---@field direction? Vec3 spot axis ---@field color? Vec3 ---@field intensity? number ---@field range? number ---@field inner_angle? number ---@field outer_angle? number ---@param key string ---@param opts? MeshBufferOpts function sdk.graphics.mesh_buffer(key, opts) end ---@param key string ---@param data MeshBufferWrite function sdk.graphics.mesh_buffer_write(key, data) end ---@param key string ---@param data MeshBufferWrite append-only delta; indices are absolute in the combined mesh function sdk.graphics.mesh_buffer_append(key, data) end ---@param key string ---@param opts? LightOpts function sdk.graphics.light(key, opts) end ---@return PlayerSnapshot function sdk.player.read() end ---Freeze and hide the local skater and remove their collision participation. ---False releases only this mod's suspension; unload/world change also releases it. ---@param suspended boolean function sdk.player.suspend(suspended) end ---@return table function sdk.player.skaters() end ---@param id string|number ---@return PlayerSnapshot|nil function sdk.player.skater(id) end ---@param body string ---@param offset? Vec3 function sdk.player.attach(body, offset) end function sdk.player.detach() end ---@return string|nil function sdk.player.attached() end ---@param body? string ---@param offset? Vec3 function sdk.camera.follow(body, offset) end function sdk.camera.clear_follow() end ---@param position Vec3 ---@param look_at? Vec3 function sdk.camera.set(position, look_at) end ---@param peer string|number|nil peer whose actual camera transform/FOV to mirror; nil restores native camera function sdk.camera.watch(peer) end ---@param key string ---@return boolean function sdk.input.down(key) end ---@param id integer ---@return number function sdk.input.action(id) end ---@return PadSnapshot function sdk.input.pad() end ---@param key string ---@param text string function sdk.ui.text(key, text) end ---Local-only text in Pause > Multiplayer > Debug; never draws a gameplay overlay. ---Up to 8 entries per mod, 1024 UTF-8 bytes each. Empty text removes an entry. ---@param key string ---@param text string function sdk.ui.multiplayer_debug(key, text) end ---@return NetworkInfo function sdk.net.info() end ---@return string[] function sdk.net.players() end ---@param key string ---@param value any JSON-compatible; at most 512 encoded bytes; nil clears function sdk.net.publish(key, value) end ---@param peer string|number peer id from info().local_id / remote peers ---@param key string ---@return any|nil function sdk.net.read(peer, key) end ---@class TeleportOptions ---@field position Vec3 world position, each coordinate within +/-100000 ---@field heading? number radians, default 0 ---@field velocity? Vec3 world linear velocity, each component within +/-200 ---@param options TeleportOptions moves only the local player through native travel function sdk.player.teleport(options) end sdk.session = {} ---@return {active:boolean, local_id:string, is_host:boolean, authority:string, players:string[]} function sdk.session.info() end ---The transport host may reclaim authority; the current authority may renew it. function sdk.session.claim() end ---@param peer string|number connected peer; transfer is ratified asynchronously by host function sdk.session.transfer(peer) end ---@param peer string|number connected peer; requires session authority ---@param options TeleportOptions function sdk.session.teleport(peer, options) end sdk.volumes = {} ---@param key string mod-owned id; at most 32 boxes per mod ---@param options {position:Vec3, size:Vec3, rotation?:Quat, visible?:boolean, color?:Vec3, opacity?:number} function sdk.volumes.box(key, options) end ---@param key string function sdk.volumes.remove(key) end ---@param key string ---@return {position:Vec3,size:Vec3,rotation:Quat,inside:string[]}|nil point overlaps, not physical collisions function sdk.volumes.read(key) end ---@param key string mod-owned id; at most 2 per mod, 4 total ---@param options {position:Vec3,look_at:Vec3,fov?:number,width?:integer,height?:integer} fov radians [0.2,2.5]; sizes [64,512], multiples of 16 function sdk.camera.capture(key, options) end ---@param key string releases the named target; bound meshes lose their image function sdk.camera.clear_capture(key) end ---@class MenuItem ---@field id string unique within this menu ---@field label string ---@field description? string ---@field enabled? boolean default true ---@field children? MenuItem[] submenu, up to 4 levels ---@param key string mod-owned id; up to 8 menus per mod ---@param options {title:string,section?:string,items:MenuItem[]} up to 64 total items ---Actions dispatch on_event {name="menu_action",menu=key,item=item.id} to the owner, including while paused. function sdk.ui.menu(key, options) end ---@param key string function sdk.ui.remove_menu(key) end ---@class NativeContact ---@field a {kind:string,index?:integer} board, skater, external, or world ---@field b {kind:string,index?:integer} ---@field point Vec3 world contact point ---@field normal Vec3 native A-side normal ---@field force Vec3 native solved normal plus friction force ---@field normal_force Vec3 ---@field friction_force Vec3 ---@field impulse Vec3 force times simulation dt ---@field static_friction number combined contact coefficient ---@field dynamic_friction number combined contact coefficient ---@field material_tags integer[] A and B material tags ---@field id string stable body pair, shared by manifold points ---@field phase 'begin'|'stay'|'end' ---@field relative_velocity_before_solve Vec3 A minus B at contact point, including angular velocity ---@field closing_speed number m/s; zero on end ---@class NativeJoint ---@field index integer zero-based native joint ID (use this, not Lua array index) ---@field name string native authored joint name ---@field parent integer native part index ---@field child integer native part index ---@field swing_limit number radians ---@field twist_limit number radians ---@field free_swing boolean ---@field free_twist boolean ---@field drive_enabled boolean false when a mod suppresses the child's animation drives ---@field override_owner? string ---@field enabled boolean ---@field possession_enabled boolean ---@field load? NativeJointLoad most recent eligible solved row ---@field parameters integer[] native words, read-only ---@field frames integer[] native words, read-only ---@return {tick:integer,dt:number,contacts:NativeContact[],joints:NativeJoint[],parts:table[],ragdoll:boolean,partial_ragdoll:boolean} local player only function sdk.player.physics() end ---@return NativeContact[] most recent solved frame, max 128 active plus end reports to reach 256 function sdk.player.contacts() end ---@return NativeJoint[] function sdk.player.joints() end ---@return {index:integer,position:Vec3,velocity:Vec3,angvel:Vec3,inverse_mass:number}[] function sdk.player.parts() end ---@param joint integer zero-based index from sdk.player.joints() ---@param options JointOverride angles [0.01,pi], radians ---Replaces this mod's override; omitted properties follow native state. Another mod cannot take an owned joint. function sdk.player.set_joint(joint, options) end ---@param joint integer restores this mod's joint override function sdk.player.reset_joint(joint) end ---Restores all joint AND part overrides owned by this mod. function sdk.player.reset_joints() end -- General engine access: see GENERAL_API.md for units, lifecycle and limitations. sdk.commands = {} ---@class CommandResult ---@field token integer latest request token for this key ---@field ok boolean host execution succeeded; not remote acknowledgement ---@field error? string ---@field value? any catalog for engine_inspect, otherwise nil ---@field tick integer ---@param key string at most 64 result keys per mod ---@param command table validated native command; no nested request ---@return integer token function sdk.commands.request(key, command) end ---@param key string ---@return CommandResult|nil nil until the latest token is observed function sdk.commands.result(key) end sdk.engine = {version=1} ---@return string[] function sdk.engine.systems() end ---@param system string player, rig, bodies, input, graphs, animation, scoring, world, camera, network, commands ---@return table|nil latest snapshot function sdk.engine.read(system) end ---@param key string command result key ---@param system 'graphs'|'scoring' function sdk.engine.inspect(key, system) end ---@class BodyReference ---@field kind 'skater'|'board'|'mod' ---@field index? integer zero-based native physical body ID ---@field key? string mod-owned Rapier body key ---@class NativeBody: BodyReference ---@field position Vec3 world centre of mass ---@field rotation Quat XYZW ---@field velocity Vec3 world m/s ---@field angvel Vec3 world rad/s ---@field inverse_mass number ---@field inverse_inertia Vec3[] world matrix columns ---@field state_flags integer effective native solve state ---@field name? string mapped animation bone name ---@field joint? integer native joint whose child is this body ---@field collision_enabled? boolean effective enabled flag ---@field animation_drives? boolean permits native animation drives ---@field possession_drives? boolean permits native board-holding drives ---@field material? {static_friction:number,dynamic_friction:number} ---@field override? {owner:string,options:PartOverride} sdk.bodies = {} ---@param ref BodyReference ---@return NativeBody|table|nil function sdk.bodies.read(ref) end ---@param ref BodyReference ---@param value Vec3 world N s ---@param point? Vec3 world point; omitted means centre of mass function sdk.bodies.impulse(ref, value, point) end ---@param ref BodyReference ---@param value Vec3 world N m s function sdk.bodies.angular_impulse(ref, value) end ---@class JointOverride ---@field swing_limit? number [0.01,pi] radians ---@field twist_limit? number [0.01,pi] radians ---@field free_swing? boolean ---@field free_twist? boolean ---@field enabled? boolean false removes entire constraint including linear attachment ---@field drive_enabled? boolean false suppresses child animation drives ---@field possession_enabled? boolean false suppresses child board-holding drives ---@field descendants? boolean extends drive suppressions to child subtree ---@class PartOverride ---@field motion? 'dynamic'|'frozen'|'static' solve flags 4/2/1; not a player state change ---@field collision? boolean ---@field friction? number [0,10], both material coefficients ---@field animation_drives? boolean ---@field possession_drives? boolean ---@class NativeJointLoad ---@field linear_impulse Vec3 world N s on child/A ---@field angular_impulse Vec3 world N m s, direct angular couple ---@field force Vec3 N ---@field torque Vec3 N m, excluding linear anchor lever-arm contribution ---@field solver_words integer[] packed native u32 values ---@class NativeRig ---@field tick integer completed solve cursor ---@field dt number seconds ---@field parts NativeBody[] ---@field board NativeBody[] ---@field joints NativeJoint[] ---@field contacts NativeContact[] at most 128 active, plus end reports to reach 256 ---@field contacts_truncated boolean observation rows were omitted; pair tracking continues ---@field ragdoll boolean native mode ---@field partial_ragdoll boolean native mode sdk.rig = {} ---@return NativeRig ---@param fields? string[] Optional top-level rig fields; omit for the complete rig. function sdk.rig.read(fields) end ---@return NativeBody[] function sdk.rig.parts() end ---@return NativeJoint[] function sdk.rig.joints() end ---@return NativeContact[] function sdk.rig.contacts() end ---@param index integer native joint ID, not a Lua array index ---@param options JointOverride replacement override; omitted fields follow native settings function sdk.rig.configure_joint(index, options) end ---@param index integer native joint ID function sdk.rig.reset_joint(index) end ---@param index integer physical skater part ID ---@param options PartOverride function sdk.rig.configure_part(index, options) end ---@param index integer physical skater part ID function sdk.rig.reset_part(index) end ---Restores all joint AND part overrides owned by this mod. function sdk.rig.reset() end ---@param id integer mapped gameplay action 64..81 ---@param value? number [-1,1]; nil restores normal input function sdk.input.override_action(id, value) end sdk.graphs = {} ---@param graph 'action'|'motion' ---@return {current?:integer,previous?:integer,name?:string,dt:number,state_times:table,active_behaviors:integer[]}|nil function sdk.graphs.read(graph) end ---@param graph 'action'|'motion' ---@param target 'state'|'transition'|'behavior' ---@param index integer runtime ID from the catalog; zero-based ---@param enabled? boolean nil restores the original gate function sdk.graphs.set_enabled(graph, target, index, enabled) end -- World audio extension 1 (capability `world_audio`): publish traffic vehicles, pedestrians and -- skaters to the game's retail world audio, exactly as an engine system would (doc -- docs/hails-additions/15-world-audio.md). Keys belong to this mod; 48 objects per mod, 128 in all; -- an object not updated for 0.5 s is parked; everything is removed on disable / reload. The game -- decides who is audible with retail's limits (4 nearest cars within 40 m, 15 nearest peds within -- 50 m, footsteps for the nearest 3, one skater within 30 m; 8 / 24 / 3 with the opt-in -- non-retail "more audible" setting). ---@class WorldAudioOptions ---@field position? Vec3 world position (ignored while body is set) ---@field velocity? Vec3 m/s; default: from the position change (give it for teleporting objects) ---@field heading? number rad about +Y, 0 = +Z ---@field body? string follow one of this mod's physics bodies (position, rotation, velocity) ---@field engine? string traffic: aud_traffic_engine record (c01_family01, c03_sports01, c04_taxi01, c05_truck01, c00_heavy01, c06_sports02, c07_family02, c08_family03) or a living-world model mapped to one as retail does (taxi01, patrol01, sedan02, hatchback01, sports03, muscle01, suv02, pickup01, minivan01, ...); unknown = silent ---@field speed? number traffic / lite skater: m/s (default |velocity|) ---@field load? number traffic: the driver's signed acceleration m/s² (default: from the speed change; hard stop ≈ -15) ---@field horn? integer traffic: 0 none, 1..5 horn kind, 6 alarm (prefer the events) ---@field skidding? boolean traffic: the tyres skid ---@field voice? integer ped: the model = speech voice id 41..96 (0 none); its shoe class, kind, speech words and far threshold follow (retail's aud_characteristics). skater: its voice (AI skaters 89..96): the bail grunt ---@field shoe_class? integer ped: 1..5 (default: the model's, else 2; 1 is silent) ---@field weight? integer ped: 1..5 (default 1) ---@field close_range? boolean ped: a security guard's close-range footstep / speech levels (default: the model's) ---@field feet? boolean[] ped: {foot A planted, foot B planted} ---@field materials? integer[] ped: audio surface materials under the feet (default 0) ---@field footsteps? boolean ped: footsteps on (default: retail's 3-nearest rule) ---@field source? string skater (spawn only): 'lite' (default) or 'state_log:' (a ghost replaying logs/.tsv of this mod or SKATE_AUDIO_STATE_LOGS/.tsv) ---@field from? number ghost: window start (s) ---@field seconds? number ghost: window length (s, default 20), looped ---@field wheels? boolean[] lite skater: wheels down {FL, FR, RL, RR} ---@field material? integer lite skater: material under the board (default: the ground's) ---@field grinding? boolean lite skater ---@field grind_material? integer lite skater ---@field air? boolean lite skater: in the air sdk.world_audio = {} ---@param key string ---@param kind 'traffic'|'ped'|'skater' ---@param opts? WorldAudioOptions function sdk.world_audio.spawn(key, kind, opts) end ---Merge fields into the object's description (a field of another kind is an error). ---@param key string ---@param opts WorldAudioOptions function sdk.world_audio.update(key, opts) end ---@param key string ---@param event 'horn'|'alarm'|'speech' ---@param opts? {kind?:integer, seconds?:number, value?:string|integer} horn: kind 1..5 for seconds; alarm: retail's 8 s; speech: value name (warn = 53, cheer, slam, flee, nearby, DoWarning, LongCheer, ...) or number; the ped says a line of its voice through retail's speech manager (gated by the event's timers and probability) when the speech decode is installed; a repeated value re-triggers function sdk.world_audio.event(key, event, opts) end ---@param key string function sdk.world_audio.remove(key) end ---@param key string ---@return {kind:string, audible:boolean, instance?:integer, parked:boolean}|nil function sdk.world_audio.read(key) end ---@return {more_audible:boolean, instances:{traffic:integer,peds:integer,skaters:integer}, published:table, audible:table, speech_lines:integer} function sdk.world_audio.info() end