Skip to content
tynt

tynt documentation

Understand how tynt isolates untrusted cartridge code.

Cartridge security

tynt runs cartridges in a fresh opaque-origin sandboxed iframe and disposable worker, with network and storage APIs unavailable. Messages are validated, lifecycle calls have watchdogs, and drawing and audio have fixed budgets.

Drawing coordinates and dimensions must be finite and within ±1,000,000. Rendering clips work to the 160 × 144 canvas, and an aggregate budget of 1,000,000 conservative rasterization work units prevents many individually valid commands from creating excessive host work. Byte, command-count, text, sprite, and map limits apply separately. Invalid output stops the run before it is replayed.

Only one worker tick may be outstanding. Pausing discards late frames and audio rather than building a queue, while single-step execution retains watchdog protection. Muting or stopping also cancels playback waiting on browser audio permission. Pending playback is capped at 32 requests, and at most 64 live or scheduled oscillator voices are retained across frames; excess voices are dropped. Audio resources are disposed when leaving a preview; browser audio failures do not stop gameplay.

Public cartridges are compiled at catalog-generation time without executing their source. Their generated code and source maps load through size-limited, bounded caches; they still run in the same sandbox as editor cartridges. Failed asset or compiler downloads are not permanently cached and can be retried.

Public covers are decoded with CRC checks, required to be exactly 320 × 288 pixels, and re-encoded before publication. These protections reduce risk but cannot eliminate browser-engine vulnerabilities or brief denial-of-service attempts.

Review the complete diff before checking out a contributed branch or running repository commands. A cartridge-only change belongs inside one cartridges/<slug>/ directory. Report vulnerabilities using the repository SECURITY.md instructions.