CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.26k stars 4.12k forks source link

Dormant zombies: a huge game changer that we're ready for now. #65305

Closed I-am-Erk closed 8 months ago

I-am-Erk commented 1 year ago

Is your feature request related to a problem? Please describe.

36832 outlines a previous version of this but we now have tools to make it much more accessible.

Many monsters, including zombies, robots, and magiclysm golems, should not simply wander around all the time in brownian motion when not being observed. They should enter a dormant mode.

I will write this issue looking principally at zombies. We have a hard cap on the number of zombies we can tolerate in a location before they smash everything around them and cause lag, as well as just becoming silly from a game perspective.

Solution you would like.

We should create "dormant" monsters, a form of trap that represents zombies lying around acting like human corpses. Imagine this as a "low power" mode, but it's also a way to keep run of the mill zombies present and dangerous, give them a way to ambush players, make night raiding scarier, discourage gunfire, but also encourage players to venture into more populated areas.

Implementation recommendation
  1. Create a new item, "corpse_zombie_dormant". This is indistinguishable from the regular human corpse. (Note in the hopes of discouraging more repetition in the comments: it's not all that important if players can figure out which corpses are dormant zombies and which aren't.)
  2. Create a trap, "tr_zombie_dormant". Add a bit of code somewhere to ensure that when tr_zombie_dormant is placed on the map, an associated corpse_zombie_dormant is placed. We may also want a sanity check that places the same trap down whenever the corpse item is placed, so you can never have one without the other. (See comments for some other ways this might be implemented)
  3. When the trap is triggered, run an EOC or spell that revives the corpse_zombie_dormant in the same tile. More specifically, just delete the corpse and spawn a zombie there... we don't need to use the actual revive code.
  4. Error trapping: the trap should trigger when you're in an adjacent tile, not just when you step on the tile, and the trap should trigger if you interact with or smash the corpse_zombie_dormant, or if the corpse_zombie_dormant is damaged but not destroyed (eg you drive on it with a car). The trap should ideally not be triggered by other zombies.
  5. Stretch goals: it would be very cool if a damaged corpse_zombie_dormant revived as a zombie with fewer HP. However, the number of times you're giong to be able to damage one partly before it wakes up are pretty few so this isn't necessary on a first pass.

Once we have the basic ability to step on a zombie corpse and have it wake up and menace you, we need to work on the zombie hive mind a bit and make these guys really scary.

This concludes the primary goal: if you stumble on a zombie corpse, it wakes up and attacks you, and wakes up its friends. However, I also mentioned making guns scary!

Goal 2: A quieter place

It's been a long discussed thing that the primary balance concern for guns should really be that it's a terrible idea to make a ton of noise in a crowded apocalypse, but we haven't realized that problem.

We need another EOC that triggers when the player makes noise. I would suggest this begin at noise level 12 with a radius of 2 tiles around the noise source, and the radius expands by 1 tile every 2 noise thereafter. The EOC should have a chance of triggering dormant zombies in the radius, but not be a guarantee. Ideally, the chance should decrease the further the corpse is from the source of the noise, but it could also just be something like a flat 25% chance, if that's too hard to design. IMO if the dormant zombie is a few tiles from a gunshot it should wake up for sure, whereas if it's across the city, there should be a good chance it doesn't wake up.

This may need tweaking to ensure zombies that are wandering around do not wake up all the others all the time with their crashing and bashing. To that end we probably don't want the secondary "wake up nearby dormants" to trigger if the first dormant was woken up by noise.

Return to sleep

Another thing we may want to consider is making woken dormant zombies a special type of zombie rather than an instance of mon_zombie, and have them return to a dormant state if they don't see a hostile trigger after five minutes or so. I am not sure how to implement this but I suspect there's a way to do a monster-end eoc or spell, it may need triggers that don't exist yet.

Balance changes to follow

Once we have these working, we can add a ton more zombies to lootable locations, but we should also reduce monster spawn rates. Overall there should be more zombies in the world, lying in crashed cars, etc etc, but they should be less of a CPU draw and less of a source of chaos this way. We can start adding them to places where otherwise they'd destroy everything around them, for example. We can even have them spawn in starting shelter basements and places like that, if we're careful, because now they don't just eat you right away... draw in a blood trail, put a corpse on a bench down there, and you've got context to watch out and a good warning about the bodies you may encounter.

Describe alternatives you have considered.

My older issue, linked above, suggests a code based way to do this, while this does it by EOC.

It's not necessary to implement it as a trap, but I do think it's good to be able to leverage the whole thing with traps and perception allowing you to recognize if a particular corpse is a dormant zombie.

Additional context

I think this has the potential to massively improve the feel and balance of the early game.

crypticcollaborator commented 1 year ago

I think this is an excellent idea which could resolve many of the issues with monster performance in large spaces that we've seen. A good approach to this would be to create a JSONized system where traps can spawn arbitrary items and arbitrary monsters. There's many different places in the game where dormancy would be appropriate beyond zombies - robots behind walls in TCLs, slime pits, rooted fungus, rooted triffids, corpse pits

bombasticSlacks commented 1 year ago

Should we potentially just have items allowed to have proximity EOCs? Then stuff like cupboards and computer monitors could have EOCs trigger to display items when you are adjacent or potentially allow you to read a nearby screen. Making it a trap that also juggles a corpse just seems like a lot of extra overhead for the scripting.

I-am-Erk commented 1 year ago

You'd know better than I if that's easier to implement, but I'd be fine with that. The advantage to making it a trap is that it leverages some aspects of existing traps, such as your perception score helping you recognize from further away if a corpse is a dormant zombie. However, we could potentially have a 'proximity eoc' get some kind of flag for indicating that it should behave like a trap and reuse that code, maybe?

bombasticSlacks commented 1 year ago

I see you're point yeah, perhaps "only" being a trap is the solution then. It's hard to say, but I don't think long term we should build off juggling both things.

I-am-Erk commented 1 year ago

There might be easier ways to do the trap than what I've described here, like it might be possible and simpler to have a trap that is coded to "look like" a particular item - so we make a tr_zombie_dormant and add a looks_like_item attribute with corpse_human (or whatever the exact item code is), and this tell the game to lie to the player and say there's a human corpse item in that tile.

or we just make the trap look like a corpse visually and not worry about it. Players are going to start treating all corpses as posisble zombies so it doesn't add all that much to get into the weeds trying to make them indistinguishable.

SeanMirrsen commented 1 year ago

I think there's a... slight gameplay/concept discrepancy with this idea, in that... well, the player is already given warnings on all corpses intact enough to rise. Any intact corpse is a danger because it can revive.

I think this idea needs to morph a little, into a more generic concept of the player noticing whether or not a corpse is intact enough to rise. Because right now the player immediately knows when a corpse is intact, it's highlighted for them. If that's changed to where the player would need some level of relevant knowledge, and perception, to know of the danger of an intact corpse and to gauge whether a corpse is intact enough, the 'traps' could naturally form out of sufficiently intact corpses.

And then, mostly intact corpses could be scattered around places alongside destroyed ones, and would all function exactly the same in regards to re-rising, as in waiting until the player is sufficiently near them. Players with good perception could receive warnings that a corpse is about to rise when approaching, and other such relevant notions.

kevingranade commented 1 year ago

Some ancient history for context https://discourse.cataclysmdda.org/t/zombie-evolution/3847?u=kevin.granade https://discourse.cataclysmdda.org/t/zombie-behaviour-changes/491?u=kevin.granade

I-am-Erk commented 1 year ago

I think there's a... slight gameplay/concept discrepancy with this idea, in that... well, the player is already given warnings on all corpses intact enough to rise. Any intact corpse is a danger because it can revive.

I think this idea needs to morph a little, into a more generic concept of the player noticing whether or not a corpse is intact enough to rise. Because right now the player immediately knows when a corpse is intact, it's highlighted for them. If that's changed to where the player would need some level of relevant knowledge, and perception, to know of the danger of an intact corpse and to gauge whether a corpse is intact enough, the 'traps' could naturally form out of sufficiently intact corpses.

And then, mostly intact corpses could be scattered around places alongside destroyed ones, and would all function exactly the same in regards to re-rising, as in waiting until the player is sufficiently near them. Players with good perception could receive warnings that a corpse is about to rise when approaching, and other such relevant notions.

This is a fun stretch idea, but the "will rise randomly at some point" and "is actually already a zombie, and it's just sleeping" factors don't really need to interact all that much. If we use a corpse item, maybe the trickiest part is just making sure it has the tileset overlay warning that it could rise. Most of the time that warning is just a qol feature, it's very rare for it to provide helpful information you don't already possess.

I do think that it'd be reasonable to randomly replace some of the corpses in the body pile map extras with dormant zombies.

kevingranade commented 1 year ago

I think there's a... slight gameplay/concept discrepancy with this idea, in that... well, the player is already given warnings on all corpses intact enough to rise. Any intact corpse is a danger because it can revive.

The reasons the player unambiguously knows that a downed zombie is capable of rising are: In almost every case the player either downed the zombie or saw it happen. The zombie corpse is visibly regenerating, like twitching, dormant zombies won't do this.

Dormant zombies are literally indistinguishable from corpses.

GuardianDll commented 1 year ago

Add a bit of code somewhere to ensure that when tr_zombie_dormant is placed on the map, an associated corpse_zombie_dormant is placed

Should be not only the corpse, but the loot groups, that are bonded to respect zombie type. Zombie corpse with no loot is just a giant exclamation mark for the player

I-am-Erk commented 1 year ago

The loot groups in this case would be spawned with the zombie. There should be no way to start looting a dormant zombie without it waking up.

LordZanos commented 1 year ago

I think it would be good to see damaging these before they wake up prioritized, it would add some more value to silent ranged weapons like bows; which typically can do enough damage in a single hit to unarmored zombies to prevent them from getting up.

I-am-Erk commented 1 year ago

The trouble there is that it opens up some cans of worms. Does a dormant zombie getting killed while dormant cause other dormant zombies to rise? (probably yes). How long does it take to regenerate after being killed? It's a bunch of other coding bits.

GuardianDll commented 1 year ago

There should be no way to start looting a dormant zombie without it waking up.

you can just look at it's loot from afar

image

I-am-Erk commented 1 year ago

That's something that can be fixed up in a future pass then, but as I said to Slacks, once this is known as a thing, it means players are going to be suspicious of every corpse anyway, so it's not that big a deal if it becomes fairly easy to identify the dormant ones. It's better if it's tricky but it doesn't dramatically alter the mechanic, since the main way they're going to get you is either by you stumbling on them by accident or by you waking them up with noise.

NetSysFire commented 1 year ago

Create a new item, "corpse_zombie_dormant". This is indistinguishable from the regular human corpse.

Given we have so many different zombies and they also have the characteristic black goo and filthy clothes on them, I do disagree on the "indistinguishable" part. I mean sure, this could work for normal, tough, fat, child etc zombies but not for say a hulk or skeleton.

There are also very few human corpses in most locales, even in the beginning (sort of related: #64222, #56958), making this a rather obvious trap.

However, zombies utilizing the environment could be fun. E.g zombies entangled with roots or other vegetation (seen in the walking dead) that grew over them while dormant. Or, while much more rare, a zombie who went dormant in say a closet and it will surprise the player.

Taking the environment in account, we also need to clarify how maggots, carrion feeders and other decomposing processes affect them.

I-am-Erk commented 1 year ago

At the moment, I haven't put any consideration into mutated zombies as dormant. It may be that they don't go dormant, or if they do, they should definitely be more visible, but it's largely bikeshed to the issue. For the rest, the reason to make them a trap is that then your perception can play a role in distinguishing between stuff like dried blood versus gross zombie goo. Once you recognize it as a trap, you've spotted giveaways that it's not just a corpse.

Ultimately though, while it would be fun to add ways to make it surprising, making the trap hard to identify is really pretty secondary. The thing these guys add is that if you're walking around in a dark house, it's easy to step on one, and soon, making a racket will wake them up and call them to you. That's the mechanic we need first, and from there we can worry about how to make it effective as a trap in the meta.

I-am-Erk commented 1 year ago

Kevin pointed out that another way to go about this would be to create a proxy monster that, as soon as it is generated, casts a spell that deletes it and replaces it with a trap and a corpse. There are some pretty good advantages to this but I'm on my phone, will post them later.

Qrox commented 1 year ago

Many mechanisms you mentioned about dormant zombies (such as using preception to discover whether one will revive/wake up) can equally apply to reviving zombies and there is also the potential for dormant and reviving zombies to interact, so if a new system is to be made for dormant zombies. zombie revival should also use that system, because otherwise it will inevitably cause discrepancies and become a maintanence hell.

PatrikLundell commented 1 year ago

I'm not keen on using trap work arounds because it will cause various issues, such as the one @NetSysFire mentioned and that the inevitable mega super tough dormant zombie that you managed to whittle a bit of health off of before you had to escape to huff in a corner for a quarter of an hour to regain stamina then goes dormant and thus is respawned at full health (and with different looks, when creature variations exist, such as male<->female, which is weird enough when you leave a location and return).

I'd rather see a system where various "creatures" can be dormant and activated by proximity, sound, or damage. Ideally, going back to dormancy should allow for an optional return to the start location (which would fix trap spiders, for instance). For that system to allow players to be fooled, creatures would have to be given different sprites and descriptions based on their dormancy state (and, as an extension, other possible states that might change the appearance/functionality of a "creature").

I-am-Erk commented 1 year ago

Qrox: where I'm at right now and hope to add in today as an alternative way to do it would utilize revival as the mechanic that wakes up dormant z, so that would probably cover your concern.

Patrik: I'm not sure what you mean about trap workarounds; using traps is one of the solutions to netsysfire's concerns. I wouldn't get worried about the possibility of a strong dormant creature going dormant, healing, and reviving at this stage... that requires there to be significantly strong dormant enemies, and the ability for enemies to go dormant again, neither of which are part of an initial implementation of this. However that problem can still be solved by storing the HP of the dormant creature into the durability of it as a corpse item.

I don't have any objections if someone decides to code a bespoke new system for this, but since that's been requested since 2013 or so, I'm not holding my breath. However it can be done basically right now using eocs, and in the process would help to extend and improve scripting options.

kevingranade commented 1 year ago

this could work for normal, tough, fat, child etc zombies but not for say a hulk or skeleton.

Yes evolved dormant zombies world look like their own downed corpses.

There are also very few human corpses in most locales, even in the beginning (sort of related: #64222, #56958), making this a rather obvious trap.

That's something this would change, we'd be placing dormant zombies and "just a regular corpse" that will eventually turn into a dormant zombie if left alone in most places where zombies spawn now.

Its less that its a trap per se and more that it's an environmental hazard. We need to adress the "what does it look like" issue, but that's a detail, not the main point.

Taking the environment in account, we also need to clarify how maggots, carrion feeders and other decomposing processes affect them.

It's a race between decomposition and blob restructuring. Once the blob is fully entrenched the zombie or proto zombie has a functioning immune system again that fights off decomposing agents.

I-am-Erk commented 1 year ago

I'll move this into the main post later I hope, but here's an alternative implementation based on a half-joking comment Kevin made.

  1. Create a monster, "pseudo_dormant_zombie". This monster dies and casts a spell or activates an eoc the moment it spawns. Its corpse, "dormant_zombie_corpse", has all the properties of a normal zombie corpse. This spell/EOC also creates a trap, "dormant zombie activate", on the same tile. The pseudo monster is invisible, and shouldn't give a "the dormant zombie dies" message.
  2. The dormant zombie corpse is a regular corpse in all regards, including registering as able to revive. However (this part will need a little code support) it does not automatically revive on a timer, it only revives when it gets a revive signal, eg from a necromancer... Or the dormant zombie trap.
  3. When triggered, the dormant zombie trap revives corpses in its same tile

Note that the corpse of a dormant zombie should look like a human body when examined at a distance. The trap, when spotted, will identify it as a zombie. However, as reiterated a few times, people will pretty quickly start treating all unattended corpses as "possible zombie traps" so it's not that big a deal making the trap hard to identify

Conceivably, we might want to make "dormant wake up" an alternative kind of revive that uses revive code but only works on corpses that, like the dormant corpse, do not revive on their own. If this is difficult I don't think it's incredibly important, the only problem if it's not is that if there are multiple revivables on the same tile they will all wake up, but I don't think that's going to happen often and if it does, it's not going to seem especially weird.

As noted above, there are improvements we could work on on revive that would help this out, like transfering corpse item damage onto the revived zombie. However this isn't necessary for a first pass.

The remainder of the above issue (noise effect, activating nearby dormants, having zombies go dormant after a while) can be managed as listed. Sound waking dormant zombies is the only one I think we need on a first pass, zombies going dormant again is comparatively low priority. We definitely don't need evolution for dormant zombies for quite a while, one of the roles they can play is helping to keep regular cannon fodder zombies in circulation into the later game.

The main thing this does is solve the issue of having a proper zombie corpse and a trap spawn in the same tile, and also it allows us to put them into monster spawn lists, which will make them much easier to insert into the game.

I-am-Erk commented 1 year ago

Tangential but I want to make a note of it: it'd be nice if we could make pulped corpses look different in tilesets. Part of why we have a revive marker is that pulped corpses really should look pretty pulped.

Also related, I'd love to add some more context sprites for corpses to go with this, so that they look different if they're on sofas or car seats or in a bathtub.

John-Candlebury commented 1 year ago

I'd consider visibility to be a very important issue here, and this needs a tileset independent solution. If random items in the ground risk killing me, they deserve to be appropriately marked on the map, no need to constantly check the "V" item menu to asses risk (which it really isn't built for). I'd already consider the fact that you have to rely on tile sets for the map to mark tiles with non-pulped corpses to be a related misfeature.

At the minimum the solution is to give corpse items draw order priority so they always show at the top of item piles (this generally happens ever since corpses became containers but its not guaranteed to happen if a corpse spawns in the same tile as some other item). But if items might actively turn into enemies, I think they deserve to be shown as possible monsters in the minimap, compass and the list all monsters menu.

I-am-Erk commented 1 year ago

I agree with you candlebury, but I'd call that an issue related to revivable corpses in general, and not so much this issue. In fact since this is a trap as well as an item, it's likely going to be more flagged as a concern than a regular revivable corpse would be

Totally agree that corpses should always be the top level displayed item though, and open to suggestions on how ascii could represent non-pulped corpses.

estebandellasilva commented 1 year ago

There is also the question on how to handle evolution - as time progresses the normal zombies get less - will those dormant zombies stay dormant or will they evolve over time Or will they evolve slower?

I-am-Erk commented 1 year ago

Presently I wouldn't allow dormant zombies to evolve. There are many different ways we could take their evolution in the long run, but it is something up in the air for now.

Reviewing what I wrote above about starting with a monster and triggering an event on spawn, the initial barrier I'm seeing is that there's no easy way to trigger an effect or spell on monster spawn. I'm going to see if I can track down where to add this in the code though.

SeanMirrsen commented 1 year ago

I still hold the opinion that the 'traps' should be nothing so complex. Just make it so dead bodies have a great variance in how long they take to naturally rise, or re-rise. This will make all intact zombie corpses potentially dangerous if you haven't just recently caused them. Under the guise of that notion, you can introduce a sneaky feature where an intact dead body - zombie or not - can 'skip ahead' in its revival timer when the player approaches. Make the player pass a check to see if their character notices the threat, and alert them the corpse is 'live', and the trap springs a set time after the check regardless of whether the player notices - probably the handful of seconds it would have taken the player to approach.

I-am-Erk commented 1 year ago

That's not a "just do this", afaik that's an enormous rewrite to item and revival code.... And most of the rewriting would be trying to make it function like something we already have, a trap.

keampe commented 1 year ago

So, the goo pits in the old science lab transform a creature while keeping it's items. Could that code be leveraged for this?

I-am-Erk commented 1 year ago

The goo pits work differently in almost every way and are hardcoded.

Really what's outlined above is much simpler than any other way I can think of, otherwise this wouldn't have been sitting as a desired issue for ten years.

keampe commented 1 year ago

So, if I get this right you spawn a zombie, kill it with an EOC that also spawns a trap under it. That trap, when triggered essentially casts the Necromancer raise dead spell on that tile?

Neat! You could even have the trap make sound so that if any other dormants are particularly close, they also rise.

remuluson2 commented 1 year ago

Tbh the main thing that I would love it for is places like TCLs and other laggy, zombie-fest areas into much more playable experiences.

I-am-Erk commented 1 year ago

That's definitely one of the appeals, remuluson; it also lets us add more zombies to towns without having them become similar instant lag-fests.

I-am-Erk commented 8 months ago

There are still bits to do but the crux of this can now be joyously marked as done