stevebob.net

RPG Engine: Introduction

2012-10-26 03:19

This is the beginning of the actualization of an idea I’ve had floating around for several months now. I’ve spent the better part of the last two years making cool graphical demos and applications of questionable usefulness, and now I’m going to try to put the knowledge I’ve gained as a result to some practical use - namely, making a game. Due to the interesting technical challenges involved, I’m going to document my progress, the problems I face and my solutions for overcoming them in this blog. I’ll also use it to demonstrate different features of the engine/game as they role out.

Background

I had many sources of inspiration for what I’m planning on basing the storyline around. Though I’m still not sure exactly how it will go, it will hopefully have something to do with space, spaceships and settling on other planets. Especially that last point - I think there are some really interesting challenges involved with colonizing new planets that would be fun to explore in the video game genre.

I struggled for a while to come up with a medium to express this story. I thought about making a source mod, but I didn’t want to mess around with 3D modelling of characters, since the stock Half-Life 2 NPCs will not suffice. I’ve been playing a lot Brood Wars lately and it occurred to me that an (pseudo) isometric RPG would not be THAT hard to implement, and since all the characters, items, environments - all the graphical elements are just in the form of 2D sprites, the artwork would not be infeasible to create.

Technical Overview

Admittedly, that description was kind of vague. The truth is I’m not EXACTLY sure how a great deal of the engine will work, but these details can be worked out on the fly. In terms of how I want it to look, I’ve been looking at the classic RPG Fallout) which also uses an isometric point of view. Something that I want to add to this engine that Fallout didn’t do is the option for a real-time combat system (Fallout’s is strictly turn-based).

Demonstration

I've been hacking on this project for a few days now, and it currently stands at 554 lines of javascript (not counting comments or whitespace). Functionality so far is:

  • Drawing floors of given elevation
  • Drawing slanted floors using two points to specify orientation
  • Drawing wireframe walls (they obscure one another but not the avatar
  • Drawing an avatar
  • Avatar movement, including moving between adjacent floor polygons
  • Avatar collision detection (though it's kinda broken around corners)

Use WASD keys to move the avatar in the demo below. The colour of the walls indicates whether the avatar is in front (red) of or behind (blue) the wall. Check out the XML that generates this world here.

In the demo, it appears that some visible surface detection is already taking place. This is a cheap trick I pulled for the purpose of this demo. In this case (and I think this is true for all cases where all the polygons are vertical), there is an ordering on the walls that if they are drawn in that order (drawing over what was previously on that position on the canvas) it looks correct. (That is, no wall ever needs to be split into two as is sometimes the case when determining draw order for regular polygons.) I've figured out this order in this case, listed the walls in that order in the XML file, and the engine draws them in the correct order.

Eventually, a Binary Space Partition Tree will be generated for the walls (in fact a great deal of such trees will be generated and the best one will be chosen) once, and a new, optimized XML file will be generated with the walls listed in the correct order. The "front" side of the walls is defined as the the side facing the view point. Since this is an isometric 3D engine, the same side of each wall constantly faces the view point. The main benefit of this is that there is a simple, constant way to traverse the BSP tree. Namely, draw the right (behind) sub-tree, draw the root polygon, then draw the left (front) sub-tree. For reasons about to be explained however, it is still in our favour to keep the tree representation around.

But what about characters?

Characters can move, and this turns out to be a problem for BSP Trees. They are great for determining draw order of a static 3D scene, but fall down when things start moving around and changing. Characters can be thought of as a single polygon, which is vertical, like a wall. The polygon constantly faces the view point (that is, they always face "down" the screen). We can simply insert each character's polygon into the BSP Tree to determine the draw order of a frame.

The blue, red colouring in the demo was used to come up with an algorithm for determining draw order given a movable avatar. The idea was to use information about which walls the avatar was "behind" to modify the draw order produced by traversing a BSP Tree. This seemed to work (in theory) for rooms that had corners with angles less than 180 degrees. Once convex corners start appearing, problems arise, which is why BSP insertion is the current plan for visible surface detection with movable characters.