Jump to content

makr.js — An Entity-Component-System engine


ooflorent
 Share

Recommended Posts

  • 3 weeks later...

Hello everyone,

 

I'm currently working makr v2. It is an entire rewrite of the library and still focus on blazing fast execution.

It heavily relies on ES6 features. Here is a comparison between system declaration in v1 and v2:

// Beforefunction MovementSystem() {  makr.IteratingSystem.call(this)  this.registerComponent(ComponentRegistry.get(Position))  this.registerComponent(ComponentRegistry.get(Motion))}util.inherits(MovementSystem, makr.IteratingSystem)MovementSystem.prototype.process = function(entity, dt) {  var position = entity.get(ComponentRegistry.get(Position))  var motion = entity.get(ComponentRegistry.get(Motion))  position.x += motion.dx * dt  position.y += motion.dy * dt}// Afterclass MovementSystem extends IteratingSystem.use(Position, Motion) {  updateEntity(entity, dt) {    let [position, motion] = entity.get(Position, Motion)    position.x += motion.dx * dt    position.y += motion.dy * dt  }}

World creation:

// Beforevar world = new makr.World()world.registerSystem(new MovementSystem())world.registerSystem(new CollisionSystem())world.registerSystem(new RenderingSystem())// Afterlet world = new Makr({  types: [Position, Motion, Body, Display],  systems: [    new MovementSystem(),    new CollisionSystem(),    new RenderingSystem()  ]})

Major changes:

  • Uses ES6
  • Cleaner API
  • Tests
  • Browserify support
  • No more singletons
  • ComponentRegistry is now automatically called
  • and more!

It would be great to hear some feedback from you guys!

Cheers!

Hey, discovered your project after searching for CES for javascript. I like the emphasis you put on performance since I'm making a multiplayer game. How's the development going for v2? Any idea when it will be ready since I'd like to use it for my game?

Link to comment
Share on other sites

Hey, discovered your project after searching for CES for javascript. I like the emphasis you put on performance since I'm making a multiplayer game. How's the development going for v2? Any idea when it will be ready since I'd like to use it for my game?

 

v2 is almost done. The API is finalized but I have to write the documentation, examples and some benchmarks.

If you are interested I could send to you an alpha preview. Performance are good but need a few more tweaks.

 

 

@ooflorent: I have used your makrjs to make an ECS plugin for Phaser. See:

http://www.html5gamedevs.com/topic/11676-phaser-ecs-plugin/

Your makrjs overlay is simple and not intrusive, this a good point!

Be sure to update to makr v2 when it will be available.

Link to comment
Share on other sites

v2 is almost done. The API is finalized but I have to write the documentation, examples and some benchmarks.

If you are interested I could send to you an alpha preview. Performance are good but need a few more tweaks.

 

 

Your makrjs overlay is simple and not intrusive, this a good point!

Be sure to update to makr v2 when it will be available.

That would be nice! How would you like to send it?

Link to comment
Share on other sites

Hi, I have some news!

 

I have open-sourced v2 development branch. You can find it on GitHub (experimental/v2).

Warning: There are still a lot to do (tests, documentation, benchmarks, examples).

 

 

Why is there a v2? Wasn't v1 good enough?

While v1 was fast it was not so pleasant to use it. I have seen several games hacking makr to simplify the API but hitting really hard the perfs. v2 was done to prevent "wild" extensions of makr by providing a better API. Moreover it is faster than it was before!

 

What is different in v2?

Well, almost everything!

  • Component types are now automatically detected (no more ComponentRegistry)
  • Systems are gone (the developer can use whatever implementation he wants)
  • All internals

What are v2 limitations?

It cannot handle more than 32 components. Current implementation relies on a 32-bits integer to store component masks while v1 uses bit sets. This limitation may be removed in the future if it does not impact perfs to much.

 

I tried v2 but it seems broken...

The library is under active development and some features may be bloated. If you encounter an error or something, just drop an issue on GitHub and I'll fix that!

 

What will be v2 API?

EntityManager(...ComponentType: Function)  #create(): Entity  #get(id): Entity  #query(...ComponentTypes): Entity[]  #valid(id): BooleanEntity  #id: uint32  #mask: uint32  #valid: Boolean  #<T>add(component: T): T  #<T>remove(ComponentType: Function<T>): void  #<T>get(ComponentType: Function<T>): T  #<T>has(ComponentType: Function<T>): Boolean  #destroy(): void
Link to comment
Share on other sites

 

Hi, I have some news!

 

I have open-sourced v2 development branch. You can find it on GitHub (experimental/v2).

Warning: There are still a lot to do (tests, documentation, benchmarks, examples).

 

 

Why is there a v2? Wasn't v1 good enough?

While v1 was fast it was not so pleasant to use it. I have seen several games hacking makr to simplify the API but hitting really hard the perfs. v2 was done to prevent "wild" extensions of makr by providing a better API. Moreover it is faster than it was before!

 

What is different in v2?

Well, almost everything!

  • Component types are now automatically detected (no more ComponentRegistry)
  • Systems are gone (the developer can use whatever implementation he wants)
  • All internals

What are v2 limitations?

It cannot handle more than 32 components. Current implementation relies on a 32-bits integer to store component masks while v1 uses bit sets. This limitation may be removed in the future if it does not impact perfs to much.

 

I tried v2 but it seems broken...

The library is under active development and some features may be bloated. If you encounter an error or something, just drop an issue on GitHub and I'll fix that!

 

What will be v2 API?

EntityManager(...ComponentType: Function)  #create(): Entity  #get(id): Entity  #query(...ComponentTypes): Entity[]  #valid(id): BooleanEntity  #id: uint32  #mask: uint32  #valid: Boolean  #add(component: any): any  #remove(ComponentType: Function): void  #get(ComponentType: Function): any  #has(ComponentType: Function): Boolean  #destroy(): void

Great news! Will try it out sometime soon and perhaps contribute if I find issues/needs.

 

Btw, this is just a thought but instead of having to do

if (entity.has('componentName')) {

    entity.get('componentName')

}

 

wouldn't it be cleaner just doing:

var component = entity.get('componentName'); //returns false if not found

if(component){

    //do stuff

}

 

although this is already possible since it would return undefined if nothing was found and the condition would be falsey, so it might be unnecessary making it explicit. You would avoid the extra function calls although in cases where you'd have more failing checks it could be slower I suppose.

Link to comment
Share on other sites

V2 does not identify components using strings but using their constructor, resulting in a huge speedup.

There are two ways of checking if a component exists:

function Position(x, y) {  this.x = x  this.y = y}// Using Entity#hasif (entity.has(Position)) {  // ...}// Using Entity#getvar pos = entity.get(Position) // `null` if not assignedif (pos) {  // ...}
Link to comment
Share on other sites

 

V2 does not identify components using strings but using their constructor, resulting in a huge speedup.

There are two ways of checking if a component exists:

function Position(x, y) {  this.x = x  this.y = y}// Using Entity#hasif (entity.has(Position)) {  // ...}# Using Entity#getvar pos = entity.get(Position) // `null` if not assignedif (pos) {  // ...}

Yeah it was just an example, but good to hear about the speedup nevertheless.

I suppose it doesn't matter having the extra method there for people who need it for whatever reasons.

Link to comment
Share on other sites

I suppose it doesn't matter having the extra method there for people who need it for whatever reasons.

 

I don't think I would add a way to identify components using strings.

Is there any reason to use them? There a so many drawbacks...

  • Poor minification
  • No existence check if mistyped
  • Not coupled with the component type
Link to comment
Share on other sites

 

I don't think I would add a way to identify components using strings.

Is there any reason to use them? There a so many drawbacks...

  • Poor minification
  • No existence check if mistyped
  • Not coupled with the component type

 

I was talking about the has method on the entities. I agree there's no good reason for the strings ;).

Link to comment
Share on other sites

One thing I would like to see from makr v1 in v2 would be the group functionality. Say I want to get all entities with rigid bodies except the player entities. This isn't possible without doing ugly if checks on the entities (unless I've missed something). Of course I could implement this separately, but it would be cleaner simply having it included in the EntityManager.

Link to comment
Share on other sites

  • 2 weeks later...

Hi ooflorent,

 

I'll be trying out your new version this week. It looks VERY promising. The api looks clean and I like your coding style. I'll report back once I got my hands on this. Thank you so much for this!

Such a nice comment!

 

I was quite busy the last few weeks so the release is not ready (what a shame!).

I can't wait to hear your feedback. Feel free to PM me if you have any questions or encountered issues.

Link to comment
Share on other sites

Why another entity component engine?

ImpactJS is ec, PandaJS is ec why re-invent the wheel????

If the wheel is square it has to be reinvented.

Jokes aside, even if they weren't fullblown game engines I highly doubt as much thought and care has been put into their ECS part of the engine from a performance standpoint.

It would be more accurate to call makr a library, and I think ooflorent has done a fantastic job on keeping the library user friendly without sacrificing performance.

Link to comment
Share on other sites

 

I have released 2.1.0 on NPM.

Still to be done:

  • Examples
  • Benchmarks against other ECS
  • Full documentation (code, API, site)

 

Sweet!

I ran the benchmarks on my machine and got these results:

 

                      Components
     622,440,815 op/s » count
      39,752,941 op/s » index
      33,749,710 op/s » mask
 
                      ContiguousStorage
      18,873,964 op/s » #get
      21,130,211 op/s » #set
      21,387,212 op/s » #delete
      21,413,487 op/s » #destroy
         819,545 op/s » #resize
 
 
  Suites:  2
  Benches: 8
  Elapsed: 11,387.23 ms
Link to comment
Share on other sites

 

I have released 2.1.0 on NPM.

Still to be done:

  • Examples
  • Benchmarks against other ECS
  • Full documentation (code, API, site)

 

I added some additional benchmarks and made a pull request. Pretty good results, the biggest bottleneck seems to be the query method when there's a large amount of entities.

Link to comment
Share on other sites

  • 3 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...