Seed Game Engine - Messaging & Input

in #utopian-io7 years ago

GitHub PR (for this blog, includes bulleted list of changes)
GitHub Repo (Seed Engine)
GitHub Repo (Seed Engine Game Boilerplate)
Demo

Seed Game Engine - Messaging & Input

Welcome to the second Seed Engine development post! This post will be a continuation on adding Components and corresponding Managers. I'm working on extending the features a little bit before I continue with rendering. In the past few days I've been working on a fast system to manage keyboard and mouse input. To make input events work best, I also implemented cross-component messaging.

If you're hoping to start using the engine, it's still very early. I would recommend waiting until rendering, text, collisions, and physics are mostly complete. There is more info on this in the Roadmap section.

Engine-Wide Messaging

Intro

An Entity-Component System helps couple functionality to appropriate entities in the game world, but it can be difficult to communicate with two objects or systems which have no correlation. In situations like these, restructuring code or searching for the correct object to work with the specific use-case is unrealistic, especially if it isn't going to be needed in every game. Messaging is a great use case for attaching these uncommon communications, with little hassle.

Basic Messaging

A messaging system allows for setting or changing data to automatically trigger an event to all entities waiting for changes. There are many ways to accomplish this, but the core functionality of a messaging system typically includes:

/*
* Sends a message to all listeners listening to messageID. 
* A message can be any type of data.
*/
sendMessage(messageID: number, message: *);

/*
* Starts listening for a message under the ID messageID.
*
* Triggers the callback with the new message as the only parameter.
* Returns: A number ID to close this listener.
*/
listenForMessage(messageID: number, callback);

/*
* Closes a listener, the callback will no longer trigger.
*
* messageID: Message to stop listening to.
* listenerID: Listener ID of your listener.
*/
stopListening(messageID: number, listenerID: number);

Implementation 1

I expanded on this basic layout to a directory-style lookup, with hierarchal event listening. This allowed me to store data like:
set('Users/user1/name/first', 'John');
and it would trigger events, returning a change with 'John' for anyone listening to 'Users', 'Users/user1', 'Users/user1/name', or 'Users/user1/name/first'. The source code can be viewed here.
I ended up removing this as it was taking longer than I wanted to work on it, and I didn't need something so complicated yet. I may find it useful later for organizing and storing game state data. You can run the seed engine unit tests with npm for testing results. I tested 10,000 different sets and gets in ~5 ms.

Implementation 2

All I really needed was a flat storage (key: value), but it would be nice to separate them by system. Instead of making just one centralized system to handle all messages as a singleton for anyone to access, I made one for miscellaneous data, and additional messagers in managers which needed them, such as the InputManager. You can see the current implementation here, the global singleton, and in the InputManager.

Input Management

The input is managed by the DOM initially, and is listened to for updates. The InputManager attaches a listener for left & right clicks, and key down & up events. These DOM events are trimmed and prettied before sending them through the InputManager's Messager. Repeated keydown events from DOM are also rerouted as "key" events, for natural text input.
The InputManager goes further to update each key when pressed, held, or released after each game step. This allows for getters by KeyCode to return key states, without needing an event for every key. With getters, they will only update once per update, staying consistent with ECS.
Events aren't used heavily here, but they do make it easy for text input or specific uses which may be outside of a typical GameObject object.

Demo

Below is a photo of the seed boilerplate hosted here. The source code is on GitHub. This photo displays 3 viewports, and 2,000 GameObjects rendering basic squares without textures. Each object independently moves and listens for click and keyboard input for additional movement. Running at 60fps. I promise my next post will have something more interesting as an example!

Seed Boilerplate

Roadmap

The Seed Engine scope is only as large as KOE needs to finish its development. All systems that have to be completed to allow KOE to run are integrated into the Engine. In other words, the Engine will contain fewer features until later development (late 2018), but will not take shortcuts in design, allowing future features to be seamlessly implemented.

The documentation contains much of the engine structure already, and you can see more about the Engine structure and game design in this document.

Engine Features:

ECS System
  • Core Game Loop
  • Baseclasses
  • Scenes and Scene Management
  • Game Objects
    • Scene vs Persistent Objects
  • Viewports
  • BaseComponent
  • Messaging
Components
  • Renderable, Renderable2D, RenderableSprite, RenderableShape
  • Audio
  • Collider, Collider2D, CircleCollider, BoxCollider
  • Transform
  • Input
    • Controllers
  • Physics
Rendering (2D for now):
  • Multiple Views per Scene
  • Matrix transformations
  • Camera per view
  • Multiple Lights per view
  • Multiple Shapes
  • Textures (Sprites)
  • Animations (SpriteSheet Textures)
  • Particles & Particle Systems
  • Effect shaders (Shadow, fire, water)

Documentation

You can view the documentation here. This PR had limited comments as some sections of the Input Management may change with rendering (to utilize GPU picking), and the collision manager. Documentation can be contributed, but I will be updating it next PR myself.

Contributing

The GitHub readme links to the contributor section, where feature requests can be viewed. The Seed Engine is open source under the MIT license, anyone may contribute. At this time, features or updates must follow the guidelines of the request. Feature proposals are welcome!
There will be more contributor requests next PR.

Thanks for making it this far! Please leave a comment if you have any questions or critiques :)

Sort:  

Hey @jaegar
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Contributing on Utopian
Learn how to contribute on our website or by watching this tutorial on Youtube.

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

  • More comments in the code would be welcomed.
  • I'm curious to know what types of games would use this engine.
  • Any blockchain plans for this engine?

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

- More comments in the code would be welcomed.
Of course! I'll continue with class, function, and member commenting. I hope to have more commented examples eventually as well.

- I'm curious to know what types of games would use this engine.
I'm currently designing it in scope for Kingdom of Eloria. Aside from what KOE will be, Seed Engine will offer 2D collisions, input, physics, spritesheets and animations, text, UI, shader effects... The goal is to be able to make just about any Top-Down or Platform viewed games. This will hopefully expand when 3D comes into question.

- Any blockchain plans for this engine?
KoE is an casual MMO RPG that will be using the engine, and will be using Seed to communicate with other players.

Seed is an experimental decentralized network for which the Seed Engine will be designed to create modules with. It is being developed right now by Carson Roscoe.