Friday, March 20, 2009

Plague 3.21

SanityImpaired made lots of suggestions for Plague today that I've been meaning to get round to for ages (like, months now) and some new ones (that make Plague much more difficult, so credit/blame him not me :P ), and somehow I've managed to do them all in one night. Thanks SanityImpaired, that was excellent motivation!

Plague seems to be getting slow again. I think I've squeezed too much AI into a polling package, and I need to rebuild it to be more event based and poll far less often (like once every second instead of 30 times a second). I've started that work, but I thought I'd just push this out tonight anyway.
  • changed weapon probabilities to be harder 
  • limited player to one grenade 
  • decreased ammo, weapons in map creation. Yep, its REALLY hard now 
  • allowed ai survivors to sprint, in all sensible scenarios I have thought of so far (if you think of some more, or something doesnt seem right, let me know) 
  • allowed zombies to form swarms with leaders 
  • leader zombies can now notify squads of targets (no they dont issue move commands) 
  • respaced survivor formations again to make them tighter 
  • made it so that survivors try not to crowd each other.


sanityimpaired said...

When I changed it to five weapons, it worked well for a single person. For 10 survivors... well I managed to win my fifth try. :p

I guess it depends on what feel we're after. Do we want all of the survivors to be able to defend themselves, or do we the majority hiding behind the few with guns?

If the former is what we're after, we probably want 10 guns on the map. If the latter, 5 is perfect.

sanityimpaired said...

Idea - Starting Pistol:
One of the problems with having fewer weapons on the board is that it makes finding the first one much harder. The odds of losing because you just couldn't find a gun go up drastically - and it sucks losing because of pure bad luck.

My solution: start the player off with a pistol. It's not enough firepower to handle most hives, but at least it's something.

I did this by inserting the following line into the first loop of top_up_survivors() in
if player:
self.add_sim("Pistol", square.location, sim_cat = "weapon")

I'm finding that ups the odds significantly even with only five weapons on the board, while still leaving good odds of being overwhelmed. Big guys are SCARY now.

sanityimpaired said...

Idea - Guys with Guns in Front:
Currently, individual's positions in formation are fixed. Basically, each survivor has an assigned position in formation. With wedge and chevron formations, this can lead to having a survivor with a gun way in the back where he can't get a clear shot through the unarmed survivors in front of him.

This coudl be remedied by having the formation list sort in order of weapon strength each time a survivor picks up a new weapon. This puts the guys with weapons in front in chevron/wedge formations rather than being jammed in the back.

Another way to do this would be to assign formation positions dynamically, with each survivor beign assigned a formation position based on how close they are to it and whether or not they have a gun. That's going to be a nightmare to code, though.

sanityimpaired said...

Idea - Stop/Follow Commands:
One of the things that could be useful is a command to stop all survivors from moving. There are a few different uses for this:
1) Set up a static formation, then scout ahead to lure zombies back to the formation.
2) Stop survivors from running into certain death chasing a weapon/item/etc.
3) Keep those thieving buggers from grabbing a weapon you really want yourself.

The easiest way to do this would be set AI survivors speed to 0 when the "stay" command is hit, and to change it back to normal when "follow" is hit.

sanityimpaired said...

Idea - Narrow Line with Guns in Front:
Rather than having line formation form a single thickness long line, it would be nifty to have line formation create two lines, with the survivors in front having the guns.

This makes line formation more useful for narrow spaces/advancing while still putting the unarmed survivors behind the armed ones.

It also means if you get charged from behind things turn ugly fast. Which I'm a fan of. :)

Benedict Carter said...

I was going to the majority hiding behind the few (because you lose points if they die).

A starting weapon is a good balancing idea , although I must admit I was having fun running around crazy scared looking for a gun.

Benedict Carter said...

Agreed survivors with guns should be up front, and I do want dynamic position allocation. The issue with dynamic reallocation is more calculation to find the best position, and theres got to be some mechanism to "disallow" positions because they've been filled. The filled part is the part I'll have to think how to do.

Then mixing that in with gun strength is going to be a nightmare as you point out since I'd have to come up with a metric that balances gun strength and distance from free position. Urgh. Thoughts?

I was also OK with survivors with guns at the back so the can defend the rear.

Benedict Carter said...

Stop/Go is a good idea, but in the current implementation it would apply to all followers (i.e.: you cant select a group like in an RTS yet), and that might be kind of annoying if some are in the "wrong" location when you call stop.

I also want a "go to here and wait command" (which I think would accomplish the same thing but be a bit more flexible?). Shouldnt be too hard to do next.

If you want to experiment, set sim.acc_mod = 0 to stop and sim.acc_mod back to 1 to go.

Benedict Carter said...

Woo, I like the idea of two lines, guns in front. I cant think of a way to mathematically figure out the position location since it requires knowledge of previously filled positions, which is now conditional.

An alternate formation would be a gun-sim sphere around no-gun-sims, and it wouldnt matter if it was ragged (ie: formation ring, but if no gun then formation_location = middle, and the middle survivors can crowd around each other).

I think I'll have to give sims a formation_position attribute to allow the more structured formations, and then come up with a method to assign the formation_position, and then link that into the formation_location routine.

How important is this vs other things I can work on?

Eg: To me, Stop/Go/Goto seems like its quite a big win for little work, whereas more structured formations seems like a moderate amount of work with a much smaller payoff.


Benedict Carter said...

Oh yeah,

Why no gun at the start? Well my initial vision of Plague about a year ago (when I had no idea how to program, or how much work everything is) was to have a city simulation (with pop 100-100k depending on game size) where you start out as an ordinary citizen and a zombie Plague breaks out.

Naturally you'd be statistically unlikely to be near the starting infection, so you would probably have time to find weapons, food and barricade yourself (or perform the start of whatever other survival strategy you had in mind) once you realised a Zombie horde was rampaging through the city.

Early versions of the game were like this (before I started adding Line of Sight, etc, that massively increased the computational load per sim).

If I can get the game performing well with a large number of sims again, I'll change the starting conditions so theres a clump of zombie hives somewhere (not distributed like they currently are) and 1000 or so survivors again. Then the initial zombies will consume the population while you flee in terror.

It was actually pretty fun, and I wonder if I should quickly (relatively speaking) spin out a Plague-lite version that doesnt have things like fire, line of sight, reasonable physics, etc...

Of course stripping out line of sight leads to a whole new class of problems (like zombies trying to get at sims behind walls, sims shooting into walls to get zombies...) which is why I added it. Otherwise there has to be other LOS checks which tend to poll instead of be event based, which is slow...

sanityimpaired said...

Don't get me wrong, I like the running around trying to find a gun part. The problem is that it doesn't work well when you have a pack of survivors you're responsible for protecting that get massacred while you run around looking for a gun. :(

This won't really matter once the engine is finished and you start breaking it into phases and such. Phase 1, you're alone being chased by zombies looking for a weapon. Phase 2, find other survivors. And so on.

sanityimpaired said...

It's really a balancing act between scale and detail. The more things you have active at once, the less complex they can be without bogging the whole system down. A lot of MMORPG emulators have exactly the same problem because they have hundreds of thousands of monsters in their world.

The solution is to not create zombies until they're close enough to the survivors to matter. It gives you the ability to have only a few zombies actually doing anything so you can afford good AI and such, while still being able to build a large environment with lots of zombies in it.

One way to do this is to break the map into sections, and have each section store a list of zombies in it's territory. As survivors enter sections, the sections themselves spawn the zombies they contain. As survivors leave, the section stores the inactive (ie. not chasing anybody) zombies for later.

You could do something similar by creating objects to represent swarms of zombies. They'd be placed on the map as per usual, and would populate/destroy zombies around them as survivors move in and out of range.

The former is very efficient, the latter allows you to do things like have swarms of zombies moving around the map on their own. Zombies attacking the survivors while they think they're in a safe zone = win.

Benedict Carter said...

Yeah, I agree for the current phase adding a starting pistol is a good idea. I might also assign a few to other survivors at random (and maybe make yours random as well to mix it up). It might make even more sense to not have weapons distributed about the level, and instead just have some starting weapons. Thoughts? Maybe have the super weapons as an occasional bonus find?

Yes, I'm planning on stiching maplets together (to allow larger gameplay spaces) but theres a whole host of technical problems that put that one in the "too hard for now" basket. The original design was for a large continuous world where sections were loaded dynamically, ala Morrowind, until I realised it was probably a very complicated problem well beyond my current abilities and knowledge. I then changed the design to be more like XCOM, with a strategy layer and battle scenarios. (Obviously, I have yet to build the strategy layer as well).

I had been thinking about grouping zombies with one AI and no physics when they werent around survivors, (and the same for other survivor groups) but it had to wait until I've tightly coupled zombie mobs (at the moment they are loosely coupled, which is better than it was yesterday). I was thinking I had to build "swarm movement" for when the player got close to explain why there was a mob of zombies moving about as one unit, but talking about it now with you I guess I dont, I can kludge something together which will look good enough to the player. Thanks, that was valuable.

Theres actually no reason why Plague cant have both of course, maplets and abstracted mobs (apart from maplets being complicated to implement).

Sadly I wont be able to do any work today, I've got prior commitments. I should have another release done tomorrow night though (my timezone).

sanityimpaired said...

Code when you have time. Real life always takes precendence over hobbies. :)

Are you eventually going to move to tiled map design for indoor areas? That might work well for sectioned zombie design: have any tiles connected to the one the survivors are currently in spawn zombies.

sanityimpaired said...

I'm looking into adding a freeze/follow key, and I'm looking at

There are a lot of if statements in here that probably don't need to run. For example, in player_controls(), you've got a separate if statement to check for each keypress. Wouldn't it be much more efficient to use elifs instead?

sean said...

Wow, you guys are flying along...

Adding Stop/Go/Goto would be a huge bonus. I was actually gonna stick it in myself but I got distracted and you seem to have it covered. Instead I made a title screen, and since I drew in a button for 'options' I figured that'd be nice too, so there's a menu that lets you toggle full screen, sound and a bunch of difficulty settings (max zombies, survivors, etc.)

It still needs a bit of cleaning up, but I'll hopefully be able to post it later today. Then I can get back to making the horde shamble like proper zombies.

sean said...

Also, some of the pygame people are working on a site that's more community project oriented at

It's not totally finished yet, but it does seem to be working and a forum might be easier for spamming ideas/requests/todos than comments.

Benedict Carter said...


I dont know when/if Plague will move to tiled maplets - I suspect if it is ever to get bigger continuous play spaces it'll need to. I think because of the technical challenges (eg: how to do zooming?) it'll have to wait. I would like to get it eventually done though, because all of the games in my head have large continuous worlds to play in.

In the mean time I think I'll implement distance checks between groups, since there shouldnt ever be many groups (eg: ~10 per current map size).

It wont take me long to add stop/go orders as I have the code designed already.

Are elifs more computationally efficient than ifs?

sanityimpaired said...

Yeah, comments are kind of a crappy way to have a dialog - especially when it involved more than one thread of conversation.

Also, options menu? Nicely done, sir!

Whenever the interpreter hits an if statement, it has to determine if the condition is true. When it encounters an elif statement, it only checks the condition if the previous if/elif's conditions all returned false. So elifs are much more efficient if you stack them with the most likely outcome first, because it stops checking once it finds the right answer.

This gets more significant the more often the function is called, and the more work is involved in checking the condition.

Another thing that might speed the function up is calling pygame.key.getpressed() once at the beginning of the function and storing it in a local variable which you then check against. That means less function calls to pygame, and thus less overhead.

I come from a C/C++ background, and as a group C programmers are obsessed with this kind of stuff. That's also why I'm not doing a lot of recoding, I have very little experience with Python. :p

Do you want me to rewrite player_controls() and post it for comparison? I ask because people sometimes take that kind of thing personally and that's not at all my intent.

Benedict said...



I'm cant wait to see what you've done, esp. the options menu!

(btw: I left this comment a few hours before, but it didnt get uploaded... the delay in my response to your latest post in no way reflects my excitement about what you've been up to)

Benedict said...


Elif: Ah, of course!

Please, by all means rewrite, its been on one of the "to do" lists for a while now as I've been aware I've done it in a suboptimal way.

I don't take "these things" personally - I love learning and I'm happy to learn from others. Have at anything you want.

You'll probably see lots of things to improve as you dig through the code. I've only started to learn programming recently in my spare time, and Plague is my first project, so I know for a fact that theres lots of suboptimal code around.

Benedict said...

Sean/SanityImpaired/Michael(if you are around):

Do any of you want to become admins for this pyed-project as well?

Any of you have any preference for a standard "open" copyright licence as opposed to the thing I wrote in the readme? I'm open to suggestions.

Any idea if it supports a bzr repository? It would be good to get some version mngt since you are submitting code (sounds like you've got some substantial stuff coming through Sean).

小小彬 said...