Catalog npm
Back to packageRELEASE DETAILS

0.6.3

npm

1681-engine

A 2D game engine on PixiJS 8 for any art style: scenes and a fast ECS, a fixed-step loop, asset loading, Tiled maps, sprite animation, input actions, camera follow, audio and deterministic, server-replayable movement, plus Dither, an optional pixel-art mo

2decsgame-enginegamedevmultiplayerpixel-artpixijstiledtypescript
Published18 Oct 2026
Direct dependencies19
Transitive dependenciesNot calculated

README

Current package documentation

1681 Engine

CI Docs License: MIT

A 2D game engine for the web, built on PixiJS 8 and written in TypeScript, for games in any art style: hand-drawn, HD, vector or pixel art. Pixel art gets a module of its own, Dither.

It grew out of a shipped online action RPG, so its pieces were made for a real game under real load: a fast ECS, a fixed-step simulation a server can replay bit for bit, Tiled maps, input that works the same on keyboard, gamepad and touch, and for pixel art, effects painted on the world's own pixel grid and dithered lighting.

import { Engine, Scene, defineComponent, system } from '1681-engine';

const Position = defineComponent<{ x: number; y: number }>('Position');

class Level extends Scene {
  override onEnter() {
    this.world.spawn([Position, { x: 0, y: 0 }]);
    this.world.addSystem(
      system('drift', 'fixed', ({ world, dt }) => {
        world.each(Position, (_e, p) => (p.x += 30 * dt));
      }),
    );
  }
}

const engine = await Engine.create({ parent: document.body });
await engine.scenes.replace(new Level());

Status: 0.x, early. The API will change between minor versions until 1.0. See CHANGELOG.md.

Entry points

ImportForHolds
1681-engineevery 2D gameengine, scenes, ECS, rendering core, assets, Tiled maps, animation, input, camera, rig maths, audio, networking
1681-engine/pixelpixel-art gamesPixelLayer, pixelPaint shapes, colour ramps, dithered Darkness lighting, Evaporation, sprite pixel tools
1681-engine/uigames with menus and a HUDcanvas widgets, focus, the pure layout maths, the DOM/React bridge (DomOverlay, createStore, InputShield)
1681-engine/postfxfull-screen effectsPostFx (a chain of filters, flashes, shockwaves, animated uniforms), bloom, vignette, colour adjust, chromatic aberration, CRT, pixelate, shockwave, and FxFilter to write your own in GLSL and WGSL
1681-engine/mobilea phone app on CapacitorcapacitorConfig, the Android back button (BackStack), safeAreaInsets, keepScreenOn, nativeBuildOf; Capacitor is handed in, never imported
1681-engine/reacta UI written in ReactPanel, TabStrip, SplitPane, Select, Tooltip/TitleTips, ConfirmDialog, ChoiceDialog, Slider, PixelImage, Glyph, UiProvider, useStore, themed by CSS custom properties (baseCss)

The core never imports the pixel module (a test holds it to that), so a game that does not use it does not ship it. React and React DOM (19) are optional peer dependencies needed only by 1681-engine/react; nothing else imports React. Start a pixel-art game with Engine.create({ pixelPerfect: true }): sharp textures and a camera that lands on whole pixels. Without it, textures are smooth and drawn at the screen's own density.

Features

AreaWhat you get
EngineEngine (canvas, renderer, frame loop), a stack of Scenes (replace, push, pop, async loading), a fixed-step FixedLoop with interpolation and spiral-of-death protection, typed EventBus.
ECSWorld on sparse sets, prefabs with variants (definePrefab, PrefabLibrary from data): typed components, query, allocation-free each, numeric components in typed-array columns (defineFields) walked through a cached slots() list — a step over 50,000 bodies in 0.1 ms. Systems in fixed and frame phases, recycled ids with generations, error isolation.
AssetsAssetLoader: images, sprite sheets, JSON, text and Tiled maps with their tilesets, with progress and a concurrency limit.
TilemapsTiled JSON maps (CSV or base64 layers, groups, objects, properties, flipped tiles), drawn in culled chunks by TilemapView, with collision from a layer or a tile property.
AnimationAnimator clips (fps or per-frame durations, looping or finishing) and an animation system for sprites.
InputActions: named actions bound to keys, chords, gamepad buttons and sticks, and on-screen touch buttons, with per-step edges and analog values. Keymap rebinding of keys and pad buttons, InputCapture for "press a key", input recording and exact replay, AimGesture and TargetLock for touch, stick maths, touch detection. Guide
CameraZoom, bounds, shake, flash, and track with a soft follow that is the same at any frame rate, a deadzone and an offset.
RenderingStage with world and screen layers, display objects, tweens, timers, bitmap labels, a texture atlas that splits pages by the GPU's limit, guards that keep one bad frame from stopping the loop.
CharactersA 2D skeleton rig drawn by RigView from cut-out images or vector shapes, PosePlayer blending key poses with crossfades, and a built-in humanoid with 72 poses and ready clips (idle, walk, run, roll, slash, thrust, cast, throw, emotes).
LightLightLayer: smooth darkness with soft radial lights, colour washes and flicker (the pixel module has its own dithered Darkness).
AudioWeb Audio sound engine (synthesized recipes, recorded takes cleaned in a worker, voice limiting, distance muffling, panning), SpatialAudio for looping sounds placed in the world, and music: streamed tracks crossfaded and looped. iOS unlock handled. Guide
MultiplayerAn authoritative Room and its socket host for Node, a client Connection, PredictedMover (prediction and reconciliation over deterministic movement: in tests and in the example the server never has to correct it), InterpolationBuffer for everyone else, binary snapshots, clock sync, input validation and flood limits, cadence rules, bodies the server moves, interest management by distance and lag compensation for shots. A LobbyHost with rooms (host, codes, ready, chat, settings), a rating Matchmaker that keeps parties whole and balances teams, ready checks with decline lockouts, and a LobbyClient. Guide
Pixel art (/pixel)PixelLayer (thousands of pixel rects in one pooled texture), pixelPaint shapes shaded from hue-shifted ramps and faded by ordered dither, Darkness with dithered lamps and transient lights, Evaporation, the selective outline.
UI (/ui)Canvas widgets with keyboard and gamepad focus, the pure layout maths, and a DOM/React bridge laid over the canvas. Guide
React kit (/react)Windows, tabs, split panes, drop-downs, tooltips and dialogs that never overflow the screen, themed by --e1681-* properties. Guide
PhysicsPhysicsWorld: circles, boxes and convex polygons that turn when asked (contact points, torque, rolling), sensors, layers, kinematic platforms and spinners, one-way preSolve, raycasts, tiles merged into boxes with snag-free seams. Guide
Post-processing (/postfx)Bloom, vignette, colour grade and flash, chromatic aberration, CRT, pixelate, shockwaves; WebGL and WebGPU. Guide
ParticlesEmitter on one pooled ParticleContainer, curves over life, a shared budget that thins under reduced effects. Guide
NavigationA* findPath with reach, costs and end-only tiles, straightenPath, floodFill, nearestOpen; flow fields for crowds and steering (seek, arrive, separation, flocking). Guide
AIBehaviour trees shared by many agents, reactive composites that halt what they interrupt, a trace, trees from JSON. Guide
DialogueBranching scripts as data with conditions, variables, commands, translation and saves; a checker and a playground. Guide
SavesSaveStore slots with migrations, checksums and a backup, pluggable backends, Autosaver. Guide
TransitionstransitionTo with fade, crossfade and dithered wipe, Letterbox. Guide
LocalisationTranslator with the English source as key, contexts, plurals, live switching; extractStrings. Guide
AmbientDayClock, deterministic weatherAt and WeatherLayer, ColorGrade; in /pixel, NightShade, SwayProp, DitherVignette. Guide
Game feelPooled FloatingText for damage numbers, hit-stop, recoil and flash curves. Guide
LDtk and autotilingLDtk projects (IntGrid, auto-layers, entities with fields, world layouts, level files) read into the same tile map as Tiled; 4-bit and 47-tile blob autotiling that retiles only what an edit touched. Guide
Ambient lifeDrifting leaves, embers and ash, birds, butterflies, fireflies and chimney smoke, pooled and alive only in view. Guide
Desktop (/electron, /updates)File-by-file web patching by sha256, an OS-encrypted session store and a window lockdown for Electron; the update rules shared with phones. Guide
Mobile (/mobile)A Capacitor config with a game's defaults, the Android back button, the safe area, a screen kept on, the native build for over-the-air updates. Guide
DiagnosticsError capture, WebGL context loss, a boot watch, frame sampling, and a DebugOverlay with collision boxes. Guide

A React UI

import { createRoot } from 'react-dom/client';
import { ConfirmDialog, Panel, TitleTips, UiProvider, askConfirm, injectBaseCss } from '1681-engine/react';

injectBaseCss(); // the base stylesheet, first in <head>, so the game's own CSS wins
// theme it with custom properties: frames are 9-slice border-images the game draws
document.documentElement.style.cssText += `
  --e1681-font: 'My Pixel Font'; --e1681-accent: #f0c060;
  --e1681-frame: url(/ui/frame.svg); --e1681-frame-slice: 16 20 20 16 fill; --e1681-frame-width: 16px 20px 20px 16px;`;

createRoot(document.getElementById('ui')!).render(
  <UiProvider labels={{ cancel: 'Annuler', ok: 'OK' }}>
    <Panel title="Inventory" onClose={close} width={420}>…</Panel>
    <ConfirmDialog />
    <TitleTips />
  </UiProvider>,
);
if (await askConfirm('Drop the sword?')) drop();

Windows and dialogs are fitted into the screen by fitToViewport and placed in whole pixels; tooltips and the select's list by placeTooltip and listWidth. On a touch device (isTouchUi, or UiProvider touch) a Panel is a full-screen sheet and tooltips are off. Every word the kit prints is a prop or a labels entry with an English default.

Install

npm install 1681-engine pixi.js

pixi.js (8.6 or later) is a peer dependency. The package is ESM only and ships its TypeScript types. On a server (the multiplayer Room) it needs Node 22 or later.

The engine renders with WebGL 2 by default. Engine.create({ preference: 'webgpu' }) opts into WebGPU, which is experimental here: it falls back to WebGL where the browser lacks it, but has not been profiled the way the WebGL path has.

Documentation

https://phadec.github.io/1681-engine/ — the guide, the API reference and the examples running live.

The documentation site (guide, API reference generated from the source, live examples) is built with npm run docs:build and published to GitHub Pages by .github/workflows/docs.yml; npm run docs:dev serves it locally.

  • Getting started: an engine, a scene, entities and systems, assets, a Tiled map, input, the camera, a rigged character, light and music, and multiplayer, step by step.
  • Architecture: how the frame loop, scenes, ECS and rendering fit together, and the rules that keep it fast.
  • A page per module: input, physics, navigation, particles, game feel, ambient, transitions, post-processing, lobby and matchmaking, UI, React kit, localisation, saves, diagnostics and debug, behaviour trees, dialogue, mobile.
  • Examples, run with npm run dev:
    • top-down: a Tiled map, asset loading, an animated hero, input actions on keyboard, gamepad and touch, camera follow.
    • platformer: physics from a tile grid (crates, a moving platform, one-way planks, sensor coins), particles, a canvas HUD and pause dialog, a versioned save, scene transitions, two languages, rebindable keys and a debug overlay.
    • night-garden: smooth vector art, a rigged hero animated by blended poses, a lantern and fireflies in the dark.
    • pixel-dungeon: the pixel module: dithered torchlight, a carried light, slimes that evaporate into their own pixels.
    • ecs-stress: tens of thousands of bodies on typed-array components, with the frame rate and step time.
    • multiplayer: npm run example:server, then two tabs: prediction, reconciliation and interpolation.
    • physics-toys: bodies that turn (crates, balls, polygons, a spinning bar) under bloom, a vignette and the other effects.
    • lobby: npm run example:lobby, then the page: rooms, codes, ready flags, chat, the queue and a ready check.
    • walk-room: the smallest whole game, with pixel effects.
    • dialogue: a playground for dialogue scripts, checked as they are typed and played with their variables in view.

Develop

npm install
npm run dev        # examples at http://127.0.0.1:5180/
npm test           # unit tests under node
npm run typecheck  # sources and tests
npm run bench      # ECS benchmark
npm run build      # dist/: both ESM bundles and their .d.ts files
npm run check      # typecheck, test and build, as CI runs it
npm run docs:dev   # the documentation site, with the API reference and examples

Contributions are welcome: read CONTRIBUTING.md first.

License

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 22

Native requirements
19 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
ws
Environment
{
  "local_name": "ws",
  "alias": false,
  "peer_metadata": null
}
^8.22.0development
tsx
Environment
{
  "local_name": "tsx",
  "alias": false,
  "peer_metadata": null
}
^4.20.5development
vite
Environment
{
  "local_name": "vite",
  "alias": false,
  "peer_metadata": null
}
^7.1.4development
react
Environment
{
  "local_name": "react",
  "alias": false,
  "peer_metadata": null
}
^19.3.0development
vitest
Environment
{
  "local_name": "vitest",
  "alias": false,
  "peer_metadata": null
}
^4.1.11development
pixi.js
Environment
{
  "local_name": "pixi.js",
  "alias": false,
  "peer_metadata": null
}
^8.21.0development
typedoc
Environment
{
  "local_name": "typedoc",
  "alias": false,
  "peer_metadata": null
}
^0.28.20development
@types/ws
Environment
{
  "local_name": "@types/ws",
  "alias": false,
  "peer_metadata": null
}
^8.18.2development
react-dom
Environment
{
  "local_name": "react-dom",
  "alias": false,
  "peer_metadata": null
}
^19.3.0development
vitepress
Environment
{
  "local_name": "vitepress",
  "alias": false,
  "peer_metadata": null
}
^1.6.4development
playwright
Environment
{
  "local_name": "playwright",
  "alias": false,
  "peer_metadata": null
}
^1.64.0development
typescript
Environment
{
  "local_name": "typescript",
  "alias": false,
  "peer_metadata": null
}
^5.9.2development
@types/node
Environment
{
  "local_name": "@types/node",
  "alias": false,
  "peer_metadata": null
}
^22.0.0development
@types/react
Environment
{
  "local_name": "@types/react",
  "alias": false,
  "peer_metadata": null
}
^19.3.0development
@types/react-dom
Environment
{
  "local_name": "@types/react-dom",
  "alias": false,
  "peer_metadata": null
}
^19.3.0development
typedoc-plugin-markdown
Environment
{
  "local_name": "typedoc-plugin-markdown",
  "alias": false,
  "peer_metadata": null
}
^4.13.1development
typedoc-vitepress-theme
Environment
{
  "local_name": "typedoc-vitepress-theme",
  "alias": false,
  "peer_metadata": null
}
^1.1.4development
@vitest/browser-playwright
Environment
{
  "local_name": "@vitest/browser-playwright",
  "alias": false,
  "peer_metadata": null
}
^4.1.11development
react
Environment
{
  "local_name": "react",
  "alias": false,
  "peer_metadata": {
    "optional": true
  }
}
^19.0.0peer
pixi.js
Environment
{
  "local_name": "pixi.js",
  "alias": false,
  "peer_metadata": null
}
^8.6.0peer
electron
Environment
{
  "local_name": "electron",
  "alias": false,
  "peer_metadata": {
    "optional": true
  }
}
>=28.0.0peer
react-dom
Environment
{
  "local_name": "react-dom",
  "alias": false,
  "peer_metadata": {
    "optional": true
  }
}
^19.0.0peer

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "shasum": "143c24c38b557089f123566f6748b2bee7b6c03b",
  "tarball": "https://registry.npmjs.org/1681-engine/-/1681-engine-0.6.3.tgz",
  "fileCount": 1006,
  "integrity": "sha512-BWDO/bx15aEwkFhG2uQmneMYuaqP2L3amn7QgskQZd3PSkYz0Q5xSHVkHRWeeq32r1uZdDFVOiwrnswPY6qFbg==",
  "signatures": [
    {
      "sig": "MEQCID9eEc9HU2nOb/E9zvcrF+vH1g43BYFUcsL1Tyzx1yreAiBrQm/Cj2TFZXtkh3szVeFnHI8acAZ4/WcAqtJG/LD2Xw==",
      "keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
    },
    {
      "sig": "MEQCICfwW43UodORXEO1LBUEhh9T/MooH+sCjLK6SV16FNCcAiAbgFsbP+ydsLtiIHuoB9h/cl7C1zNXzTWxXw+jf1dxnQ==",
      "keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
    }
  ],
  "attestations": {
    "url": "https://registry.npmjs.org/-/npm/v1/attestations/1681-engine@0.6.3",
    "provenance": {
      "predicateType": "https://slsa.dev/provenance/v1"
    }
  },
  "unpackedSize": 1872079
}

Repository

PENDING
phadec/1681-engine

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 18:16 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:8fbced9d52a2f00bfe0823562d201c4e5490ef0a8e39ca90b1dd441681cf3b0c

Other collected versions

0.6.819 Oct0.6.718 Oct0.6.618 Oct0.6.518 Oct0.6.215 Oct0.6.115 OctView all collected versions →