Weapon arsenal

The guns the player owns: switching, number keys and a radial wheel, an ammo reserve per gun, auto-switch on empty, guns and ammo granted by inventory items, and the weapon HUD; settings, data, services, events, hooks.

Source: module-kits:kits/weapons_arsenal/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs weapons-arsenalMCP tool: gripforge_docs { "topic": "weapons-arsenal" }

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.

Turn it on #

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 #

<!-- test: kits/game_engine/host/parity/weapons.arsenal.reserve.json --> 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:

[ { "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 #

SettingTypeDefaultMeaning
switchSecondsnumber (s)0.25no fire while the new gun comes out
autoSwitchbooleantruean empty magazine and reserve switches to the next owned gun with ammo
startWeaponstring""gun equipped at start when owned (default: the first owned)
wheelTapSecondsnumber (s)0.25a shorter press of weapon_wheel keeps the wheel open until the next press or a pick (0: open only while held)
hud.layoutcard, carousel, reticle, nonecardthe weapon HUD always on screen (none: the game draws its own)
hud.wheel, hud.blur, hud.toast, hud.hintbooleantrueradial 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 #

HookPayloadWhat a tap may do
arsenal.giveentity, gun, reservechange reserve, or cancel (not granted)
arsenal.switchentity, gun, frompick another owned gun, or cancel (the gun in hand stays)
arsenal.ammoentity, gun, amountchange amount, or cancel (nothing added)
{ "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).