Docs/Game data/Module system
Module system
Configure this device for multi-device packs — add exports (Provider) or bindings (Consumer) and let the Composer wire the @editable plumbing.
Last updated 2026-06-14
What is this?
The Module tab is the configuration sheet for the multi-device wiring of this device. It doesn't define behavior — it tells the Composer what public API to emit, and which other devices this one talks to.
“Provider” and “Consumer” are roles you fall into by what you add, not a toggle you flip: add Exports → you expose a public API (Provider); add a Binding → you call another device's API (Consumer). The labels next to the Exports and Bindings sections just name those roles.
Conceptual background lives in Concepts: Multi-device. Read that first if “Provider” / “Consumer” aren't familiar terms.
Provider mode — exports
On a Provider device, the Exports list declares which methods are public. Each export is one row:
- ID — snake_case name (e.g.
award_coins); the Verse name and internal helper are derived from it automatically. - Verse name — PascalCase method name, derived from the ID and shown read-only (e.g.
award_coins→AwardCoins). - Params — list of
(name, type). The implicit first param is always theagent(Player). - Return type —
void,int,logic, etc. - Internal helper — the generated helper function the public export delegates to (also derived from the ID, e.g.
AwardCoinsHelper). Add your own body under the export'sLogictab, or leave it to auto-call.
Consumer mode — bindings
On a Consumer device, the Bindings list declares which Providers this device depends on. Each binding row:
- Target device — the Provider device in your project.
- Editable name — PascalCase Verse variable for the binding (e.g.
Economy). - Consumed ports — the Provider's exports this consumer actually calls (checkboxes populated from the target device's exports).
📌 Note
inventory_slot, etc.) that the Provider already emits, so they aren't duplicated. Tick it on a device that binds to a Provider which owns those shared types.💡 Tip
Walkthrough: economy pack
On the Provider device
Open the Module tab, set a Verse Class Name (e.g.economy_device), then add two Exports:award_coins(Amount:int):voidandtry_buy(Price:int):logic. Adding exports is what makes it a Provider.On the Consumer device
Open the Module tab and add a Binding: targeteconomy_device, Editable NameEconomy, and tick thetry_buyconsumed port. (Tick Consumer mode too if the Provider owns shared types this device reuses.)Use the binding in a rule
In the Consumer, add a rule:WHEN On Button Pressed → DO Call Binding Port. Set Binding NameEconomy, Port Method NameTryBuy(the PascalCase Verse name), and Arguments100. Use Return Value to capture the result if needed.Wire in UEFN
After import, the Consumer's Details panel exposes anEconomyfield. Drag the Provider actor into it. Pack is wired.
Gotchas
⚠️ Watch out
⚠️ Watch out
📌 Note
What gets generated?
Provider exports become <public> methods that wrap internal helpers. Consumer bindings become typed @editable fields:
economy_device := class(creative_device):
AwardCoins<public>(Player:agent, Amount:int):void=
AwardCoinsHelper(Player, Amount)
shop_device := class(creative_device):
@editable Economy:economy_device = economy_device{}
OnPress(Agent:agent):void=
if (Economy.TryBuy[Agent, 100]):
# success path
...
See also