Friday, April 25, 2008

Meta-thinking and Emergent Behavior

Ok, taking a shot at writing something themed for Blogs of the Round Table.

A short while ago I decided to grab an xbox360 finally. Of course I went with one of the 'hot' games, Halo3. I've been wanting a FPS again for a while and I've been through Pandemic's Mercenaries way, way too many times lately. So I started Halo3 and couldn't help looking at it in terms of the games I usually play and wondering what did, and didn't work for me.

First I have to say, I am enjoying the game. It is visually stunning, the AI is actually quite good, and it is mindless fun that I can relax too. Having said that, I also found it a very disappointing game in it's simplicity and linearity. For any given situation is was always fairly clear what the 'solution' was. If the situation was unusual then the needed weapon would happen to be nearby. Often there was only one way to do something,.. each area had one entrance and one exit, and clues were everywhere regarding which one you should be moving towards. There was little to no state-fulness between areas (weapons and vehicles reset back to designer intention), etc etc.

Compare this to a military sandbox like Mercenaries.. no real entrance/exits, multiple solutions to given problems, flexibility for un-anticipated solutions, state-fullness between missions so that you can prepare and keep things that are useful, etc etc. This usually works pretty well for me.

Yet, when I think about it, I can't stand 'puzzle games'. When I say puzzle game I am not necessary meaning mini-games where you have to solve some explicit puzzle. I mean any game where the designer integrates a problem to be solved... which actually brings me to my main point. Meta-thinking.

When one designs a game, there is always some meta-thinking involved. The designer HAS to think about how the player will interact with the world. For instance the designer probably wants to think about what they player would expect the left arrow to do when moving and thus move accordingly. This is just part of good interface design.

Beyond that though, designers often try to design 'puzzles' that involve the designer trying to guess how the player will see the puzzle, and more importantly the player trying to guess what the designer was thinking the player would think. Essentially from the player's perspective you have to figure out what the designer was thinking.

Now, in the real world when you are presented with a problem it usually has not been specifically 'designed', thus trying to solve it involves a good model of the real world and such. In a virtual (highly simplified and artificial) world this doesn't work. Which gets me to part (2) of my topic, emergent behavior.

Within this context, emergent behavior is what you get when you set up the virtual world well enough that the player can apply general-purpose problem solving to a situation rather then guessing about the designer's pre-conceived solution. This is where the games that tend to work well for me diverge from the ones that don't. Rather then having one or two solutions baked in, these games provide a sandbox in which the designer can challenge the player but does not have much control over how the problem is solved and thus it starts feeling more 'real world' to me.

It is never perfect of course. Even the most flexible games still represent a subset of the real world thus one still has to think about what the designer decided to include, how they implemented it, and how it is balanced.

Now I admit part of this is humans are pretty difficult for me to understand, thus attempting to meta-think someone who's background and assumptions I don't know is generally an exercise in frustration rather then enjoyment.

Monday, April 21, 2008

Nothing Ventured

A few weeks ago I had decided to take the plunge and apply at Three Rings since they were opening up a location in Philly. I didn't consider my chances all that good but went for it anyway. They presented a fascinating opportunity if things panned out so it would have been silly of me to not at least try for it.

Today I received the official 'we are going to pass' email. Not surprising but a bit disappointing.

I decided to actually bluntly ask Three Rings where I had gone wrong. Probably a faux pas I know but I never get any feedback on 'why' from various companies and these peeps seem informal enough to maybe actually be willing to say something. That and it would be nice to keep the dialogue open in case something else came up in the future.

Still, even without getting the job the experience it'self was probably worth it. I got to play in their development environment, learned a new language, and worked with a network programming paradigm that was new to me. It was interesting to see how in some ways their network API was way ahead of what we use, and in other ways so far behind. So I learned stuff.

Saturday, April 19, 2008

Duke Nuk'em. Horrible for interesting reasons

Last night I got a craving for mindless FPS. Not a type of game I have many of I'm afraid. I usually just play Mercenaries when I want thing to go 'splode but I had just finished running through it twice the other day, so that wasn't going to cut it.

So I poke through my collection of games and find 'Duke Nukem, Time to Kill', a PS1 game from years back. I had forgotten just how horrible it was. But horrible for what I think are interesting reasons.

Time to Kill was made in the shadow of Doom. Doom was a fairly revolutionary (in the iterative sense) game,.. it had a highly efficient engine, lots of variety, a good pseudo-3d environment, good controls with lots of capabilities without overwhelming the person, and smooth movement.

Time to Kill seemed to try to take this formula expand upon it and bring in things that, I am guessing at the time, conventional wisdom felt would be 'better'. So it added an inventory (which was clunky access and use), step based movement instead of phantom-slidy (which result in coarse grained control that made maneuvering difficult), the ability to put away your gun and do other things like climb (which was more realistic perhaps but added unnecessary and confusing state-fulness), and a more 3D engine that followed Doom's pseudo 'everything on one plane' 3D but added multiple slices (or something) so you could climb around. It felt like a bad comprise.

The end result? An utterly unplayable game that felt like it was designed by a few modders who looked at doom and asked 'wouldn't it be cool if?' but failed to integrate everything into a balanced game.

At least that is my take ^_^

Ultimate solution? I finally bought an xbox360 and a copy of Halo3,.. which I have a different set of complaints about having come from Mercenaries ^_^ but that is a different rant.

Friday, April 18, 2008

Moving windows, forks, shares, and ARG!

I just spent the last 3 days working on a problem that SHOULD have been incredibly simple. Take a few windows, slide them to their new positions. The devil was, however, in the details.

Each of these windows is owned by a loadable module. Each module has a binding that translates requests form the loader into commands that the API used by the binding can use. This allows multiple graphics engines to run side by side and opens up all sorts of cross platform capabilities in the future.

Now, each module is loaded by the, well, loader, then forked off with a block of anonymous shared memory between them for message passing. This means that the loader has no way to execute commands directly in the process space of the module. Now comes the tricky part.

Moving a window around. xlib has a simple call for this, move window. The bindings do not expose the Window reference directly though, instead they take a 'move' signal. Each module is runing in it's own space and is thus subject to the scheduling whims of the kernel. So if you do something like:

for(modules module)
module->move(x,y);

you will get a whole mess of modules all moving themselves in the order and timing of the kernel's liking. Unfortunately these are low level graphics modules, which means they do not get the nice automatic refresh that you would get on a desktop. End result? Artifacts as they slide over eachother.

Now, a way to deal with this would be to have each one call the other modules and say 'hey, I drew over you, refresh yourslf' with the problem that they are all running at different speeds and thus no messages can get across quickly enough. The loader can in theory coordinate them but at best it can only suggest when to draw, it can't control the execution dirrectly.

So what I ended up trying to do was using a set of mutexes to let the loader control when each one drew. Essentially:

for(modules module)
module->lock();

for(frames)
{
for(modules module)
module->unlock()
sched_yield()
module->lock()

for(modules module)
module->unlock()
sched_yeild()
module->lock()
}
for(modules module)
module->unlock()

And on the module side:

while(!done)
Lock()
Move(one_frame_x,one_frame_y)
Unlock()
sched_yeild()
Lock()
Redraw()
Unlock()


So each module has it's mutex released in turn, gets to move it'self, then each module in turn gets to draw it'self.

Oh, that should have worked, but didn't. It turns out (and this took forever to track down) under the 2.4 kernel semaphores can't be shared between processes (threads are ok, but forked processes fail) and mutexs just quietly don't work.

Well, you learn something new every day.
Ugh. The things that should be simple.

Monday, April 14, 2008

delete(this)

For any given language there are always language features that are considered so 'wrong' that no programmer 'should' use them ever. I've always found this a rather interesting bit of behavior and group think among programmers and it is actually a topic I've used as an interview question in the past.

You can guage someone's perspective on what they think about the 'unholy' language features. If one claims that a methos is always the right solution, or that a feature is always the wrong solution, that tells me something not so great about how flex able in understanding problems someone is... i.e. when presented with a screw do they still try to use a hammer?

Goto is the classic example,.. a dangerous command that comletely breaks OOP if OOP is your hammer. But that isn't the one I wanted to babble about.

Today I realized I was using "delete(this)". It isn't even the first time I've used it in this project. Deleting 'this' is considered one of those no-nos that many say 'well, it just means you structured your program wrong!'... unfortunately people tend to say this without actually knowing the structure, they can simply 'tell' because you came up with the 'wrong ' solution.

In this case, yes, I used it with one particular class. The case? Threaded classes that want to be able to terminate themselves. Nothing else 'owns' the object. Adding a manager (the 'correct' solution) is significant extra complexity, indirection, a bottleneck, and breaks from an event-driven design. The thread class ends up needing to know about the manager, the manager needs to know about the threaded class, you have statefullness to keep in sync, a deeper stack to do anything, and have the potential to introduce all sorts of race conditions. On top of that in order to do it right you need a whole mess of mutexs to make sure that different threaded classes don't screw with the manager's data.

All that to get around 'oh no! delete this is bad!'. And of course, the real problem is going to be the code review...

This also highlights the problem (and advantage) of multi-paradigm languages like c++. You can use any paradigm you like but start mixing them and you run into arguments. On top of that, in order to support so many ways of programming, it implements each of them poorly.

For instance, the delete(this) problem is handled elegantly in ObjC via Retain/Release. I would be surprised if Java didn't have a solution to the situations too. C++? You have to do something 'evil'. Oh well, evil needs luffs too.

Saturday, April 12, 2008

Wumpus

So, I am writing a demo game as part of a challenge.

1 Week, in an API I am not familiar with in a language I don't know. Interesting I admit but stressful too.

Anyway, I have finished up the tutorial so I think I have an idea of how the system works. A nice block diagram or UML would have been good, but I think I am getting it. Very 'automagic' oriented,.. a bit like gendef + netsprites from our system but with more crack. But anyway.....

So now I am at the stage where I have to make an actual minigame.
I had several ideas for what to do. I tend to have that problem, there are so many games I would love to have the time (and art skills) to write. Unfortunately many of them get pretty complicated pretty quick and are not all that easy to simplify into a 'you have a couple days to learn and code' type project.

I thought of various smaller ones... a turn based artillery game came to mind (since that is a simplified case of one of the other games) but even that felt like a bit much. While it would be fun to throw together a quick physics engine that would be one more thing to worry about.

So what about Wumpus world? Ok, it's been done to death, there is no real originality or creativity. But it is a well understood problem (thus I can focus on the things I don't understand like the API). I also have a bit of a soft spot for the game given all that time spent solving it in college ^_^.

And thus my evil plan.

Friday, April 11, 2008

First Post

FOOM!

So, here I am starting a industry like blog?

Well, the idea came from an IGDA meeting I attended on teusday. Two speakers, Jason Della Rocca and Corvus Elrod. Corvus had an interesting suggestion for how to connect with the community,.. and let's face it, community is NOT my strong point ^_^

Anyway, he suggested blogging, and that is what I'm gonna do.

So, why Ethics of Madness? I originally thought some combination of cats, and games, and things like that.. but it is overdone. Next I thought 'For love of Evil', because Evil needs luffs. But madness. I'll spend an afternoon trying to figure out how vfork works when a shell script would take 5 minutes because it's interesting.

Granted it's interesting in the same way that 'hmmm, what can I learn from driving this corkscrew into my leg!' which is really a whole different blog. So that is the madness part. The ethics? Ahm... I'll figure that part out later.