Coder Social home page Coder Social logo

3mcd / harmony-ecs Goto Github PK

View Code? Open in Web Editor NEW
36.0 36.0 1.0 897 KB

A small archetypal ECS focused on compatibility and performance

Home Page: https://3mcd.github.io/harmony-ecs

License: MIT License

JavaScript 2.04% TypeScript 97.11% HTML 0.85%
binary ecs entity-component-system game-dev game-developement javascript object typescript

harmony-ecs's Issues

Strict build

Enable noImplicitAny and strict in tsconfig.json and put the fires out.

I :heart: this effort

Hey @3mcd!

First off, I recently read this blog post and super appreciate the shoutout and that you are also trying to bridge the synchronization gap between SoA and objects. I don't feel so lonely now ๐Ÿ˜…. Also, great job implementing archetypes! I still haven't had time to implement those.

Second, I was hoping that you would be willing to weigh in on an alternative way forward for the synchronization of data between SoA and objects that I drafted a short proposal for. As always, my focus is performance ๐ŸŽ๏ธ. I believe this method of synchronization can bring the most performance benefits and provides an extreme level of interoperable flexibility, but I am keen to get a wide variety of opinions on this. Let me know what you think!

Cheers ๐Ÿป

Predictive Systems

Overview

I recently helped port the fantastic prediction/reconciliation algorithm CrystalOrb from Rust to JavaScript. The JS port works very well (see a very rough demo here) but CrystalOrb's current design (see this issue) works best when most game logic is located in the World.step function. Furthermore, the CrystalOrb client maintains two separate (but complete) simulations, without exposing one as the source of truth for client-only physics (e.g. particle physics).

This design makes it a bit tricky to implement ECS alongside CrystalOrb, since ECS logic is traditionally implemented as small, pure-ish functions (in that they usually only modify a small subset of entities and components), and writing non-predictive code is a bit difficult without implementing an entire command/snapshot/interpolate workflow, or writing similar command logic around the CrystalOrb "protocol".

It would be awesome if Harmony (and eventually Javelin) had support for this kind of predictive algorithm out-of-the-box. I'm dubbing this "Predictive Systems" in the meantime. Of course, currently Harmony doesn't have a concept of systems at all (only entities, components, and queries), but new structures could be introduced with this proposal which cover other best practices for system design and organization outside of netcode.

Proposal

Out-of-scope

  • Peer-to-peer. I think designing the structures and functions involved within the model of the classical authoritative server <> client architecture is necessary to keep goals reasonable.
  • Network transport/message protocol. User (or consuming library i.e. javelin) will need to bring their own encoder/decoder and networking stack.

In-scope

CrystalOrb does a few things that we can learn from:

  • Clock synchronization of client and server using timestamps (although the author has some regrets about using wrapped i16 vs float64 -- I think the wrapped approach is cool and shaves a few bytes off each snapshot message)
  • Client prediction with fast-forwarding using multiple simulations
  • Commands
  • Interpolation
  • Client can tick at monitor refresh rate and still be accurate

Things we'll want to add

  • Easily distinguish between predictive systems and states (components) and non-predictive ones
  • Abstract the "current" predicted state to non-predictive systems (i.e. it seems like there is only one physics world to the client)
  • Allow predictive state and non-predictive state to easily mesh

New structures and functions to consider

  • Timestamps
  • ClockSync
  • Command
  • Systems vs. predictive systems, auto-creating Archetype columns for predicted state, snapshot state, and maybe interpolated state?

API Sample

// System is defined like normal, without any notion of prediction
function input(ecs) {
    let command: InputCommand
    while (command = Command.take(ecs, CommandType.Input)) {
        const velocity = Entity.get(ecs, command.entity, Velocity)
        if (command.jump) {
          velocity.y += 10
        }
        // ...
        Entity.set(ecs, command.entity, Velocity, velocity)
    }
}

// On the client, we define a blend function that could interpolate between
// the latest predicted state and previous snapshot
function blend(queryFrom, queryTo, t) {

}

const pipeline = Pipeline.make(
    // On the client, a predictive system is configured with one or more
    // types to simulate in the future (relative to a server). Queries executed
    // within the predictive systems would somehow interact with "overlayed"
    // entity tables that shadow the original archetypes 
    System.makePredictive(input, [Prefabs.Player], [Commands.Input], blend),
    System.make(render),
)

// Some built-in commands would provide clock sync instructions and state
// snapshots to the pipeline's state for each predictive system
const commands = Command.makeCommandBuffer()

Pipeline.step(pipeline, world, commands)

// The server will need to generate snapshots at regular intervals and 
// send timestamped payloads to the client

`moveToArchetype` performance

Entity relocates are currently slow because most of the code was hurriedly written to get my ideas down. moveToArchetype and related functions need to be refactored.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.