Game state
Coins, levels, quest progress and inventories belong to the game. You read them with hooks.
Reading a variable
Section titled “Reading a variable”export const StatusPanel = (): Component => { const poison = useServerState(Varps.POISON); const stamina = useServerState(Varbits.STAMINA_ACTIVE); const shown = useServerState(ItemVarps.SHOWCASED);One hook reads both kinds of game variable: whole values (Varps) and fields
packed inside one (Varbits). A reference can say what the variable holds. VarpRef<3997, 'item'> reads back
as an Item and goes straight into an item prop:
export declare const ItemVarps: { readonly SHOWCASED: VarpRef<3997, 'item'>;};<sprite x="right" y="center" w={36} h={32} item={shown} itemCountMode="never" />Reading a skill
Section titled “Reading a skill”const attack = useSkill(Skills.ATTACK);const baseAttack = useSkillBase(Skills.ATTACK);useSkill is the level now, boosts included; useSkillBase is the level
underneath. Show the first; check requirements against the second, so a potion
does not unlock a door. To pass a skill to a child component, pass its level:
const SkillTile = ({ icon, level, base, x, y }: { icon: Sprite | null; level: Int; base: Int; x: Int; y: Int;}): Component => (Reading an inventory
Section titled “Reading an inventory”useInventory returns a handle to the whole container:
const inventory = useInventory(Inventories.INVENTORY);inventory[slot] | the item in a slot, or -1 if it is empty |
inventory.count(slot) | how many of the item in a slot |
inventory.total(item) | how many of an item across the whole container |
inventory.size | how many slots there are |
inventory.map(fn) | one component per slot — see Rendering lists |
Game state is read-only
Section titled “Game state is read-only”Game state has no setter. To change it, send the server an interaction, such as a right-click option:
<sprite x="center" y="center" w={36} h={32} item={item} itemCount={count} options={['Use', '', '', '', 'Drop', '', '', '', '', 'Examine']} />Showing a value before the server confirms it
Section titled “Showing a value before the server confirms it”predictServerState overwrites the client’s copy, so a toggle can look switched
the moment it is clicked:
<layer w="fill" h={24} onClick={() => { predictServerState(Varbits.STAMINA_ACTIVE, 1 - stamina); }}>The next server update replaces it. For a value your interface owns, use interface state.
Reading once
Section titled “Reading once”useServerStateOnce reads a value while the component builds and follows
nothing afterwards:
const atOpen = useServerStateOnce(Varps.POISON);const now = useServerState(Varps.POISON);When now moves the component redraws, and atOpen keeps the value from when
the panel opened. For an editable copy, seed a cell with it:
const [stamina, setStamina] = useState(useServerStateOnce(Varbits.STAMINA_ACTIVE));Following a result
Section titled “Following a result”useDerived redraws only when a function’s result changes:
const combatLevel = (): Int => { const attack = useSkill(Skills.ATTACK); const strength = useSkill(Skills.STRENGTH); const defence = useSkill(Skills.DEFENCE); const hitpoints = useSkill(Skills.HITPOINTS); return (attack + strength + defence + hitpoints) / 4;};const level = useDerived(() => combatLevel());The reference has a page for each: useServerState, useSkill, useSkillBase, useInventory, predictServerState, useServerStateOnce and useDerived.