Project Zomboid

Lone Survivor



Hello! The last couple of weeks has had an unusually high number of absentees, by coincidental combinations of gaming conference attendees, long-planned family visits, and even an unforeseen emergency hospital stay (that turned out fine, don’t worry) meaning we’ve been running on a somewhat diminished team of late, but that should be sorted out by next week and we’ll be running at full steam again! – so unfortunately, there aren’t any sexy vids or pics to show off. However, still we have some super interesting stuff to talk about! However, it’ll likely take the form of ‘lotsa text’ so prepare yourself for that!
 

41.69


First, 41.69 (nice) build is still in progress, we’re testing a bunch of changes at the moment and are eager to get it out there, but are still weighing up the cost of disrupting the MP servers with the benefit of the goodies within, and making the call on when we’ll push to unstable and start the release process. We’ll let you know when we know more.

Here’s the changelist of 41.69 thus far!
 
https://pastebin.com/ZhRhKVZi


NPC Narratives


For the blog, we figured a good way to give people something real tasty to sink their teeth into regardless of the lack of fancy vids or pics, would be to show off the text results of our future Narrative NPC system that we discussed a few weeks back planned for Build 43.
 
As we detailed in our first NPC ‘meta’ system explanation, we have a powerful narrative event system that can be used to add context-driven ‘storylets’ together into a somewhat convincing narrative for NPCs when they are away from the streamed-in world. These would define the goals of the NPCs, as well as evolve their situation so that when the player runs into them they have a convincing backstory, or events can transpire to affect those groups when they are not around for the player to witness. They will also drive events with npcs while the player IS present, leading to interesting generated story events for the player to interact with.
 
These events set flags on characters, move their virtual presence along road networks and between houses of which all the rooms on the entire map are accessible even when the tiles themselves have not been streamed in. We can add extra data and tags that change the NPCs states and allow them to experience simplified narrative events that will branch and trigger randomly, and each of these events can have numerous outcomes of which we can attach a line of dialogue recounting the event later, so the characters will be able to sit around a campfire and let the rest know their story, or group members can recount the events of an eventful trip the player wasn’t part of, or what transpired at the safehouse while the player was away.
 
Context-sensitive text scripting is used to modify these lines of dialogue to fit the situation. For example, a tag for a character’s name in the dialogue can be substituted with ‘my mother-in-law, X’ or ‘my nephew, Y’ tracking the relationship between the two characters, or even between the character being spoken about and a third character (‘X’s brother, Y’). Other things such as a town location can be substituted where necessary, and there can be variant lines that are picked based on the characters, their flags, or other environmental conditions. Or just raw RNG, to mix things up a bit.
 
Pat_Bren has been busy coming up with a whole metric ton of varied events and mini-narratives, and Lemmy has been integrating these into the event system. There’s a lot more to add yet, but it's starting to yield some cool results.
 
Here’s a few narrative outputs. Full disclosure: some massaging of the results has taken place here, it’s somewhat curated as the system is still capable of some very odd results and the pool is not yet large enough to avoid ‘arrow to the knee’ situations, if we just threw in the first 10 results it’d probably not be so impressive at this stage, so we’ve picked ones with the least overlap — though you’ll likely notice a few repeated statements (in most cases this also demonstrates the variants or alternate paths we have there to mix it up) – our goal is, ultimately, with progressive builds, to widen the library of narrative events and lines to the point where each story feels completely unique (easier to do without voiced dialogue, but we apologise profusely to our translators). 
 
Please be aware these are still work in progress, and we still need to do some work to make these flow as naturally as possible as if recounted later to another character — rather than as a straight log of events that can seem a bit terse and unnatural, so none of the text is remotely final and we still need to figure out a good balance of information that would feel natural to share to a third party potentially weeks later…

(It’s very important to note that, at present, these narratives are limited mainly to the meta, and while we talk about how they will impact characters the player witnesses, there is still a lot of work to do in that department. This is all very super work-in-progress, and while a metric ton of work has been done across the NPC codebase, it's still a big job to piece it all together to work as one.)

I knew the electricity would be cut off.
We stocked up and ate the fresh food first, then we lived on cans.
We already had a generator and we used it for a while, until it caught fire…
The flames spread quickly.
Juan got the extinguisher, but it wasn’t enough.
The smoke got to Keith, but we were able to drag him out of there.
The whole house was on fire, and we lost everything.
I thought the Murphys might help us out, but they wouldn’t let us inside, they said it was too dangerous…
We were so desperate, we moved into a nearby house.
We pushed a bookcase in front of the back door.
Broke apart a table and used the pieces to secure the windows…
Then we just held out there as long as we could…


There were four of us. We were holding up in West Point. It was crazy!
My brother-in-law, Jason, just abandoned us, left us to fend for ourselves. We never saw him again.
We tried to find a store that was safe. We had to go out and look for anything we could get our hands on…
But those things were everywhere. We couldn’t get anything… There were too many of those things!
We had nothing, food had run out.
Then a couple of days later, someone started banging on one of the windows. We had no idea who it was!
It was Jim, a neighbor of ours, wanting to come inside.
But what if he was sick? We couldn’t risk it.
I hope he made it…

Those things broke through the barricades and poured inside.
I did the best I could, but there were just too many!
We panicked and ran…lost Lang and Dillon, I don’t know if they got away, or…
I think they got away. They’ve got to have, right?

Just before the shit hit the fan, my sister Annie got sick.
We tried to take her to the hospital… but the highway was blocked with traffic.
By that time we realised it was too late, the car was blocked in, there was no way out.
We had to abandon the car and make our way on foot.
Annie was real bad, her fever was getting worse. Bryan, her husband, had to carry her.
There was nothing I could do for her… I did what I could, but it just wasn’t enough.
We didn’t know. We had no idea what would happen!
When she turned, she bit Bryan on the back of the neck.
We left them both out there, God help us. We left them both walking around out there!

I tried to get home to my family. When I got home they’d already bugged out, they left a note saying they’d gone up to Riverside to my inlaws.
Why didn’t they wait?
I know I’ve got to get over there, before…

There was little I could do for him.. I did the best I could, but we didn’t have enough supplies.
He knew what was going to happen.
He asked me for pills and locked himself in the bathroom
We buried him out back… that is, after we…

Just before the shit hit the fan, Joe got sick.
We tried to take him to the hospital, but the streets were clogged with traffic, so we came back.
Joe said he didn’t want to become like those things…
He asked me for a rope and barricaded himself in, but he still came back…
The barricades weren’t strong enough.
He escaped and bit Sergei.
I had to put him down too.
I’ll never be able to forgive myself.
It’s like a nightmare…

Alanna, my wife, had a fever that morning, but she hadn’t been bitten.
In less than an hour she kept getting worse until she turned and tried to bite me.
I had to… oh God… Her body’s still there…
I tried to get to my brother Jack’s house.
Those things started chasing me but I stole a car and got away…
I had to keep on the move to get away from the infected.
Then I hit someone with my car. There was no time to brake…
The man wasn’t badly injured, thank God.
He introduced himself as Kevin Jones, a plumber from Rosewood.
He was alone, I think he’d lost someone.
When we finally reached Jack’s house, he and his wife Carol were okay, thank God.
They couldn’t believe we weren’t infected.
That was the worst day of my life. At least, up till then…


Let’s pick one of them and break down how it works:
Just before the shit hit the fan, my sister Annie got sick.

We tried to take her to the hospital… but the highway was blocked with traffic.

By that time we realised it was too late, the car was blocked in, there was no way out. We had to abandon the car and make our way on foot.

Annie was real bad, her fever was getting worse. Bryan, her husband, had to carry her.

There was nothing I could do for her… I did what I could, but it just wasn’t enough.

We didn’t know. We had no idea what would happen!

When she turned, she bit Bryan on the back of the neck.

We left them both out there, God help us. We left them both walking around out there!
As is probably clear, this is all too self-consistent to be completely random. This isn’t just a bunch of random disconnected events triggering one after another, but rather a mini-narrative that is comprised of several related events, each of which has various ways they can pan out and also conditions that can lead to them triggering in the first place, leading to a whole host of other outcomes that will affect the group in different ways.
 
To show this, you’ll see another branching version of this same narrative in the list of outputs above, starting with ‘Just before the shit hit the fan, Joe got sick’. Though it sharing the specific phrase ‘shit hit the fan’ text was a coincidence, it could have equally started with ‘Just before things got really bad’ or ‘Before all of this’.
 
Narratives have natural endpoints that can end that narrative, or instead, they potentially lead naturally into another if relevant. In other cases they can set flags on characters or groups that will lead to other events, or even other narratives, having a chance of triggering on them in the future. This is the way the narratives can ultimately serve as larger building blocks to make longer character stories that flow into each other convincingly.
 

So back to this demo narrative above:
 

“Just before the shit hit the fan, my sister Annie got sick.”
 

As detailed before, we generate the starting NPC groups from various families, with some other elements to mix things up. In the first event of this narrative, we pick an appropriate member of the household to ‘get sick’. This will set the first constant within this narrative that will be referenced and used throughout.
 

Then the second event in the narrative is thus…
 

“We tried to take her to the hospital… but the highway was blocked with traffic.”
 

This event will trigger the characters of the group (however it was generated) including the unfortunate Annie, to set a goal to travel to the Louisville hospital. Wherever they are in the world, a path will be generated along roads to that location. Even though the characters, nor a vehicle, are streamed into the world, and they exist virtually in the ‘meta’, we can randomly assign them an appropriate car and start them moving at approximately car speed along the roads en route to Louisville.
 

If the player were to cross paths with this virtual ‘radar blip’ of these characters, it would spawn in the car with them inside, moving in the correct direction at the appropriate speed, and the more direct vehicle controlling AI would take over with the same destination in mind.

This event can play out in various ways, hitting the military blockade, crashing the car, getting stuck amongst a group of zombies.
 

Getting stuck in traffic has various outcomes, including for example a car-jacking attempt, or the person being carried turning in the car. Some of these may lead to more generic events or narratives or may continue the main mini-narrative to a further conclusion.

Assuming all this carries on within the virtual meta world, they will make their way until they hit one of the traffic jam zones on the highway, which in this case causes it to trigger the next event in the narrative.
 

“By that time we realised it was too late, the car was blocked in, there was no way out. We had to abandon the car and make our way on foot.”
 

Alternatively, it could be they managed to drive back home or get through the jam and onto the next problem. But, in this case, the narrative branches to this outcome. We flag they have lost their car, and are now on foot. 
 

We set their goal to still be heading toward Louisville hospital, however, now they are flagged as on foot and the group’s ‘radar blip’ moves at a much slower rate along the road. If a player intersected with their journey, we’d spawn the characters all on foot, and the AI would take over from there with the same pathing goal.
 

Now they are on foot, this opens the door for other events linked to this narrative to fire that wouldn’t be possible within a vehicle. One such event that can randomly trigger is a worsening of the health condition of whomever was chosen to be the sick one, which is what happens next.
 

“Annie was real bad, her fever was getting worse. Bryan, her husband, had to carry her.”
 

True, at this time we don’t have any way to ‘make this real’ should the player happen upon this group, since we don’t have support for characters carrying others at the moment. We hope to add this, and should we do this, then when we spawn the characters in the flesh we would set them up as appropriate to the event – but regardless, at the moment these narratives in particular take place way too early for players to actually intersect with, so we can take a few liberties in these particular narratives anyway.
 

Notice Bryan is referred to as ‘her husband’, which is automatically generated using Annie as the context character, and the code examining the closest relationship between these two characters. We could instead have an alternate line of dialogue using the speaking character (Annie’s sibling) as the context and it would instead read ‘my brother-in-law, Bryan’, finding the shortest link between the speaking character and Bryan was through Annie. We plan for this to be expanded in the future to automatically modify based on all manner of things, such as character opinion, and/or character’s traits (My idiot brother-in-law, Bryan, for example) though this may not be present in the first iterations of the system.
 
So now, we have flagged that the ‘ill person’ is being carried, and is being carried by Bryan. This opens up the potential for new events to be triggered, and indeed that is what happens. Poor Bryan.
 
Again, some choices, what they do with the zombie Annie and Bryan, there could be a third victim in attempting to put them down. These branches are, relatively, painless to write, and can be expanded on far into the future. It means we can have many small narrative threads, ones that last days, or ones that last months, that thread-in appropriate events to steer the story in believable directions, with written or designed outcomes that make sense and feel like a real story, in a manageable and expandable way.
 
The ‘quests’ that we have with our story generation will likely fit in line with this above narrative system. Is a character split from their loved ones, on their way to another town to find them? Maybe you can help? We’re hoping for a more organic structure of interaction and transaction with NPCs that emerges from this narrative system and leads to some really cool and believable stories being told with our NPCs.
 


Header Image pilfered from a previous blog out of laziness, sorry! You can find all our previous blogs here.
Block of italized text has nothing more to say today, bye bye!