Borut Profile picture
14 Dec, 44 tweets, 8 min read
Now that Weird West dev is slowly but surely calming down a bit I'd thought I'd start some design/tech threads...
The first is about how we can better build game worlds for storytelling - embodied games, where you're a person or thing running around a world (3D mostly but some of this applies to a 2D too). Not all games certainly, but a lot.
"Modern" game engines have not really changed how we build these games in the last 15 years. We can put more stuff in them, and that stuff looks way nicer, but in terms of how the player experience in the world is built, it's pretty much the same.
You can load/stream levels you specify, animations are hooked up in giant rickety state machines, sounds are often hooked up in a 100 separate places in each system, etc. You place actors in those levels and you can add components to them that enable certain features on them.
With Weird West, we wanted to make a world that was very dynamic and reactive the player. A choice you made in the story somewhere might have visual impact on the world elsewhere even much later on.
We wanted to make places felt alive (or dead, as the case may be) - if you shoot up everybody in a town, it becomes abandoned. Other things can move in. Kill them and maybe the people come back.
And with this One Weird (West) Trick, you can make that a lot easier to do.
This approach has a lot of history actually - something I learned from the ex Looking Glass devs I worked with on LMNO (EA's ill fated Spielberg action FPS).
In Thief (by Looking Glass Studios), a core component of the game was sound - the player needed to know what sounds they were making and how that would affect the NPCs, and there was a complex sim of how sound propagated through space.
And arrows. A lot of them. Fire arrows, water arrows, etc, plus all sorts of different materials you could hit, and different properties of the sound they might make. And so everything was tagged, the arrow, the surface, the room - "fire", "water" "wood" "stone" "arrow" etc
To implement what kind of sound you got based on all those combinations, most games would have a list of arrow hit sounds, maybe multiple lists, one for each arrow type, with a row for each surface you could hit. With a default, as well as lists for all the other weapon types.
But instead of a list, it was more of a database. And it would be used to search for the best match, with all the tags that got passed from all the elements (arrow, surface, room) involved.
There's typically a default hit sound too. But now it's much easier to add more layers to that logic - "hit wood" might apply to any weapon hitting wood.
"hit wood echo" could replace the default when the player enters a trigger volume with the tag "echo". But you could also specify "hit wood arrow echo", or "hit wood arrow burning echo"
Now all this logic might be easy enough to put in the script for the arrow hitting stuff. But says there's 5 categories of things like echo, and now your arrow script is that much more complex.
Or, your list has entry for every possible combination. Instead, you can add a sound to the database & fill in the data for that sound. The game does the searching & not your easily broken if/then logic. It's easier to organize reusing sounds without duplicating entries.
On LMNO, we were pushing this whole approach into the more of the game - animation, level design logic, AI, and of course sound. Buuuut that's a story for another time (I think the NDA's expired on that one...? 🤣)
Bit of an aside, Left 4 Dead's rule based database for dialogue is similar (GDC talk on it: gdcvault.com/play/1015528/A…) - it's filtering on rules not data tho, which is slower. If you can push the conditions the dialogue needs into data, you can run a lot more dialogue, more often.
When I saw that talk originally, I was like, whoa they were doing very similar things to what we were trying to do on LMNO. Of course there were multiple Lookin Glass and Ion Storm (Thief: Deadly Shadows) devs there at the time, perhaps not surprisngly.
So on Weird West, I wanted to push this as much as possible - we vary levels, random props or decor, loot, animation, music, and definitely dialogue - we have roughly 35k lines total, and dialogue is fired very frequently based on whatever to you do.
What drives all this is a shared data model for all objects state - tags can be applied to an object in the game, or listed in a filter to be used when searching. Tags are just name-value pairs.
A tag with just a name and no value is basically a boolean, but you can have values like SpaceType:Indoors or Money:100
When creating locations, the game filters the types of buildings by the type of location, region, & state of the game. Entering a location, the sublevels loaded and layers shown are also filtered by the tags, on the world in general, the location itself, or the specific building.
Why is that cool? Let's say the player completes a quest objective for a character. On the other side of the world, with one line of script, you make a building like that character's house look totally different. (This is also in part based on the way our world persists).
Let's look at another way we can convey story - character animation. It's often the case where character animations are generalized for all characters (or all characters of a type)...
But when you add character of that type who is a special character in the story, you want to customize their animation to give them a little more personality - Or sometimes prevent animation.
There's Pigman Joe, who our writers talked about in their recent lore stream (twitch.tv/videos/1228775…). Most pigmen are, well, they're not exactly county fair prize-winning pigs here. Joe, though, he's got his own thing going on.
The way his animation would normally have to be handled is a lot of custom logic in the global animation state machine. Or, it could just be one tag to restrict his unique id, and problem solved - he's no longer eating dirt like the rest of those mudsuckers.
What drives this is a shared representation, or object model, for the data representing these properties.
Called tags for historical reasons, like I said earlier these name-value pairs are just variables, you can store numbers, strings, other data as needed (dates, coords, etc)
For filtering purposes you can list multiple values ("class:outlaw, class:farmer" will allow an asset to be applied to those only two character classes). You can use comparators like > or < for tag values like numbers where that makes sense.
And you can further by adding fully fledged logical evaluation (like parentheses with && and ||). Internally, tag names and string values are all hashed strings, so any reasonable search is basically comparing maybe a few hundred integers, tops.
But wait you ask, don't Unity, Unreal, et al have systems that let you define properties on game objects? They do, and Unreal also has a tag system where you can apply random text tag (just a name, no value) to an actor in the world or one of its components.
You can find that actor or component, in game script, by tag. But you can't really do anything else or filter any assets for it, it doesn't hook up to most other systems.
Probably the last biggest improvement in editor workflow was maybe 15? years ago when you became able to search for assets in the editor instead of navigating through complex folder structures.
In fact you can often search for specific properties one those assets. Need to only find textures of a certain format? Easy, with a little knowledge of the engine's search syntax. This was a huge quality of life improvement for devs when it became used throughout the editor.
Then what do you do with that asset? How do you plug it into the game? Plop it in a level, state machine. Want a variation on an animation that already exists? Find the asset, find the script or place it's used, add some explicit logic to vary it or to pick in between the two.
This doesn't scale. Not only does it not scale if you're making a very big world - it really doesn't scale if you're making a very dynamic world - where lots of parts of what you see in the world can change based on the state and what you do as a player.
At the end of developing the game, this kind of logic is always creaking under its own weight, making scripts huge, hard to load - and adding customization becomes harder and harder as you have to sift through more if/then statements.
What game engines need to do, with all this talk of new versions, is allow the game to search for assets *at runtime* using the same object model.
Then the notion, esp when polishing, of adding content for an exception, to give the player feedback for something they may be missing, maybe a feature that turned out to be cooler than planned, or add an easter egg, is no longer as hard, from the duct tape holding them in place
There's a reason immersive sims use this paradigm more heavily, not just the Looking Glass lineage - b/c a focus of the genre is storytelling in embodied world. Then all those interconnected gameplay systems make it that much harder to rely on script exceptions for these things.
But as the amount of data we have in games grows, thanks to other engine technology, the more imperative it will be to incorporate this authoring style into editors, engines and help devs use it as much as they need to.
Beyond genre, really this approach empowers so much more in terms of the kind of rich, dynamic, worlds you can build - hopefully you'll appreciate that in Weird West when it launches on Jan 11th - wishlist here 🔌 😄store.steampowered.com/app/1097350/We…

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Borut

Borut Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @plushapo

28 Dec
A little post holiday down time means it's time for a sequel to this thread (because everyone likes sequels right?), on using tagging for better gameplay implementation:
In the first thread I glossed over a few of the ingredients in the "secret recipe" of making tagging work to really transform your workflow to build stuff more easily.
The first, which I kind of implied in the sound example, is how tags stack. It starts from the object which relevant to the event - like the character speaking, if it's an NPC firing a bark.
Read 36 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(