Skip to main content

Architecture

Envy is organized into a small set of focused layers.

1. Core ECS

The ECS core lives in src/core.

  • src/core/component/ contains component definitions and base classes
  • src/core/system/ contains the system contract
  • src/core/world/ contains the runtime world

The main types are:

  • World, which stores entities, components, and systems
  • Entity, which exposes component operations directly
  • Component, which is the base class for ECS data objects
  • System, which defines update logic executed on each step

2. Three.js integration

The Three.js layer lives in src/three.

  • src/three/components.ts contains shared render-side components
  • src/three/systems/ contains the Three.js-specific systems
  • src/three/world/ contains the single-scene bootstrap helper
  • src/three/scenes/ contains the multi-scene manager
  • src/three/canvas/ contains the renderer canvas manager

The main types are:

  • TransformComponent, which stores position, rotation, and scale
  • Object3DComponent, which wraps a Three.js Object3D
  • TransformSyncSystem, which queries TransformComponent and Object3DComponent
  • SceneAttachmentSystem, which attaches and detaches Object3D instances
  • ThreeSceneManager, which manages multiple independent scenes
  • ThreeCanvasManager, which controls canvas size, ratio, and centering

Execution flow

  1. Create a World or a ThreeSceneManager
  2. Create an entity
  3. Instantiate components and attach them with entity.addComponent(...)
  4. Register the systems you need
  5. Let systems query the world with world.query(...)
  6. Call step(deltaTime) or update(deltaTime)

Philosophy

The library favors a small and explicit API.

  • no hidden magic
  • no unnecessary abstraction layers
  • a data model that is easy to test
  • systems that are easy to compose

The goal is to keep the framework modular so you can reshape behavior by adding or moving components instead of rewriting whole objects.

In practice, that means you should be able to move an object's behavior with just a few line changes, while keeping the code simple, maintainable, and reusable.