Thursday, February 28, 2008

Games Should be Fun - All the Time

I was playing Resident Evil 4 on the PS2 last night. It's a very graphically impressive game. However, it does have a major flaw (which it shares with most other games) - it's not always fun to play.

[Spoiler warning] If anyone out there has RE4, it's the bit where you have to fight the first giant/ogre thing (see right). It's one of those boss battles where you have to guess where the weak spot is, and also what else you have to do. If you don't work it out, you'll be stuck on the level forever, and the only way I can see of working it out is to spend a whole day on it, or look on the internet. In this case, you have to shoot it in the head until something bursts out of it's neck, and then run up to it and jump onto its back and stab this thing. You have to do this 3 times as well, so hopefully you won't run out of ammo.

The problem with the bit in question, as well as getting a bit tedious, was that it is preceeded by a 30-second movie clip that you can't skip through. Every time you die, you have to run back to the same point in the game, and then sit through the same clip again. Why do companies think that we want to watch the same clip over and over again? To massage their ego?

The various GTA (and a lot of other) games suffer from this problem as well. If you fail at a mission for example, you then have to go through the build-up to the mission all over again (reloading the game, running to that area of the map to get the mission, run to the area of the map where the mission takes place etc..). This wouldn't be a problem if these bits of the game were fun, but running across a map is rarely fun, especially the second (or third...) time round.

The bottom line is games should be fun. All the time.

Monday, February 25, 2008

Laser Tactics - CPU v CPU

One of the best ways of testing your AI is to get it to play against itself. Often this isn't possible as most computer AI is very simplistic, involving standing still and shooting at the player, or following a set route and waiting for the player to trigger some change.

However, the AI in Laser Tactics is quite advanced (IMHO), and there is AI available for both sides in nearly all the various missions and objectives. So I quickly added the code so it's possible to select AI for both sides (previously you could only choose it for one side). The game also has a "Ghost" mode, which allows a player to view the game through the eyes of a unit that is CPU-controlled.

Once I'd set all this up, it's actually great fun watching the computer play against itself, especially when the missions actually have objectives (meaning it's not just a case of watching the units wander around shooting on-sight). And of course, it's ideal for checking that the AI works well and doesn't have any of the usual problems that AI suffers from (like get stuck in a loop or end up wandering in the wrong direction). Add to this the "randomly-generated map" option and it almost feels like I'm watching two humans battle each other. Place your bets now!

Monday, February 18, 2008

Blindingly Obvious Java Tips #2

Todays tip is all about getting your game to run at a consistent speed. You may not think it a problem on your new game, since you probably crammed in enough features to keep the CPU busy for just the right amount of time, but once you try and run it on a Cray (since surely that must have a JVM??) you may find it slightly unplayable.

So, to stop it running too fast: First, define a variable of type "long" at the start of your program for how long you would like the program to take over each game loop. In the example below, I've chosen the name "LOOP_DELAY" for this var, and I usually give it a value of around 25. You'll probably want to tweak this amount. Also, declare another long called "start_time".

Anyway, at the start of your "game loop", write something like:-

start_time = System.getCurrentTimeMillis();

This will store the current time when the computer started the game loop. Finally, at the end of your game loop, write something like:-

long wait = LOOP_DELAY - System.currentTimeMillis() + start_time;
Thread.sleep(wait);

(You'll need to wrap this in a try/catch BTW). This bit of code will make the program pause for a certain amount of time at the end of each game loop, that time being the number of milliseconds you wanted it to take over each game loop, minus the amount of time it took to actually process the code in your game loop. This will cause each game loop to take a consistent amount of time, assuming that the time it takes to process the code in the game loop isn't longer than the time you want it to wait for!

Friday, February 15, 2008

Announcing Laser Tactics!

If you've read one of my earlier article, you'll know that I've decided to "re-released" Nuclear Graveyard under a new name - "Laser Tactics" (kindly suggested by Charlie). And now I've finally got round to it. I've given it a few more tweaks, and I'm pretty pleased with it all. I've taken a few more screenshots to celebrate, which I'll be sticking on the website as soon as I can.

The only problem with it is that it's not an FPS, and it's not turn-based, and most people expect a game like this to be either one or the other. If anybody reading this decides to give it a go, please bear this in mind: Your unit's APs are replenished in realtime!


Thursday, February 14, 2008

Blindingly Obvious Java Programming Tips #1


(This is number #1 in my intended series of Programming tips for Java. They are probably blindingly obvious to most people, but they have passed me by until recently, and it doesn't do any harm to mention them in case anyone else has missed them to).


Daemons

Todays tip is all about setting threads as "Daemons".

I used to have a problem in my games that used multiple threads, in that it was very hard to get them to actually end. Even when all the windows were closed, there was still a process running in the background. I usually fixed this by adding a "System.exit(0);" to the code when I wanted it all to end, but this is certainly not the best way to go about it.

A Java program ends when there are only "daemon" threads running. This means, in short, that any thread which isn't what you would call the "main program thread" should be marked as a daemon so that it ends when the main program thread ends. This is simply a case of writing "mythread.setDaemon(true);". Incidentally, threads are not daemons by default.

Wednesday, February 13, 2008

Programming Affects the Mind

I've long suspected that spending too long programming affects the way the mind works, and I've finally come across a quite-good example:-

My wife innocently asked me if our car boot was locked. Being a programmer, where accuracy and logic is paramount, my mind was instantly plunged into a spagetti of possible answers and their respective problems.

Our car's boot (trunk for Americans) can only be opened with a key or by using the lever by the side of the drivers seat. There is no button on the boot to open it if the car is unlocked, which it was. So was the boot actually unlocked? One possible answer is "no", since it couldn't be any more unlocked than it was. However, giving this answer implies that it was possible for her to go out and open the boot, but I'm not sure she knows about the lever (since she's not a driver) and she doesn't have a key, this wouldn't work. So is the answer "yes it is locked", since the boot cannot be opened directly? But this can't be correct, since it is openable without a key, which is presumably the definition of "locked". Is the correct answer "sort of"? No, not if you want to be helpful. Is the correct response to explain how the various boot locking mechanisms work or describe where the lever is? Probably not, since it would take too long.

In the end I just ummed and ahh'd and said I'd open it for her.

Monday, February 11, 2008

The Problem with RTSs

One problem is knowing whether to put an apostophe in the word "RTS's". However, the other problem I have with them is always feeling that it's pointless trying different actions; either they won't make any difference, or it's all down to chance anyway.

I really want to enjoy RTS's, ever since I played what I think is the very first one: Stonkers (not Dune II!). I've not played many of the later ones, but I've played C&C, StarCraft, Age of Mythology, and quite a few free ones, and even written my own.

The typical scenario goes like this: I select a group of units, move them towards the enemy, and err, repeat. All I can do now is watch them do battle. Maybe my units will win, maybe they won't. Should I try some newfangle tactics? Does it make any difference if I have some units on the left side of the enemy and some on the right side? Or maybe I should build a tank instead of two foot-soldiers? Is it better to have a tank than two footsoldiers? I don't know. All I know is the units keep shooting at the enemy and eventually some of them die. The tank is more powerful but has a slower shot rate, but I can't be bothered to check the "stats" to see if the more powerful gun with a slower shot rate is better than two weak guns with a faster shot rate.

I might be fighting another small skirmish in another part of the map while this is going on. When I go back to the original skirmish, some of my units have survived and the enemy seems to be dead. Or did they retreat? And if they did, how much damage was inflicted? Who knows. I'm no closer to knowing what the best tactics are, or if it makes any difference.

So by now I've lost interest and decided to play an FPS or something.

Friday, February 08, 2008

Name of the Game

I've been toying with the idea of changing the name of my game Nuclear Graveyard (again), since it has nothing to do with anything nuclear, and even less to do with graveyards. The reason I chose it was because I got a DynDns domain name, and I chose "ng" as the prefix to the standard domain "game-host.org". I chose NG as I was thinking of the phrase "network game", since at the time I didn't have any idea what I wanted to do with it! I then decided to give my new (at the time) game the initials "NG", and the rest is history.

I have toyed with the idea of giving it the ridiculous name "Space Nazis", just to see if it would perk up interest. However, this would be misleading as most people would expect some wacky platformer or something, whereas Nuclear Graveyard is a 3D multi-player "serious" strategy FPS game.

I might just change it back to its original name "Laser Squad 3D", since that sums it up perfectly if you remember the original Laser Squad game. I think it's a bit of a cliche to add "3D" to the end of a game's name though, which is why I changed it in the first place.

So, watch this space...