Development - worldscapes/engine GitHub Wiki

Developement process

Since design decisions require planning, it's not always possible to find right solution before actual testing and prove of concept. Because of that Engine plan will change with time and change how they work.

Trying to think over everything before doing can lead to wrong design solutions and stagnation on some problems, but too few preparation leads to mess and product which does not achieve it's goals.

To avoid such problems, development should be based on iterations:

  1. Describe all thoughts about feature / problem in appropriate documentation article
  2. Implement basic solution (it's not always required to be optimal and should allow easy replacement)
  3. Repeat again

Imporant point is that all features should be documented before implementation.

Release process

There are two branches: master and development

Release packages are created from pull requests to master, prerelease packages are created from pull requests to development branch.

New versions should be defined manually, but each conseqent pull request bumpes -beta postfix.

Roadmap

  • General structure
    • Server side
      • API Object
      • Basic update ticks
    • Client side
      • API Object
      • Basic update ticks
    • Typing tools
    • Error handling
  • Server-side simulation:
    • ECR:
      • Store
        • Standartized snapshot
      • Entities
      • Components
      • Resources
      • Rules
        • Rule basis
        • Custom rule injection
        • Queries
          • Component lookup
          • Combination function
          • Filtering
        • Conditions
        • Body
        • Typing
    • Commands
      • Custom command handler injection
      • Rule world update handlers
  • Framing
    • Abstraction basis
  • Merging
    • Abstraction basis
  • Network
    • Server basis
    • Client basis
    • Connection
    • Messages
    • Time synchronization
    • Ping test
    • Translation
    • Sending server world state (Temporary)
    • Sending commands from client
  • Validation layer
  • Client-side simulation
  • Display
    • Method to receive world state
    • Callback to provide input to Engine

Potential improvements after Worldspaces Arkanoid POC:

  1. Engine configuration should be as simple as possible. User should not care about Engine parts syncronization and moment when parts are ready to use.
  2. Change DisplayApi.onInput() since it has reverced dependency direction and is counterintuitive
  3. Server and Client should be separate packages to avoid unused code
  4. Ability to use composition (Mixins?) for building Rules and Querries Rules and Queries often share common parts. For example many Rules need to check that game started and many Rules need to request Settings resource for READ. To simplify that Rule and Query structure should allow easy composition
  5. Convenient way to copy components (Is it needed when you keep components small?)
  6. Instantiating components not using constructors
  7. Some Rules are only used to clean up state, they should be executed by the end in any order.
    There can also be Rules to be potentially executed before clean up (like entity destruction rules). Maybe several execution stages (maybe even customizable) are needed.
  8. Add way to assign predefined IDs to entities.
  9. Change Display layer to receive data based on Querries.
  10. Add space for different query change detection strategies. When query is executed for simulation, we just request it's result, but in case of Display we need it only when it's updated
  11. Finding Entity by ID (?)
  12. Enitity Archetypes for two purposes:
    • Simple creation
    • Simple lookup
  13. Simplify working with actions
    • Autogeneration of action requests
    • Function to simplify activation checks in condition - is not needed with Component Actions
  14. Implement tools for testing rules
    It should take world snapshot and compare response Rule condition or body gives with expected one
  15. Add built-in support for Players and managing their Connections
    • Players should be passed to Engine when it's bootstrapped. For each Player Engine creates appropriate Entity which gets Player input
    • Each Connection should be assigned to some Player. PlayerId is required when establishing Connection
    • Game can restrict Connection count for one Player, it should be done in Player parameters
  16. Add mechanism on Client and Server to filter incoming messages. It's needed to remove unallowed actions and duplicates which can cut performance.
  17. Execution of some Rules can be significantly optimized if run only when Rule query result changed.
    Changes can be detected using Proxy which wraps the StoreApi object. The smaller the block of data requested by the rule, the rarer the rule should be recalculated. Some Selectors can be marked to not trigger a recalculation.
    Not all rules fit this, some rules should be called even if data did not change. Those rules usually are based on Time and not on player input or game state.
  18. Avoid checking resources for undefined (which is annoying) as well as isSet in condition
  19. Most of the time user spends on
    1. Writing querries and conditions - can be automated by adding a way to compose querries and conditions
    2. Creating component and resource classes - can be automated by adding cli
  20. Improve rule debugging. It should be easy to track which rule is activated and what do they do
  21. Singleton entities There is a need to have an Entity that exists as a single instance and has a predefined ID. Such entities potentially can be requested through a separate Query field
  22. Add a pre-created Entity to attach global Events
    • It should be easy to add new events (without [0])
    • It should clean up events automatically
  23. Add customizable Serializers
  24. Feature flags to enable part of functionality only. This can improve how scalable and testable the Engine is.
    Feature flags should also be available in the Display layer

Guaranteed improvements after POC

  1. Recreate all API Object implementations to use closures instead of classes Closures should not return API Instance immediately, but instead, give a Promise. It will simplify synchronization on different parts for Engine user
  2. Network should have a way to:
    • Disconnect adapter
    • Reconnect adapter
  3. Message mapper should wrap NetworkAdapter to add an additional abstraction layer between Adapter Api and Server / Client Network and make it more reusable without other Engine parts
  4. Entities requested with a single HAS selector should be still returned
  5. Adapter should notify when a new connection is opened/closed
  6. Write comments for all API objects
  7. Rename AuthClientApi to AuthWriter and AuthServerApi to AuthReader which allows them to be more versatile and to use them for token authentication
  8. Implement logging to make Engine easier to debug and track activity

Potential features for Engine DevTools

  1. Implement benchmarking tools to control simulation and network performance It can also have some implemented UI to simplify visualization
  2. Add a way to visualize World structure It will help to simplify development and reduce cognitive load. Currently, it's hard to remember all the entities and their structure. Also, it's hard to visualize the game world as JSON, so there should be some better option
  3. Add a way to manage simulation flow (run N simulation ticks, playback several ticks)