#Himalaya: A harmonic composition

No, this page is not turning into a music theory blog. Instead, I’m gonna tell you a little something about the newly introduced component system of the Himalaya game engine.

Remember the original design approach I posted when the framework was still very early in development?

GameElements

My original idea was to have an abstract class as a template for all entities in the game. An entity, such as the player character, would then simply derive from the GameEntity class and implement all the additional functionality that it needs. The “Actor” class was supposed to be a GameEntity that provides additional features for visual representation of the object on the screen. But as the Himalaya engine grew bigger, I realized that this design was good, but not necessarily ideal.

What are you made of?

I came to the conclusion that a component-based approach, similar to the one in the Unity engine, was a much nicer way to describe the functionality of a game entity. What do I mean by “component”? Well…an entity component is basically responsible for handling one specific part of an object in our game. They enable us to easily implement similar behavior in two entities, just by using the same components. An example: For our player character we could create a game entity with one component that handles user input, one that handles collisions, one that renders a sprite on the screen and one that animates said sprite.

Take a look at this chart for clarification:

HimalayaComponents

As you can (hopefully) see, a lot of the classes that I talked about in previous posts have been converted to entity components to conform to the new system. Of course this new design renders the aforementioned “Actor” class obsolete, since it would basically just be a GameEntity with a Sprite and a SpriteAnimator attached to it. Currently, I still keep the Actor class in the library, but I marked it as “obsolete”. It will be removed very soon, though.

Entity Components that need their logic updated each frame implement the IUpdate interface. The GameEntity the component belongs to then makes sure to actually call the update logic regularly. Similarly, components that contain render logic use the IDraw interface and have their draw method called by their entity at the appropriate time.

The Transform component is a special little snowflake, because it is used by every single entity and cannot be removed. I mean, every object needs to be able to be positioned at least, right? Also, some entity components allow only one instance of them to be attached to a game entity. That is the case for our special little friend Transform, but also applies to the CollisionController, the Sprite and the SpriteAnimator for example. With this system, we can easily pick from all the features we need and add them to a specific game entity.

youJustBlewMyMind.gif

How about some code?

Alright, let’s take a look at the EntityComponent class first:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yetibyte.Himalaya.GameElements;

namespace Yetibyte.Himalaya.GameElements {

    public abstract class EntityComponent {

        #region Fields

        protected bool _isActive = true;
        protected GameEntity _gameEntity;

        #endregion

        #region Properties

        public virtual bool AllowMultiple => false;
        public virtual bool IsRemovable => true;

        public GameEntity GameEntity {

            get => _gameEntity;

            set {

                GameEntity futureGameEntity = value;

                if (IsAttached)
                    _gameEntity.RemoveComponent(this);

                futureGameEntity?.AddComponent(this);

                _gameEntity = futureGameEntity;

            }

        }

        /// <summary>
        /// Whether or not this component has been attached to a <see cref="GameElements.GameEntity"/>.
        /// </summary>
        public bool IsAttached => _gameEntity != null;

        /// <summary>
        /// Determines whether or not this component is currently active. This also takes into account the active state of
        /// the <see cref="Yetibyte.Himalaya.GameElements.GameEntity"/> this component is attached to. If the GameEntity is not active, this will return false
        /// regardless of the local active state of this component. A component that is not attached to any GameEntity is always considered inactive.
        /// </summary>
        /// <seealso cref="IsActiveSelf"/>
        public bool IsActive {

            get => _gameEntity != null && _gameEntity.IsActive && this.IsActiveSelf;
            set => this.IsActiveSelf = value;

        }

        /// <summary>
        /// The local active state of this component. This ignores the active state of the <see cref="Yetibyte.Himalaya.GameElements.GameEntity"/> this component is attached to.
        /// Pleae note that, even if this is set to true, the component may still be considered inactive by the <see cref="Scene"/> because the GameEntity is not active or this
        /// component has not been attached to a GameEntity at all.
        /// </summary>
        /// /// <seealso cref="IsActive"/>
        public bool IsActiveSelf { get => _isActive; set => _isActive = value; }

        /// <summary>
        /// Determines the order in which <see cref="EntityComponent"/>s are processed. The processing order goes from
        /// high priority to low priority components. Note: This does not affect the draw order for drawable components.
        /// </summary>
        public int Priority { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// Sets the <see cref="Yetibyte.Himalaya.GameElements.GameEntity"/> this component is attached to without
        /// the overhead of recalculating relations. Only use this if you know what you're doing!
        /// </summary>
        /// <param name="gameEntity">The new GameEntity.</param>
        internal void SetGameEntityDirectly(GameEntity gameEntity) => _gameEntity = gameEntity;

        /// <summary>
        /// Called when this <see cref="EntityComponent"/> is attached to a <see cref="GameElements.GameEntity"/>.
        /// </summary>
        public virtual void OnAdded() {

        }

        /// <summary>
        /// Called when this <see cref="EntityComponent"/> is removed from a <see cref="GameElements.GameEntity"/>.
        /// </summary>
        /// <param name="gameEntity">The GameEntity this component was removed from.</param>
        public virtual void OnRemoved(GameEntity gameEntity) {

        }

        #endregion

    }
}

Good thing I (almost) always document my code. That saves me some explaining now, if it’s even necessary since this class is pretty short and straight forward and doesn’t do that much on its own. This is simply an abstract class for the different component types to derive from. Entity Components can be set to “inactive” to temporarily prevent them from being processed. The order in which components are updated can be determined via the Priority property. This is useful and even necessary in some cases. For example, it makes sense to first check for keyboard input with the ControlListener component and then after that process the input in a Behavior component.

Speaking of Behavior component. As I mentioned above, the logic and – well – behavior of a game entity is no longer intended to take place directly in a subclass of GameEntity. This is the job of the Behavior component. It has methods for initialization and updating that we can override to describe the behavior of an object such as the player character. It is where we implement all the logic that handles how an entity interacts with its environment.

Components can be added to or removed from a GameEntity with the following simple methods. I added some comments for explanation.

public void AddComponent(EntityComponent component) {

	/* If we passed null for some reason or a component that was already added
	 * to this GameEntity, return without adding anything. */
	if (component == null || HasComponent(component))
		return;

	// Get the type of the component we want to add.
	Type componentType = component.GetType();

	/* If the component does not allow multiple instances of it in one entity and there
	 * is already a component of the same type in this entity, return without adding the component. */
	if (!component.AllowMultiple && HasComponentOfType(componentType))
		return;

	// If the component is currently already attached to another entity, detach it.
	component.GameEntity?.RemoveComponent(component);

	// Add the component to this entity's collection of components.
	_components.Add(component);

	// Set the GameEntity of the component to this one.
	component.SetGameEntityDirectly(this);

	// Call the OnAdded method of the component we just added.
	component.OnAdded();

	// Fire the ComponentAdded event.
	OnRaiseComponentAdded(new ComponentEventArgs(component));

}

public void RemoveComponent(EntityComponent component) {

	/* If we passed null or the component is not attached to this entity
	 * or it is not removable, return. */
	if (component == null || !HasComponent(component) || !component.IsRemovable)
		return;

	// Remove the component from the collection of components in this entity.
	_components.Remove(component);

	// Set the entity of the component to null.
	component.SetGameEntityDirectly(null);

	// Call the OnRemoved method of the component we just removed.
	component.OnRemoved(this);

	// Fire the ComponentRemoved event.
	OnRaiseComponentRemoved(new ComponentEventArgs(component));

}

To retrieve components attached to a GameEntity, we can use one of the following methods:

/// <summary>
/// Returns a collection of all <see cref="EntityComponent"/>s attached to this <see cref="GameEntity"/> that are of or derive from the given Type.
/// </summary>
/// <typeparam name="T">The type to filter the components by.</typeparam>
/// <returns>A collection of all components attached to this entity that derive from the given type.</returns>
public IEnumerable<T> GetComponents<T>() where T : EntityComponent => _components.OfType<T>();

public IEnumerable<T> GetActiveComponents<T>() where T : EntityComponent => _components.OfType<T>().Where(c => c.IsActive);

/// <summary>
/// Returns a collection of all <see cref="EntityComponent"/>s attached to this <see cref="GameEntity"/>'s children that match the given Type or derive from it.
/// </summary>
/// <typeparam name="T">The Type to filter the components by.</typeparam>
/// <param name="includeSelf">Should the root <see cref="GameEntity"/>'s components be included in the collection?</param>
/// <param name="recurse">Should the components attached to grandchildren, great-grandchildren etc. also be included in the collection?</param>
/// <returns>A collection of all components that meet the specified conditions.</returns>
public IEnumerable<T> GetComponentsInChildren<T>(bool includeSelf, bool recurse) where T : EntityComponent {

	IEnumerable<T> ownComponents = includeSelf ? GetComponents<T>() : new T[0];

	if (_childEntities == null) // Just a safety precaution
		return ownComponents.Concat(new T[0]);

	if (!recurse)
		return ownComponents.Concat(_childEntities.SelectMany(e => e.GetComponents<T>()));

	return ownComponents.Concat(_childEntities.SelectMany(e => e.GetComponentsInChildren<T>(true, true)));

}

/// <summary>
/// Returns the first <see cref="EntityComponent"/> attached to this <see cref="GameEntity"/> that matches the given Type or derives from it.
/// </summary>
/// <typeparam name="T">The type of the component to look for.</typeparam>
/// <returns></returns>
public T GetComponent<T>() where T : EntityComponent => GetComponents<T>().FirstOrDefault();

What’s somewhat interesting here is the generic method GetComponentsInChildren that optionally recurses through the entire entity hierarchy and returns all the components of the desired type it can find. By now you should also be able to tell that I’m a big fan of LINQ. 😀

If we wanted to get the Sprite component of a game entity, we would simply do something like: “entity.GetComponent();”

If we know there are multiple components of the same type, let’s say Behavior, and we want to retrieve them all, we’d just go: “entity.GetComponents();”

We’re getting there…

The Himalaya engine is getting richer and richer in features. There’s still a lot to do, but I’m having a lot of fun developing this framework, even though it takes more time than I can afford to spend sometimes. 😀

There are a few more features I haven’t written about yet, but I’ll take care of that shortly. Next time we’ll focus on collision detection and response. I hope you’re looking forward to that.

And as always, let me remind you that the source code of the Himalaya engine can be found in my GitHub repository.

See you around!

Advertisements

#Himalaya: Need Input

A few weeks have passed and the Himalaya game engine has grown a lot. Sorry for not posting earlier but I was busy with so many things at once that I didn’t really know what to write about. However, from the many features that were added to the framework, let’s focus on the one that handles user input.

c308d88f9e24a0e87e70925ad19c39c2cae411a95aa5312b9f0e3c671739ccfe

Just like Johnny 5 in the late 1980s movie, most games need input to function. Luckily, XNA/Monogame already has us covered with a few classes that handle keyboard, mouse and gamepad input. Using only the vanilla Monogame framework, you’d typically do something like this to make a character jump:


// Get the current state of the keyboard.
KeyboardState currentKeyboardState = Keyboard.GetState();

// Get the current state of the first gamepad.
GamePadState currentGamePadState = GamePad.GetState(PlayerIndex.One);

/* Check if the spacebar is pressed in this frame and was not pressed
in the previous frame or if the "A"-Button is pressed in this frame
and was not pressed in the previous frame. */
if((currentKeyboardState.IsKeyDown(Keys.Space) &&
    previousKeyboardState.IsKeyUp(Keys.Space)) ||
    (currentGamePadState.IsButtonDown(Buttons.A) &&
    previousGamePadState.IsButtonUp(Buttons.A))
{
    // Call the jump method we defined somewhere.
    Jump();
}

/* Update the variable that stores the previous keyboard state,
which we declared as a field of this class for example. */
previousKeyboardState = currentKeyboardState;

// Same thing goes for the gamepad's state
previousGamePadState = currentGamePadState;

And this works just fine, of course. But in many cases, we don’t want the controls to be static. We’d rather have a generic “Jump”-button that substitutes for some button that can be changed at runtime. Also, we don’t want to keep track of the state of our input devices all the time. We want to simply be able to tell, if a certain button is pressed, released or held down. Let’s assign all the dirty work to someone else.

So I figured I’d design a system, that makes it really simple to create controls for a game. My idea was to enable the developer to define game controls by a name and sort of map them to different keys or buttons. So in our example, the dev could create a game control named “Jump” and map it to the spacebar and the “A”-button on the gamepad alternatively.  Well, sometimes code is worth a thousand words, so here you go:

public GameControl RegisterControl(string name, Keys key, Buttons button, Keys alternativeKey, Buttons alternativeButton, bool doRepeat = false, float repeatInterval = GameControl.DEFAULT_REPEAT_INTERVAL)
{
    // do magic
}

This method is part of the class “ControlSettings” which basically holds a map of all game controls registered. You can use this class to set up a complete set of controls and then request their state from somewhere else in your code. When you call this method to register a game control, you pass it the name of the new control and the key(s) and/or button(s) it should be mapped to. Optionally, you can also configure the control to be retriggered at a certain time interval. There are multiple overloads of this method for when you only need to assign one key or one button and so on. An instance of ControlSettings needs to be attached to a “ControlListener”, which will internally use XNA’s input system to update the state of each “GameControl”. For checking the state of a control, the ControlListener provides the following methods:


public bool GetButtonDown(string controlName) => KnowsControl(controlName) ? Settings.ControlMap[controlName].IsDown : false;
public bool GetButtonUp(string controlName) => KnowsControl(controlName) ? !Settings.ControlMap[controlName].IsDown : false;
public bool GetButtonPress(string controlName) => KnowsControl(controlName) ? Settings.ControlMap[controlName].IsPressed : false;
public bool GetButtonRelease(string controlName) => KnowsControl(controlName) ? Settings.ControlMap[controlName].IsReleased : false;

KnowsControl, as you might have guessed, simply checks whether a GameControl with the given name was registered to the ControlSettings attached to this ControlListener. So if we were to check if a control, that does not exist, is pressed for example, it will always return false. Aside from these methods, there are also events that are raised when a control is pressed and released respectively.

When you create a ControlListener, you need to define which gamepad (1 – 4) it should process the input of. This way, you can create different control settings for each individual gamepad. So let’s get back to the example from earlier and use this system. First we need to create the settings and the listener:


// Create a new instance of ControlSettings
ControlSettings settings = new ControlSettings();

// Register a control named "Jump" that responds to space and the "A"-Button
settings.RegisterControl("Jump", Keys.Space, Buttons.A);

// Create a control listener and pass it the control settings
ControlListener listener = new ControlListener(PlayerIndex.One, settings);

Then, provided we call the Update method of our listener each frame, we can do this:


if(listener.GetButtonPress("Jump"))
{
    Jump();
}

Or, for an event-based approach, we could subscribe to the “ButtonPressed” event and go:


private void OnButtonPressed(object sender, GameControlEventArgs e)
{
    if(e.ControlName == "Jump")
    {
        Jump();
    }
}

giphy

But, wait! There’s more!

Aside from those simple game controls that keep track of whether they are up, down, pressed or released, there are also a special kind of game controls that store a value ranging from -1 to 1. The class is called “GameControlAxis”. A GameControlAxis is registered in a similar manner to a GameControl:


public GameControlAxis RegisterControlAxis(string name, AxisDirection direction,Keys positiveKey, Keys negativeKey, Buttons positiveButton, Buttons negativeButton, Keys alternativePositiveKey, Keys alternativeNegativeKey, Buttons alternativePositiveButton, Buttons alternativeNegativeButton, GamePadAxes gamePadAxis, float deadzone = GameControlAxis.DEFAULT_DEADZONE)
{
    // sorcery and wizardry
}

Instead of just mapping one key/button to the control (not counting the alternatives), we can map two keys and/or buttons to it; one that increases the axis’ value and one that decreases it. The parameter direction can be either “AxisDirection.Horizontal” or “AxisDirection.Vertical”. It is needed for when we map the control to a control stick on a gamepad to determine whether to pick up its horizontal or vertical offset. This is also what the optional deadzone is for. Usually, you don’t want to pick up a value from a stick that is only very slightly off-center or a shoulder button that is only marginally pressed down. Deadzone defines a threshold that has to be reached in order for a value to be picked up.
To access the value of a GameControlAxis, we simply call listener.GetAxisValue(“someName”). A GameControlAxis is especially handy when it comes to movement controls. We could register a GameControlAxis called “Horizontal” with the keys “A” and “D” or the left and right arrow keys mapped to it. Then when we want to move our character horizontally, we just add to their x-coordinate the character’s speed multiplied by what “listener.GetAxisValue(“Horizontal”) returns.

This whole system draws some inspiration from the Unity game engine, which I’m sure you already noticed if you’re familiar with it. I just think this is a very handy and intuitive way to handle user input.

So, that’s it for today, guys! As you know, the source code of Himalaya is available in my GitHub repo! Next time we’ll look into some of the other features that I’ve been working on during the last couple weeks.

YTMC DevLog #2: Flooded with Tools

This is part two of my developer log on “Yeti’s Tile Map Creator”, an extension for the Unity game engine.

TL;DR

  • Tile eraser tool is now fully functional
  • Added flood-fill tool that lets you quickly fill an area with a pattern of multiple tiles
  • Created a utility class that can be used to quickly and conveniently add keyboard shortcuts to the Map Creator
  • Added a few keyboard shortcuts

The new tools

Eraser

Let me try to make this sound super exciting: 

Holy sperm whale stuck on a pear tree! With the newly introduced eraser tool all your mistakes will be forgiven! Accidentally misplaced a tile? Unhappy with your creation? Feeling miserable about your recent life choices? Worry no more! YTMC’s eraser tool will wipe out all of your little screw-ups and help you make things right again. And it comes in many different sizes! The future is NOW!

All jokes aside, it lets you delete tiles. That’s about as exciting as it gets. To create this tool, all I had to do basically, was make some minor tweaks to the method responsible for placing tiles. Oh, and the eraser can be resized. Yea…

Flood-fill

I added a tool I honestly wasn’t sure I would when I started developing YTMC. But after a few test drives I realized that a flood-fill/bucket tool was indispensable. 

Since I never had to deal with anything similar to implementing a flood-fill tool for what you could call an image processing software, I consulted the good ol’ internet to get an idea of what an efficient and memory saving algorithm for the job would look like. I quickly found myself on Wikipedia with a pretty straight-forward solution (pseudo-code ahead):

Source: https://en.wikipedia.org/wiki/Flood_fill

I didn’t expect the thing to be too complicated. But I was a little surprised it was going to be THAT simple. 

As always in programming, there are of course plenty of other ways to implement this feature. But I figured this one was the best option to go for.

A lot of other solutions are based on recursion, but I was looking for a way that takes up as little memory as possible. Considering how many recursive method calls the process would make, I didn’t want to take the risk to leave the user with a stack overflow exception when they try to flood-fill a larger area.

My adaptation of the algorithm was implemented really quickly. However, I wanted a tool that can fill an area with not just one tile repeatedly, but with a pattern of multiple tiles. So, I extended the algorithm to meet that requirement.


Being lazy for the lazy

I wanted to accelerate the workflow for the user even more by adding keyboard shortcuts to YTMC. So, I thought about a way of implementing hotkeys without messing with any of the code I had already written.

What I ended up doing was creating a utility class that contains a collection of all the hotkeys available. This way, it’s really easy and convenient for me and future users of the tool to add new keyboard shortcuts that trigger a specific functionality.

Let me give you a brief insight into the code to give you an idea of what I’m talking about. Obviously, the following C# code was simplified for demonstration purposes:

Here’s a rough draft of the Hotkey constructor:

public Hotkey(Modifier m, Key k, Action<MapCreator> a) {
	// some stuff
};

So now we can add hotkeys to the HotkeyList utility class like this:

private Hotkey[] hotkeys = new Hotkey[] {

	new Hotkey(control, escape, (mc) => { mc.DoStuff(); })

};

For the “Modifier” parameter we pass a representation of the modifier key (alt, control, shift etc.) that needs to be held down for the shortcut to be triggered. Knowing that, I reckon you can guess what we pass for the “Key” parameter. 

The fun part is the last parameter. Here we pass an anonymous method that is to be called when the key combination is pressed. In this simplified example, think of “mc” as being the main window of the Map Creator. We can now let our anonymous function use all the public members of the Map Creator window and its components. This way, we don’t have to make any changes to the Map Creator’s code itself. Also, we now have an excuse to make use of lambda expressions to show the world how cool and clever we are. Amirite? 😀

Up next

I guess, my next bigger step will be to add a collision editor to the Map Creator. I’ve planned it to be a visual tool that enables the user to simply add closed polylines to the map that will eventually be converted to Unity colliders. But we’ll see what I’ll end up doing exactly.


The visuals

To conclude this devLog entry, I’m gonna leave you with a few gifs to showcase the progress of YTMC:

Tileset used in these examples made by: Reemax

See: http://opengameart.org/content/lpc-cavern-and-ruin-tiles

var introduction = new BlogEntry();

Well hello, stranger!

I figured I should introduce myself since you happened to stumble upon this blog.

The name my dear mama gave me is Alex, friends also know me as “Yeti”. Lucky Goodrich is a pseudonym I came up with during a really boring internship when I was like 18. I’m a 1990-born programmer and software designer in the making. My native language is German and I live in a German speaking country you might know as “Germany” (I know, crazy, right?). However, I’ve always been more of the cosmopolitan type of guy when it comes to presenting myself on the web (Does that make sense? I’m not as good at using big words as I wish I was).


I spend a lot of time playing video games (mostly Nintendo) and watching cartoons (I will never be too old for Adventure Time – Oh, dear Glob, I love it so much). But the hobby I’m most passionate about is programming, hence this blog. My favorite food is whatever I find in the fridge.

While I do have an educational background in the wonderfully messed up world of computer science, I unfortunately could not yet make the passion I have about it my actual profession.

However, I recently mustered all ambition I could possibly find inside my generic nerd/geek body to refine my abilities and skills and all that good stuff and finally get productive.

image

Off the top of my head, I would name C#, Java, Javascript, Actionscript, PHP and C++ as the languages I’ve worked with over the past few years. But, there is probably more that I can’t remember right now. Every now and then, I’ve found myself experimenting with development tools and stuff. There was a time where I ambitiously created Skyrim Mods for my personal use only (I really should have published them on Steam or something. Stupid me!).

Back in the day, when I was an even more messed up teenager, I used to make games using the good ol’ RPG Maker (ah, the memories, they’re golden) and also Flash. The latter I also created websites with and all that. You know, Flash stuff… One of the tools I recently spend the most time on is – who would’ve thought – Unity3D. (Yes, I have Unity installed on my PC, I’m a professional now :D)


Whatever, I don’t want to make this too long and tell you about my first day at elementary school. Just know, that I set myself the goal to become a professional software/game developer sooner or later. I want to soak in all the knowledge regarding the arts of programming, game design and everything around that. Currently, I am working on an editor extension for Unity that makes it easy for newbies to create tile-based levels. In fact, that one is almost finished (yay!). More about that in future blog entries.

I’m really new to this blogging stuff, so please excuse my noob-esque writing style. There’s probably a lot more I could tell here, but I feel like this should do for now.

Thank you so much for stopping by!


Bonus: Here is a picture of me and Super Mario (well, his voice actor):

image