#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!

#Himalaya: Multi-threading in the brain

While getting into Powershell at dev school (which is defs a handy tool for .Net developers), I was working on Himalaya and implemented a basic content pipeline extension that reads and interprets lua scripts (thanks to MoonSharp) and turns them into sprite animations, based on a prototype I made a week ago. Details to come…

Yes, that is reddit in the background. Don’t judge! 😀

YTMC DevLog #3: Maxing Out My Procrastination Skills

TL;DR

  1. Map Files can now actually be saved and loaded
  2. Maps can now be resized at any time
  3. Maps can now be shifted
  4. Optimized and documented code a bit further.
  5. Been hella lazy
  6. Regretting 5.

What I don’t hate myself for

Okay, so before I get deeper into why I made so little progress during the last two weeks, let’s look at the bright side of things. It’s not that nothing happened. It’s not that nothing was accomplished. But, unfortunately for me, it’s pretty safe to say, that what I actually got done was a matter of 3 hours tops. Wow, I’m really bad at seeing things from an optimistic point of view…

Anyway, let’s talk the new content!

Saving and loading

Yes, it’s true. An important step has been made, that got YTMC closer to actually serving a purpose. Lots of “doge” memes are popping up in my mind as I’m writing this. Maps created in YTMC can now be saved and loaded (wow, very progress, such improve, so effort).

The technical stuff around this was pretty straight forward and not time consuming in any way, since I had already gotten familiar with Unity’s serialization features beforehand. Also, the underlying data structure was basically already there thanks to me always thinking ahead as much as possible. Well, in programming that is. If only I could say this about life in general. 😀

So, basically all I had to do here was code a quick method that serializes all the important information of a map and saves it to a file. For this purpose Unity’s ScriptableObject class comes in quite handy as it makes this process pretty convenient for both the potential user of my tool and, of course, me as the developer. I already had a class called “MapFile”, which derives from ScriptableObject, ready and waiting to fulfill its purpose. So, I identified all the data within a “Map” object that needs to be stored in order to reconstruct it later and set up the “MapFile” class accordingly. So the above mentioned method basically creates an instance of said ScriptableObject and deep-copies all the important stuff from the “Map” class into it.

With that being said, it’s obvious that the loading method basically does the exact same thing in reverse. However, since I handle the rendering of the map that is currently being worked on inside the Map Creator’s UI through actual meshes attached to GameObjects, I also had to make sure those get recreated automatically. This makes loading a map take a while, depending on how big it is and how many layers it has. But, no matter how complex the map, we’re still talking about seconds here, so no big deal.

All of this was not rocket sience in any way and did not take very long to implement, especially because everything was laid out accordingly beforehand.

Resizing

How do I start? The ability to change the dimensions of a map after it has been created was one of the things I’d been procrastinating to work on for a while. The reason was simply because it was such a tiny amount of work to do so that I was always like “I’m gonna implement it the moment I need it”. The underlying logic was already written and stuff. All that was left to do was create a simple UI to enable the user to actually use this feature. 

But get ready for some A1 irony. When I finally got my lazy butt to creating that UI, I was really sick. In fact, I was feeling so under the weather that I could not even handle simple math! There is a preview feature included in the map resizing UI that required some 6th grade mathematics to implement… That was something my temporarily medically impaired brain could not process at that moment. So this tiny little piece of work took me way longer than it should have. When I looked at it after I felt better I couldn’t believe how such a simple thing could have kept me busy for such a long time… Just embarrassing! 😀


Where has the time gone?

Yeah, I’ve already made it pretty clear that I have been very lazy. A lot of time passed without leaving any kind of productive result. That just sucks and there’s no excuse for it. I procrastinated the heck out of YTMC and the reason is simple: I lack discipline.

The other day, I stumpled upon a very interesing quote on twitter. It quoted a post by tumblr user theangryviolinist. They were asked by someone if they could provide a few tips on how to muster the motivation to keep on practicing regularly. And the answer was just brilliant. See for yourself: 

“[…] Better to cultivate discipline than to rely on motivation. Force yourself to do things. Force yourself to get up out of bed and practice. Force yourself to work.

Motivation is fleeting and it’s easy to rely on because it requires no concentrated effort to get. Motivation comes to you. You don’t even have to chase after it.

Discipline is reliable, motivation is fleeting. The question isn’t how to keep yourself motivated. It’s how to train yourself to work without it." 

– theangryviolinist

And even though I got so inspired by this, I still somehow managed to procrastinate my plan to get more disciplined. The only thing I never procrastinate is procrastination itself. Yea, pretty meta, huh?

But there were also other reasons I wasn’t that productive. Most importantly, my friend @theinfernogames was about to release his game “Battle Forever” and needed me as a tester. That consumed a lot of time, buf I enjoyed it and I was happy to help out. For more info on “Battle Forever” check it out on itch.io.


I’ll be back

I will terminate procrastination Arnold Schwarzenegger style and do my best to provide a new update as soon as possible. There is not much left to do, so it really shouldn’t be too long before “Yeti’s Tile Map Creator” is all finished and ready to be released.

Thanks for your attention!