Progress of the week: lens-flares
Models, charts, diagrams, ... If you went to school... and still remember some of it, you may also remember those stupid business diagrams. Flowcharts, state diagrams, functional Heinz Ketchup charts, the dr.Eukaneuba sequence model, or whatever they were called. Don’t get me wrong, *some* of those models actually are very useful. But I got the impression that each and every person wanted his moment of fame by introducing yet another model, made of some circles and blocks. Typically made by the “management layer” to simplify complex structures, making your work look easy. Or to talk a lot about something without actually doing something.
By dr.Ricky mcPoopy
Most of those models make sense more or less, but… really. The model above was made within 2 minutes by using some fantasy. They aren’t some miraculous cure to solve complex problems, and do we really need to learn hundreds of those at school? The purpose of such diagrams is to illustrate difficult stuff in an easy way so an outsider could say “Crap, now I understand!”. And probably to let the managers understand themselves what they are selling, as they usually don’t know or don’t care about the deeper technical details.
Nothing wrong with that, not everyone is a technician, nor has time to dive deep into the matter. But the main beef I have with those models is that there are too many, and moreover, they usually just can’t cover the whole thing. Either they are so simple and obvious that drawing them is a waste of time as an ape could have guessed that as well, or they are incomplete. The security system of a nuclear powerplant can’t be written down in a few circles on a whiteboard, because it’s too fucking complex! Too bad if you don’t understand it then, but that’s why there are experts in the world, let them do their jobs.
IT studies often come with these diagrams as well. But of course, the examples are always too easy. say, how to make a vending machine?
The Snack-Swindler 3000
Nice, but useless. Drawing that diagram costed me 5 precious minutes that could have been used to directly program the damn thing. And though it’s easy to understand, it’s incomplete. What if we ran out of Snickers? How about sending a text-message to the vending service when it needs a refill? What if some asshole threw wooden coins into it? By the way, this program hangs if you insert a coin but don’t finish the selection or ran out of money (and you don’t get change then, screw you).
Sure I understand that books will use simple examples just to illustrate how it can be done. But then try to make the same model for a more advanced application. For example, how a harvesting machine with 200+ IO and 30 different functions should work. Nope, that wouldn’t fit on a single A3 paper, unless you just want to explain your customers that the machine can be switched on, off and drive. But you don’t need a paper for that.
Of course you can zoom in though. First make a simple overview diagram, then describe each of the sub-functions with another diagram, and eventual even deeper sub-diagrams. Now we get a more complete view. But… now it lost its simplicity. Sure the managers won't like that, non-technicians probably won’t read them, or they get lost in all the states, conditions and relations. Also, making those diagrams *correctly* is sometimes even harder than just programming it, and therefore takes a lot of extra time. And to ruin it completely, paperwork will always be outdated as soon as you start programming. Because in practice, things will always turn out different. No, I’m not a big fan of them.
Not only lamps, everything that shines (such as specular hightlights) can cause lensflares.
AI State Machines
But there are exceptions. If you work in a bigger team, or your product will be used by other technicians, you owe them proper documentation for a start. In that case the energy in (re)writing these diagrams may become a necessary evil. But what I really wanted to write about, are “State Machines” used for AI.
As explained in the first post, and a bit above here as well, AI is complex. Especially when trying to make it “imperfect” with fuzzy human logic. A common problem I ran into, is the AI trying to do two things at a time and getting confused, or not doing what you would like it to do. Not because of the computer having a free will, but because the conditions are getting strangled. Let’s make an example, coding a soldier. We start simple, he just stands and starts shooting at you when he sees you. So the code could look as follow:
If ( icansee( player ) ) then beginIt works. But now we get the brilliant idea to let the soldier run to a health-station in case his health drops below 50%:
....Shootbullets( @player, randomize a bit );
End;
If ( health < 50 ) then beginIt still works, but the soldier actually got easier to kill, as he turns his back to you when hurt him. Dumbass! We need to tweak some of the conditions before he starts walking. Like not just walking away as long as it sees the player.
....moveTo( nearbyHealthStation );
End else
If ( icansee( player ) ) then begin
....Shootbullets( @player, randomize a bit );
End;
If ( health < 50 ) and (NOT icansee( player ) ) then beginHmm… turns out soldiers never run to the healthstation in practice, or at least never reach it as the player keeps showing up and thus interrupting his journey. Besides, a soldier that immediately starts firing and only walks if he can’t see you doesn’t exactly act “human”. Maybe we should add some delays before the soldier starts firing or stops walking. And maybe it should be distance dependant. If the player is far away, it’s safer to walk to a health-station. Unless he is sniping. Unless the health-station is very nearby. Unless random(10) = 2. Unless…
....moveTo( nearbyHealthStation );
End else
If ( icansee( player ) ) then begin
....Shootbullets( @player, randomize a bit );
End;
You see, the conditions add up quickly. The code gets ugly, harder to debug, and at some point the soldier just doesn’t know what to do anymore because there is always some condition that blocks. Or the soldier acts nervously, changing his mind all the time and thus never actually completing a single task. I think in general it’s better to let an AI decide something and stick to his plan. But to prevent dumb actions, the decision should be a good one in the first place. Anyway, defining AI behavior is one of those situations that cries for some simplification. Well, check this out:
That's a State-Machine. Not quite as brilliant as the Mickey Mouse success model, but still usefull, and covering some AI fundamentals for pretty much any action game more or less. And because it’s so simple, it forces you to think and program simple to prevent scenario’s where Rambo keeps running while one leg was blown off by a landmine, Red Sonya picking up three machineguns at the same time, and Nick Nolte keep shouting after being killed 300 times. It doesn't tell quite yet how to make our "Soldier" from above act smarter, but starting with a clean way to code saves half the problems. Really. With a state-machine, each state basically defines the current behavior of your NPC, and the lines between them are possible transitions that have to be checked. If the conditions of a transition become true, the current state changes.
Let the battle begin
If you think about it, you will probably recognize the states described above in most action games. Make noise, and nearby guards that heard it, will react. But instead of directly shooting you, there should be some delay. “Fuzziness” would be to increase an awareness level, depending on how frequent and how loud our noises are. A single footstep shouldn’t make the alarm bells ring yet. Just a “huh?” from a guard. Firing a gun on the other hand makes the guards Alert. Once alerted, NPC’s will take action. They go towards the last heard sound position (with a random radius around it maybe to prevent exact magical tracking), pick binoculars, sound the alarm, call each other, arm their weapons, et cetera. As for Tower22, our monsters won’t radio Charlie Hotdog Echo base for howitzer support, but they will curiously check the area as well. Same thing in essence.
Alert isn’t the same as combat yet. The NPC knows there is a threat, but doesn’t know where (well, the computer of course knows, but don’t cheat!). But by moving into your position, chances get bigger they will detect you eventually, if you didn’t start shooting before already. To prevent all enemies dumbly coming around a corner to get shot, some scripting or hints can give a role to each NPC. “Scouts” will move to you, “Support” will back them up, “Guards” will move into a fixed fire position, and Spiderman will quickly swing to a roof.
Once a NPC saw you (or your buddies) good enough, the shit is on. Combat state will activate, and the careful Alert state will change into a faster, aggressive Combat state. NPC’s will shoot on sight, and also adjust their pathfinding tactics. Take short quick routes, from one covered spot to another. Then depending on their role, they will either stay on a distance, flank you, or engage as lunatics. Secundary needs such as reloading a weapon, retreating or healing can be done on special conditions.
Maybe not exactly what they teach you in the army, but it is an option.
The State Machine above is basically a sub-machine of the "Combat" state. Probably I missed some links (which is another problem with models, they quickly get a messy spaghetti), but it seems quite easy and fun to program AI this way. Too bad T22 monsters don't carry guns though, so this whole tactical plan can be thrown in the garbage bin :)