Laserbrain Studios

Games Forum Blog Contact


New-ish device and new map (oh, and AI)

0 Comments July 31st, 2012 by Christian Knudsen

I was out celebrating my one-year anniversary with my wife yesterday, so here’s the update for last week one day later than usual…

I’ve begun work on the map for the first pre-alpha release. This will not be a finished map in the game, but a map for testing various game mechanics. I’m basically going to try out various things to find out which is the most fun to play, so I’ll probably be iterating over different map designs to get a good sense of what makes a great map in this game before starting work on the maps used in the actual game. Anyway, I’ve compiled a list of art assets and world objects that I’m currently missing, so I’ll probably be spending a good deal of the coming week making those.

Click to enlarge

This past week, I also split the Remote Trigger device into two devices for various reasons. The primary being that I couldn’t really see much use for opening and closing doors remotely – the more interesting use is of course to lock them remotely, trapping guards and other NPCs in rooms. So that’s now a separate device: the Lock Override. The remote trigger has been renamed the Electric Surge and can only be used on electrical devices. I think this makes more sense.

And work still continues on the AI. I’m working on the search algorithm for when guards hear a gunshot or you escape their line of sight or they find a corpse. The idea is that the map tile where they heard the gunshot coming from or last saw you or found the corpse will act as the center for the search. But it takes a bit of work coming up with a good algorithm that works both in wide open spaces and inside a building with corridors. I’ve got some ideas that I’m testing out, though.

Bug fixing and even more AI

0 Comments July 23rd, 2012 by Christian Knudsen

This past week I finally managed to squash a bug that would sometimes corrupt map files when I removed world objects in the map editor. I was basically just setting the object type to zero when saving the map, but when loading it, the code wasn’t expecting zero’ed object types, so it would try to place these non-existent objects. It was of course just a matter of not writing these objects to the map file at all. Seems simple, but still took a bit of time to figure out.

And, as always, work continues on the AI. This week I fiddled a bit more with AI shooting – primarily tweaking the checks so that there’s a pretty big chance of a hit when firing at a target right next to or very close to the shooter. My algorithms were working fine for shots at a distance, but the AI would often miss a target right in front of it, which seemed kinda silly at times.

I’ve also started work on characters detecting you from hearing you. My current framework is that characters will always react to gunfire (if they’re a guard that’s within range of hearing it) by going to the spot they think the sound came from and starting a search routine with that spot as the center. If you’re making noise in a yellow area, this can cause characters to turn to face you – and react with suspicion if you’re sneaking or crouching. And any noise made in a red area can cause a guard to start searching for you and attacking you if you don’t leave quickly enough (or if the guard is already hostile towards you).

That’s the basic framework, which I’ll then tweak so that civilians for example react differently than guards. For one, they shouldn’t always come running to investigate the sound of gunfire, but should instead most of the time run away from it in a panic. After that, I’ll start working on NPCs reacting to finding a corpse.

Improved aiming and a bit of vacationing

3 Comments July 16th, 2012 by Christian Knudsen

I was in France on holiday for most of last week, so I didn’t get all that much work done. I did manage to improve the aimed shooting, though.

Before, the crosshairs themselves would be jittering about on the screen, so you’d have to fight with the controls to line up a shot. This could be quite annoying sometimes – even more so on on a trackpad. I’ve now changed it so that the silhouette of your target will move instead. The movement is also more smooth. I’m considering having the silhouette move more when the target is walking/running to simulate the difficulty of hitting a moving target, but I’m not sure about that. I’ll do some testing.

I also improved the AI shooting and the player non-aimed shooting. Before, a random body part would be chosen to take damage. Now the AI just uses the same character masks that are used for an aimed shot to check for a hit – meaning that body parts can be hidden behind other body parts if the target character is standing with his side to the shooter, for example.

Taking damage and more AI

1 Comment July 9th, 2012 by Christian Knudsen

Work continued on the AI for Hostile Takeover this past week. I also ran into some issues with characters not getting drawn on the correct level if they’re in an elevator when a saved game is loaded. This almost took an entire day to figure out. A bit annoying, but it felt good when I finally figured out what was wrong (as is the case 99% of the time, it was all due to developer stupidity).

If a patrolling guard (and sometimes other types of NPCs) sees you crouching or sneaking around in a yellow area, he will stop and look at you, his hostility level will go to suspicious (making his dot on the map go from green to yellow), you will lose a bit of stealth and he’ll utter a line of dialogue.

If a guard spots you in a restricted (red) area, different things can happen. If he was already suspicious of you, he will attack you almost immediately. He will also attack you almost immediately if there isn’t a yellow area on the level you’re currently on. If there is a yellow area (such as an elevator going to an area that isn’t restricted), he’ll tell you to leave the restricted area. If you don’t leave quickly enough – or you start walking deeper into the restricted area – he’ll attack you. Attacking is still very much work in progress. For now, an attacker will just stand motionless and shoot at you. So I’m currently working on getting them to change position if line-of-sight is broken.

Click to enlarge

I also got damage to show correctly on the upper right display. And blood splatters on various interface elements to signify damage to arms and legs. Finally, I made damage to your legs affect mobility. If the health of your legs is less than 75%, you won’t be able to run, less than 50% and you can’t walk either, and at less than 25%, you’re unable to sneak as well. This automatically means that people will grow suspicious of you if you’re in a yellow area and your legs have received more than 50% damage, since you’ll only be able to sneak or crouch then.

Click to enlarge

Finally, I added checks for player death. There are three ways you can die from damage: If your total health reaches 0, if your head gets completely damaged or if your torso gets completely damaged. This will all sound very familiar to players of Ascii Sector.

This week, I’ll mostly continue with AI stuff, but there are also some minor interface quirks I’ve run into that I want to address.

Optimization and AI

1 Comment July 2nd, 2012 by Christian Knudsen

I finally got the last big optimization working last week – well halfway. Explanation follows.

The way I do the x-ray effect in Hostile Takeover is to draw the area around the player character without drawing walls in front of him nor any other objects that you should be able to see through. This is drawn to the back buffer and never actually shown on screen. I then read this from the back buffer into a 128×128 pixel image and change the alpha value of the pixels so that the further they are from the image center, the more transparent they are. I then draw the screen as usual and finally draw this 128×128 image back on top of this.

The problem with this is the part where I read the pixels from the back buffer into the 128×128 texture. The whole rendering pipeline is optimized for writing/uploading information to the GPU and framebuffer, not reading/downloading. So on older systems, this can create a bit of a bottleneck. The solution is to use a framebuffer object (FBO) instead. FBOs were an extension to OpenGL that I believe now has become a core feature. Instead of writing to the back buffer and then reading back the information in order to apply the gradual transparency and writing the whole thing to a texture, I can use FBOs so that a texture can be set up to work like a framebuffer, meaning that I can draw everything directly to the texture – cutting out the bottleneck of reading pixel information from the back buffer.

It all works fine and dandy and quite a bit faster – at least when running in a window. I’m having an issue with the 16-bit depth of the game messing up the FBO in fullscreen. So for now, it’ll just fall back to the slower method when running in fullscreen, and I probably won’t be spending more time on this for the pre-alpha release. But if you’re running the game on a computer that isn’t more than 5 years old, you probably won’t have any issues with this anyway. And if you do, you can just run in window mode for now.

So that’s off my to-do list for now. Which means that I’m now finally fully into AI. The first thing I did was extending the pathfinding code to work across multiple layers, meaning that NPCs now know how to use elevators. Following that, I’m focusing on patrolling guards and how they’ll react to spotting you.

Click to enlarge

Click to enlarge

There are three types of areas, color coded green, yellow and red on the map. In a green area, your stealth level can’t decrease. In a yellow area, it’ll decrease if you get spotted doing anything you shouldn’t be doing. And in a red area, you’ll lose stealth as soon as you’re spotted – and if you don’t leave fast enough (of if the guards are already suspicious of you), you’ll get attacked. All that is working, except for the attacking part. So I’m currently teaching my little NPC dudes how to shoot guns. They’re slowly getting the hang of it.