npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

aecs

v0.0.28

Published

An entity component system made with typescript.

Downloads

32

Readme

Awesome Entity Component System

An entity component system made with typescript.

Install

npm i --save aecs

Getting Started

To use the entity component system, you first must create an instance of Engine.

import { Engine } from "aecs";
const engine = new Engine();

Define your Components:

import { Component } from "aecs";

// Components can have custom constructors, but they must be able to be initialized
// with no arguments, because the engine creates the instances for you.
// Try not to save complex data types in your components
// due to the handling of references inside javascript

export class PositionComponent extends Component {
    public x: number = 0;
    public y: number = 0;
}

Create an Entity type:

import { Entity } from "aecs";

//can have a constructor but is not needed
//the type is basically only used for queries from your systems

export class PlayerEntity extends Entity {}

For the creation of your entities it makes sense to define a Prefab.

import { Prefab } from "aecs";

export class PlayerPrefab extends Prefab<PlayerEntity> { // <-- entityType needed
    private spawnX: number = 0;
    private spawnY: number = 0;

    protected init(): void {
        //code here runs only once for the creation of the prefab instance
    }

    public someSetterDefinedByYou(x: number, y: number): void {
        this.spawnX = x;
        this.spawnY = y;
    }

    public instantiate(): PlayerEntity {
        const positionComponent = new PositionComponent();
        positionComponent.x = this.spawnX;
        positionComponent.y = this.spawnY;

        return new PlayerEntity(<<<SOME_ID>>>, [positionComponent]);
    }
}

Finally a System is created to work with the entities and components

import { System } from "aecs";

//in this system we will instantiate a player and listen for keyboard inputs to move the player around

export class PlayerSystem extends System {
    private playerPrefab: PlayerPrefab;

    init(): void {
        this.playerPrefab = this.prefabManager.getPrefab<PlayerPrefab>(PlayerPrefab);
        this.playerPrefab.someSetterDefinedByYou(10, 10);
        this.ecm.instantiatePrefab(this.playerPrefab);
    }

    // we have multiple ways to query for components/entities
    run(delta: number): void {
        //query by id
        let playerEntityItem = this.ecm.getEntity<PlayerEntity>(<<<SOME_ID>>>)

        //query by entity type -> returns array
        let playerEntities = this.ecm.getEntites<PlayerEntity>(PlayerEntity);

        //query by a specific component + id
        let positionComponent = this.ecm.getComponent<PositionComponent>(PositionComponent, <<<SOME_ID>>>);

        //query all by component type -> returns array
        let positionComponents = this.ecm.getComponents<PositionComponent>(PositionComponent);

        if(some key pressed) {
            //do things with entities & components here
        }
    }
}

AECS is defined by multiple Worlds. Think of a world like a container which hold multiple prefabs & systems. So you could have for example a GameWorld and a MenuWorld etc. To get the engine running we need to define a world for our systems and prefabs to run.

import { World } from "aecs";

export interface WorldProperties {
    someValue: string;
}

export class SomeWorld extends World<WorldProperties> {
    init(): void {
        this.initPrefabs([
            new PlayerPrefab(PlayerEntity)  // needs the entity type
        ]);

        this.initSystems([
            new PlayerSystem(true)  // bool if active or not
        ]);
    }

    update(delta: number): void {
        this.callSystems(delta);    //in our loop we call all systems
    }
}

In the last step we add our created GameWorld to the engine and start it all up

engine.addWorlds([
    new SomeWorld({someValue: "someValue"})
]);
engine.setActiveWorld(SomeWorld);
engine.start(60);   // number of ticks we want to have per second

//alternative you can manually call the update loop with
//engine.update(deltaTime?: number);

Important!

When you build your project with webpack it is needed to the following option to your webpack.config.js, otherwise aecs will throw all sorts of errors during runtime!

optimization: {
    minimizer: [
        new ESBuildMinifyPlugin({
            keepNames: true
        })
    ]
},