# The player's arsenal in your game (weapons.arsenal) ## What it is for `weapons.arsenal` decides which `combat.ranged` guns the player owns, which one is in hand and how much ammo is left behind each magazine. The guns themselves (damage, fire rate, magazine, reload) are the `guns` collection of `combat.ranged`; this kit adds ownership, switching (next, previous, number keys, a hold-to-open radial wheel), a reserve per gun, a magazine kept across switches, an automatic switch when a gun is empty, and guns or ammo granted by inventory items (a shop, a chest, a pick-up, a reward). It suits shooters, action platformers, gun roguelites and twin-stick games. See also the [combat guide](guide:combat). ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "weapons.arsenal" } gripforge_gamekit_configure { project_id: "gkp_…", id: "weapons.arsenal", config: { "switchSeconds": 0.25, "startWeapon": "pistol", "hud": { "layout": "card" } } } ``` It requires `combat.ranged`, `input.actions` and `game.engine`. Then list the guns in the `arsenal` collection. ## First example Three guns, the first two owned from the start, the launcher granted by an inventory item and fed by another; the trace replays this (fire, reload, save, load) against the Rust kit: ```json [ { "id": "pistol", "owned": true, "reserve": 5, "start": 5 }, { "id": "rifle", "owned": true }, { "id": "launcher", "reserve": 20, "start": 4, "item": "launcher_item", "ammoItem": "rockets", "ammoPack": 3 } ] ``` The pistol has a reserve of 5 rounds behind its magazine; the rifle has no `reserve`, so its reloads are free. ## Settings and defaults | Setting | Type | Default | Meaning | |---|---|---|---| | `switchSeconds` | number (s) | `0.25` | no fire while the new gun comes out | | `autoSwitch` | boolean | `true` | an empty magazine and reserve switches to the next owned gun with ammo | | `startWeapon` | string | `""` | gun equipped at start when owned (default: the first owned) | | `wheelTapSeconds` | number (s) | `0.25` | a shorter press of `weapon_wheel` keeps the wheel open until the next press or a pick (0: open only while held) | | `hud.layout` | `card`, `carousel`, `reticle`, `none` | `card` | the weapon HUD always on screen (`none`: the game draws its own) | | `hud.wheel`, `hud.blur`, `hud.toast`, `hud.hint` | boolean | `true` | radial wheel while held, blurred game behind it, gun name at a switch, hint line under the wheel | An `arsenal` document is `{ id, owned?, reserve?, start?, item?, ammoItem?, ammoPack?, icon? }`. `id` is a gun of `guns` (other ids are ignored). `reserve` is the most rounds carried besides the magazine; absent, reloads are free. `start` is the reserve when the gun is granted. `item` grants the gun, `ammoItem` adds `ammoPack` rounds per unit (default a quarter of `reserve`, at least 1). Document order is the order of the wheel and of next and previous. Inputs: `weapon_next`, `weapon_prev`, `weapon_wheel` (hold), and `weapon_1` to `weapon_10` for the owned gun of that rank. ## Services, events, variables - `weapons.arsenal` (service): `view()`, `owned()`, `current()`, `give(gun)`, `equip(gun)`, `cycle(dir)`, `addAmmo(gun?, n?)`, `setWheel(open)`, `hover(gun)`, `pick(gun)`, `catalog()`. - Events: `arsenal.acquired` (reserve -1: free reloads), `arsenal.switched`, `arsenal.ammo`, `arsenal.empty` (a reload was refused, the reserve is empty), `arsenal.wheel`. It listens to `combat.reloaded`, `combat.empty` and `inventory.changed`. - Variables: `arsenal.gun`, `arsenal.reserve` (-1: free reloads), `arsenal.owned`, `arsenal.wheel`. - Content: actions `arsenal_give`, `arsenal_ammo`, `arsenal_equip`, condition `arsenal_has`. A reload takes at most the reserve, and the rounds loaded leave it when the reload ends. A gun put away keeps its magazine. Any gain of a gun's `item` or `ammoItem` in the inventory is converted into the gun or the ammo and taken back from the bag, so a shop, chest or reward counts once. ## Hooks and modding | Hook | Payload | What a tap may do | |---|---|---| | `arsenal.give` | `entity`, `gun`, `reserve` | change `reserve`, or cancel (not granted) | | `arsenal.switch` | `entity`, `gun`, `from` | pick another owned `gun`, or cancel (the gun in hand stays) | | `arsenal.ammo` | `entity`, `gun`, `amount` | change `amount`, or cancel (nothing added) | ```json { "id": "game_double_ammo", "hook": "arsenal.ammo", "match": { "gun": "launcher" }, "mul": { "amount": 2 } } ``` The settings and the `arsenal` collection are moddable. ## When it does not do what you expect - A document is ignored: its `id` is not a gun of `combat.ranged`. - Reloading never runs dry: the document has no `reserve`. - The gun does not fire after a switch: `switchSeconds` has not passed, or the wheel is open. - No gun from a shop: the item needs a price in the shop kit, and must match `item`. ## Limits Runs on the web and in the native player. The HUD, wheel and toast are drawn by a `ui.webui` fragment themed by `ui.theme`. ## Versions Kit version 1.2.0: weapon HUD templates and the radial wheel (1.2.0), number keys (1.1.0).