Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

663 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Opal

Opal Engine

Opal is a browser-based 2D game engine with an integrated editor. Open a tab, sign in, and build — no install and no client build step for game authors. Behavior is authored with Object Flow / Scene Flow (Blueprint-style node graphs), objects use a Unity-like component model, characters can be rigged in Skeleton Studio, and art/audio are prepared in dedicated baker workspaces (Art Canvas, Sound Canvas). Games run in the browser and publish to the arcade, or export as .opal bundles / static standalone players.

Use it: opal-engine.com · Docs: opal-engine.com/docs · Arcade: opal-engine.com/arcade

Opal Editor


Getting Started

Make games (normal path)

Open opal-engine.com/create, sign in, create a project, and start editing. Projects save to your account, follow you across machines, and publish to the arcade when you're ready.

Develop the engine

npm run dev            # editor on :5173 (binds 0.0.0.0 for LAN)
npm run dev:local      # same, bound to 127.0.0.1 only
npm test               # Node unit suite (src/game + src/app + server tests)
npm run build:player -- path/to/game.opal   # static editor-free player → dist/

Open http://127.0.0.1:5173/ (or your machine's LAN address on port 5173). Local/dev builds persist through the Node server's data folder (.opal-data/). Without a server API, the editor falls back to IndexedDB.

On a tablet on the same network, open the computer's LAN address; Safari's Add to Home Screen works well for a full-screen editor session.

Mode How you reach it Storage Best for
Hosted opal-engine.com/create Account-backed server Daily building, publishing, arcade
Local dev npm run dev Server data folder Engine development, LAN testing, bg-removal tooling
Static / offline Editor without /api IndexedDB Offline editing (no account publish)

Documentation

User manual, component guides, and reference live at opal-engine.com/docs. Locally:

npm run docs:dev          # Author docs with live reload
npm run docs:build:local  # Build static docs for /docs/ beside the editor

Run docs:build:local once so /docs/ works alongside npm run dev.

Architecture for contributors: docs/ARCHITECTURE.md — vanilla ES modules (no bundler for the editor), layered core < runtime < {behavior, project} < editor < app, with an import-boundary guard so runtime never imports editor (the standalone player depends on that).

Production ops: DEPLOY.md and OPAL_SERVER_RUNBOOK.md cover the self-hosted box (Fedora mini-desktop + Cloudflare Tunnel), auth, env vars, and npm run deploy. Pushing to main does not update the live site — ship with npm run deploy on the box.


Editor Workspaces

The top bar switches what you're editing. The stage and panels adapt to the active workspace:

Workspace Primary use
Arrange Scene layout — hierarchy, transform gizmo, inspector, assets
Object Flow Per-object visual scripts
Scene Flow Scene / project rules, startup, win/lose, transitions
Motion Keyframe clips + Motion Machine state machines
Sound Sound Canvas — compose and bake WAV library assets
Art Art Canvas — slice sheets / assemble frames, bake .ssb bundles
Rigging Skeleton Studio — bones, slots, IK, meshes, skins, clips
Components Browse built-ins and author project components
Scripts Project JavaScript helpers / behavior scripts
UI In-game HUD, menus, buttons, labels, layout

Play mode runs input, physics, Flow, animation, audio, components, and UI in the viewport (or fullscreen). Stop discards the play session and returns to editing.

Debugging: Stats overlay, live Flow overlay, Problems panel, editor console, and Graph Explorer (workbench Graph dock — scene hierarchy, events, prefab anatomy, asset dependencies, component map, runtime trace).


Visual Scripting (Object Flow & Scene Flow)

Every object can carry event-driven node graphs — tap, drag, drop, rub, enter area, collision, scene start, and more — and you build behavior by wiring nodes together. Execution flows along white wires; data flows along typed colored wires. You plug values into parameter ports the same way Unreal Blueprints do.

Many fields accept = expressions (for example =self.hp + params.amount on component params). Prefer Get/Set variable nodes for GameState; UI bindings read project variables as self.score.

Scene Flow is the same system at scene/project scope: transitions, win conditions, global variables, timers, and startup logic.

The node catalog grows as you attach components — each component's actions, conditions, and events appear as nodes you can drop into a graph. Project components and scripts can extend that catalog further.


Component System

Opal uses a typed component model. Attach built-ins from the inspector, configure fields, and call their actions/conditions from Flow. Components declare lifecycle hooks (onAttach, onDetach, onTick, play start/end) and can require other components (for example, Health Bar pulls in Health).

Built-ins (current)

Category Components
Core Motion, Sprite Renderer, Sprite Animator, Sorting Group, Interactable, Tappable, Draggable, Drop Zone
Control Platformer Controller, Top-Down Controller, Side-Scroller Controller, AI Mover
Combat Health, Stats, Health Bar, Ability Cooldown, Combat Action, Turn Queue, Team, Hazard
Items Inventory, Pickup
Logic Timer, Spawner, Projectile
Physics (2D) Rigid Body 2D, Collider 2D, Joint 2D, Ragdoll
Scene Scene Camera

Full field/action/event reference: docs/components/built-in-reference.md (also on the live docs site).

Project components

Author custom components in the Components workspace (Component Studio): fields, events, actions, and conditions via a step-based action builder (set field, call component, emit event, if/else, for each) or inline script bodies. Project components save with the project and register at load beside the built-ins.


Physics

2D physics is first-class and backed by Rapier (@dimforge/rapier2d-compat) when available. Typical setup:

  • Collider 2D — shape (box, circle, capsule, …), sensor/trigger mode
  • Rigid Body 2D — dynamic / fixed / kinematic body
  • Joint 2D — constraints between bodies
  • Ragdoll — skeleton-driven soft bodies where configured

Collision and sensor events feed Object Flow / Scene Flow. Scene-level physics tuning lives on the scene. See docs/manual/physics-and-collisions.md and docs/physics.md.


Motion, Art Canvas & Skeleton Studio

Motion workspace

Sprite / transform keyframe animation — position, rotation, scale, opacity — with onion skinning, easing, clip looping, scrubbing, and a dope sheet. Motion markers can fire sounds, VFX, shake, and speech at the playhead.

The Motion Machine builds state machines over clips: states (each backed by a motion or skeleton clip), inputs (bool / number / trigger), and transitions (crossfade, on-complete, triggers). Regular motion clips and Skeleton Studio clips share the same machine on an object.

Sprite Animator plays frame sequences (including .ssb bundles from Art Canvas) as a component.

Art Canvas

The Art workspace is a frame-animation baker (not a realtime sub-rect renderer). Slice sprite sheets, assemble loose sprites, preview timing, register frames, bake variants, and save reusable .ssb sprite sequence bundles to the library. Consume them from the asset library or Object Flow (Sprite Sequence). The graph persists on the project record (project.artGraph).

Skeleton Studio (Rigging)

Bone-based character animation inspired by Spine:

  • Build bone hierarchies (bone, pose, bind, IK, mesh, weights tools)
  • Attach art through slots; multiple skins with swappable attachments
  • IK constraints — tip + target, chain solves automatically
  • Region → mesh conversion and painted vertex weights
  • Animate bones, IK targets, slot attachments, colors, draw order, and mesh vertices on a dopesheet with easing
  • Save finished characters as reusable character assets
  • Drive skeleton clips from the Motion Machine alongside regular motion clips

Setup / Animate mode mirrors Spine's workflow: rig in Setup, pose and key in Animate.


Sound Canvas & Audio

Audio clips are library assets (there is no separate scene-local clip registry). Import WAVs via Add → Sounds, or bake them in Sound Canvas.

Sound Canvas (Sound workspace) is an audio baker — sibling to Art Canvas. Compose from Sample / Mic / Tone / Noise nodes, shape with a processor chain (trim, gain, fade, pitch, reverse, lofi, filter, echo, reverb, normalize, mix, variation), preview, and bake to 16-bit stereo WAV library assets. Baker only: it never runs in the player and never binds onto scene objects. The graph persists on the project (project.soundGraph).

Playback paths:

  • Play Audio Flow nodes
  • Motion markers (sound: / sfx:)
  • Scene music (scene.audio — music asset + volume), which also plays in the standalone player on boot and scene changes

UI, Variables & Prefabs

UI workspace. Author in-game HUDs and menus (panels, text, buttons, bars, sliders, images) with layout, anchors, styling, and bindings to GameState / object state. UI is game content, not editor chrome.

GameState & object variables. Typed variables (number, bool, text) live in two places: project-wide GameState (persists across scenes; Variables panel in the top bar) and per-object variables (inspector Variables card). Flow, expressions, UI bindings, and components read and write them.

Prefabs. Save configured objects (components, motion, Object Flow, children) as reusable blueprints in the asset library. Place from the library or spawn at runtime; per-instance overrides with revert. See docs/prefabs.md and docs/manual/prefabs-and-spawning.md.


Asset Studio, VFX & Speech

Asset Studio (Cutout Tool). Crop, cut out backgrounds, add padding, apply outline or shadow, and save finished assets to the library. Background removal runs locally through a Python / platform backend when the server has models installed (BiRefNet variants, ISNet, U2-Net, BRIA RMBG-2.0, BEN2, or Apple Vision on macOS). Crop / padding / outline / shadow still work without removal models.

VFX. Built-in particle presets (sparkle, smoke, bubbles, magic, confetti, fire, splash, …) triggered from Flow or motion markers, with position, count, duration, and color controls.

Speech. Speech / say bubbles from Flow actions and motion markers (speech: / say:), drawn over objects at runtime.


Multiplayer

Optional WebSocket rooms sync objects and network Flow events across clients. Deploy the Cloudflare Worker in workers/opal-room/, paste the URL into the editor Share panel, and connect with a shared room code. See docs/manual/multiplayer.md and workers/opal-room/README.md.


Storage, Publishing & Standalone Player

Scenes and projects autosave as you work.

Path What it does
Publish to Arcade Hosted portal → public /g/<slug> and /play/<slug> pages (remix optional)
Export Game Full .opal project backup (assets + scenes + GameState + …)
Export Scene One scene as JSON
npm run build:player -- game.opal Static editor-free player folder from an exported .opal

On opal-engine.com, projects save to your account. Local/dev projects save through the server data folder; without a server API the editor uses IndexedDB. Account login, cross-device storage, arcade publish, and background-removal tooling need the server API; IndexedDB editing and static players do not.


Project Layout

Path Purpose
index.html Editor shell
player.html Standalone player shell
server.cjs Zero-dependency Node server — auth, projects, scenes, assets, publishing, background removal
src/main.js Browser entry (boots createEditorApp())
src/app/ Editor composition root (createEditorApp, bootstrap, frame loop, phases)
src/player.js Standalone player entry (editor-free runtime)
src/game/ Engine — runtime, components, physics, flow/rules, motion, skeleton, UI runtime, audio, VFX, scene editor, studios, persistence
src/game/physics/ Rapier-backed 2D physics runtime
src/game/components/ Component define/host/registry + built-ins + Component Studio
src/game/flow/ + src/game/rules/ Node-graph engine + behavior model/runner
src/game/scene-editor/ Editor UI (inspector, hierarchy, commands, canvases, …)
src/game/graph-explorer/ Graph Explorer workbench (relationship / trace views)
docs/ User manual and reference (VitePress → /docs/ on the live site)
bundled/ Starter assets and demo scenes seeded for new users
workers/opal-room/ Cloudflare Worker + Durable Object for multiplayer rooms
tools/ Background-removal scripts (Python / Swift Vision)
scripts/deploy.sh Production deploy on the opal box (npm run deploy)

Layer map and dependency rules: docs/ARCHITECTURE.md.


Contributing

Opal is MIT-licensed and open to contributions. Bug reports, feature ideas, and pull requests are all welcome.

  1. Fork the repository.
  2. Create a feature branch.
  3. Run npm test (and targeted suites as needed).
  4. Commit your changes.
  5. Push and open a pull request.

Contributor notes that pay for themselves: ground claims in the current source (not old roadmap docs), prefer node --test + the existing harnesses over manual preview poking, and keep runtime free of editor imports. See CLAUDE.md for local footguns and verification habits.

See LICENSE for details.

About

Vanilla-JS game engine for web games

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages