Skip to content
This repository has been archived by the owner on Dec 13, 2022. It is now read-only.
Eric McDaniel edited this page Sep 10, 2021 · 7 revisions

Welcome to the harmony-ecs wiki!

Harmony is a small, archetypal ECS focused on performance and compatibility. Harmony aims to be one of the fastest pure-JavaScript ECS implementations with support for multiple component storage types.

Getting Started

Let's get started with Harmony by building a small "game" with pseudo-code where two turrets shoot projectiles at each other.

First, install Harmony with your package manager of choice.

npm i harmony-ecs

Then, make a world, and specify the number of entities which might exist in that world.

import { makeWorld } from "harmony-ecs"

const world = makeWorld(1_000_000)

Define the types of data an entity might have in your game.

import { makeSchema, formats } from "harmony-ecs"

const Vector2 = { x: formats.float64, y: formats.float64 }
const Health = makeSchema(world, formats.uint32)
const Gunner = makeSchema(world, { fireRate: formats.float64, lastFire: formats.float64, power: formats.float32 })
const Velocity = makeSchema(world, Vector2)
const Transform = makeSchema(world, { position: Vector2, rotation: formats.float64 })
const Projectile = makeSchema(world, { damage: formats.float64 })
const Allegiance = makeSchema(world, formats.uint32 )

Make some entities.

import { makeEntity } from "harmony-ecs"

const Turret = [Transform, Allegiance, Gunner, Health] as const
const Bullet = [Transform, Allegiance, Projectile, Velocity] as const

makeEntity(world, Turret, [
  // transform
  { position: { x: -10, y: 0 }, rotation: Math.PI * 2 },
  // allegiance
  1,
  // gunner
  { fireRate: 1, lastFire: 0, power: 10 },
  // health
  100,
])
makeEntity(world, Turret, [...])

Define some queries.

import { makeQuery } from "harmony-ecs"

const turrets = makeQuery(world, Turret)
const bullets = makeQuery(world, Bullet)

Write some logic!

import { makeEntity } from "harmony-ecs"

for (let i = 0; i < turrets.length; i++) {
  const [entities, [t, a, g]] = turrets[i]
  for (let j = 0; j < entities.length; j++) {
    fire(world, t[j], a[j], g[j])
  }
}

for (let i = 0; i < bullets.length; i++) {
  const [e, [t, , , v]] = bullets[i]
  for (let j = 0; j < e.length; j++) {
    move(t[j], v[j])
  }
}

// iterate each bullet
for (let i = 0; i < bullets.length; i++) {
  const [be, [bt, ba, bp]] = bullets[i]
  for (let j = 0; j < be.length; j++) {
    // iterate each turret
    for (let k = 0; k < turrets.length; k++) {
      const [te, [tt, ta, , th]] = turrets[k]
      for (let l = 0; l < te.length; l++) {
        // check for un-allied turret-bullet collision
        if (ta[l] !== ba[j] && intersects(tt[l], bt[j])) {
          applyProjectile(world, bp[j], th[l], be[j], te[l])
        }
      }
    }
  }
}
Clone this wiki locally