# ujjwalvivek/tinyts architecture

> Architecture diagram of the GitHub repository ujjwalvivek/tinyts, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-22). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ujjwalvivek/tinyts
- Repository: https://github.com/ujjwalvivek/tinyts

## Overview

1. **Repo shape**
   - This is a TypeScript-first 2D web game engine named **TinyTS**.
   - The repo is split into the reusable engine library under `src/`, a separate sample app under `game/`, and many browser demos under `examples/`.
   - The README positions the library as embeddable, zero-runtime-dependency, and usable both as a bundled npm package and via a global browser build.

2. **Primary runtime flow**
   - The main entrypoint is the engine bootstrap API exposed from `src/index.ts`, centered around `engineStart()`.
   - An app passes in update/render callbacks plus configuration such as size, pixel scaling, and backend preferences.
   - The engine then owns the game loop, calls user update logic on a timestep, and delegates drawing to the active renderer.
   - Shutdown/restart is a first-class concern; the README emphasizes `engineStop()` fully dismantles internal state.

3. **Core engine layer**
   - `src/core/` holds the foundation used by all subsystems: `engine.ts`, `scene.ts`, `ecs.ts`, `timer.ts`, `input.ts`, `canvas.ts`, `assets.ts`, `math.ts`, `easing.ts`, and `textInput.ts`.
   - This is where scheduling, scene management, entity/component lifecycle, input state tracking, and asset loading are coordinated.
   - Tests in `src/core/test/` suggest these modules are designed to be reusable and headless-testable, not just browser-bound.

4. **Scene and application orchestration**
   - Scene management is explicit via `src/core/scene.ts` and `src/scenes/` in the game example.
   - The engine likely swaps or stacks scenes to separate gameplay, menus, or loading states.
   - The sample game in `game/src/scenes/game.ts` and `game/src/ui/screens.ts` shows how the engine is used as a host for game-specific state flow.

5. **Rendering subsystem**
   - Rendering is modular under `src/render/`, with shared interfaces in `renderer2d.ts` and concrete backends in `rendererCanvas2d.ts`, `rendererWebGL2.ts`, and `rendererWebGPU.ts`.
   - `camera.ts`, `spriteAnimation.ts`, `font.ts`, `embeddedFont.ts`, `procedural.ts`, and `color.ts` indicate a layered rendering pipeline that supports sprites, text, shapes, camera transforms, and procedural drawing.
   - The README says the engine auto-falls back from WebGPU to WebGL2 to Canvas2D, so backend selection is a major architectural boundary.

6. **Canvas and overlay composition**
   - The engine uses a canvas-centric output model, with a primary render canvas plus an optional overlay canvas.
   - The overlay layer is used for text and debug UI, and the README notes it is synchronized with the main renderer.
   - This means the final frame is composed from at least two coordinated surfaces: game rendering and UI/debug overlay.

7. **Input and text entry**
   - `src/core/input.ts` and `src/core/textInput.ts` cover keyboard, mouse, touch, and gamepad-style interaction.
   - Input appears to be stateful and frame-updated rather than event-only, which fits the engine’s fixed-timestep loop.
   - The `examples/input-tester` and `examples/text-input` demos likely exist to validate these device and text paths.

8. **Audio subsystem**
   - `src/audio/audio.ts` is the main audio runtime, with tests under `src/audio/test/`.
   - The README describes synthesized audio, voice pooling/stealing, grouped volumes, spatial audio, clip caching, and a sequencer.
   - This subsystem is separate from rendering and likely consumes engine timing to schedule notes, envelopes, and playback updates.

9. **Physics and world simulation**
   - `src/physics/` contains collision and simulation helpers: `aabb.ts`, `tilemap.ts`, `tilemapHelpers.ts`, `spatialGrid.ts`, `verlet.ts`, and `noise.ts`.
   - The README calls out swept AABB, tilemap collision, spatial broad-phase, and verlet integration, so physics is a distinct subsystem with both geometry and world-generation utilities.
   - Tests around tilemaps, verlet, and noise indicate these modules are used as standalone building blocks, not only by the main engine loop.

10. **ECS and object lifecycle**
   - ECS is part of core rather than a plugin, with view caching, component pooling, entity ID recycling, serialization, and add/remove hooks described in the README.
   - This suggests gameplay systems can be built around pooled components and cached entity views for performance.
   - The architecture likely favors data-oriented, frame-updated systems instead of class-heavy object graphs.

11. **FX, plugins, and extension points**
   - `src/fx/particles.ts` provides particle system support.
   - `src/plugins/` contains higher-level presets and integrations such as asset helpers, audio presets, particle presets, and a debug overlay plugin.
   - These look like optional composition layers that sit on top of the core engine and renderer rather than being required for basic usage.

12. **Game/content example package**
   - `game/` is a separate Vite-powered package with its own `package.json`, `tsconfig.json`, and `src/` tree.
   - It includes `world/atlas.ts`, `world/palette.ts`, `world/renderer.ts`, `game/textures.ts`, `game/interactables.ts`, and UI/scenes code, which implies a real gameplay showcase built on top of the library.
   - This package demonstrates how the engine is consumed as an application, not just as a library.

13. **Examples and documentation as architectural proof**
   - `examples/` contains many self-contained browser demos for mechanics and subsystems: platformer, roguelike, particle lab, sound lab, sequencer lab, framebuffer, tilemap patterns, etc.
   - These demos are static HTML entrypoints, which shows the engine can be embedded directly without a heavy app framework.
   - `README.md`, `REFERENCE.md`, `TUTORIAL.md`, and `RELEASE-NOTES.md` form the documentation surface around the codebase.

14. **Build, test, and release boundaries**
   - Root-level `package.json`, `tsconfig.json`, and `typedoc.json` support library packaging and docs generation.
   - The repo includes CI and release workflows in `.github/workflows/ci.yml` and `release.yml`, plus tests spread across `src/**/test`.
   - `scripts/embed-font.ts` and `src/render/embeddedFont.ts` show that font assets are part of the build pipeline, not just runtime files.

Main entry points: [`src/core/engine.ts`](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/engine.ts) (Loop), [`src/plugins/debugOverlayPlugin.ts`](https://github.com/ujjwalvivek/tinyts/blob/main/src/plugins/debugOverlayPlugin.ts) (Plugins), [`src/index.ts`](https://github.com/ujjwalvivek/tinyts/blob/main/src/index.ts) (Engine API), [`src/render/rendererCanvas2d.ts`](https://github.com/ujjwalvivek/tinyts/blob/main/src/render/rendererCanvas2d.ts) (Backends)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_root["TinyTS"]
  node_node_entry["Engine API<br/>bootstrap<br/>[index.ts]"]
end

subgraph group_group_core["Core runtime"]
  node_node_engine["Loop<br/>[engine.ts]"]
  node_node_scene["Scenes<br/>scene orchestration<br/>[scene.ts]"]
  node_node_ecs["ECS<br/>entity system<br/>[ecs.ts]"]
  node_node_input["Input<br/>device state<br/>[input.ts]"]
  node_node_textinput["Text entry<br/>text input<br/>[textInput.ts]"]
  node_node_assets["Assets<br/>asset loading<br/>[assets.ts]"]
  node_node_timer["Timer<br/>scheduling<br/>[timer.ts]"]
  node_node_canvas["Canvas<br/>surface management<br/>[canvas.ts]"]
end

subgraph group_group_render["Rendering"]
  node_node_renderer2d["2D API<br/>render interface<br/>[renderer2d.ts]"]
  node_node_renderers["Backends"]
  node_node_render_util["Render utils<br/>render primitives<br/>[camera.ts]"]
end

subgraph group_group_audio["Audio"]
  node_node_audio["Audio engine<br/>audio runtime<br/>[audio.ts]"]
end

subgraph group_group_physics["Physics"]
  node_node_physics["Physics core<br/>simulation helpers<br/>[aabb.ts]"]
end

subgraph group_group_ext["Extensions"]
  node_node_particles["Particles<br/>fx system<br/>[particles.ts]"]
  node_node_plugins["Plugins<br/>integration layer"]
end

subgraph group_group_game["Sample game"]
  node_node_game_main["Game app<br/>sample application<br/>[main.ts]"]
  node_node_game_scene["Game scene<br/>game flow<br/>[game.ts]"]
  node_node_game_world["World layer<br/>content systems<br/>[renderer.ts]"]
end

subgraph group_group_examples["Examples"]
  node_node_examples["Demos<br/>[index.html]"]
end

subgraph group_group_docs["Docs & build"]
  node_node_docs["Docs<br/>documentation<br/>[README.md]"]
  node_node_build["Build & CI<br/>tooling<br/>[package.json]"]
end

node_node_entry -->|"starts"| node_node_engine
node_node_engine -->|"drives"| node_node_scene
node_node_engine -->|"updates"| node_node_ecs
node_node_engine -->|"polls"| node_node_input
node_node_engine -->|"routes"| node_node_textinput
node_node_engine -->|"ticks"| node_node_timer
node_node_engine -->|"renders to"| node_node_canvas
node_node_engine -->|"selects"| node_node_renderer2d
node_node_renderer2d -->|"implemented by"| node_node_renderers
node_node_renderers -->|"uses"| node_node_render_util
node_node_engine -->|"loads"| node_node_assets
node_node_engine -->|"plays"| node_node_audio
node_node_engine -->|"simulates"| node_node_physics
node_node_engine -->|"emits"| node_node_particles
node_node_plugins -->|"extends"| node_node_assets
node_node_plugins -->|"extends"| node_node_audio
node_node_plugins -->|"extends"| node_node_particles
node_node_plugins -->|"adds overlay"| node_node_renderers
node_node_game_main -->|"uses"| node_node_entry
node_node_game_main -->|"hosts"| node_node_game_scene
node_node_game_scene -->|"uses"| node_node_game_world
node_node_examples -->|"demonstrates"| node_node_entry
node_node_docs -->|"describes"| node_node_entry
node_node_build -->|"supports"| node_node_docs
node_node_build -->|"embeds font"| node_node_render_util

click node_node_entry "https://github.com/ujjwalvivek/tinyts/blob/main/src/index.ts"
click node_node_engine "https://github.com/ujjwalvivek/tinyts/blob/main/src/core/engine.ts"
click node_node_scene "https://github.com/ujjwalvivek/tinyts/blob/main/src/core/scene.ts"
click node_node_ecs "https://github.com/ujjwalvivek/tinyts/blob/main/src/core/ecs.ts"
click node_node_input "https://github.com/ujjwalvivek/tinyts/blob/main/src/core/input.ts"
click node_node_textinput "https://github.com/ujjwalvivek/tinyts/blob/main/src/core/textInput.ts"
click node_node_assets "https://github.com/ujjwalvivek/tinyts/blob/main/src/core/assets.ts"
click node_node_timer "https://github.com/ujjwalvivek/tinyts/blob/main/src/core/timer.ts"
click node_node_canvas "https://github.com/ujjwalvivek/tinyts/blob/main/src/core/canvas.ts"
click node_node_renderer2d "https://github.com/ujjwalvivek/tinyts/blob/main/src/render/renderer2d.ts"
click node_node_renderers "https://github.com/ujjwalvivek/tinyts/blob/main/src/render/rendererCanvas2d.ts"
click node_node_render_util "https://github.com/ujjwalvivek/tinyts/blob/main/src/render/camera.ts"
click node_node_audio "https://github.com/ujjwalvivek/tinyts/blob/main/src/audio/audio.ts"
click node_node_physics "https://github.com/ujjwalvivek/tinyts/blob/main/src/physics/aabb.ts"
click node_node_particles "https://github.com/ujjwalvivek/tinyts/blob/main/src/fx/particles.ts"
click node_node_plugins "https://github.com/ujjwalvivek/tinyts/blob/main/src/plugins/debugOverlayPlugin.ts"
click node_node_game_main "https://github.com/ujjwalvivek/tinyts/blob/main/game/src/main.ts"
click node_node_game_scene "https://github.com/ujjwalvivek/tinyts/blob/main/game/src/scenes/game.ts"
click node_node_game_world "https://github.com/ujjwalvivek/tinyts/blob/main/game/src/world/renderer.ts"
click node_node_examples "https://github.com/ujjwalvivek/tinyts/blob/main/examples/index.html"
click node_node_docs "https://github.com/ujjwalvivek/tinyts/blob/main/README.md"
click node_node_build "https://github.com/ujjwalvivek/tinyts/blob/main/package.json"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_entry,node_node_game_main,node_node_game_scene,node_node_game_world toneBlue
class node_node_engine,node_node_scene,node_node_ecs,node_node_input,node_node_textinput,node_node_assets,node_node_timer,node_node_canvas,node_node_examples toneAmber
class node_node_renderer2d,node_node_renderers,node_node_render_util,node_node_docs,node_node_build toneMint
class node_node_audio toneRose
class node_node_physics toneIndigo
class node_node_particles,node_node_plugins toneTeal
```

## Components

### TinyTS

Library, demos, and sample app

- [Engine API](https://github.com/ujjwalvivek/tinyts/blob/main/src/index.ts): bootstrap · Main entrypoint that starts and stops the engine loop · `src/index.ts`

### Core runtime

Engine loop, scenes, input, ECS, timing, and shared utilities

- [Loop](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/engine.ts): runtime loop · Owns fixed-timestep update, shutdown, restart, and orchestration · `src/core/engine.ts`
- [Scenes](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/scene.ts): scene orchestration · Scene switching and application flow coordination · `src/core/scene.ts`
- [ECS](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/ecs.ts): entity system · Entity/component lifecycle, pooling, view caching, and hooks · `src/core/ecs.ts`
- [Input](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/input.ts): device state · Keyboard, mouse, touch, and gamepad-style state tracking · `src/core/input.ts`
- [Text entry](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/textInput.ts): text input · Text composition and committed text handling · `src/core/textInput.ts`
- [Assets](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/assets.ts): asset loading · Loading and caching of runtime resources · `src/core/assets.ts`
- [Timer](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/timer.ts): scheduling · Timing and tick coordination for the game loop · `src/core/timer.ts`
- [Canvas](https://github.com/ujjwalvivek/tinyts/blob/main/src/core/canvas.ts): surface management · Primary canvas and overlay surface coordination · `src/core/canvas.ts`

### Rendering

Backend selection and 2D drawing pipeline

- [2D API](https://github.com/ujjwalvivek/tinyts/blob/main/src/render/renderer2d.ts): render interface · Shared renderer contract for 2D backends · `src/render/renderer2d.ts`
- [Backends](https://github.com/ujjwalvivek/tinyts/blob/main/src/render/rendererCanvas2d.ts): render backends · Canvas2D, WebGL2, and WebGPU rendering implementations · `src/render/rendererCanvas2d.ts`
- [Render utils](https://github.com/ujjwalvivek/tinyts/blob/main/src/render/camera.ts): render primitives · Camera, color, fonts, sprites, and procedural drawing helpers · `src/render/camera.ts`

### Audio

Synthesis, voices, sequencing, and playback

- [Audio engine](https://github.com/ujjwalvivek/tinyts/blob/main/src/audio/audio.ts): audio runtime · Playback, voice pooling, spatial audio, and sequencing · `src/audio/audio.ts`

### Physics

Collision, grids, tilemaps, verlet, and noise

- [Physics core](https://github.com/ujjwalvivek/tinyts/blob/main/src/physics/aabb.ts): simulation helpers · Swept AABB, tilemaps, broad-phase grids, verlet, and noise · `src/physics/aabb.ts`

### Extensions

Plugins and visual effects built on top of core

- [Particles](https://github.com/ujjwalvivek/tinyts/blob/main/src/fx/particles.ts): fx system · Particle simulation utilities for effects · `src/fx/particles.ts`
- [Plugins](https://github.com/ujjwalvivek/tinyts/blob/main/src/plugins/debugOverlayPlugin.ts): integration layer · Optional presets and debug overlay for assets, audio, and particles · `src/plugins/debugOverlayPlugin.ts`

### Sample game

Standalone Vite application using the engine

- [Game app](https://github.com/ujjwalvivek/tinyts/blob/main/game/src/main.ts): sample application · Standalone app entrypoint and package boundary · `game/src/main.ts`
- [Game scene](https://github.com/ujjwalvivek/tinyts/blob/main/game/src/scenes/game.ts): game flow · Sample gameplay scene and state progression · `game/src/scenes/game.ts`
- [World layer](https://github.com/ujjwalvivek/tinyts/blob/main/game/src/world/renderer.ts): content systems · Atlas, palette, renderer, textures, and interactables for the demo game · `game/src/world/renderer.ts`

### Examples

Browser demos for subsystems and gameplay patterns

- [Demos](https://github.com/ujjwalvivek/tinyts/blob/main/examples/index.html): browser demos · Self-contained examples for mechanics, rendering, input, audio, and physics · `examples/index.html`

### Docs & build

Documentation, scripts, CI, and packaging

- [Docs](https://github.com/ujjwalvivek/tinyts/blob/main/README.md): documentation · README, reference, tutorial, and release notes · `README.md`
- [Build & CI](https://github.com/ujjwalvivek/tinyts/blob/main/package.json): tooling · Packaging, typedoc, font embedding, and GitHub workflows · `package.json`

## Connections

- Engine API → Loop: starts · Bootstrap API creates and manages the runtime
- Loop → Scenes: drives · Loop advances the active scene graph
- Loop → ECS: updates · Runtime coordinates entity/component lifecycle
- Loop → Input: polls · Frame updates read device state
- Loop → Text entry: routes · Text entry is integrated with input handling
- Loop → Timer: ticks · Fixed timestep and scheduling are driven by timer state
- Loop → Canvas: renders to · Engine owns the main and overlay canvas surfaces
- Loop → 2D API: selects · Engine chooses a renderer contract
- 2D API → Backends: implemented by · Backend-specific rendering implementations satisfy the interface
- Backends → Render utils: uses · Backends rely on camera, font, color, and drawing helpers
- Loop → Assets: loads · Asset lifecycle is coordinated by the engine
- Loop → Audio engine: plays · Audio runtime is updated alongside the main loop
- Loop → Physics core: simulates · Gameplay systems can use physics helpers during updates
- Loop → Particles: emits · Visual effects plug into the runtime and renderer
- Plugins → Assets: extends · Asset helper plugin builds on core loading
- Plugins → Audio engine: extends · Audio presets build on the audio runtime
- Plugins → Particles: extends · Particle presets wrap the particles system
- Plugins → Backends: adds overlay · Debug overlay integrates with rendering surfaces
- Game app → Engine API: uses · Sample app boots through the engine API
- Game app → Game scene: hosts · Application entry delegates to the game scene flow
- Game scene → World layer: uses · Gameplay scene builds on world and rendering assets
- Demos → Engine API: demonstrates · Demos show direct embedding of the engine in HTML pages
- Docs → Engine API: describes · Documentation explains the public bootstrap and runtime model
- Build & CI → Docs: supports · Tooling generates docs and release artifacts
- Build & CI → Render utils: embeds font · Build script feeds embedded font assets to rendering
