Globals
Ten names are in scope in every file without an import. They make a value from its parts, convert one kind of value to another, or do the arithmetic the operators do not.
tileOf(x, z, plane): CoordcomponentOf(interfaceId, child): ComponentIdinterfaceOf(ref): IntstringOf(n): StringparseInt(text): IntlistOf<Value>(entries): List<Value>mapOf<Key, Value>(pairs): Map<Key, Value>Math.min · Math.max · Math.clamp · Math.pow · Math.sqrtRandom.int(max): IntTrig.sinDeg(angle) · Trig.cosDeg(angle)The hooks — useState, useServerState and the rest — are not global; they
are imported from 'ts2'. See the hooks reference.
Reference
Section titled “Reference”tileOf(x, z, plane)
Section titled “tileOf(x, z, plane)”A world position from its three axes. x is east–west, z is north–south,
plane is the floor, with the ground at 0. The result is a
Coord, which reads the same three back as
.x, .z and .plane.
const LUMBRIDGE = tileOf(3222, 3218, 0);componentOf(interfaceId, child)
Section titled “componentOf(interfaceId, child)”A component’s address in an interface outside this project — the frame an interface opens into, or a panel another build owns — from the interface’s number and the component’s position in it. Both halves must fit in 0..65535.
It may not name an interface this build numbers (TS2E235). Name a component
of your own through the ref its interface declares — see
Refs.
<Measure target={componentOf(1200, 0)} />interfaceOf(ref)
Section titled “interfaceOf(ref)”The number of the interface a module-scope ref’s component belongs to. The ref
must be bound on a <ui> or a static element (TS2E215). It is for telling
the game which interface you mean — see
Interfaces and slots.
stringOf(n)
Section titled “stringOf(n)”A whole number as text.
<text x={{ center: -24 }} y={ROSE + 6} w={40} h={16} text={stringOf(degrees)} font={Fonts.BOLD} align="right" valign="middle" shadow color={Colors.YELLOW} />A template literal converts for you — `${degrees} degrees` — so
stringOf is for a prop that wants a String and has nothing to add to it.
There is no String(n).
parseInt(text)
Section titled “parseInt(text)”Text as a whole number. There is no text a player types that you can read back — see Keyboard and input — so this is for text that arrived from a table or a parameter.
listOf and mapOf
Section titled “listOf and mapOf”Declare a collection. Both are on the collections page.
Whole numbers in, whole numbers out.
Math.min(a, b) | The smaller |
Math.max(a, b) | The larger |
Math.clamp(lo, hi, value) | value, held between lo and hi. The bounds come first |
Math.pow(base, exp) | base raised to exp |
Math.sqrt(n) | The whole-number square root, rounded down |
const degrees: Int = Math.clamp(0, 359, angle * 360 / TURN); const travel: Int = Math.max(1, gutter.height - thumb.height); const offset: Int = Math.clamp(0, travel, event.mouseY - thumb.height / 2);Not available: Math.floor, ceil, round, abs, log, exp,
random, sin, cos, atan2. There is no floating point, so there is
nothing to round; randomness is Random.int, trigonometry is Trig.
Random.int(max)
Section titled “Random.int(max)”A whole number from 0 up to but not including max.
onClick={() => { setAngle(Random.int(TURN)); }}>Trig.sinDeg(angle) and Trig.cosDeg(angle)
Section titled “Trig.sinDeg(angle) and Trig.cosDeg(angle)”Sine and cosine, in the client’s own units — not degrees, whatever the names
say. The angle is in 16,384ths of a full turn: a quarter turn is 4,096, an
eighth is 2,048. The result is scaled by 16,384: Trig.sinDeg(4096) is
16,384, Trig.cosDeg(0) is 16,384, and a value halfway is 8,192. Multiply by
the radius first and divide by 16,384 after:
const Needle = ({ angle }: { angle: Int }): Component => ( <rect x={ROSE / 2 - DOT / 2 + Trig.sinDeg(angle) * RADIUS / TURN} y={ROSE / 2 - DOT / 2 - Trig.cosDeg(angle) * RADIUS / TURN} w={DOT} h={DOT} color={Colors.AMBER} fill />);y grows downwards on screen, so north is the cosine subtracted.
Turning a needle
Section titled “Turning a needle”const TURN = 16384;const EIGHTH = 2048; <layer x={0} y={ROSE + 28} w={74} h={22} onClick={() => { setAngle((angle + EIGHTH) % TURN); }}>Reading a position back
Section titled “Reading a position back”const Position = (): Component => ( <text x={0} y="bottom" w="fill" h={28} font={Fonts.SMALL} align="center" valign="middle" shadow lineHeight={14} text={`Lumbridge: ${LUMBRIDGE.x}, ${LUMBRIDGE.z}<br>${LUMBRIDGE.plane === 0 ? 'ground floor' : `floor ${LUMBRIDGE.plane}`}`} color={Colors.DIM} />);Troubleshooting
Section titled “Troubleshooting”My needle points the wrong way, or barely moves
Section titled “My needle points the wrong way, or barely moves”You passed degrees. Trig.sinDeg(90) is the sine of 90/16,384 of a turn —
almost zero. A quarter turn is 4,096. And the result is scaled by 16,384, so
divide after multiplying by your radius.
Math.clamp gives me the bound instead of the value
Section titled “Math.clamp gives me the bound instead of the value”The bounds come first: Math.clamp(lo, hi, value).
”’String’ only refers to a type”
Section titled “”’String’ only refers to a type””String(n) does not exist. Write stringOf(n), or put the number in a
template literal.
The build names my own interface’s number in an error
Section titled “The build names my own interface’s number in an error”componentOf(n, …) where n is a number this build assigned (TS2E235).
Address the component through the ref its interface declares instead.