-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Kernox is built on the Entity-Component-System (ECS) architectural pattern, designed for building highly decoupled real-time applications in JavaScript/TypeScript. This architecture promotes separation of concerns and provides excellent performance for applications that need to process many objects each frame.
The ECS pattern separates data from behavior:
- Entities: Objects that exist in your application (e.g., players, enemies, projectiles)
- Components: Data containers that define properties (implemented as attributes in prototypes)
- Systems: Logic processors that operate on entities with specific components
This separation enables:
- Better code reusability
- Easier testing and debugging
- Improved performance through data-oriented design
- Flexible entity composition through multi-inheritance
=======================================================
| Kernox |
| (Central Integration Point) |
=======================================================
|
|--> EntityFactory
| --> Creates entities from prototypes
| with multi-inheritance support
|
|--> CollectionManager
| --> Manages entity collections
| (ArrayList, etc.)
|
|--> SystemManager
| --> Executes systems sequentially
| each frame
|
|--> EventBroker
| --> Dispatches events between systems
|
|--> AddonLoader
--> Loads and integrates addons
(bundles of resources)
The main application class that orchestrates all other managers. It provides:
-
Execution loop: Runs at 60 FPS using
requestAnimationFrame -
Addon integration: Loads resources through the
use()method - Manager access: Provides getters to all manager instances
- Frame tracking: Monitors FPS, delta time, and frame count
Location: src/Kernox.ts
Handles entity creation and prototype management:
- Registers entity prototypes with attributes
- Creates entity instances from prototypes
- Supports multi-inheritance between prototypes
- Deep-copies prototype attributes to avoid reference issues
Location: src/entity/EntityFactory.ts
Manages collections of entities:
- Creates and retrieves collections by name
- Supports different collection types (ArrayList, custom collections)
- Automatically assigns entities to collections based on their prototype
Location: src/collection/CollectionManager.ts
Executes application logic:
- Instantiates and initializes System classes
- Runs systems sequentially each frame
- Provides dependency injection for collections and events
Location: src/system/SystemManager.ts
Facilitates communication between systems:
- Event-based pub/sub messaging
- Namespace support for addon isolation
- Type-safe event handlers
Location: src/event/EventBroker.ts
Packages and loads application resources:
- Bundles prototypes, systems, collections, and dependencies
- Manages namespaces to prevent naming conflicts
- Supports addon dependencies
Location: src/addon/AddonLoader.ts
-
Initialization
const app = new Kernox(); app.use(myAddon); // Load resources app.execute(); // Start execution loop
-
Setup Phase (happens once when addon is loaded)
- Register prototypes with EntityFactory
- Instantiate collections in CollectionManager
- Create and initialize Systems in SystemManager
-
Execution Loop (runs every frame)
======================================== | 1. requestAnimationFrame callback | | 2. Calculate delta time (dt) | | | | 3. SystemManager.execute() | | --> Execute each System in order | | 4. Schedule next frame | ======================================== -
System Execution (each frame)
- Systems can read/write entities in collections
- Systems can dispatch events
- Systems can listen to events from other systems
Prototype Definition � Registration � Entity Creation � Collection Assignment � System Processing
-
Define Prototype: Create a
PrototypeSchema<T>with attributes -
Register: Call
entityFactory.prototype(schema) -
Create Entity: Call
entityFactory.create(type, params) - Auto-assign: Entity is automatically added to specified collections
- Process: Systems iterate over collections and process entities
Kernox uses namespaces to prevent conflicts between addons:
// Explicit namespace
app.entityFactory.create("myAddon.Player", { hp: 100 });
// Implicit namespace resolution (when unambiguous)
app.entityFactory.create("Player", { hp: 100 });Resources (prototypes, collections, events) can be accessed with or without namespaces. If multiple addons define the same resource name, you must use the explicit namespace.
With a 60 FPS target, each frame has ~16.67ms to complete all processing:
- Entity iteration should be O(n)
- Avoid expensive operations in hot paths
- Use collections efficiently
- Consider object pooling for frequently created/destroyed entities
- Entities are created with unique IDs
- Collections hold references to entities
- Entity attributes are deep-copied from prototypes
- Consider implementing object pooling (via
sendToRest()method)
- Separate Concerns: Keep data (entities) separate from logic (systems)
- Single Responsibility: Each system should handle one specific task
- Event-Driven: Use events for cross-system communication
- Composition: Build complex entities through prototype inheritance
- Namespace: Use namespaces for addon isolation
- Modular: Package related resources into addons
- Entities and Prototypes - Learn how to define and create entities
- Collections - Understand entity storage and access
- Systems - Implement game logic and behavior
- Events - Communication between systems
- Addons - Package and organize your application