Skip to content

Server entry points

The server calls into an interface through a function you export. The examples on this page build a courier’s delivery panel.

An exported function is what the server calls

Section titled “An exported function is what the server calls”

An entry point is an exported function with typed parameters:

src/integrating-entry.ts2
export const deliveryArrived = (parcel: Parcel, count: Int, state: Delivery): void => {
const [, setParcel] = useState(deliveryParcel);
const [, setCount] = useState(deliveryCount);
const [, setState] = useState(deliveryState);
setParcel(parcel);
setCount(count);
setState(state);
};

It writes cells and returns. Components that read those cells redraw:

src/integrating-entry.ts2
const DeliveryRow = (): Component => {
const [parcel] = useState(deliveryParcel);
const [count] = useState(deliveryCount);
const [state] = useState(deliveryState);

To hand a value to an interface as it opens, write it into a cell first.

Parameters are values: Int, String, Boolean, an item, a sprite, any of the game’s typed numbers, or an enum you declared. Never a component. An array arrives as Ints<T> or Strings; walk it with while over its length:

src/integrating-entry.ts2
export const deliveriesListed = (names: Strings, counts: Ints): void => {
const [, setParcels] = useState(listedParcels);
const [, setItems] = useState(listedItems);
let total: Int = 0;
let i: Int = 0;
while (i < counts.length) {
total = total + counts[i];
i = i + 1;
}
setParcels(names.length);
setItems(total);
};

A value the server chooses and the panel branches on is an enum tagged @wire, with every member written out:

src/integrating-entry.ts2
/**
* Where a delivery has got to. The server sends one of these, so every value
* is written out and never moves.
* @wire
*/
export enum Delivery {
NONE = 0,
SENT = 1,
ARRIVED = 2,
LOST = 3,
}

The server names the same members: Delivery.LOST, never 3. Give every member an explicit number.

Add members with the next unused value. Never change or reuse one.

When the server passes an interface id, compare it with interfaceOf(ref):

src/integrating-entry.ts2
export const courierAt = (frame: Int, parcel: Parcel): void => {
if (!isTradingPost(frame)) {
return;
}
deliveryArrived(parcel, 1, Delivery.SENT);
};

An entry point may call another.

When the server pauses for the player to press something, resumePauseButton(target) tells it which component was pressed. The target is a ref, a ComponentId parameter, or event.self:

src/integrating-entry.ts2
const Continue = (): Component => {
const pressed = useRef();
return (
<layer x={0} y="bottom" w="fill" h={20}>
<rect ref={pressed} w={0} h={0} hide />
<text w="fill" h="fill" text="Click here to continue" font={Fonts.PLAIN}
align="center" valign="middle" shadow color={0x0000ff}
options={['Continue']} onOptionSelect={() => { resumePauseButton(pressed); }} />
</layer>
);
};

The hidden rect gives the server a stable component to recognise.