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

Did you miss me?

Explaining myself

Well, where do I start? After 9 months of silence, my blog returns in a new look and on a different website. What happened? Where the fudge have I been? I’m gonna try and shine some light into my mysterious disappearance.

When I first started blogging on Tumblr, I was unemployed. I guess that already explains a lot, but let me continue with my justification. I don’t want to ramble too much though, so I’ll try to make it short.

I’m the type of guy that needs to be productive in order to be happy. A day without any result or any sort of progress feels empty and wasted to me. That’s one reason why I love coding. And that’s also one of the reasons why I created my blog. But when you’re unemployed, you have so much time that it actually becomes a burden at some point. You get lazy, you start slacking. “Yea, I could do this and that right now… or I could do it in an hour. What’s the difference anyway? I got like millions of those.”

stewieGun

I tried to sort of counter that by not only pursuing my hobbies, but writing about them. That way I was able to fill the huge amount of free time I had at hand a bit better and also actually had proof that this time had not been wasted. Plus, since I always wanted to become a software developer, I thought this was the best possible way to invest my time. At some point, however, it had overcome me. Anyone who knows me personally can confirm that I was going through some tough times back then. I don’t want to go into too much detail here, but let’s just say, updating my blog was not my top-priority in life during that time.

And blah blah blah, yada yada yada, here we are now. Currently, I’m getting trained to become a certified software developer. Less than two years from now I will have a super fancy certificate that proves my coding and software designing abilities. The training is going pretty well. Actually, it could hardly be any better. My grades are on point and I actually get kinda bored evey now and then, because most of the stuff they teach I already know. But unfortunately, in Germany you can have skills as sick as cancer but still won’t get a job because you don’t have some certificate to prove your “haxX0r Sk1llZzZ”. Well, whatever. I’m making a good investment into my future as a developer and for boring moments I always have my laptop with me so I can work on my programming projects.

Speaking of programming projects…

What’s next?

A few weeks ago during said training I started working on a little game just to keep myself busy. At first, I didn’t even know what kind of game I wanted to make. I wanted to keep it really simple and small because I originally intended to only ever work on it every now and then between classes and stuff. Also, my possibilites were kinda limited because I didn’t have a laptop back then. So I only had a portable C# IDE (SharpDevelop, check it out, it’s pretty cool) on a freaking flash drive to work with. I couldn’t use a powerful framework such as MonoGame as I usually would. So I ended up using a C# binding of SFML.

Here’s some material of what that looked like:

Click image to enlarge.

A couple hours into the development of this little project, someone suggested I create a tutorial on game development, and that is how this came to be:

 

I don’t know when I will find the time to continue this series, though. It’s fun, but it’s also very time consuming considering all the editing and other stuff that needs to be done to end up with a halfway decent video. We’ll see about that.

Shortly after that video was made, I got myself a new laptop. That meant no more restrictions when programming on the go. And so I decided to switch to MonoGame. Porting what I had already coded to MonoGame was not a big effort at all. However, I came to the conclusion that I should first build myself a little framework (on top of MonoGame) that is designed particularly for my intentions. So the plan is now to get a basic structure, a simple engine done for future game projects of similarly small scope. And that’s exactly what I’m gonna be working on and blogging about from now on.

I present to you:

himalayaEngineLogo384px

I started this project about two weeks ago and there’s already some code you can check out on GitHub:

Yetibyte.Himalaya on GitHub

And that’s it for now. I stayed up all night. I’m tired. It’s 9 in the morning already. My English is starting to get bad. Stop I will now. You guys later I will see. Buh-buh!

 

 

YTMC DevLog #1: Retrospection

What is YTMC?

YTMC stands for Yeti’s Tile Map Creator and it is an editor extension for the game engine Unity that allows the user to visually create 2D tile maps inside Unity without the need of any third party software. It’s quick and efficient and should improve the workflow of 2D game projects a ton. The tool is still in development, hence this devLog.


Catching up

I have been working on this project for a couple of weeks now; not continuously though. Now that I started this blog, I would like to document the progress in its development.

Since I’ve already been working on YTMC for a while, I dedicate the first devLog entry to catching up on what’s been done so far.

Tileset Creator:

A visual editor for creating, editing, renaming and deleting tilesets in a special format that is used by the map creator.

Key features already included:

  • Create, rename and delete tilesets.
  • Import tilesets in .png format (not that exciting)
  • Automatically extrudes the edges of the individual tiles to avoid visual seams and fragments when rendering the scene. This is a common problem with tile based games in the Unity engine. With this feature you don’t have to worry about that any more. The user can choose the amount of extrusion in pixels or completely disable this feature.

Map Creator:

A visual editor for creating 2D tile maps using the tilesets created in the tileset creator. (This is where the fun stuff happens.)

Key features already included:

  • Create a new map with given dimensions, tilesize and tileset.
  • Create up to 32 layers that can be re-arranged, deleted and renamed.
  • Show/hide layers.
  • Draw tiles onto the layers with the pencil tool.
  • Customize the layout of the Map Creator window.
  • Zoom in and out and move the viewport (WOW!!!)
  • The canvas’ grid and background can be toggled on and off (AMAZING!!!)

The struggles  of developing a Unity Editor extension

Unity serialization

Everyone who’s ever developed an extension for Unity will agree and probably burst into laughter followed by bitter tears of agony, when I say:

Unity serialization is a moody b*tch!

The way serialization is handled in Unity is pretty strange and unpredictable at first. I’m not saying it’s bad or anything. But I know for fact that I’m not the only one who had a hard time getting the hang of it. It simply does not behave the way you would expect and can deliver some strange issues that will drive you nuts initially.

image

However, once you get used to its quirks and bad habits you can use those to your advantage and develop workarounds for things you planned differently.

Due to the problems I had with serialization in Unity I lost some time and had to redesign a few ideas and data structures.

But me and Unity serialization are friends now. Not best friends, but… we’re getting along.

Memory Leaks

Another thing that gave me a few headaches at first were memory leaks caused by the way assets are treated in Unity. It’s always best to save procedurally generated assets to disk in Unity, that’s for sure. In some cases though, you certainly don’t have to. But you always have to make sure to destroy assets you created on the fly when they are no longer used.

Knowing all this now, I don’t have to worry about memory leaks anymore. The tool is running just fine without any problems!

Layer restriction

This isn’t a big deal at all, but I wanted to mention it anyway. I restricted the amount of layers for each map to 32. Technically, that limitation doesn’t necessarily need to exist. However, memory is limited and since the Map Creator creates multiple mesh assets for each layer, mermory could potentially pile up and slow down the user’s PC eventually. To avoid that, I decided to include this restriction. But I guess you should be good with 32 layers, right?


What’s planned and needs to be done

A lot of the key features are already done, but here are the things I will be working on next:

  • Eraser tool to delete tiles (already halfway done and just a matter of minutes).
  • Fill/bucket tool.
  • Selection tool for copy-pasting tiles.
  • Collision editor for visually adding colliders to the map directly on the Map Creator’s canvas.
  • Settings window
  • Help window
  • Change the current map’s tileset at any time.
  • The ability to actually save the maps! (LOL)

There’s probably more that I can’t remember now. =/

Anywho, that’s what this devLog is for, right? So updates are to come.


Additional notes

I’m trying my best to keep the code as clear and managable as possible (which is generally a good idea, lol) and provide documentation, so that people using this tools can extend it to their needs if they want to.

I plan on offering the tool for only a couple bucks on the Unity Asset Store. Don’t worry, it’s definitely not going to burn a hole in anyone’s wallet. I promise!


Visual impressions

Well, the headline pretty much sums it up. Here are a few visuals of YTMC. Remember that everything is still work in progress. Also, I’m not trying to showcase my mapping skills here. 😀

The tileset I used in this demonstration is from a game I created in cooperation with “Inferno Games” last year. It’s called “Runtime Error!” in case you want to look it up. Maybe I will post about it later.

image
image
image
image
image
image

That’s it for now

If your have any questions regarding this project, feel free to ask. I will try to update this devLog as often as possible to a reasonable extent.

Have a great day, everybody!