OPX//77
opx_infinityinventory

Items

Last updated on

The item and weapon catalogue — the row format of data/items.lua and data/weapons.lua, and what ships.

Catalogue files

  • Items: modules/inventory/data/items.lua (M.Data.ITEMS). Weapons: modules/inventory/data/weapons.lua (M.Data.WEAPONS).
  • The key is the item name: letters, digits, _, - and ., up to 48 bytes.
  • A malformed row is a boot warning and is left out.
  • No way to add items at runtime.

Item fields

data/items.lua — one row
water = {
    WEIGHT = 500, CATEGORY = 'drink', MODEL = 'food.drink_packaged',
    USE = { STATUS = { thirst = 35 }, ANIMATION = { NAME = 'drink', DURATION_MS = 3000 } },
},
FieldDefaultEffect
WEIGHTDEFAULT_ITEM_WEIGHTGrams per unit.
CATEGORYmiscWhich tab shows it.
STACKtruefalse: one unit per slot.
DROPtruefalse: cannot be dropped on the ground or moved into any memory-only container (no_drop).
LABELlocale inventory.item.<name>, else the nameA locale key or plain text.
DESCRIPTIONlocale inventory.item.<name>.descriptionA locale key or plain text.
IMAGEnoneImage name for the screen.
MODELDROPS.MODELA curated Open77.props alias drawn for a pile. A .mesh path is refused at load. See Pile models.
USEnoneMakes the item usable. See below.

USE sub-fields:

FieldDefaultEffect
CONSUME1Units removed per use. A use handler can override it.
CLOSEtruefalse keeps the screen open after a use.
STATUSnone{ needName = amount }, added by the server through the needs contract (reason use) after the unit is consumed.
ANIMATIONnone{ NAME, VARIANT?, DURATION_MS? }. With DURATION_MS a non-cancellable progress bar plays it; without, animations plays it once.

An item with neither USE nor a registered use handler cannot be used (not_usable).

Weapons as items

M.Data.WEAPONS has three tables:

TableFieldsMeaning
AMMOWEIGHT, MAX, MODELAmmunition items. Category ammo, always stackable and usable. MAX is the rounds per box (1–100000, default 250 with a boot warning when not a whole number): an ammo slot holds at most MAX, never above MAX_STACK. Shipped: handgun 500, rifle 900, shotgun 190, sniper 170.
CLASSESAMMO, MODEL, MAGAZINEShared settings per class (handgun, rifle, melee, …).
WEAPONSRECORD, CLASS, WEIGHT, MAGAZINE?, MODEL? + item fieldsOne weapon item each. RECORD is an Items.* TweakDB record. A weapon whose class is unknown is left out.
data/weapons.lua
AMMO = { ammo_handgun = { WEIGHT = 10, MAX = 500, MODEL = 'crate.ammo_box' } },
CLASSES = { handgun = { AMMO = 'ammo_handgun', MODEL = 'military.case', MAGAZINE = 15 } },
WEAPONS = { weapon_chao = { RECORD = 'Items.Preset_Chao_Default', CLASS = 'handgun', WEIGHT = 1000 } },
  • A weapon is never stackable. Each unit gets metadata { serial, ammo }: a serial of two letters and eight hex digits, and ammo = 0. A serial passed in metadata is kept only when one weapon is added.
  • Using a weapon draws it into game weapon slot WEAPONS.SLOT. Using it again puts it away. Moving, giving or dropping a drawn weapon first puts it away and reads its rounds: that try is refused with holstering, the next one goes through with the right ammo. Other modules put it away with HolsterWeapon.
  • Using an ammunition item loads it into the drawn weapon of the matching class, up to the weapon's MAGAZINE (or its class's). The rounds are kept on the weapon's ammo metadata and read back from the game every WEAPONS.AMMO_SYNC_MS; they only ever go down that way.
  • With WEAPONS.REMOVE_UNBACKED = true, any equipped weapon no bag item backs is taken off the player every WEAPONS.SCAN_MS.
  • Drawing a weapon needs the host's Open77.weapons relay. Without it the use answers weapons_unavailable.

Shipped items

  • Drinks, food, medical items (they heal: HEALING), materials (scrap_metal, electronics), lockpick, hauling_crate (10 kg, used by hauling), phone, id_card, shard, vehicle_key, eddies, four ammunition types and 189 weapons.
  • vehicle_key is non-stackable and carries metadata { plate, label }, written by vehiclekeys. The screen and the hotbar show a stack's own metadata.label when it has one. Use CountWhere to find a key by plate.
  • door_key is non-stackable, has no USE and carries metadata { type, label }, cut by doorlock. A door that lists { name = 'door_key', metadata = '<type>' } opens for a key of that type.

Pile models

Every droppable item names the nearest prop the platform hosts. The alias list is compiled into the Open77 client, so a resource cannot add one; most non-food items draw a stand-in.

ItemsMODEL
water, coffeefood.drink_packaged
nicolafood.soda_can
burrito / chips, kibblefood.street_food / food.snack
bandage, bounce_back, maxdocmedical.container
scrap_metalgarbage.industrial_trash (stand-in)
electronics, phoneelectronics.monitor.device (stand-in)
id_card, shard, vehicle_key, door_keycrate.valuable (stand-in)
lockpickcontainer.toolbox
hauling_cratecrate.small
ammunitioncrate.ammo_box
handgun, revolver, SMG, melee classesmilitary.case
rifle, precision, LMG, sniper, shotgun classesmilitary.case.large
axes, hammers (approximate) / Caretaker's Spadetool.fire_axe / tool.shovel
eddiesnone (DROP = false)
data/items.lua — a pile model
shard = { WEIGHT = 20, MODEL = 'crate.valuable' }, -- an alias name, never a .mesh path
  • A weapon's own MODEL wins over its class's.
  • Decorative weapons (a pile that looks like the weapon itself) are not possible from a resource: a raw .mesh draws as a marker, a raw .ent is refused (template_backend_disabled), and nothing registers a new alias. It needs one alias per weapon family in the platform. The note is at the top of data/weapons.lua.

On this page