The tide command
tide builds and runs games. A game is every .tide file in a folder and its subfolders, with the .c files and libraries there when it calls C (see Calling C). Commands take the game's folder, or use the current one.
tide <command> [folder] [options]| Command | What it does |
|---|---|
tide run [folder] |
Builds the game and plays it |
tide build [folder] |
Builds the game into <folder>/build, named after the folder |
tide schedule [folder] |
Shows which systems can run at the same time, and why the others wait |
tide editors |
Adds Tide to VS Code, Cursor, VSCodium and Windsurf |
tide upgrade |
Updates tide to the newest version |
tide version |
Shows tide's version and channel, where it's installed, and which compilers it found |
tide help |
Lists every option |
tide cc <options> |
clang, built into tide, for C you build yourself (see Calling C) |
run and build
| Option | What it does |
|---|---|
--release |
Optimized, the way players get it |
--web |
A web page (WebGL 2), built with clang's WebAssembly target |
--title <title> |
The window's title, over the game's title setting (default: that, or the folder's name) |
--stats |
Shows the frame rate, the ping, the bandwidth (what goes over the network each second, up and down), the tick, the entity count and the threads ticks run on |
-o <path> |
build only: where the program goes |
--no-open |
run --web only: serves the page without opening a browser |
tide build --release --web makes one self-contained .html file with the game inside. It opens straight from disk, and can be put online as it is.
Threads on the web
A game's ticks run on every core when the page is cross-origin isolated: served with these two headers, which let it share its memory with the workers its threads run in.
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corptide run --web serves the page with them. Where a page is put online, the host has to send them: on itch.io, it's the SharedArrayBuffer support option in the game's embed settings. A page without them, or opened from disk, runs the same game on one thread, with the same results, so web players on either kind of page play together. Workers only start once a tick has enough work for them.
Hot reload
While tide run plays a game, saving a .tide file rebuilds it, and so does saving one of its C files, headers or libraries. The game carries on with the new code in the same window:
- If you changed only code (systems, views, event handlers, methods), the match and everything local, like menus, carry on where they are.
- If you changed data (components, fields, singletons, the input), the game is carried over to it by name, and goes on from where it was.
- If the new code has errors,
tideprints them and the game keeps running its last build.
Carrying the game over works like this:
- Every field of the same name keeps its value. An
intfield that became afloatis converted, and so is an int vector that became a float vector of the same size. An enum field keeps its member by name. - A new field gets its declared default. So does a field whose type changed to one it doesn't convert to, like
float2tofloat3. New text and list fields start empty. - Renaming a field is removing it and adding a new one: its value is lost.
- An entity keeps its ID. When you remove a component, entities that had it keep their other components. An entity whose remaining components can't exist together in the new code is dropped.
- A changed default doesn't change existing entities, only new ones.
- A waiting task carries on when its async function's code is the same, and is dropped when it changed: where it was waiting is gone.
- If the scene the game is in is gone, the game starts over.
tide says what happened after each reload, like reloaded, and carried the game over to its new data layout; 1 field reset; 2 entities dropped.
When the game gets into a state you don't want, type r and press Enter in tide's terminal to start it over. With a match on several windows (--host in one, --connect localhost in another), each window reloads when you save, and players stay in the match. A window that joined another's match joins it again a second after that match ends without it: when the other window starts it over, or is still on a build with another data layout. On the web, a reload goes on with the match closed for now: the room closes, and the other players drop out.
tide run --web reloads too. tide serves the game's page at an address on your machine, like http://127.0.0.1:52407/, opens it in your browser, and keeps running until you press Ctrl+C. What each reload did shows in the browser's console. VS Code and JetBrains IDEs can play it beside your code instead (see Editors).
Hot reload is only for tide run: tide build makes a plain program, or a page with nothing of it.
Multiplayer
tide run can start a match others join, or join one. For --host, the game's Main scene must be the match's (see Scenes); a game that starts in a menu does the same from code (see Multiplayer).
| Option | What it does |
|---|---|
--host [port] |
Opens the match for others to join: in a room, whose code the game can show, and on UDP port 7777 by default (not on the web) |
--join <code> |
The match in the room with this code, like K7QF2M |
--connect <address> |
The match at an address, like 192.168.1.5 or localhost:7777 (not on the web) |
upgrade
| Option | What it does |
|---|---|
--nightly |
Follow nightly versions from now on |
--stable |
Follow stable versions from now on |
--version <v> |
Install exactly this version |
tide says, at most once a day, when a newer version is out. Set the TIDE_NO_UPDATE_CHECK environment variable to stop it looking, as on a build server.
Files
tide keeps its work in a hidden .tide folder in the game's folder. You can delete it any time, and git ignores it. tide build puts what it makes in build/, with the game's .dll, .so or .dylib libraries next to the program. C files and libraries in hidden folders or in build/ aren't part of the game.