Categories
Game Design Game Development Geek / Technical Linux Game Development

Stop That Hero!’s End of January Progress Update

Halfway through January I gave a progress update for Stop That Hero!, and in the two weeks since, I’ve accomplished a fair bit.

Recap

In the beginning of the month, I did work to create a command system, separated the game’s simulation from the rendering of it, and even added some game play related to the Hero conquering towers. There were other things accomplished, but they were slight changes compared to these major pieces.

Treasure Collection

Since then, one of the things I worked on was treasure collection. Items can be collected, which basically means running an arbitrary command. Since I don’t have much game play in, there isn’t much implemented in this regard. Right now, if the Hero comes across a treasure chest, it just disappears. Well, actually, it has its targetable component turned off so that the Hero ignores it, and it changes its renderable component so that it draws something other than the treasure chest sprite.

Why? Because I haven’t needed to delete game objects before, so there’s no way to do it. Also, I apparently never needed to hide sprites before, so there’s no way to do that, either. The “hacks” are functional for now, so I can move on to other things. I’ll come back to change these when I need to, and I may be surprised to find that I won’t need to. I already do enough unnecessary work as it is, so there is no need to add to my burden. B-)

Enemies

The next major thing I did was create a slime monster to chase after the hero. With the command system, it was as easy as creating a new command which populates the datastore with components that make up that monster. I simply took the CreateHero command, did some copy-and-paste magic, then modified its speed and the renderable component. Now I can create a slime as easily as a Hero!

Except I had no way to interact with the game yet. How did I test that the command worked? I changed the level loading code. Any treasure chests or towers defined in the level would create slimes instead. When I ran the level, the Hero had to find his way to the Castle past an entire army of slimes slowly approaching him like zombies!

Stop That Hero! - Slimes Everywhere!

Once I was satisfied that the new Slime would work within the game, I changed the level loading code back.

Front-end Architecture

The game simulation is well-defined and is easy to update. If I want to add a feature, it can be as simple as creating a new UpdateSystem, perhaps with associated components that entities can make use of.

As happy as I am with the internals of the game, I was getting frustrated with the user-facing parts. Getting from initialization to the menu to the level selection screen to the game session was poorly-defined and hard to change. I haven’t even provided a way to quit the game outside of clicking the application window’s X. When I wanted to work on providing menus for the player to click on in-game, I realized I had to do something about the front-end if I was going to make the UI work easier on me.

Here’s how my application’s architecture looked:

Old Game Architecture

As you can see, the game took up the lion’s share of the application. There was no concept of screen transitions or anything like that. You were either in a complex menu, or you were playing the game. I had no concept that a game application was anything other than a game.

I spent a few days figuring out the approach I should take. I didn’t realize that my game isn’t everything at first. It’s a tiny part of the full application. To flesh out that application, I settled on creating a state machine. I don’t know why I didn’t think to do it before. I’ve done it for Game in a Day back in 2005.

I spent a few days coding up an implementation of a state manager, and I spent a good chunk of my time at the Global Game Jam getting individual states implemented. My application is now run by a high level state machine, which looks close to what I designed on my white board.

Stop That Hero! state machine design

In fact, something like this has been scribbled down multiple times in notebooks and scrap pieces of paper every time I stopped to think about the high level, and it is only now that the state machine is actually implemented.

Also, note that there is one state I call “In-Game Session”. It’s in this state that the game runs. In terms of number of states, it only makes up about 10% of the application!

And additions and changes are easier now. If I wanted to add an Options screen, it would have been difficult to shoehorn it in my old architecture, but now I can simply create a new state. It’s kind of like programming tiny applications that work together.

Now the application’s front-end feels as good to work with as the game code, and since it makes adding and updating application states/modes so easy, I wish I had implemented the high level state machine in the first place.

User interaction

As great as all that rearchitecting is, I still didn’t have a way for the player to interact with the game simulation. Without interaction, it’s not a game.

So how do I add interaction?

Well, it’s the part that I don’t have working yet. Here’s how I approached it so far:

I have the game running as a LevelInstance, which has a collection of UpdateSystems and the database of game objects/components. I created a View that has a collection of RenderingSystems and access to the LeveInstance object.

I didn’t use Model-View-Controller because I didn’t feel it was a very good fit based on my understanding of how it would apply to a game.

If you’re familiar with MVC, the LevelInstance is the Model. So the V part of MVC is obvious, right? Not exactly.

My View is quite dumb. All it does is get information from the model and render it. The game simulation doesn’t care how it is being rendered, and in fact, I can have multiple views attached to a running game.

Ok, so far, so good. What about the Controller?

If you read about MVC, you don’t typically put business logic in the Controller. If I was making a game where you controlled an avatar with direction keys and a jump button, I think I could make things work fairly easily. The Controller would detect button presses and send commands to my game that make sense. For example, if I press the Spacebar, the Controller maps that to the Jump command, and the model knows that the player should jump, never caring that the Spacebar or another key was pressed.

But in Stop That Hero!, you’re not controlling an avatar directly. You are clicking UI elements. Here’s how I envision the player’s interface:

Stop That Hero! Pie Menu Demo

When the player clicks on a tower he/she controls, a pie menu appears around that tower. Each of the four items represent what monster can be created.

Here’s where I’ve been struggling.

If the View knows nothing but to render what’s in the model, and the Controller simply handles input and processes commands, who owns the in-game UI? Does the Model need to provide logic for the View to know what menus to display and how to display them? How does the knowledge that a mouse click (Controller) happened over a tower (View using Model data) get turned into a menu, and then who is in charge of that menu? These struggles were why I wasn’t happy with MVC as the way forward.

Until I had a discussion with Larry, that is. He is way more knowledgeable than I am when it comes to software architecture, and he pointed out that Web MVC is different from MVC.

In Web MVC, the View is simple and dumb.

In a regular MVC, however, the View might have so much logic and data that it rivals the complexity of the Model.

I’ve never thought about the View in this way before! And yet, it seems to make sense. Using StarCraft as an example, the actual game simulation is a complex RTS. Yet, there is a bunch of code to implement the interface that the simulation doesn’t ever care about.

For instance, if you’re playing as the Terran,what happens when you click on an SCV?
StarCraft SCV Unit

  • The SCV in question gets a little circle drawn around it to let you know what unit is selected.
  • The Status Display changes to reflect information about the SCV, such as health, armor strength, how many kills it has, etc.
  • The command buttons at the bottom right change to reflect actions the SCV can take.
  • The portrait changes to static before showing the face of the SCV’s driver.

StarCraft SCV

And until I had this discussion about heavy vs light Views, it never occurred to me that all of those things happen without the game simulation knowing.

If you tell the SCV to move to a specific location, the game cares. If you command the SCV to harvest minerals, the game cares. If you make an SCV repair a bunker, the game cares. Yet, all of the logic dealing with clicking on buttons and units is in the View. It’s only when the player actually does something that results in a command to a specific unit that the game model cares, and even then, it doesn’t know you clicked anything or hit a hotkey. It merely receives a command from somewhere saying “SCV 1 MOVE TO X, Y” or something like that.

Sometimes I struggle with knowing where code should live in my game’s architecture. With the restructuring of my application into a state machine and a good discussion about MVC, the way forward seems clearer. Stop That Hero!‘s player-facing code needs to be a lot more involved than I originally expected. While the game logic is where a lot of the simulation occurs, the interface has a lot of its own logic. It was logic that I knew needed to be implemented, but now I know where the code’s home is.

8 replies on “Stop That Hero!’s End of January Progress Update”

Interesting discussion on using MVC for your architecture. I like how you broke down the SCV example. I’ll have to remember that when I work on my next game.

Regarding using state machines to manage your game application, that’s something I’ve always struggled with. I always try to create general state manager code so I don’t have to rewrite it for every project, but I always find examples of how I can complicate things. The biggest struggle I have is handling state transitions. Each state should probably have a “transition in” and “transition out” animation, but what if I want to blend these together? One state’s “transition out” might not be mutually exclusive with the next state’s “transition in”. Also, what if a state acts as an overlay? For example, the in-game pause menu might just be drawn on top of a faded game screen. Should the pause menu be a separate state, or is it just a substate of the in-game state?

One of these days, I’ll figure it out. In any case, I do enjoy reading about your game dev work. Keep those posts coming!

Thanks, Daniel!

Regarding MVC, I don’t use it very strictly, if at all. My game might more accurately look like MV instead of MVC. I wasn’t trying to do MVC so much as find a good pattern for separating the interface from the game, so I might end up with something very different from pure MVC anyway.

My current implementation of state machines doesn’t do any transitions yet. It’s just immediately a new state. I can see doing a fade as part of a running state before doing a transition, though, and then the new state would fade in before it would handle updates.

In a way, it’s like having substates: FADE-IN, RUNNING, FADE-OUT, or something like that. It doesn’t have to formally be a mini-state machine, but it sounds like it would function that way.

In my own example, I found that instead of having separate states for the Main Menu, Instructions Screen, and Quit Screen, they were already handled within a menu. So the Main Menu state has a multi-page menu and only switches state when a New Game option has been selected.

On the other hand, my In-Game state will push a Pause state on top. What it means is that the In-Game state can continue updating and drawing under the Pause state. I suppose if the Pause state needs in-game data, it might make sense to keep it as part of the game instead of making it a separate state.

I think that the general state manager code will stay mostly the same from project to project, but each project will have to figure out its own transitions between states and probably what states are available.

MVC is a pet peeve of mine, really: http://www.garfieldtech.com/blog/mvc-vs-pac

What most web developers call “MVC” isn’t. It’s a different pattern pushed by Sun in JSP that everyone adopted, even though it’s a frequently bad pattern. It also has little if anything to do with traditional MVC, which is what makes sense in most GUI applications.

It’s also not uncommon for the Controller to get absorbed into the View in practice. Having that separation is nice, but not always completely practical. That will vary with the application.

Great to see it coming together, GB!

Hey Gianfranco,

Good to hear you’ve gotten so far along. You’re putting a lot of thought into each step, which is a red flag in my head. Can you get a dirty version of the game up and iterate on it at all? The most important part of your game must be how a player can sell it to another player. If I were to make another game it would be with that in mind (so make a slightly minimal game but made with ‘viral’ in mind.

Diwant

Thanks, Diwant! As for a minimal and “dirty” version, I’ve hacked together a prototype already. If I’m doing too much work now, it is less because I’m overengineering and more because I never had the basic tech and tools. I never did more than a small prototype, and a larger project’s scope (and the lack of 2D game engines that work on Linux) is revealing a technology requirements gulf I’m currently filling.

What I’ve found is that hacking something together might seem quick for a day, but then I struggle later with crap software. For instance, if I hardcoded the menu, it would work that hour.

But what happens when I want to change the menu? Or change how the player accesses that menu? I suppose I can continue hacking, but eventually I’ll hit a point where a relatively simple change requires messing with a ton of dependencies and code that makes no sense.

I agree that it feels like the “Game” is progressing very slowly at the expense of tech work. I am careful not to spend my time making a general purpose game engine, but without the infrastructure, I don’t have a base to build the game on.

I suppose it would be easier for me if I wasn’t a Linux-based game developer working in 2D. I’d probably use Unity, XNA, or Flash, but I’m also trying to avoid proprietary technologies. All of this conspires to a lot more work than expected.

As for viral loops, I’d like to focus on getting a playable game first.

@Franco That makes sense to me as a developer, but as a business person I would have to ask who is asking you to change the menu so often? If it is a group of people paying or ready to pay, cool. Otherwise, set it down and move on.

It’s widely understood that the interface IS the game, so if I’m making a game I intend to sell, the interface is important.

And the menus aren’t a crazy big job anyway. The big concern was not knowing how to implement them in terms of the software architecture. How do you create an interface to the game if the front-end is supposed to be dumb? The answer is that the front-end isn’t supposed to be dumb, and in fact, it can rival the complexity of the back-end. That was the point of this article: to point out a realization I had about the nature of a game’s player-facing interface.

And without the menus and a general front-end for a player to interact with, there is no “Stop That Hero!” game. I can’t set it down and move on because then all I have a simulation, and people aren’t going to buy non-interactive simulations.

Since this article, I found that the menus were fairly easy to implement by modifying my existing menu controls to accommodate arbitrary offsets and alignments. My unit tests made it easy to add the functionality I needed without worrying about breaking existing functionality. Again, the menus weren’t the big job. It was knowing where they should live in the application that was the problem.

As a designer, I need the ability to experiment with changes, whether it’s menu configurations or some other aspect of the game. If every change requires me to put on my programmer’s hat, it slows me down ultimately. The business owner in me says, “Do what makes it easier to make better games.” Sometimes it means programming a solution with a lot of assumptions just to get something done faster, and sometimes it means programming a solution with flexibility. In the case of the in-game menus, I’d like to be able configure menus in various ways. For a game with a menu-driven interface, it makes sense to me that the business demands the creation of configurable menus.

I’m keenly aware of the problem of over-engineering at the expense of the business. It would be one thing if I had a perfectly workable set of technologies I can leverage and I was wasting time making them marginally better. It’s another when I have NOTHING to build my game with and can’t find suitable 3rd-party components that fit with my goals to build a cross-platform (which includes Linux-based platforms), 2D game with few dependencies. I don’t want to roll my own tech, but any existing tech I could leverage essentially asks me to give up doing what I’m trying to do.

Comments are closed.