Monday, June 10, 2013

Return from vacation!

I've been in Europe for the past 9 days or so, which is why there wasn't any update this week. Obviously, I didn't really get much done, but I was able to do some old-fashioned level design. And I mean really old-fashioned: by sketching out maps in a notepad.

So, with absolutely nothing else to offer for the last week, here's one of the sketches of one of the several immediately available to the player at the beginning of the game.


Next up for this week: I'll be solidifying and finalizing the structure for Layering. The steps for this are as follows:

  • The current system has a hard-coded Layers structure with a fixed number of Tile Layers and Entity Layers. These are hard-coded into the engine, which isn't good, because not every game is going to use the same layer structure. So, the engine will instead search for defined layers in the Implementation assembly and dynamically use those layers in the level editor and game engine.
  • The first bullet point is pretty easy, but this next one is going to be a major change. I want to allow for layer-over-layer scenarios: that is, not just a simple drawing order, but also entirely different sets of layers that overlap each other. So, let's say my game has 5 layers: ground layer 1, ground layer 2, entity layer 1, entity layer 2, and ceiling layer 1. But what if I want an entire section above another section? It would be very limiting to just create 10 hard-coded layers in the implementation assembly. Instead, I'm going to split the level structure into Slabs which each have a collection of Layers. Slabs will also serve as physical (that is, they affect game logic, not just drawing logic) separations of entities. A special entity behavior will transfer the player between slabs--this might occur, for example, at the top and bottom of a ladder. The end goal of slabs is to allow scenarios such as walkways that pass over other parts, and the ability to walk underneath those walkways.
  • Once slabs are complete, the lighting engine is going to have to be updated to support slabs correctly. A single layer of lights will no longer be sufficient. The bottom slab (closest to the ground) will receive light from all slabs, but upper slabs won't receive light from slabs underneath them.
  • Game logic needs to be updated such that the creation of entities is not done on a Section, but on a Slab. That is, the code 'section.CreateEntity(...)' is no longer valid, since the engine wouldn't know which slab to put it on. Instead, the command slab.CreateEntity(...) will be the way to spawn new entities dynamically.
  • Finally, I'll have to update the level editor so that the user can add and remove slabs, and switch which slab they're working on. It would also be nice to view just the current slab being worked on in isolation, or a full view of the level at once. This will probably be the most boring part of the update, but good tools are essential, so it's very important to do this correctly.
Will the update come this weekend? I don't know; this isn't a small feature, and it's definitely one I want to get right. I've been putting off real level design until this part was done, because it will change the structure of the file so much and I didn't want to waste time writing data migration utilities.

So, I'll see you when it's done! For more gradual updates, check my twitter, https://twitter.com/ericswheeler

Monday, May 27, 2013

An Explosive Update: Melon Bombs

Okay, I added a cool new item to the game, the Melon Bomb.


The artist promises not everything will have skulls on it. But come on, it's a bomb.

BUT before I get to that and the accompanying video, I just wanted to point out that Super Obelisk is 100%  rendered in OpenGL now. I have nothing but praise for the folks behind SlimDX, but in the end I wanted to open up the potential for ports to Mac/Linux, and consoles. The game feels best with a gamepad, so the push to consoles is a pretty attractive prospect.

Anyway, I'm using OpenTK now, which is a framework that includes C# bindings to OpenGL. This, combined with Mono (cross-platform implementation of C#/.Net) should make the porting process smooth.

So, yeah, that took a bit of time, since I haven't touched OpenGL in many years, but overall it was a pleasant experience. I was pretty eager to get back into developing something concrete after getting things back to where they were, so I thought up the Melon Bomb, which is a bomb that happens to look like a melon.

You can lay the bomb down. You can toss the bomb in front of you. Or, you can charge up a throw and launch it across the screen at your enemies! But why read about it when you can watch it all in action? As always, here's this weeks video. As always, best to open it up and put it in HD with annotations on, since they explain what's actually happening.


No new infrastructure was required for the bomb update--just a new behavior and a new graphic asset. That's a good sign--that means engine development is slowing down and game implementation is speeding up!

Until next time!

Sunday, May 19, 2013

Framework conversion

Unfortunately there's nothing fun to show this week, because I'm doing a conversion of my graphics engine from SlimDX to OpenTK--under the hood, this means Super Obelisk will use OpenGL instead of DirectX. 

The reason I'm doing this now is to ease the process of potential porting. Thanks to the efforts of the folks behind Mono, I can continue to write the game in the language I love, C#, and still have the ability to port to Mac, Linux, and whatever other platforms (consoles, handheld) can run Mono. The problem is that DirectX is not supported on these platforms, and OpenGL is. I selected OpenTK based on the fact that it's what MonoGame uses.

I haven't used OpenGL in many years (since college), and even then, my experience with it was fairly trivial, so I've been spending the last couple days learning the ropes. And by the 'ropes', I mean things like this:

Super Obelisk: Now a game about a lonely cube in a strange world

I'm a bit further along than that now and I'm ready to actually convert my codebase to the new framework, so that's what I'll be doing today.

Sunday, May 12, 2013

Rain and the Blob Enemy

Welcome back! I have a lot of neat things to show off this week! Video is at the end of the post if you want to skip straight to that.

1. First up is a Rain Effect. This actually required very new little new engine infrastructure to create. I had to implement Texture Offset to actually animate the rain. Instead of using particles for the individual falling drops, it's just a big rain texture repeated over and over and shifted every frame to create the illusion of falling rain. The video at the end of this post shows the evolution of the rain effect.

It's rainy

2. The return of the Fade Transition. You might remember from previous videos that this had existed at one point, but I lost it in the infrastructure conversion (Lua --> C#). You can see the fade transition in the video about halfway through, when I enter the temple.

3. A Blob Enemy. I don't have a name for this thing yet, so let's just call it Blob. Look at it. Look at that thing chomp.

Okay, so the source material is pretty cool. But this enemy represents a key development milestone: this is a real enemy with real behaviors. 

Generally my engine development pattern is to attempt to make realistic game scenarios and use them to discover what the engine still needs to make them work. There's a popular saying in game development circles: make games, not engines. This doesn't really mean that you shouldn't make an engine, but it does mean that you shouldn't make an engine in a vacuum--that is, an engine without test cases to drive it will probably end up being useless when it comes to practical application.

So, anyway, back to the blob. The blob has a more complex state machine than the previous demo enemies (spike, ghost) I've created. This led to some issues where state management was difficult when states were interrupted and various animations hadn't completed yet. For example, when you get near a blob, it compresses before jumping at you. If you hit it during this animation, it gets sent into another state (knockback) before the animation completes. These effects are achieved with entity controllers, as shown in a previous blog post. After the compression effect of the blob, it has a command that sends it into an 'jumping' state. We don't want this to run anymore if the blob was interrupted by an attack (and sent into the knockback state). To solve this, I introduced state-local controllers. That is, they are controllers that are discarded if the state changes, since they're 'owned' by the current state. This makes for a much cleaner programming model.

This is sort of hard to explain without code examples, so look for a post later in the week which shows the blob source code with an explanation of how it works.

4. Hue Shift

In the video, you'll see the blob flash colors when it's hit. This is actually done with a pixel shader that shifts the hue of the entity, rather than attempted to just change the color of the vertices (which doesn't work--a green image with red vertices appears black).

Hue shifting the blob


Anyway, here's the video. Enjoy! Recommended HD/fullscreen/annotations on.





Saturday, May 4, 2013

Adding Player Health

Video is at the very end of the post in case you want to skip straight to it.

Two posts ago I introduced a new Screen Management architecture that I had implemented. Currently, Entity state can be easily managed and manipulated by using Behaviors. Additionally, Sections can be created and destroyed (and rendered at the same time, with different cameras). But what if two Sections need to communicate to each other? For example, Player Health is something that both the game screen (so enemies can reduce it) and the HUD screen (so it can be displayed) need to know about!



Both 'Sections' need to know about a shared variable, Health.

Entities are local to a section and shouldn't be passed around, so we don't really want to use a behavior attached to an entity to do our work.

One option is to use a Global state object of some sort. But that's no good, because globals are generally difficult to manage and lead to poor design. For example, if I wanted to load a game, I'd have to manually implement a 'reset' on the game state. With proper object management, I should be able to just toss out the existing game state and replace it with a fresh one. In addition, a global state would imply nonsensical designs where you could access the player's health from the title screen. So, no to globals.

Another option is to tie a Game Model (this can be any object you want) to a Section, but allow the model to be shared across sections. This is the design I ended up implementing. Here is an example of how the main game might be set up with a shared model:


The code that sets up a simple shared Game Model

Once this is done, Behaviors can access the Game Model. For the sake of convenience, I've decided to introduce a base class for behaviors that belong in-game (as opposed to, say, stuff on a start-up screen). Here is a sample (and simple) usage:


Highlighted is the code that makes the player lose health. Simple!

Note that I've added a 'damage amount' variable to the 'DamagePlayer' trigger. So now what? Well, I've created some Hearts that live in the HUD Section. Each Heart has an update method that polls the game model to determine how it should be displayed. For example, if the current health is 5, and the heart is the 7th heart, the heart should be invisible. If the current health is 5.5, and the heart is the 6th heart, then we'd show a partial heart (for the sake of simplicity, I just draw it at half-scale).


The player has 5.5 health remaining

As always, there is a fun little video of everything in action. Some notes:
  • As a demo of both subtracting and adding health, I've added a simple little ghost enemy that does damage proportional to its size and little heart pickups. The ghost in the first room does 1 damage, the bigger ghosts do 2.5 damage. The heart pickups restore 1 health.
  • The model caps the player's health at 8 for this demo. You can see that additional heart pickups, once full, don't give the player more health.
  • I'll be adding game music to the videos just for flavor. This is being played through the game's audio engine, which I added recently (it wasn't worth a blog post--it's pretty simple for now). Of course, once I get my own music I'll be using that!
  • The ghost enemy is just a demo whipped up in a few minutes, nothing necessarily permanent. True enemy design will come at a later phase.
  • I had to re-implement section transitions after changing from Lua to pure C#, but hadn't gotten around to actually doing it until this week. 
Anyway, the video. Enjoy!



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!