0.0.7 • Published 3 years ago

moonoom v0.0.7

Weekly downloads
5
License
ISC
Repository
gitlab
Last release
3 years ago

Usage: see demo.js file (const {Engine, Entity, Query} = require('moonoom'))

CDN: https://unpkg.com/moonoom (const {Engine, Entity, Query} = moonoom)

Design

data / entities
  • shorthand component access: entity.component.property, player.health.value
  • can have many of one component: entity.component$[2].property, player.debuff$[2].type
  • components can have components: entity.component.component2.property, player.arm.equipment.armour
systems / engine
  • systems are added once: engine.add('systems', ...yourSystems.map(s=> (...args)=>s.update(args))
  • systems are categorized by name, so systems can be run at differing intervals, for example logic or render loops being separate: engine.update('render', renderer)
  • systems added function should expect the first parameter to be the engine and subsequent to be parameters sent in at the update call: (engine, renderer){} for the above call for example
query
  • search with AND and/or OR
  • even depth arrays (starting at 0) are AND queries, odd are OR
  • example: ['hat', ['pants', 'shorts'], 'shirt'] = get anyone wearing hat, shirt, and (pants or shorts)
  • can exclude found entities by the same logic
  • can use wildcard * for component of any name, example if you want all entities that have armour on a body part: body.*.armour
  • can use wildcard ** for zero or more components of any name, example if you want all entities that have anything of steel: **.steel

example, system has entity.arm.armour.steel

engine.get('arm.armour') //gets all entities that have armored arm
engine.get('*.armour') //gets all entities that have something armoured
engine.get('**.steel') //gets all entities that have anything of steel

engine.search(['*.armour'], ['*.armour.steel'])
//gets all entities that have something armoured, but the armour isn't steel

API

Component

Any class instanced object. Will be named/referenced as its constructor name, in camelCase. Your original instance will be wrapped in a proxy, so === won't work unless you access the component off an entity first.

class Position{
	constructor(x, y){
		this.x = x
		this.y = y
	}
}

Entity

Bag of components and some convenience methods.

create(...componentsOrArray)

  • ...componentsOrArray any variable number of instanced Component, or arrays of instanced Components. Use arrays if you want the first component in the array to have all the subsequent components.
  • returns Entity instance
const entity = Entity.create(
	new Position(0, 0),
	[new Body(), new Torso(), new Arm(), new Arm(), new Leg(), new Leg(), new Head()]
	[new Bag(),
		[new Sword(), new Steel()]
	]
)

wrap(base, ...components)

  • base object will have all the Component attached to it. Equivalent to the arrays in create, but only makes one entity. Used for making one component have a set of other components.
  • returns Entity instance
collideds.forEach(collided=> entity.add(Entity.wrap(new Collided(), collided)))
//searchable by engine.get(collided.entity.point), if collided object had a point component

attach(engine)

  • attaches entity to the given Engine, must be done for an entity to "exist". Cannot attach to multiple engines.
  • returns the Entity instance

dettach()

  • dettaches entity from engine, if it had one
  • returns true or false if it had an engine to dettach from

add(...components)

  • adds components to this entity & its engine (if exists)
  • ...components any variable number of instanced Component
  • returns Entity instance wrapped Components, with a proxy around them. Can use this for ===.

remove(...componentsOrNames)

  • removes components from this entity & its engine (if it exists)
  • ...componentsOrNames any variable number of instanced Component or their camelCase names - if instance is given, removes strict equal match - if name is given, removes first component with the name

has(componentQuery)

  • componentQuery Component camelCase names, but also accepts . for separator, * for one component of any name, and ** for zero or more components. Example: body.arm.*.steel
  • return boolean true or false if exists on this entity

shorthand usage/proxy

const entity = Entity.create(
	new Position(0, 0),
	new Velocity(1, 1),
	new Velocity(1, 2),
	new Velocity(2, 2)
)

entity.position // {x: 0, y: 0}
entity.velocity // {x: 1, y: 1} // gets first velocity
entity.velocity$ // [{x: 1, y: 1}, {x: 1, y: 2}, {x: 2, y: 2}]
entity.position$ // [{x: 0, y: 0}]

delete entity.velocity // deletes first velocity
entity.velocity$ // [{x: 1, y: 2}, {x: 2, y: 2}]

delete entity.velocity$ // deletes all velocity
entity.velocity$ // []
entity.velocity // undefined

//you can also shorthand wrap components
entity.add(new Head())
entity.head.add(new Helmet()) //components after being added are essentially entities
//or entity.add(new Head())[0].add(new Helmet())

Engine

Bag of searchable entities & categorized systems.

add(category, ...systems)

  • category name of systems. Can only be added once.
  • ...systems any variable number of functions that want to be called every update of this engine, receiving engine, ...args

update(category, ...args)

  • category name of systems to call
  • ...args anything you want to propagate to systems

get(...componentQueries)

  • ...componentQueries any variable number of Component camelCase names, but also accepts . for separator, * for one component of any name, and ** for zero or more components. Example: engine.get('body', 'velocity', 'body.legs', '*.jets')
  • search with AND and/or OR
  • even depth arrays (starting at 0) are AND queries, odd are OR
  • example: ['hat', ['pants', 'shorts'], 'shirt']: get anyone wearing hat, shirt, and (pants or shorts)
  • returns array of Entity

search(include, exclude)

  • like query but one use

query(query)

  • query a Query instance to run on this engine
  • returns array of Entity that match query

create(...componentsOrArrays)

  • shorthand for Entity.create(...componentsOrArrays).attach(engine)

Query

constructor([include], [exclude])

  • include optional, if omitted will get all entites. Component queries: any variable number of Component camelCase names, but also accepts . for separator, * for one component of any name, and ** for zero or more components. Example: new Query(['body', 'velocity', 'body.legs', '*.jets'])
  • search with AND and/or OR
  • even depth arrays (starting at 0) are AND queries, odd are OR
  • example: ['hat', ['pants', 'shorts'], 'shirt']: get anyone wearing hat, shirt, and (pants or shorts)
  • exclude optional. Same as include but excludes the matches

search(engine)

0.0.7

3 years ago

0.0.6

4 years ago

0.0.5

5 years ago

0.0.4

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago