Search documentation

Find pages, sections, and content across all docs.

WavedashDocs

ct.js

Publish ct.js projects to the web — ct.js exports a PixiJS-based static bundle that Wavedash hosts directly.

View example project on GitHub Playtest the example project

ct.js is a free, open-source 2D game engine with a visual IDE. The "Export to web" build produces a flat directory of static files — index.html, the ct.js runtime, PixiJS, and your game code — which Wavedash hosts as-is. No SDK package to install, no bundler step.

Export your game

In the ct.js IDE: Deploy → Export to web. It writes a zip to ~/ct.js/Builds/<ProjectName>.zip containing:

  • index.html
  • ct.<hash>.js (the ct.js runtime + your compiled game)
  • ct.<hash>.css
  • pixi.js, sscd.min.js
  • favicon and touch-icon images
  • fonts/, img/, snd/ (your project's assets)

Unzip into build/ and point wavedash.toml at it.

SDK integration

window.Wavedash is injected by the Wavedash runtime before your game loads, so you can call it directly from any ct.js event. The two calls you need are updateLoadProgressZeroToOne while loading and init once the player can interact.

The easiest place to put them is on your starting room's OnRoomStart event:

// rm_main → On Room Start
if (typeof (window as any).Wavedash !== 'undefined') {
  (window as any).Wavedash.updateLoadProgressZeroToOne(1);
  (window as any).Wavedash.init({ debug: true });
}

Calling Wavedash.init() is required. Your game stays hidden behind the Wavedash loading screen until you do.

If your game has its own loading phase (loading textures, fetching state), call updateLoadProgressZeroToOne(progress) periodically and only call init() once gameplay can start.

Input and the time delta

ct.js doesn't expose keyboard.down[code] for "is the key currently held" — keyboard state lives in inputs.registry. The standard approach is to define Actions in the project (Project → Actions → Edit), then read actions.MoveUp.down, but you can also poll the raw registry directly:

const up = (inputs as any).registry['keyboard.KeyW'] || (inputs as any).registry['keyboard.ArrowUp'];
const down = (inputs as any).registry['keyboard.KeyS'] || (inputs as any).registry['keyboard.ArrowDown'];

The frame time delta is u.time (in seconds, scaled by the room's time-scale).

wavedash.toml

game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./build"
entrypoint = "index.html"

Known issues

No bundler step. ct.js's exporter writes plain static files — there's nothing to npm-install and nothing to configure. If you find yourself trying to integrate Webpack or Vite, you're working against the engine.

Asset paths are relative. The exported index.html references pixi.js, ct.<hash>.js, etc. with relative paths. Don't move files around inside build/ — keep the structure ct.js produced.

PIXI and inputs are globals. ct.js does not module-scope its runtime. PIXI, inputs, u, keyboard, rooms, templates are all available on window from inside event code.