SHOOTER TOOLS — CS COMMANDS Implementation: shooterToolsV1. This document describes the new command contract. Deployment and acceptance status is tracked in SHOOTER_CS_TRANSFER.txt; do not claim the browser has these tools until getCSSceneCapabilities reports them. Build the activity in ordinary CS JavaScript. Load a prepared environment and a prepared player profile, then place opponents and start the encounter. Do not write Unity/C# or run the native demonstration from a special warehouse command. A prepared asset is scenery/gameplay infrastructure, not load(type,name) or a shared-memory CSObject. Existing CS objects retain their normal API. Load a prepared prefab from an HTTPS Unity bundle built for this player target. var url = "https://cinematicsciences.com/game-assets/shooter-20261028/shooter-foundation" await loadPreparedAsset(url, "WarehouseSet", "set") await loadPreparedAsset(url, "ShooterPlayer", "player", -12, 0.2, -16, {invulnerable: true, impactImpulse: 240}) The example profile provides Soldier=0 and Cowboy=1, calibrated third-person weapon grips, locomotion, and authored first-person rifle/arms animation. Other profiles need compatible prepared rigs, animation clips and weapon poses. Do not promise that an arbitrary Sketchfab GLB can use these authored poses. Existing getCharacterRig, model animation and wieldWeapon tools remain available for inspecting and preparing other characters. Do not modify Dancer IK. Place an opponent; the environment needs matching walkable navigation data. await addShooterOpponent("guard", "player", -14, 0.1, -1, 0) Opponents pursue the player, test line of sight, stop at firing range, burst fire, and react at the actual hit bone. impactImpulse is an exaggerated cinematic impulse in N·s, not a claim about realistic rifle momentum. Default is zero extra cinematic impulse. Maximum 32 opponents; one local player controls MainCamera. Start/reset the player and activate opponents; pause releases mouse control. startShooter("player") pauseShooter("player") resetShooterTargets("player") WASD movement, Shift run, Space jump, left mouse fire, right mouse aim down sights, R reload, V first/third person, Q shoulder, M sound, Escape release. Click the game to capture the mouse. No JS timer should keep repositioning a physics character. The native motor, aim, recoil, spread, muzzle obstruction and raycasts run locally. Switch the view using the existing MainCamera; no additional camera is created. shooterView("player", "firstPerson") shooterView("player", "thirdPerson") shooterShoulder("player") swapShooterCharacter("player", 1) Fire/reload and inspect the actual result rather than assuming a shot fired. var result = await fireShooter("player") reloadShooter("player") var state = await getShooterState("player") State contains position, health, ammo, reloading, running, firstPerson, muted, opponents with health/phase/position/shots, and lastShot. A blocked, paused, empty-magazine or cooldown shot returns fired:false. Prepared sets report their physical assemblies and remaining joint counts. It does not expose C# objects. Every game UI needs sound on/off. Use the prepared profile's recorded sounds. shooterSound("player", false) shooterSound("player", true) setImpactSurface("propName", "Wood") Surface names: None, Wood, Concrete, Metal, Glass, Body. No impact on a miss; no synthesized notes or random pitch changes. Surface audio is limited to recordings actually included in the profile; an empty slot is silent. Drop a smoke grenade. Its rigidbody falls, the fuse detonates, radial force acts on nearby bodies, and a lit GPU smoke volume develops. Requires WebGPU compute. await dropSmokeGrenade("smoke1", "player", -12, 3.8, -8, {force: 1800, radius: 7.5}) force is the raw Unity explosion-force setting (unlike legacy explode's wrapper scaling); radius is metres. Four grenade roots maximum; remove before reusing a name. Optional settings fuse:2.2 (.1..30 seconds), seconds:14 (.1..120 seconds of emission), color:'#d1d9db'. No rigidbody interpolation. Smoke alone is available: createSmoke("fog1", 0, 0, 0, 14, "#87918a") Physical crates are original boards with breakable joints. Contact-point impulses and radial forces break constraints naturally. Reset reconstructs their joints and restores the SAME boards/materials. Never swap an intact crate for fragments. restorePhysicalAssemblies("set") The reference's older glass panels still use preauthored shards; do not describe that as force-driven jointed glass. This is separate from the physical crate tool. Unload and cleanup. clearRun also clears shooter objects and restores MainCamera. removePreparedAsset("smoke1") clearShooter() Reconstruction belongs in the saved editor code so another account can play it. Keep the UI responsive in the standard controlpanel using previewUI and registerUICommands. Never use deprecated createButton for a new shooter UI. Start/reset, pause, first/third person, target reset and sound are useful controls. The player must remain invulnerable for this comparison demonstration. Validation: compare the same assets, spawn coordinates, lighting, aiming, reload, AI pursuit, hit-bone response, smoke, audio, physical crate breakage and cleanup. Use several views and actually operate the controls; a screenshot alone does not prove movement, sound, collision, or firing works. Integration The public functions are in cs-shooter.js, loaded before the WebGPU player can restore an activity, alongside cs-gpu.js and cs-optics.js. They use script.js's existing csSceneCommand transport. The engine advertises shooterToolsV1. The legacy script.js source and its reviewed contracts remain unchanged.