Skip to content

The ts2 command

ts2 builds a project.

Terminal window
ts2 <directory>

Builds the project whose ts2.config.json is found at directory or above it. With no directory, the current one.

--frozenFail if the build would add a key to the persisted-state registry. For CI — see The state registry
--quietPrint errors only. The summary line and the config path are not printed
-h, --helpShow usage and the outputs table

Everything under outDir — dist/ by default:

interfaces.jsonThe entry points: every interface, with the components the game loads as data
scripts/<name>.cs2, scripts/<name>.binOne file per function the build wrote — every component, handler and helper — readable and assembled
symbols.jsonQualified name to number, for what a listener outside the build can name
scripts.jsonEvery function’s name to its number
calls.jsonHow to call each exported function from outside: its parameters and what each becomes
state.jsonEvery state cell’s name to its slot
varc-configs.jsonThe state slots the game must be told about
collections.jsonEvery list and map declared with listOf and mapOf

and, beside the sources, the persisted-state registry named by registry. The build writes more than the table names; Project outputs says what each file is for.

0 on success, non-zero if anything failed. Every failure prints at least one line naming the file, the line and the diagnostic code. A build with warnings and no errors succeeds.

Terminal window
ts2 .

A successful build prints where it found the config, then one summary line — this is the one for the project behind these pages:

ts2: /work/docs/ts2.config.json
ts2: 33 interfaces, 299 scripts, 299 assembled, rift-extended, cs2 237, 26 static (642 components, 49 hosted), 19 state slots -> /work/docs/dist

Left to right: how many interfaces the project declares; how many functions the build wrote out and how many of those it assembled — the two numbers agree on a good build; the dialect; the version of the game’s data it was built for; how many interfaces the game loads entirely as data, how many components that covers, and how many places inside them a component is built when the interface opens; how many state slots the project uses; and where it all went.

Terminal window
ts2 . --frozen
src/confirm.ts2:7:5: error: TS2E219: <text> draws nothing without a `font`.
<text x="center" y={42} w={{ fill: 20 }} h={16} text="Confirm" color={Colors.WHITE} />
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
hint: Add `font={...}`. The client skips a text component whose font is unset, so it would render as a silent blank.
ts2: 1 error

The codes are all on Diagnostics.

src/backpack.ts2:15:8: warning: TS2E251: `Panel` rebuilds instead of updating in place, because this loop's row count is decided at run time.
{inv.filter((item, slot) => item !== -1).map((item, i) => <Slot item={item} i={i} />)}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
hint: Move the test into the row — `map((row) => test && <x/>)` builds exactly the same rows, and a conditional INSIDE a row is a region, which an update tears down and remakes where it sits instead of rebuilding the component.
ts2: 1 warning
ts2: 1 interfaces, 18 scripts, 18 assembled, rift-extended, cs2 237, 0 state slots -> /work/backpack/dist

A warning does not fail the build; the exit status is 0. Five codes are warnings: TS2E251 (a list that rebuilds instead of updating in place), TS2E255 (a conditional region that can never be re-created), TS2E229 (a record read beside its test rather than under it), TS2E233 (a caller’s prop overriding one the component set on its own root) and one form of TS2E214 (a ref that cannot be named from outside the build). The full set for the last build is written to dist/warnings.json, so a warning that scrolled past is not lost.

Seeing why an interface is built when it opens

Section titled “Seeing why an interface is built when it opens”
Terminal window
TS2_STATIC_DEBUG=1 ts2 .

Prints each interface that is not loaded entirely as data, and why.

There is an extension for VS Code. It shows diagnostics as you type, completes names, shows a declaration on hover and jumps to a definition.

It reports an error in a file I did not change

Section titled “It reports an error in a file I did not change”

Every .ts2 file under src is compiled, not only the ones reachable from an interface.

N scripts, M assembled with M < N is a failed build, and the exit status says so: something the build wrote could not be assembled. The lines above the summary name it. Report it with the source that caused it.

It reports something about my environment rather than my code

Section titled “It reports something about my environment rather than my code”

A setup problem prints as a single ts2: … line rather than a diagnostic. It means the tool could not start, not that anything is wrong with your source.

A warning I fixed is still in dist/warnings.json

Section titled “A warning I fixed is still in dist/warnings.json”

The file is rewritten on every build. Build again.