-
Notifications
You must be signed in to change notification settings - Fork 0
Development
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:
- Describe all thoughts about feature / problem in appropriate documentation article
- Implement basic solution (it's not always required to be optimal and should allow easy replacement)
- Repeat again
Imporant point is that all features should be documented before implementation.
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.
- General structure
- Server side
API ObjectBasic update ticks
- Client side
API ObjectBasic update ticks
Typing tools- Error handling
- Server side
- Server-side simulation:
- ECR:
-
Store- Standartized snapshot
EntitiesComponentsResources-
RulesRule basisCustom rule injection- Queries
Component lookup- Combination function
- Filtering
ConditionsBodyTyping
-
-
CommandsCustom command handler injectionRule world update handlers
- ECR:
- Framing
- Abstraction basis
- Merging
- Abstraction basis
- Network
Server basisClient basisConnectionMessages- Time synchronization
- Ping test
- Translation
-
Sending server world state(Temporary) Sending commands from client
- Validation layer
Client-side simulation- Display
Method to receive world stateCallback to provide input to Engine
- Engine configuration should be as simple as possible. User should not care about Engine parts syncronization and moment when parts are ready to use.
- Change DisplayApi.onInput() since it has reverced dependency direction and is counterintuitive
- Server and Client should be separate packages to avoid unused code
- 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
- Convenient way to copy components (Is it needed when you keep components small?)
- Instantiating components not using constructors
- 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. - Add way to assign predefined IDs to entities.
- Change Display layer to receive data based on Querries.
- 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
- Finding Entity by ID (?)
- Enitity Archetypes for two purposes:
- Simple creation
- Simple lookup
- Simplify working with actions
- Autogeneration of action requests
- Function to simplify activation checks in condition - is not needed with Component Actions
-
Implement tools for testing rules
It should take world snapshot and compare response Rule condition or body gives with expected one - 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
- Add mechanism on Client and Server to filter incoming messages. It's needed to remove unallowed actions and duplicates which can cut performance.
- 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. - Avoid checking resources for
undefined
(which is annoying) as well asisSet
incondition
- Most of the time user spends on
- Writing querries and conditions - can be automated by adding a way to compose querries and conditions
- Creating component and resource classes - can be automated by adding cli
- Improve rule debugging. It should be easy to track which rule is activated and what do they do
- 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
- 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
- Add customizable Serializers
- 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
- 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
- Network should have a way to:
- Disconnect adapter
- Reconnect adapter
- 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
- Entities requested with a single HAS selector should be still returned
- Adapter should notify when a new connection is opened/closed
- Write comments for all API objects
- Rename AuthClientApi to AuthWriter and AuthServerApi to AuthReader which allows them to be more versatile and to use them for token authentication
- Implement logging to make Engine easier to debug and track activity
- Implement benchmarking tools to control simulation and network performance It can also have some implemented UI to simplify visualization
- 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
- Add a way to manage simulation flow (run N simulation ticks, playback several ticks)
- Home - About Engine
- Comparison with UE
- Approach to documentation
- Architecture
- Implementation
- Development
- Example Game Entities