Wednesday, April 24, 2013

How To Make Stuff

So, if you've been following my progress, you might remember something like this from long ago:

My first script

What's depicted here is me editing the behavior of an object--I think it was a bush--directly in the level editor. Pretend for a moment that it was actually a useful script, like describing how the bush spawns a bunch of leaves and then disappears when the player slashes it.

Obviously an inline script editor is not going to suffice if there's hundreds or thousands of these bushes in the game, since I'd have to copy the script everywhere. And then if I needed to make changes to the script, I'd need to update the copy everywhere. This is similar the 'don't repeat yourself' philosophy of programming: common behaviors should be abstracted to one place.

When I moved away from Lua and into full C# (see this blog post), I needed a way to bind entities in the level editor to behaviors in C#. Just to get things up and running so I could experiment with the model, I implemented a quick hack which looked something like this:

Just a hack to get things going, not a feasible long-term strategy.

So, basically, I was attaching behavior to entities based on the texture of the entity, and in one case, parsing the tags of the entity to differentiate between behaviors. Terrible! But this was just temporary. So over the past couple days I've implemented it the correct way.

Now, Behavior Templates can be picked directly in the level editor! That means we can write a template in the Implementation assembly and it will instantly be available in the level editor:

What's even better, I can add custom properties to the template in code...

...and have them show up as editable fields (with possible default values--use the checkbox to override) in the editor:

So, now I have a pretty good system for designing reusable behavioral entities and them placing them in levels via the level editor. 

I put together a short video of the process for Adding New Stuff, from start to finish. In the video, I take a sample graphic of a ball and create a custom behavior for it with a few properties--which can then freely be used on any level in the game--in just a few minutes. Check it out! Also, make sure annotations are on and you'll probably need HD/fullscreen to see the code.

That's all for now. Back to screen communication and making those hearts react to the player taking damage!

Sunday, April 21, 2013

Screen Management

An important part of developing a game (and engine) is a robust system for screen management. My desire to add a basic 'player health' next led to the obvious requirement to actually display that health, but I hadn't developed any sort of HUD (head-up-display) system yet.

How much health do I have left? Where am I?

There's nothing inherently complex about developing a HUD compared to other elements in the game. In a way, it's even simpler, because the HUD elements don't move that much, don't collide, and don't need too much programming behind them; presumably they're just interface elements (like health) that update their display based on some sort of background model (the game state). But what about moving around and animating these elements?

I realized quickly that there's no reason not to leverage all of my existing infrastructure for new screens. Although the 'Sections' (levels) in Super Obelisk are designed in the editor and loaded from disk, this is merely a convenience--Sections can be generated on-the-fly in code, and entities that can move, animate, create other entities, and react to input can be dynamically added. So I decided that this dynamic creation would be used to create Sections that serve other purposes besides gameplay!

I actually decided to tackle a very simple screen management task first: pausing the game. Check the video below for a very short demo of...well, pausing. I know, it's not super exciting, but a lot of game development work isn't that flashy.

Feel the thrill of watching a game get paused multiple times in mere seconds

So, what does this look like underneath the hood?

  • The IGameInterface interface, available from any BehaviorTemplate (see previous blog entries, this is the code that controls all game logic), now supports a NewSection method that pushes a new Section onto a list of Sections that the main game loop controls. Theoretically, you could use this to divide the screen up into 4 quadrants and play 4 totally separate games at once (or, if the cameras overlapped, they'd just kind of all merge into each other)
  • So, when the player presses Start, a helper class called 'PauseScreen' with a single method 'Create'--which takes in an instance of the current section and the IGameInterface--creates a 'Pause' Section. It also calls a special 'pause' method on the existing section (the gameplay) which tells the engine to stop updating entities.
  • The helper class adds a few entities to the Pause section. A transparent black solid rectangle that fills the entire view (which makes it darker), some text that says 'Paused' (with a fancy entrance--see the previous blog post), and an invisible entity which will handle input.
  • The invisible entity is given an Update handler which will react to the player pressing Start again by unsetting the 'pause' property on the gameplay section, and destroying the current section.
And that's it! For those who are code-inclined, here is the entire source code for what I just described.

I've used these enhancements to the infrastructure to create a very simple HUD with a few hearts in the top-right corner. But when does a HUD get created? Shouldn't it always be there with the game? In almost all cases, yes. So, at the Entry Point for the game (which will, in the future, create a Section for a startup screen), I create two sections: the level (hard coded for now, or provided by the editor), and the HUD. Behold, the world's ugliest HUD until I get proper graphics for it:

So, back to what started this in the first place: I have a health bar now, so...what is it displaying? Why are there 4 hearts? Well, right now, it's because I hard coded 4 hearts in there. So, how do I get real game data--the player's health, inventory, number of times they've died, the status of all of the bosses, the walls you've blown up, and a myriad of other various bits of info, both temporary and persistent--from a section? Do sections communicate with each other?

Who owns the Game Model and how is the model implemented? Does the main game instance own a single model (red line), or do sections have access to it directly (gray lines)?

I don't think so. A better approach is to have a Game Model of some sort that Sections can access. I'll be tackling this architecture problem over the next few days, which should result in a demo of my player actually taking damage until they run out of health! Stay tuned!

Tuesday, April 16, 2013

Fun with Fonts

The picture says it all:

...well, not really. It says what this post is about, but it certainly doesn't show everything! As always, there's a  video for that! Make sure you watch in a large viewer and in HD, as it might be difficult to read the fonts on the screen (which serve as annotations) in a small viewer.

So, how does this work? Easy...for now. The current implementation--but almost certainly not final--is to use a single texture source for the entire font. It looks like this:

So, I wrote a quick utility to create a texture with one frame per letter (it could also be implemented as a bunch of textures, but it doesn't make any difference--the frame version is slightly easier from a coding standpoint). Once this was done, there were actually no new features required in the engine! Just a small helper function that creates the entities for you given a string. And that's it. All of the effects you see--including the final one where I slash the letters away with my sword--are just entity features that can be found in previous posts and videos.

This is a nice start, but there are a couple problems. 

One, I would like to be able to use any font, not just this pre-built one. This would likely be accomplished by setting up a pool of available fonts at design-time, and then rendering the characters of that font to an texture at run-time (that is, when the game begins). So, there is never an actual graphics file for a font (that I own, at least--of course, the operating system has a file somewhere).

Two, the kerning is non-existent with the current method. Kerning information is available via the windows API, and it shouldn't be too difficult to use (just a slight modification of the helper method) to properly space the entities once I have it.

However, this will suffice for now, and I'll come back to these features at another time. The fonts may not look perfect, but they can do some cool things!
Note: The font in the upper left corner showing diagnostic information is rendered in a different (less flexible) way, so this is definitely a new feature.

Sunday, April 14, 2013

Fight the Darkness

I know I said I'd get into something like a health meter for enemies this time, but I got a bit sidetracked. I added lighting! And a boomerang, and jumping! A few screenshots, but be sure to watch the video at the bottom.

Lights are simply entities on a special layer that's marked as a 'light layer'. Like other entities, they can be manipulated in a variety of ways, use any texture and color, etc. This week's video will show off some of the features. Check it out!

Hopefully I can throw together a more technical blog post to explain the lighting if anyone is interested, but for now I'm out of time. Until next time!

Saturday, April 6, 2013

Player Takes Damage! Retaliate!

Okay! Big update from a technical standpoint, small update from a gameplay standpoint. Warning, if you don't really care much about technical stuff, you might want to scroll down to the second screenshot and start from there!

In my previous post, I demonstrated how a simple 'spike' enemy might be programmed, and provided the Lua scripts that control its behavior. Well, sometime in the middle of coding those behaviors, I realized how difficult creating robust code for more complex behaviors is going to be. So, I took a step back and asked myself 'why are these behaviors in Lua?'

I originally chose Lua as a scripting language for several reasons. It's lightweight, popular (not a reason in itself, but it generally means more community support), relatively fast, and easy to use. But writing extensive game logic in scripts beyond basic sequential commands has a number of disadvantages:
  • Debugging is difficult in scripting languages
  • Development is a more tedious process, since you don't get intellisense or any other productivity-boosting features of a good IDE
  • Invoking scripted methods is always going to be significantly slower than compiled code
  • Weak built-in libraries and language features compared to C#/.NET. Also, it's much easier to write run-time safe code in a compiled language.
  • The engine is already in C#, so having no cross-language boundaries is an advantage.
One reason I wanted a scripting language in the first place is so the game could be ported by having the majority of content in Lua scripts with a slimmer engine that could easily be converted to C++ if needed. However, I can use Mono in the future instead if I really want to.

So, with this in mind, I've decided to go C# all the way. Because all game logic is in a separate assembly with no dependency on the engine, it can be considered a 'plugin'. It is bound at run-time rather than compile time. The below picture demonstrates how my assembly structure is set up:

So, things like 'player' and 'spike' (currently the only two complex behaviors I have) live in the Implementation assembly. The game engine (and thus the editor) dynamically load this assembly at run-time and use reflection to instantiate 'Behavior' objects (or, in the editor's case, let the user assign behaviors to an entity. I haven't actually done that part yet.)

So, yeah, the result of all this stuff is that I'm not using Lua anymore. I may or may not use it in the future for simple behaviors (i.e. this switch opens that door, etc), but all complex behaviors will be in C#. And with the way I've structured my project, the engine can be used by anyone who wants to build their own game--they simple need to implement behaviors in their own assembly and modify a text file which tells the engine what assembly to dynamically load.

So, this conversion took the majority of my time this week, but I still had a little time to have some fun. 

Here's some things I did for fun after converting everything to C#:
  • Enhance the trigger infrastructure to take arbitrary trigger arguments. For example, the 'DamageEnemy' trigger might take 'damage amount' and 'damage type' as arguments, and also a 'damage direction' that an enemy that receives 'knockback' might use.
  • Made it so the spike enemy can 'damage' the player. There's no damage meter yet (maybe next update?), but there's a cool knockback-and-temporary-invincibility effect very similar to how 'A Link to the Past' handles damage. See video below for a demo!
  • The player can slash at the spike enemies to similarly knock them back. Also shown in the video.
Okay, here's a video of all that stuff in action:

One thing worth mentioning is how the the game handles the enemy collision with the player's sword. Here's the source code for that part:

Here is a short video showing how it works. Note that for the video I've dramatically slowed down time, zoomed in, and turned the opacity to 0.7 for the 'sword' entity instead of 0. The rotating white block is actually what's doing all of the work here!

And, if you're interested, a brief translation of the code to English:
  1. Translate the player's 'facing' variable (left, right, up, down) into an angle.
  2. Create a 'sword node' at the player's position. This is because I don't have support for rotation 'around' an arbitrary point, so to simulate that I use entity parenting--create a node, attach the thing you want to rotate to it as a child (and position it relative to the node), and then rotate the node.
  3. The line 'swordNode.Control(...)' sets up rotation from sourceRotation to targetRotation. The arc angle (it's declared outside of the shown code) is about 33 degrees (pi * 3 / 16). 
  4. Create an actual 'sword' and append it to the node. Note that the sword is an abstract thing and not visible--the graphic for the player has the sword 'built-in'.
  5. Position it 30 units ahead of the player and give it a certain size.
  6. Attach a collision event to the invisible 'sword' object. The callback (an anonymous method here) simply invokes a trigger on the target entity (it uses the player's position to calculate the knockback direction). The collision event's current target is 'spike', but in the future we'd make it 'enemy' or even 'takesSwordDamage', and make all things that can be hurt with a sword handle that trigger.
  7. I attach an 'update' function to the sword which generates some particles as it swings.
  8. I set a texture for debugging purposes, but set the opacity to 0, so you can't see it.
  9. Finally, I run the animation for the player and when it's over set its state back to 'standard' (the code above actually runs in the initializer for a 'swording' state).
Okay, that's all for this update. I hope it was interesting. Next I'll be adding a health meter to the player and to enemies, or something of that nature.