2012-01-24

Octopus City Blues and the Future of Technobabel

Basically, Technobabel is a little Android shoot 'em up I was working on with my good friend TFT. I worked on the engine while TFT worked on the art, and things were going smoothly and I got a good engine prototype running. TFT later left due to several factors (difficulty of creating large enough sprites for different phone sizes, being busy with his own game, etc.) and I tried doing everything on my own with simple art and a more realistic goal. It's simply not the same now, and I don't enjoy it. I have to downscale the original ideas considerably simply to "get it done". The last thing I want to work on is a generic shmup --if I wanted that, I could finish up Technobabel in a month or two -- what I want to do is make unique and fun games, and Technobabel is no longer that. Finishing Technobabel is too much work for a project I no longer care about.

On the other hand, I have put a lot of effort into Technobabel. It's probably my biggest software project, and I'm proud of my work and everything I learned from it. It'd a shame if all that work were to be discarded. Additionally, there is value in having released games, as I have worked on many games and demos in the past but have very little to show for it. Technobabel codebase might be useful for someone who wants to make a similar game. It's generic, well documented, and performs quite well for a Java Android application.

A project I do care about is based around a game idea I have been toying with for over a year. It's actually the amalgamation of several ideas, some dating back to my earlier game projects. The name of the game is Octopus City Blues, and it's an adventure game with horror, adventure, RPG, and simulation elements. Before I tell you more about it, please watch a concept intro I made earlier:



Octopus City Blues centers around Kaf Kafkaryan, a disturbed tentacle cutter living in a cyberpunk city built around a giant octopus. Kaf is a broken man fighting his inner demons. His desperation leads him into the dark underworld of octopus blood addiction. Dreams and reality soon converge as he is forced to do terrible things to stay alive. The majority of the game is walking around the city and talking to people; there are no battles and no stats. Instead, the game focuses on a small number of strategic and open ended missions with unforeseen consequences.


The major problem with the concept behind Octopus City Blues (which I will discuss more in the future) is that it's somewhat big in scope. Technically it's a quite simple adventure game, but there's great focus on choices and consequences and a large number of different possible outcomes for each action. This kind of game can quickly grow in complexity, to the point of requiring funding to get an artist and a composer. If done right, I think it can be quite a successful independent game for a variety of platforms. However, I don't have that sort of funding, and I don't have the free time required for such a project between my full time job and graduate study.


That's why I started working on a simpler prototype of Octopus City Blues, a watered down version of the full game with small and simplistic graphics using an existing engine. The prototype allows me to develop the idea further and to get people interested. As for Technobabel, I also plan on releasing eventually, but in a different format: I want to finish implementing a few pending tasks (OpenGL, scores, sounds, etc.) and release it as an open source project with a simple demo. I will also be reusing a large part of Technobabel's code for my new game.

2011-04-14

ASP.NET: Restoring scroll position on postback

I'm maintaining an existing ASP.NET website at work which relies heavily on postbacks. For example, you are entering the information for a receipt and you specify the payment method (cash, bank, etc.), and based on the payment method certain controls would be enabled or disabled (a drop down list of banks if you picked the bank payment method for example). The customer has repeatedly complained that having the page scroll position reset to the top of the page as they entered data was very inconvenient and they have to scroll all the way down on long pages to continue data entry.

I looked around for a way to have the browser scroll down to the same position it was at. One way to do it is by remembering the element that has focus and using a script to restore the focus to that element after the page is loaded. The problem with this approach is that on a long page when the element gets the focus the screen will scroll just enough to show the element, without showing the elements following it. You still have to scroll a bit to see the other fields.

A better approach is to maintain the window position. .NET 1.0 had a page property called SmartNavigation, which persists the scroll position between postbacks. This property is only supported by Internet Explorer and is now marked as obsolete. With ASP.NET 2.0 a new property is introduced, MaintainScrollPositionOnPostback , which seems to work with all the browsers I tried. You can set this property programmatically:
Page.MaintainScrollPositionOnPostback = true
In the declaration for a specific page:
<%@ Page MaintainScrollPositionOnPostback="true" %>

Or for all the pages by specifying it in the <system.web> section of web.config:
<pages MaintainScrollPositionOnPostBack="true" />

2011-01-03

Technobabel Technicalities - Overview

In this article, I will give an overview of the internals of the game engine I'm building for Technobabel, a 2D Android shoot 'em up. I want to document this process because it helps me avoid getting lost in the details and provides a nice future reference. Furthermore, this inside look might be useful to someone else who stumbles on this blog. Someone might know a better way of implementing a certain feature and they'd be kind enough to leave a comment.


About Technobabel
Technobabel is a horizontal side scrolling shoot 'em up game. You control a character who flies through various levels along with some sidekicks in pursuit of an alien scientist who is responsible for a robot war against humanity. The unique thing about Technobabel is that it aims to be highly unpredictable; to defy the conventions of the genre and provide a really fun and unique experience. We have complex bosses, levels where you're not limited to horizontal scrolling, and various game mechanics.

To this end, I wanted the Technobabel engine to be flexible and customizable. This is a bad excuse for the unwarranted complexity in certain parts of the engine; favoring flexibility over getting the game done means that I spent more time laying down a framework that might be an overkill for a game of this kind. Game developer people will recognize this in the overuse of design patterns and the reliance on XML files for everything. I'm always torn between making visible progress and not going for the most straightforward implementation of a certain feature, because I know that I will have to write the complex code eventually. On the other hand, there's the YAGNI principle (You Ain't Gonna Need It) and all the design guidelines favoring simplicity and quick delivery. Generally, I strive to have a balance between these two conflicting goals.

Technobabel is an Android game. I love the Android SDK, although I haven't had to deal with many platforms yet. I use the Android emulator and a used Samsung Galaxy Spica phone to test the game. I picked the Spica because it was really cheap and one of the weaker phones on the market. We want to target as many phones as possible and the Spica is a good example of the bad phones we might target. I plan to buy a Nexus or HTC phone eventually, but for now the emulator/Spica setup suffices.

High Level Overview
Technobabel classes are divided into several Java packages according to their functionality. The code of Replica Island was a great inspiration and I incorporate some of it (such as fixed size arrays and object pools) in my design. However, Technobabel code is not based on Replica Island's and the designs are fairly different. The packages are:
  • Graphics
    • Canvas Graphics
    • OpenGL Graphics
  • Input
  • Audio
  • Logic
  • Object
  • Utility
The packages are kinda arbitrary and I mostly use them because I don't like seeing a long list of classes in Eclipse. Not everything fits neatly in one package or the other, and some classes are in the root project package.

The graphics class is solely responsible for drawing stuff on the screen. There is no logic here, just drawing commands, sprites, textures, and the graphics subsystem. Both Canvas graphics and OpenGL graphics are supported. The main reason behind that is because I wanted to get things drawn on the screen as soon as possible, so I abstracted the graphics system and provided two implementations. So far the I've only worked on the Canvas implementation, and the performance is good enough. I'm trying to keep the game playable in the emulator because that's where I do most of my testing. The design of the graphics subsystem is loosely based on the design of a game I was working on with my friend ramirez, which was to support both an SDL backend as well as an OpenGL backend. Should Technobabel be ported to another platform in the future, it is trivial to provide a new implementation of the graphics primitives. The last thing I want to say about the graphics subsystem for now is that only the low level commands are abstracted, higher level concepts like renderers for sprites and backgrounds as well as draw commands only need to be written once, although you can still subclass them if there is a certain performance advantage to doing so.

So far the input subsystem has been fairly basic. This is because I only support key input at the moment (the Spica has directional keys). The design tries to separate the events understood by the game (such as move left or shoot) from the actual events that Android sends (screen touch, key press, trackball, etc.) The input subsystem queues the hardware events and dispatches them to interested listeners. Objects that want to listen to input events normally have input components that register themselves with the input subsystem and define methods such as move or shoot. Like I said, the system is still basic and I will probably need to make big changes when I actually have to support more than one input method.

I still didn't implement audio in the game, but the audio package is where the classes for playing music and sound effects will end up. There will be one audio object that has methods to play or stop music and to trigger sound effects. Logic is just a generic package for anything logic related. In fact, I think the Object package should be under the logic package. Here you find classes that deal with game levels, collision, components used by objects, and sprite updating logic.

The object package represents the core of the object system. There are two types of objects so far: bullets and game objects. They both share some common properties such as having a position and a velocity, but bullets are much more lightweight and use shared components. Game objects use the component pattern where a game object is simply a list of game components that are updated when the object is updated. Each component provide a certain capability: there are components for sprites, collision detection, input, life, and AI movement. The only difference between an enemy and a player character is the type of components attached. You can define objects in XML files by defining the components used and their properties. This makes defining enemies and side kicks fairly easy (e.g. an enemy that explodes when it gets near the player might have a component that triggers an explosion on proximity to certain objects). The object package also contains the game and bullet factories responsible for creating these objects. There is also a dedicated bullet manager to manage the lifetime and recycling of bullets. Pools of objects and bullets are used to avoid garbage collection by reusing the object when its no longer used.

Finally, the utility package is for useful utility classes that don't belong anywhere else (for now). It contains some data structures such as fixed size array, queue and hash table. It also includes SAX handler classes to parse the files that define sprites, backgrounds, levels and objects. It includes a resource manager responsible for loading resources and caching their identifiers, a class that tracks the number of frames since the game started and provides useful methods to query the current time and to check if enough time has passed since an event, as well as a debug log class taken from replica island's code.

Outside the packages there are two classes that are quite important. There is an activity class responsible for presenting the android user interface, and a game class that represents the game thread and which has methods to start, update, pause, resume, and stop a game. I will talk about the multi-threaded design in the next post, but for now it's suffice to say that the game class updates all the other components such as level, bullet manager, input and collision detection subsystems, and the objects themselves. The class also acts as a global instance which allows communication between the various subsystems. Need to get a resource? Get the resource manager reference from the game class. Need to create an object? The object factory instance is also held by the game class. It's not exactly global though, there are no singletons used, but many objects are passed a Game instance in their constructors in case they need to access the Android context or any other subsystems.

2010-12-04

Review of OpenGL SuperBible 5th Edition

This is my review of OpenGL SuperBible: Comprehensive Tutorial and Reference (5th Edition):

For years, books in the OpenGL SuperBible series were recommended for anyone looking for an excellent tutorial and thorough coverage of OpenGL features. But up to OpenGL 2.0, programming in OpenGL was done through the fixed function pipeline, and the OpenGL SuperBible books were the best place to start learning that. With GLSL introduced in OpenGL 2.0, OpenGL supported both the traditional fixed function pipeline and a new programmable pipeline where you can write your own shader programs and have much more control over the graphic card. OpenGL 2.0 tried to have the best of both worlds: if you liked the old OpenGL then you can use it, and if you wanted to experiment with modern OpenGL you can use that as well. This resulted in a huge API with conflicting design goals. This conflict can be seen in the OpenGL(R) SuperBible: Comprehensive Tutorial and Reference (4th Edition), reflecting the version of OpenGL it covered. The tutorial part focused exclusively on fixed-function OpenGL. That part was excellent and I still use it as a reference when I'm programming for old mobile devices that supported only OpenGL ES 1.0. The book also introduced shaders among other advanced topics in the second part. This introduction didn't really follow from what you learned in the tutorial part. It was a group of separate articles that were written in a different style and tone. I don't doubt you can easily pick it up and learn writing shaders from these chapters, but they didn't really go about teaching you how to write shaders, instead focusing more on showing you cool examples of stuff you can do with shaders. Given that a lot of what you do with shaders requires a mathematical background -- which the 4th edition got around by introducing only what's necessary, someone learning OpenGL without such a background would get confused when suddenly the later chapters are talking about cosines and other concepts.

Eventually, the OpenGL API evolved and the fixed function commands were all deprecated and later moved to a different profile. The new OpenGL was much leaner and only revolves about creating shaders and writing to buffers. The problem is that it's easy to teach the old OpenGL, you don't need to know the underlying details of how light is calculated or how transformations are performed to write a program in fixed function OpenGL. You can get away without teaching anything but basic mathematics, and you could still come up with strong examples. With modern OpenGL, things are different. There is no built in lighting equation, no matrix stack, no functions to rotate an object or set a camera. You have to write all of that yourself. A book teaching modern OpenGL, or the core profile of OpenGL 3.3, needs to teach you not only OpenGL, but also the fundamentals of 3D graphics. Such a book would be quite big, advanced for many users, and wouldn't be able to cover all the features of OpenGL. How can you create a simple and thorough book about modern OpenGL? If you can assume that the reader knows the fixed function pipeline, then it's easier to teach them the new features. But what if you can't assume that?

The authors of OpenGL SuperBible 5 found a way around, and it works quite well. The authors built a library that allows people to start writing impressive programs right away. They don't have to worry about setting up vertex buffer objects, writing shaders, or any of that. This way you can start teaching by giving practical examples, and you slowly teach OpenGL by introducing the concepts behind that library. Make no mistake, this book doesn't teach you to use that specific library, it teaches you OpenGL. Anything you do with the library you will learn to do yourself in OpenGL in later chapters. Shaders are introduced early and follow wonderfully from previous discussion. Many advanced features are covered in detail and you learn how to write shaders, and not just how to copy and paste example code. The result is fantastic; the tutorial part is by far the best introduction to modern OpenGL you'll find. You still don't need a mathematical background, and the 3D math chapter does a good job of introducing all the ingredients you will need to write programs.

The book is divided into 3 parts. The first part is an introduction and tutorial, the second part is about advanced topics such as buffers and dealing with geometry, and the final part is about platform specific issues including a coverage of OpenGL ES for mobile devices. The tutorial part is great and if the book constituted only of this part, it'd definitely be worth buying. The advanced topic coverage is really variable. Some topics are covered in great detail and with useful examples (I really liked the introduction to the geometry shader for example), other topics are introduced in a hurry and just throw examples at you without even explaining what the example is supposed to do or teach. I'm not sure if this is really a bad thing. You need to realize that some of these advanced topics are actually quite advanced, and the book doesn't assume much from the reader. Including them in the book is a benefit because once you've learned more from other sources or from your own experiments you can go back to these chapters and understand them better. None of these chapters is bad, they just don't follow from what you learned from the tutorial part. For example, the basic idea of multisampling is introduced early, which is good for an example where you just enable multisampling and see the result. Later chapters go into the fine details of how multisampling is implemented, based on the basic introduction. If you already understand multisampling then it'd all make sense, but if your only source is the book then it can be hard to follow. Another example is the chapter which introduces buffers, the sample program tries to 'look cool' where a simpler (and uglier) sample would have been more appropriate.

Speaking of the sample programs, the code is generally well written and properly commented. Going through the source code for the book library is a great way to learn. Most of the samples compiled fine on Linux (using the binary Nvidia driver), but some gave me black screens or wrong results. I also had to make some changes to the code to make certain samples work. A few samples don't even come with makefiles for Linux. I sent an email about it to the author and it'll hopefully get fixed eventually. The google code repository where the samples are hosted does get updated so I wouldn't worry much about that.

Summary: if you want to learn modern OpenGL (post 3.0), then get the book. Even if you already have the 4th edition and know a bit about shaders and buffers, you will still benefit from the book because it covers many more advanced topics and I'm sure there will be a thing or two you didn't know about. While I spent some time talking about perceived problems like complex advanced chapters or few samples that don't work, I assure you that it's not as bad as I make it sound. I just thought it was fair to note these minor issues in case there was a 6th edition for OpenGL 5.0! I was worried about two things when I considered getting the 5th edition: (1) I already have the 4th edition so is this an incremental update or something completely new? And (2) if the book uses a library to hide some of the advanced features then does it spend a lot of time on that as opposed to teaching real OpenGL? The answer to the first question is that it's a completely new book that is exclusively about OpenGL 3.3. The answer to the second question is, like I said earlier, that the book library is there for a purpose, which is ultimately teaching you how to do things with nothing but OpenGL. I apologize for writing so much, I never wrote a book review before. :)