Archive for August, 2010

It’s official. InfestedRL has failed.

More specifically, my 7 days roguelike challenge had failed. I am especially frustrated because I spent more than 10 hours a day working on it and still by the end of the week I’m only about 40% there.

This will be a long post-mortem in the most brutal fashion.

Engine work is IMPORTANT

I went into the challenge without finishing the engine first, thinking that since I had a prototype done in the past it would be little work to expand it into a full game. Truth? That’s about the stupidest idea ever conceived in my life.

Here’s what the engine could do before the 7DRL:

  1. Have a primitive rendering system in place
  2. Have a primitive entity management system in place
  3. Can render a player sprite to the middle of the screen, and move it around
  4. Have resource managers to manage resources needed in teh game

Here’s what I wrote in the week, including refactors:

  1. Previous animation system didn’t stood up to the test. It became messy quickly, forcing a refactor that took 2 days to implement and test.
  2. Entity management had to be expanded because of the lack of foresight.
  3. Camera entity written to isolate camera related code from the player entity
  4. Wall code re-written
  5. Scene loading
  6. Dungeon generation

Here’s what I still need to do:

  1. Refactor the input management system
  2. Refactor the entity management for flexibility
  3. Refactor render code to pre-calculate more things
  4. Save/load scene
  5. GUI system
  6. Time/turn management system
  7. Scene switching and global state management
  8. Message system
  9. FOV and LOS system

See that? The list of features needed in the engine grows exponentially once you get down and dirty into the game code. You can sit in front of the monitor the whole year, planning the game on paper, thinking that you know everything you need, but once you really start coding you’ll ALWAYS find out that you haven’t done enough planning.

Could this been prevented? Unlikely. It is an experience problem – this is my first time writing a game, and naturally, I know less than I think I do. The only way to prevent this is to continue on InfestedRL, finish it and release it.

In summary, engine work is crucial. In my experience, engine code takes 90% of the work while scripting only takes less than 5% of the time. The actual “game programming” takes very little time if you have a good engine working in the first place. If you don’t, be prepared to waste time refactoring a lot of things.

Animation system is not a smart idea

Early in my designs, I decided that I wanted to make a graphical roguelike.

Bad idea.

No, making a graphical roguelike isn’t a bad idea. Making an ANIMATED graphical roguelike isn’t too. Trying to do that in a 7DRL is however, downright moronic.

I took 2 days to write the animation system, and another day to fix it when I realized that it was insufficient to handle what I am planning to do. And another half a day to refactor a minor portion of it when I realized that my entity management system isn’t tied in well enough to the animation system.

Conclusion? Never attempt animation if you never did it before, if this is your first time writing a game, and if you have a very limited time frame to do it.

Optimization is about experience

I didn’t know that per-pixel alpha would kill the frame rate so much. Took me 2 hours to figure it out, and then another hour to convert all my tilesets to 8-bit PNGs with colorkeys and dithered alphas, which sped up the frame rate back to playable speeds.

Which brings me to my point – knowing what to do in order to get an optimized frame rate output depends on your experience in writing games. The more you write, the more games you publish, the better you will understand what kind of requirements your game needs in terms of assets and resources. What kind of file format, what kind of pixel format, etc.

I think this is the best thing the 7 days challenge had taught me. I believe I’ll learn more once I release InfestedRL.

Don’t be too ambitious, n00b

If this is your first time working on a game, do something simple. Writing a pac-man game would teach you the EXACT SAME lessons you would have learnt from writing a roguelike. Well, at least this is true in my case.

Animations, game states, global variable tracking, game logic, etc, most of them are similar in games, be it a roguelike or Tetris.

Starting with a roguelike is generally a great idea, but do not be too ambitious. A dude walking around a dungeon killing goblins (only 1 monter type) with a wooden sword (only 1 item type) is a good enough scope. Trying to add in spells, multiple monsters, bosses, and such would severely tax your capabilities to finish it in the first place.

So don’t bite off more than you can chew.

What I ended up with

I will continue work with InfestedRL, and hopefully release it sometime before the end of September. Since this is no longer a 7DRL, I’ll be adding in cut features like multiple survivor types and more monster types.

Day One is over, and here’s the list of things I’ve done:

  • Tween animation
  • Tileset animation
  • Rendered floor tiles
  • Camera with culling
  • Move character on screen

What went right

A working version of GORE (graphical object-oriented roguelike engine). By far the best thing that went right was the preparation I’ve put in prior to this challenge, and now it’s showing the results. The engine’s working fine, majority of groundwork had been laid down, and I have the prestige of fucking up the first time around so this time I know what to code and what not to. That’s incredibly valuable considering that this is a challenge with limited time, and the scope of this challenge is (admittedly) pretty ambitious.

Next thing that went right was the camera code. After spending 5 hours fiddling with the camera code, a lucky shot at an algorithm that I half understand worked on the first shot. And I had to spend the next 30 minutes figuring out how it went right.

Finally, the art. The tilesets, character animations, they were all done in the past few weeks, and provided me with something nice to look at while I perfect my code. While a simple ‘@’ is good enough for roguelikes, having nice graphical stuff moving on screen is really a good morale booster.

What went wrong

The fucking camera. Did I mention that I spent 5 hours on that thing? In a 7DRL, 5 hours spent working on something small like that is really a waste of resources. I should have finished the camera code BEFORE starting the challenge, but shit I had to procrastinate. Bad, bad mistake.

Next is sheer inexperience. This is the first time I’m coding a game, and I’m glad I started with a roguelike. Because I couldn’t have imagined coding a complete RPG with my current skills. Take for example, how to store entity information. Took me 2 refactors to get it right, and still I think I need to refactor it again some time in the future.

What to show

Here’s a video showing the results of day one:

Sigh, I’m not even 50% done with GORE before the deadline hits me like an unstoppable train.

Today is the date I promised to begin the 7DRL challenge. And begin I shall. Here’s the game description, with the MASSIVELY cut down features list.

InfestedRL is a coffee-break roguelike where you play the role of an amnesiac survivor trapped in a stone labyrinth, surrounded by devious monsters. You have no means of killing them, and you are not going to risk to find out how.

You need to survive, and escape.

In your cloudy memory you remember an exit 4 levels above you. With monsters chomping down the front door, you take one last look at the coffin where you awake from, before slipping out the rear door.

Good luck. You’ll need it.

Gameplay

In the labyrinth, you may find 3 items, each which would improve your survival odds. First up is the buzzer. Drop it and it’ll start buzzing, attracting the attention of all sound-sensing beasts. Next is the scent suppressor kit, which is a form-fitting full bodied suit you can wear to hide your scent for 20 turns. Finally, there’s the emergency construction kit, which you can use to build barricade blocks which will hamper the progress of the monsters hot on your tail.

For all you know, there are only two kinds of monsters: chompers and whiners. Chompers hob around with a maw full of teeth, and seek out prey by noise. Whiners on the other hand slither around like disgusting slugs, searching for prey by their scent.

Also, you have a special ability called the desperation feat. You can trigger this to stun all monsters on screen for 5 turns, but the catch is every use of this desperation feat reduces your sanity by 1. If you lose all sanity points, you become a monster yourself.

Finally, you have health points. Every time a monster takes a bite off you, you lose a point of HP. When it reaches zero, you turn into stone – a grisly reminder to all other survivors of the consequence of failing. When you die, you, the player, will get to control another survivor back on the first level. The game world is persistent – any barricades erected by the last survivor will remain, and all chests looted will stay empty. There are a finite number of items available in the labyrinth. Good thing is, when a survivor dies (turned into stone), you can break the statue to get back the items held by that survivor. If a survivor turns into a monster, items held are automatically dropped.

There you go, the complete description of the game. Wish me good luck!

UPDATE 4.13 AM:

Done:

  1. Finished renderable and animations
  2. Got a character moving on the screen

Next:

  1. Write camera code
  2. Move the character around the screen
  3. Render floor tiles
  4. Culling algorithm for the camera

UPDATE 6.10 AM

Done:

  1. Tested tween animation
  2. Rendered ground tiles

Next:

  1. Write camera code
  2. Move character around the screen
  3. Culling algorithm for the camera

Progress Links

Day One Post Mortem

The venerable Todd Howard of Oblivion and Fallout 3 fame explains why Fallout 3 didn’t have ladders:

Bethesda Game Director Todd Howard admitting during a panel at Quakecon today that one of the gameplay features the studio continues to cut game after game is the inclusion of ladders for players to climb without fading to a loading screen.

“Play our game; find a ladder that you can use. We don’t have them,” he said.

Howard explained the primary reason for not being able to include ladders into environments is due to their engine, saying ladders caused problems for character AI.

“One day, we tried to figure out why we wanted ladders so bad because we don’t really need them. It just felt like we’re game development pussies because we can’t do ladders.”

http://uk.xbox360.ign.com/articles/111/1112469p1.html

What a load of bull shit. Come to think of it, Oblivion and Morrowind didn’t have ladders too. It took 3 games on the same engine and still they can’t figure out a way to implement ladders in the game.

Consider this: when Half-Life was released, somewhere down the line came bot mods that were done by amateur modders. Developed by small teams (read: one-man shows), these bots have zero problem climbing ladders.

Now think: Bethesda have an entire fleet of programmers, and none of them could spend time to make the AI use ladders at all? For 3 games?

That’s not an excuse. That’s a fucking disgrace. And I suspect it has nothing to do with their programming department. I suspect that it was a high-level decision not to include ladder-handling AI, simply because the game designers themselves don’t know what to do with it.

Which reminds me: Oblivion, while having a horse for you to ride in, didn’t have horseback combat. Now consider this again: Mount & Blade was developed by practically a two-man team and featured mounted combat that wowed the entire gaming industry.

Again, a 2 man team trumping a legion of programmers in Bethesda.

Somebody please remind me why Bethesda is considered the revolutionary leader in the world of CRPGs again?

GORE Updates

What happened? Well, work got in the way.

Setting 20th August as the date when my 7DRL will begin is starting to put pressure on me. As of now, the camera code is half done, refactoring of the engine architecture is also half done. Sprite work is not finished yet either – I still have 2 more player characters, 4 more monsters, 6 items and a new wall tileset in the TODO list, and all these are going to take at least 3 days to sort out.

I really hope I can get everything laid down before starting the 7DRL, as right now my design seems pretty ambitious for such a challenge.

I’m anticipating a cut in features when the time comes. Crossing my fingers until then!

Changing ROAR to GORE!

I received an e-mail from the CEO of www.roarengine.com, where they are building a social gaming application middleware that happens to be called Roar Engine too. Funny how coincidences like these happen.

Anyway, since ROAR is just my little toy, I decided to change the name of my engine to GORE – Graphical Object-Oriented Roguelike Engine, which admittedly is more fitting to what I’m trying to build the engine for.

From ROAR to GORE, I say this makes my engine sounds much more GRITTIER and DARK, which is kind of the trend nowadays, ‘aint it? BLOOD! DARK! EVIL! APOCALYPSE! WELCOME TO… GORE!!!!!! GARRRR!!!!!

Everybody take a little step back, and the world becomes a brighter place. :)

NOTE (14 AUG 2010): ROAR Engine is now known as GORE – Graphical Object-Oriented Roguelike Engine. See this post for clarification.

I wasn’t very happy with how ROAR turned out. While the entity/renderable/map_array trio offered vast flexibility when it comes to determining rendering orders, it is a pain in the ass when it comes to updating entities.

For instance, how do I know if a particular tile is occupied? To do this I have to call the scene manager, and ask for a specific map coordinate, and then iterate through the layers on that coordinate to see if my entity is passable. All seems fine until you have entities in transit from one coordinate to another. How do I know if two entities are travelling into the same coordinate at the same time?

The current system does not take into account such situations. Worse, now I have to completely rewrite my camera code for the fact that I screwed up the logic completely. Oh wait, maybe I don’t have to. Ah, yes, I don’t exactly have to… but either way I still need to decouple my camera code from the scene manager, and have it attached to the player entity instead.

More refactoring scheduled for tonight!

ROAR Engine – 70% done

NOTE (14 AUG 2010): ROAR Engine is now known as GORE – Graphical Object-Oriented Roguelike Engine. See this post for clarification.

Alright, Renderables are done, and ground entities are done too. Basic camera works, and now I’m attempting to write one with smooth scrolling. And frankly, it’s driving me up the wall! I think I have to rewrite my entire rendering code…

More updates to come!

4.13PM: Alright, smooth scrolling camera is done. Phew! Now all I need to do is to write code to clip the sides of the camera.

4.47PM: Smooth scrolling is complete, and works properly now. There were some coordinate issues in the previous code, and now it’s fixed. Code’s locked down, and I won’t be touching any of it anymore.

One thing though – since I store surface information for each and every time (which is frankly, quite stupid), the game drops to 8 FPS when I have a 100×100 map loaded. Time to do dynamic surface loading from the resource manager!

5.17PM: Turns out the dynamic surface loading did squat to improve frame rates. A little digging revealed that I stupidly had a 3D loop in my update( ) function that runs every frame. The loop calls on_update on every single layer on every single tile, which on a 100×100 map means 100,000 on_update( ) calls PER FRAME. No wonder it’s so slow!

Removing that update loop and turning it into a 1D loop calling only entities (instead of everything) fired the FPS back to the 60 range.

New animated character

After 4-5 revisions, I’ve finally created a base template for a character sprite. This only shows the walking animation for the character facing south, so I have to repeat this process 3 more times to give the character 3 more directions. Another 10 hours of work left I guess.

No work had been done on ROAR yet – mainly because I’m exhausted from 2 parallel projects for now. I’ll resume working on the render code later today. Should be able to complete it by tonight.

Here’s the character animation:

Shaded

Back view

Side view

Death by petrification

The game design had been simplified (and as a result, became more challenging I suppose) in a way. Death in the game now turns the character either into a monster, or into a rock statue through petrification. Losing all your health turns you into a statue, while losing all your sanity turns you into a monster. This means that every death, while dropping off items for the next survivor to pick up, will turn itself into a barricade which may or may not be a hindrance to the player.

A mockup:

ROAR Engine – 60% done

NOTE (14 AUG 2010): ROAR Engine is now known as GORE – Graphical Object-Oriented Roguelike Engine. See this post for clarification.

Breakthrough! I’ve gotten a black triangle up, and now I can see how the engine works. The implementor (my roguelike) needs to define resources to load, of which the engine’s resource loader and managers will take the file paths and load them, storing them in memory for retrieval later. After that, the implementor defines subsurface pixel locations for each sprite in a tileset, of which the engine will take these coordinates and calls the renderer to create the appropriate subsurfaces and pumps them into the render queue, which the engine will call from when performing the appropriate render passes.

At this point, the differences between map_array, renderables and entities are starting to become clear. Map_array stores a 3D array of references – nothing more than just IDs stored in the array; these IDs hashes itself to the renderable array, which provides the subsurfaces and position offsets for the map_array to render. Entities on the other hand sits on top of both map_array and renderables, updating both components depending on state changes.

Next tasks on the list:

  1. Actual rendering of the map_array and renderables
  2. Animation system in renderables
  3. Entity event handler