[Music] Super happy to be here with uh the Tech Toolbox 2017. Who made that? It's awful. Uh as you can see, things are going well for us here at the Tech Toolbox. Now, we're actually all ready to go. Um I don't have a lot of things to say, but thanks for joining. If this is your first tech toolbox, let me give you a super quick introduction. Something has been becoming more and more clear to me that uh to be a tool designer should actually be a hat that you wear if your browser crashes. Um awful. It should be a hat that you wear, you know, even if you're if you're in a in a small studio or a single developer, uh you wear many hats. you're the engineer or the marketeer or whatever, but you should also consider, you know, being a tool designer and dedicating some focus to it because uh
the tools, they often influence the final product game design, but they're also at the same time invisible because they're made for the developers and not for the gamers or for the players. And I think they're not talked about often enough, especially the ones that only live for one project, but had a huge impact and are maybe were like tailored specifically to solve problems within that project. And that's the sort of stuff I uh I hope we'll be talking about today. I'm going to give it off right away to the first speaker, which is uh Michael Cook from the University of Fallmouth. Let's give him a big hand. There we go. Uh let's find out. Yeah. Are we good? Yeah. Okay. All right. Hey everyone, my name is Michael Cook. I'm a researcher in procedural generation, creativity, and AI at Fmouth University and the Metamakers Institute. I also organize the procedural generation jam and in my spare time I make games. So,
I'm really into procedural generation and I've meet loads of people who either want to be or already are. And uh over time, lots of those experiences have led to me building this tool called Dash. Uh that's enough slides. Um so, I'm going to be demoing mostly today. Uh I I really love to walk you through this tool. Um which may end up being ill advised, but uh I'll I'll try and give you just a little flavor, but the idea behind Daesh is that it lets people look at procedural generators from a different angle and it pulls in some ideas from research and and some of my colleagues research as well. It's built in Unity, but it is completely open source. So if you don't use Unity, maybe you can pull some of these ideas out and and they'll be relevant to you. I don't want to talk too much about setup, but it's quite easy to connect a generator to uh DHS. It just requires one or two lines of code to tell Daesh where your generator is, uh, what parameters you're interested in modifying, uh, maybe how to visualize it on the screen. And when it loads in, you see something like this. So, we're actually using a dungeon/cave generator that I pulled down from a tutorial. And the reason I did that is because often lots of people tell me they uh they load procedural
generators that they found in tutorials, and it's often really hard to solve problems in them. Maybe you've been handed this generator by a programmer and you're an artist who doesn't really want to dig around in code, but this generator has problems. So maybe it generates dungeons that are okay most of the time, but occasionally there's uh there's like an island that isn't connected to the rest of the dungeon like this one here. So we want to solve this problem and we could just sit here all day and change parameters and Dash lets you do that. The parameters are loaded in on the right hand side and just like in Unity itself, you can fiddle with them and generate more content, but that doesn't really tell you anything. So the next thing you can do is load metrics into dyn. So if you have an idea that you want to capture like uh how dense the level is maybe like what percentage of the tiles are solid in your map, you can write a few lines of code. So usually these metrics are quite short and DHS can load them in and every time you generate content it'll give you some feedback. So we've got a couple of metrics here that we're going to look at. One's density. So uh on the left hand side you can see that this map here is 52% dense. So 52% of the tiles are solid and it's 0.9
connected which means that 90% of the open tiles are accessible in the largest uh chunk. So what we want to do is we want to get to 100% connectedness. So again we could sit here all day and fiddle with parameters and things like that. But Dash has much cooler tools, cooler ways of helping you look at these things. And one of those is expressive range analysis. Expressive range analysis was first proposed by Jillian Smith and Jim Whitehead. Jillian's a professor at Northeastern now. Uh Jim works at UCSC uh here in California. And expressive range analysis is a really cool way of looking at a procedural generator's output. So you take two metrics that you have, two ways of thinking about your content, and DSH will go away and sample this generator hundreds of times. And each time it samples it, it'll write down those metrics and it'll put a dot on a histogram. And the more dots appear on one particular point, the whiter that dot becomes. So on this histogram here, on the x-axis, we can see density. And each dot represents a piece of content or maybe 10 pieces of content generated by this generator. And the y- axis is connectedness. So points at the top of
this and if we hover over dash actually shows us an example. Points at the top of this histogram represent content that was completely connected when it was generated or very close to completely connected. And if we hover over points at the bottom, we can see that this one is broken up into like loads of different islands. And so what this histogram kind of shows us is the spread of expressivity and the range of possibilities. How often does your generator cause these outliers and and what shape do they take? So now with this expressive range analysis, what we could do is we could sit here and change parameters every day and then we could look at the expressive range analysis and see whether we've managed to fix this problem because kind of what we want to do here is push all of these points up so the average output is more connected. But actually we can do better than that. We can ask Dash to help us with it. Because the thing with procedural generators is and the thing that people often have trouble with is that thinking about it in terms of parameters are like inputs to a black box. So you can change a parameter but you might not really know what impact it has on the output. It would be much easier if we could talk about procedural generators in terms of the things that come out the other end. And that's what metrics let us do. So DHS also has this
feature called autotuning where we can say to DH what we really want is output that is 100% connected. So we can say a connectedness of 1.0 zero and maybe 50% dense. We don't want it to just be a completely empty room. And then we can ask DHS to start autotuning and it'll go away and do all of that work for us. It'll uh maybe I'll risk it. I think I have enough time. Uh it'll use a a number of algorithms that it has to search the parameter space and each time it searches it's looking at how the expressive range is changing. Um that progress bar isn't in real time. Uh it occasionally terminates early if it if it finds a solution and it should do in this sense. So this isn't too difficult. So what this allows you to do is ask Dash for a space of outputs rather than talking about your procedural generator in terms of its inputs. Um and it's not just that uh you just have to trust it when it comes out the other end. You can run expressive range analyses to confirm the output which we'll do when this ends if it ends. Um I don't have time to look into the other features that Dash has right now. But you can do things like
look at the complete uh parameter space by doing a randomized expressive range analysis. Or you can ask it to search through your code for parameters that you haven't considered as levers for your uh generator, but they could be. So fortunately, this did end. I have no idea what parameterization it's going to return. So let's see what kind of things it's generating. Okay. Well, they're definitely 100% connected. This may not be exactly what you're imagining. So you can go back and ask Dash. You can implement more constraints. You can turn off parameters to stop it fiddling with certain things. But we can confirm that this did what we asked to by running another expressive range analysis. And if you remember what that last one looked like with a long tail of results coming all the way down the y-axis. Hopefully, fingers crossed when this uh expressive range analysis completes, we should see that all of those points have been shoved up towards the top of the histogram. And you can see we've got a couple of outliers. Uh let's hover over this one to see this one has sort of cut off diagonally, but most of the data points are actually so connected that they're right at the ceiling of this histogram. uh to to give you another idea of uh the kind of weird outputs that it can find.
Right now it's hard to tell Dan to to give you a number of options, but uh we're still developing this. So there's new features like ways of exploring these through visual examples and automatic optimization and things like that. I'm just going to switch back to the slides. Just got one slide. So Dones is still in development and it's a research tool, which means it looks ugly. It breaks things sometimes. It uses meta programming to dive deep inside your game, which means that it might jumble things up and break things. So, there's lots of warnings everywhere to back up before you use it. But what I really need is people who use procedural generation or people who want to use procedural generation but have never done it before to download da have a play with it and let me know what they think. So, it's available online. There's papers and extra information at des.projam.com procjam.com or alternatively you can talk to me on Twitter or maybe after this session or you can find me usually hanging out near the Indie Mega booth uh for the rest of GDC. Thanks very much and I'll pass.
Thank you, Michael. Has it been used in any games that are out? Um, so I'm working on a game called Rogue Process right now and it actually came from hack together tools that I'd use for that game. Uh, and I'm hoping to pull the finished thing back into Darnesh now and sort of confirm the the ideas. Uh, so yeah, where's the name come from? I I didn't I didn't know if I'd have time, but dash is the fary word for knowledge. Um, and I'm learning a bit of Farsy, so uh, yeah. Next up, we have uh Holden Link from Turbo Button, who's going to talk to us about crossplatform VR tools. Whenever you're ready, let's give him a big hand. Cool. Does that look all right up there? Sweet. Uh, hi everybody. I'm
Holden and I'm the VR guy in the session. Uh, so I'm from Torbutton. Uh, we're a tiny studio in LA that, uh, just makes VR games. Uh, we've released two so far. Adventure Time, Magic Man's Head games, and Floor Plan. Uh, we're currently working on our third VR game called Along Together. So, uh, these games have uh, released on four different VR platforms so far. Uh, Gear VR, Oculus Rift, Vive, and Daydream. Adventure Time was actually a launch title for all of the platforms that it's been released on. So, uh, we somehow ended up doing two games across four newly launched platforms with, uh, within a year with a team of three people. And also, none of us had shipped games as programmers when we started. So, for a while, our logo was a bit of a lie. So, uh, how did we do it without going crazy? Uh, I'd argue that we didn't, but I'll show you how we made the games work, at least. So, uh, we use Unity. Unity is cool. Uh, and Unity didn't have native support for, uh, most of these platforms at launch. They have varying levels of
support now, but each platform also has its own SDK and set of plugins. Uh, and to take full advantage of each platform, you have to use their SDK. And of course, some SDKs are only compatible with certain Unity versions and so on. So, uh, before we were working in VR, we were using things like in control and rewired to handle gamepad input and some some of our game jam projects. And we wanted something kind of like that that could wrap all the different VR headsets and SDKs uh the same way that those those things wrap gamepads. So we made a thing that we call T-Butt. Uh we call it T-But because that's the obvious namespace abbreviation for Turbo Button and there's no other reason. Um it's a wrapper for VR SDKs that supports Oculus Rift, Steam VR, PlayStation VR, Gear VR, Daydream, and Cardboard out of a single Unity project. So, our games use uh T-bot functions for accessing stuff like the cameras and the controllers, and then T-But turns it into SDK calls for whatever SDK that we're targeting. Uh, a lot of the stuff that I'm going to show
today is up on GitHub now, and I'll share the link at the end. So, uh, here's a little interface we made for uh, switching between SDKs. Uh, we're using Unity's built-in scripting defines to handle swapping between them, and they all get toggled on and off one at a time so that they don't cause any conflicts with each other. Um the other big reason for doing this is that uh we're not actually allowed to ship um other some competitors SDKs on certain platforms. So this sections off the SDKs from getting compiled in builds as well. So uh we're making a game right now for Daydream uh where you play as a kid's imaginary friend and uh you follow them around uh on their adventures. A big part of the game is looking around and grabbing things in the environment, but there's actually minimal support right now for testing Daydream games in the Unity editor. It looks kind of like that. So, you have to like hold the alt key on the keyboard and use the mouse to rotate your view around. Uh, and you can't see anything in any any connected headsets. So, there uh I'm using the I use the platform switching tool and uh that makes our Daydream game retarget the Oculus SDK instead of the Daydream
SDK because if you're developing for Rift Vive in Unity, uh you can see your game directly in the headset straight out of the Unity editor. So, it uh does take a few seconds to recompile, but I didn't have to make any scene changes. And when I hit play, our camera is now running through the Oculus SDK so we can test our Daydream game and headset. Um, it's a much better workflow for us. Um, and it's one that we initially started out of necessity because we didn't have access to enough phones. Uh, but we've we've stuck with it. Uh, here's what that camera wrapper looks like in the inspector. So, most of the VR platforms have their own camera rig prefab that you just uh drag into the scene, and it's super easy to get started with them. But when you're trying to swap between different uh different headsets, swapping out those camera prefabs can be a bit of a pain, especially since they have to live in your scene for the most part. So the uh the camera rig we made uh is the only one that lives in our scenes and it just pulls in whatever camera rig it should be using for each platform and then applies the same settings uh so you only have to put your settings in one place um onto uh all of those different camera
prefabs. So that's everything from like the standard Unity camera stuff to uh stuff like tracking volumes and sorting methods. Uh for example, it's like more optimized to have the camera do sorting in a different way on Android compared to PC. So uh we can set all of that stuff up to to work for all the different platforms here. Uh we actually do the same thing with input as well. So in our game code, if we want to check a button presses on a motion controller, for example, we have a button was pressed function that accepts a button type and then a left or right controller. So for example, we can say like main trigger on the right hand and it will return whatever that button means across PlayStation Move, Vive or Oculus Touch. Uh new controllers are getting announced for VR platforms all the time. Samsung uh actually announced a new one on Sunday. Um, so this actually makes it way easier for us to support all of those uh new controllers as they come in too because we can just add them to one place in this this shared codebase between our games and then it works across all of them. So uh we made a little interface
for the editor that lets us toggle a bunch of different controller settings for our games like how many motion controllers they need or uh if they work with game pads or touchpads. We can also uh set up different hand prefabs and uh controller models for each different type of controller. Uh, and that's really important to make sure that like each controller feels right uh in in your hands in VR so they all have different different scales, different offsets and sizes. We also, uh, set up button mappings uh, for each controller. And we do this on a per game basis because uh, what we found is that we couldn't really get a one-izefits-all solution. And when it makes sense to have like two buttons be the same thing on across Vive and Touch in one project, they might need to be different in another. So we uh we serialize our button mappings out to JSON and then bring them in at uh at runtime to create a lookup table for that script that I showed on the uh last slide. So setting stuff up this way has been uh really helpful in our current projects uh even just for development purposes. So this is the Daydream controller. Uh it it essentially has like a subset of the functions of the
Oculus Touch and Vive controllers. It uh it has a a touchpad. It can track rotation but it uh doesn't track position. So, for testing on PC, there's a controller emulator that is provided as part of the SDK. Um, and it lets you turn any Android phone into a Daydream controller, but it's uh it's not exactly the same thing as the real one. Like, it doesn't have a clicky button. Uh, you have to like double tap on the touchpad to simulate that. Um, and sometimes it's kind of hard to tell where you're pressing on the phone screen. So, because we wrap all of our input, uh, we can just switch over to the Oculus SDK and use touch controllers or the SteamVR SDK and use Vive controllers. and different people on our team are using all sorts of different controllers to uh to test the game in the editor. It's also really helpful to have this uh control option for play testing so that we get like a live mirror of uh what our players are seeing. So uh the way this works is that when we're running on PC, we uh first search for that controller emulator and then we fall back to Rift Revive controls if we don't find it. Uh when running on Android, it's not compiling any references to Rift Revive stuff and
it just goes straight to using the Daydream controller. So we added like a a layer to uh to our input wrapper to throw out the position data from the the viven touch controllers for that. Um and we also have offsets that we can specify to make uh the data that we get out of those controllers match what we would get out of the daydream controller. So whenever we're developing for a mobile VR platform, our workflow is actually that we uh just have one person on the team make builds for uh for the actual target device every uh every couple weeks. Uh and then everybody else is testing in the editor on Rift Revive. So we uh very rarely actually have to make builds and and go straight onto the device. It uh takes a week or two of work each time we add a new platform to T-But, but once we add those platforms means that all of our games work across them. Uh wrapping code is not a revolutionary concept by by any means. Uh and a lot of VR developers are uh are doing this uh themselves. We wanted to go ahead and share how we're doing it uh so we can get feedback about what we should be doing better, of course, from other developers, but uh also to help other people who are getting started uh get a get a start with it. Um, so source
for the platform switching tool, the camera rig wrapper, and a standalone version of the daydream wrapper are all up on GitHub there. And there's also a wiki with documentation for setting them up. I hope you found this useful, but more than anything, I hope you write butt more often in your code. Thank you. Thank you so much. Uh, what a great resource to uh share with everybody else. And good name, too. uh more butt name tools for just abbreviation reasons. Uh next up we have uh Ryan Williams from Spryox. You may know Sprite Fox from games like Alphabar. Anyone? Yeah. Thought so. You ready to go? Let's give him a big hand. Hi, I'm Ryan Williams and uh as was just announced I work at Spry Fox. I want to tell you about a little library we made
uh called Dark Config. It is a tool for improving iteration time by hotloading text files directly into games. As you know, faster it iteration time is always better. Faster speaking time always better, too. Um and hotloading assets and behavior is one of the key ways to get a shorter iteration cycle. So there's there's lots of tools out there that do this. This is not unique. Um but there's they're just not really suited for our use case. And I think that you might find that to be true as well. So you might find dark config to be useful as well. So dark config sits in kind of a sweet spot where it's very general purpose. It's it helps you iterate quickly with its hot loading. It's easy to integrate new configuration files with the game. And you can express virtually anything in those files. So you can use it for all sorts of things. And so by doing that, it takes over some of the mental burden of developing, which is super important
because when you're working on something, you really need to be focused on your problem, your gameplay, and you don't want to be wrestling with like, oh, these files aren't loading. So that's great. Let me let me show you what I mean with the the classic live demo um of fast iteration. This this will there's no way this can possibly go wrong. Uh so we use uniting and that that throws a lot of you. This is um the current title I'm working on. It's called Steamirds Alliance and it's a it's a big game. It's an MMO. It's um it's got a tremendous amount of content. We put almost everything in Dark Config in this game. We have close to a thousand configuration files for this uh which we have manually typed. Um so ignore that error message. That's because I'm offline. The uh the configuration file I want to show you here is describing the backgrounds here behind this area. So I'm flying around and I've got this beautiful procedurally generated world behind us. And on the
left here is the configuration file that describes the parameters for that background. So, one of the things that's useful is being able to reuse and pastiche existing assets. We're an indie and so making new stuff is expensive and we're often just trying experiments and we want to try something new. So, we have this based on property here like this. This is the section that describes this dungeon that I'm currently in. And you can see it's only using a subset of all the fields that I've got available for all these other things. So, we've got this based on and that steals all the fields from a different area. So, I can change this and I'm going to try to get like a cryogenics lab type appearance here. So, I can change that and then boom. Let me make this a little bigger. Um, it just changes every single asset on the screen. And then I can refine that, right? Like I can change um I remember that the Highlands has kind of like a mechanistic background. So, Highlands. So, cool. We got some stuff
down there. Uh fog. Let's do the bring the fog up. Okay, that wasn't enough. Let's do more. That's the right amount of fog. Um, let's change the walls. Oops. Oh, I didn't know there was sound. Cool. So, yeah. So, we're kind of getting there towards a cryogenic lab. The last thing I want to do is just turn off the uh the snow. So, okay, cool. That's that's different than what we started from. And, you know, just to prove to you that it's not exactly like the Highlands. I can steal the rest of its fields. And you can see, you know, the lighting makes a big difference. So, cool. So, we wouldn't just stop there. we would probably, you know, make new assets, but we wouldn't have to remake
everything for that area. And that's because dark config allows us to do this quick reloading and see that we've made something um uh that's distinct enough. So, okay, express anything. Why is this important? Well, it's really valuable to be able to use this general purpose tool for something that's an experiment. And if you end up using that feature or functionality, then you can make a more specific purpose tool. So, let me show you some of the expressiveness of dark config um in some of these configuration files. This is the configuration file that defines how the procedural generation layout of the dungeon works. So, this defines where the enemies are spawned, where the walls are. Um, and we use, as you can see, YAML. YAML is a very human file format. Um, it doesn't have a lot of boiler plate that XML and JSON have. So, it's a lot more fluid to type. And the other nice thing about it is it supports uh sort of different layouts for how you do things. So, for a
list data structure, you can do a dash at the beginning of the line. And you can see here's an here's two list items here. Um, but that doesn't always work. That's kind of cumbersome if you're just doing a point. So, this is another list. And you can do that wherever you want and it just looks the same in the in the code. The other thing that we do that's fairly interesting and this is specific to dark config is that you can override the parsing in certain cases and do heterogeneous lists. So this is a heterogeneous list here. This is an enum. This is another enum and this is a structure and there's just like a little hook in the code that looks at that list and parses this out. And it makes it so that when I'm authoring this file I don't have to have like a separate field for show in. And I can just say, okay, this this this room spawns at uh this area and it's right there. Uh you can also see that we have ASKY maps in here. That's always nice. It's almost visual, you know, if you just just imagine. So yeah, so it's it's not going
to be the greatest at any particular thing, but it is, you know, pretty good at a lot of things. Um, and the last thing that I think is really important is that you actually make your game configurable. I don't know if you're like me, uh, where I work with a bunch of other folks, but those people really hate it when they can't change something about the game. So, I really think, um, I've really focused on making Dark Config easy to integrate into your game. And often times, it's just one line. And I I know that this is an important property because I've been that guy who hasn't made my game configurable. And these guys have been all like I don't want to learn C to have to edit this game. I want to like, you know, be a designer or an artist. So, um, this is the line that integrates that this dungeons. We were looking at before. And this does two things at once. It loads the the file the first time and anytime that file changes it hotloads that and propagates those
changes everywhere in the world uh the game world. One of the nice properties of dark config is that it updates the objects in place. So you see it blows this onto this dictionary and then I take objects out of that dictionary and I'll just pass them around. You know I pass that to the constructor of some other thing. this object just like goes all over the place and everywhere that uses it doesn't have to care that it came from a configuration file. It just knows that when the configuration file hotloads the properties in that object will change and um this is the object just so you can see it. It's just just some fields and they'll just be updated when the file gets updated. So that means that much more things are hotloaded, much more things are editable by other members of the team than if this had been a lot harder to integrate. So that's a very important value for us. And I want you to do this. I want you to iterate fast. Express lots of things in your games. And I want you to actually do it.
We are proud to announce that uh this is Spryfox's first open source project. It's up here on GitHub and you can check it out. Uh try not to inundate me with pull requests while I'm at GDC. Thank you. Um and uh I want to drop in here that it's not just a Unity thing. thing. We use Unity, but we've made dark config so it supports any C# project. So you can um I expect to see you in all sorts of weird wonderful places. Thank you very much and happy developing. Uh yeah, thank you so much. That's really interesting. I love also how like text is such a good like lowest common denominator you can like build more stuff onto. Like I think last year or two years ago we had Omar Cornet talk about um dear Imui about like writing C++ visual tools. He's right there. I see him. Uh talk about like C++ um more visual tools that that you can build on
top of anything. So you could go, you know, Unity to text file to like a custom level editor uh without having to make that level editor into Unity or compatible. That's really really cool. Uh next up we've got Shukia, also known as your boy Sugar. who's uh here to talk about procedural mess deformation and how they use that in their game design. Are you ready to go? Yeah, it's not working. Hm. Are you on a different one? Yeah. There we go. Okay. Yeah, that's me. Are you going to introduce yourself or I will I will um really happy to have sugar here and have some other South African developers as well. I got to lucky enough to go to Amaze Johannesburg a few years ago and met all these like great great people. Uh and it's a it's a huge pleasure to be able to have them here on stage with me.
All right, you ready to go? Yeah, let's do it. Let's give him a warm hand. Thanks. Thanks for that introduction. What's up, guys? I'm Shukia Kimmani, but you guys can call me Sugar. And I'll try my best to keep this short and sweet. Um, I'm the I'm the the lead programmer down at Yamok, small game development studio in Johannesburg, South Africa. And we've been working on our debut title, Semblance. And while we started working on this project, I started developing a tool that creates procedural animations on dynamic 2D meshes. It's a lot of words, okay? But basically, it's just to animate our character. and make him feel as juicy as possible. But like any of us programmers, it was a tool because I
can't art, I can't animate, but I can write some pretty good code, right? And most of us have our prototypes look like little rectangles jumping around with on top of other rectangles. And I wanted to do something a bit more interesting. And Mike Bethl has shown us that a rectangle can be pretty interesting. So I started investigating what other people were doing with rectangles and games like super sex soccer and tennis use a rectangle and change the width and height of the rectangles and they start to feel to it they start to come more alive and then around the same time Zach Bell um released ink and he started tweaking the corners of the rectangle and that's when I started thinking what if I used bezier curves what if we define our rectangle based on bezier curves. And for you who don't know what a bezier curves is, it's pretty much the pen tool in Photoshop. So you got two points, the anchor points that are the beginning and end of the Bezier curve,
and you have two other control points to change how the curve works. And I did that. So we got the rectangle based on Bezier curves. And at this point, I wasn't too sure I was still working with a rectangle anymore, cuz you could change it into any shape that I really wanted. And this was fun, but creating the mesh was the first problem. And using the bezier curves, you can go all all across the bezier curves in different steps. The more steps you use, the higher fidelity you get, the smoother curves you have. And then from there, the first thing you need to the next thing you need to do is create the triangles. And triangulating every frame becomes very costly. And so we developed a way of just putting one vertex in the middle of the rectangle and having all the tries go right to the middle. And that way we didn't have to retriangulate every frame. And the middle middle vertex was able we it's just an average
of the four corners. So it was able to move around and you were still able to change the mesh the way the way we wanted. But now it's just a mesh. Why not just slap on a sprite? I mean, then at this point, you can have more complex shapes and still be able to not have to animate every frame and then you can just deform the mesh in the way you want it. And this is how we started creating the key frames that you would animate to. But procedural animation, we just use numeric springing. And that way you can jump from different key frames into other ones and it would still look nice and springy and interesting. And that's that's when we finally ended with this tool that helped uh either of us go in and change Squish's animations by just by the key frames a little tools to swap it the mirrors, flip it, and then eventually just save it into the bank of
animations. And then inter internally in code, we could just trigger off those different animations. And what's great about the key frames and the procedure animations that you could blend in between any of those key frames and that was fun. And we still needed the the square to look. And so we added eyes and just make it a little springy and became a lot more interesting, a lot more fun to play with. But at this point, the tech was being built and it's just a collection of algorithms, right? You have your bezier curves, you have a physics simulation on the springs. And we started asking ourselves, but but what if we just add it to the platforms as well. And then that way you have this interesting mechanic where you can start changing the world and spring it as much as possible. And that's basically what the tool is. And if you need to ask me any more questions, just holler at your boy. Or if you're more into Twitter,
just throw it on Twitter as well, man. Thanks guys. That was excellent. Thanks, Sugar. Uh, I hope a lot of people will hollow at your boy and definitely check out Semblance. I'm really excited to hear more about it. Um, next up we have Chris Martins who's going to talk about a tool called Scepter. Are you ready to go? Yeah, I think so. Come up. Number one. Yeah. Let's give another big hand. Chris Martins. All right. Thank you. Uh, well, that was awesome. I'm like really excited and honored to be here among all of these people making amazing things. Um, so I made a thing called Scepter, which I'm calling a a tinker tool, kind
of if you know what a tinker toy is. Um, so it's a tool for tinkering with rule sets. And what I was kind of inspired by was the idea of rapid prototyping. Um, I guess I should say I'm an academic. Um, I'm an assistant professor at North Carolina University. Uh, so a lot of what I do is is sort of research motivated. And um I'm interested in rapid prototyping games and particularly like I really like using you know index cards and paper prototyping sorts of things especially when making uh analog prototypes and I really wanted something that could be used similarly in the digital space to um basically drive get right to the heart of rule sets without having to muck around with uh graphics and and input controls and things like that. So um this slide has a little tiny bit of scepter code on it that you can look at without understanding for now. Um but it's effectively a very tiny programming language for prototyping system designs. And I'm going to show you three examples to kind of demonstrate the breadth of what I like to do in Scepter.
Um it can be used for a number of things but I want to talk a little bit about uh using it for codifying resource economies in games doing a little bit of procedural generation and prototyping interactive fiction. So this next part is going to be the most syntax heavy that we'll get. Um but the uh so just just to give you a sense an overall sense for how this works we use something called linear logic rules. And these are just rules where you have a left-hand side that when the rule is selected um that left-hand side gets replaced by a right hand side. Um so the only syntax specific toceptor in this rule is uh the lolli and the tensor and lolli just separates the lefth hand side and the right hand side and tensor connects together the pieces that go on either side of the rule. Uh so what are those pieces? Those are uh I'm being intentionally vague about what they are because they can literally be anything that describes some kind of segment of or or slice of the world state uh that
you're trying to describe. So without further ado, let's look at our first example. Uh so resource economies. So what I mean by resource economies is the kind of thing that you often find as a central play element in games like Minecraft or really any kind of crafting game. uh where you have recipes that can be uh put together from resources that you're collecting around the world. Um and you can also typically have some kind of feedback loops in these systems where the recipes allow you to create new tools that allow you to uh uncover and obtain richer resources. So in scepter you can write a sort of system like that with rules that look kind of like this. Uh so that the pieces of world state that you represent are things that the player has in their inventory which is like this have predicate and they can have for example um a material m in some quantity which is a quantity plus two. Uh so this is a kind of pattern matching if you're used to that from another programming language. Um, so what this rule does is it basically says if you have a material M in a quantity quantity plus two, you
can replace that piece of world state with having a shield made out of that material and having M in a quantity that is two less than the quantity you started with. Um, the things in purple are variables and they can stand for arbitrary things in the world. So for example, M here, if this were like sort of a Minecraft world, could stand for any material like wood or stone. Um, you can also have a rule like a mining rule which says if you have a pickaxe made of some material and there's some ore in the world of some other material M prime and M can break M prime uh and you have a quantity of M prime equal to Q, then you can replace all of those things with having a quantity of M prime that's one more than that. Um, it should be noted that we don't actually want to get rid of these two pieces of our world state. So we have a little bit of syntactic sugar for uh keeping those things around and you know basically checking a condition without deleting them. Um so what can you do with a rule set like this? Um so the author can uh
select subsets of these rules that either run autonomously so the system will pick randomly among all available rules that can fire or you can run run them interactively. the user picks. Um, so in the Minecraft example, this could be used for example to basically run this rule set at random and see what kinds of things in the world can be, you know, put together and interacted with to create the kind of feedback loop feedback loops I mentioned. Um, or you could interact with the system to try and debug it. Uh, so the next example is procedural generation which is basically the you know this is the kind of mode where you would always want to be running the rule sets autonomously. So in a simple procedural generation example um so I have like a screenshot of Spalunky here to suggest um maybe we want to generate some kind of level uh with uh starting with like an empty 2D array of tiles and then populating them with some random tiles including walls and ladders and spikes and things like that. Um, so
because scepter randomly picks between sets of rules that can fire, you can start out by saying everything in the world is empty at coordinates x and y and then you can at random replace those things with uh the fact that there's a wall there or the fact that there are spikes there. Um, you can also introduce some more interesting constraints uh like for example, if you only want to put a ladder in a location where there's an empty space above, then you can also add that condition. Um, again checking that condition without deleting it. And you can, for example, if you only want, if you want to place the player in a random position, but you want to make sure you can only do that once, you can add a token to the rule that basically says, uh, is the player free? Like, has the player not been placed yet? And then remove that token from the world so that that rule only fires once. And finally, my third example is prototyping um, interactive fiction. Uh so by interactive fiction, I'm thinking in kind of like the parser interactive fiction sense where you're typing commands like go north, take lamp. Uh and you can describe these sorts of user
actions and interactions with the world in a similar manner. Um starting with you know character in a room if you um that should have a the indirection should have a dollar sign next to it. Uh so if the room is in a particular direction towards room two then you can move in that direction and be in room two. Um the interesting thing about this is that it's also fairly straightforward to start scripting um more interesting types of interactions like character conversation. Uh so if you're in uh a room and the a character is also in that room and you have some knowledge about a topic then you can start talking about a topic and then maybe this rule interacts with another one that takes the um you know talk about uh predicate and then the character can respond to it. So uh just the so these first two points are kind of in summary. Uh you can you can take rule sets and you can either run them as generators, run them as interactive prototypes or kind of combine the two uh to switch between automated generation and interaction. Um
another thing that you can do is run them to analyze causality between events. So, as one example, so in interactive fiction, we often have like these quest or progression structures that talk about kind of which pieces you need to advance to certain puzzles. Uh, and then what that permits at, um, as an outcome that will allow you to advance to new puzzles. And you can there's a visualization component to scepter that allows you to see the causal structure between events that happen in the world. Uh, so with that, I will throw up the GitHub link. And this is, by the way, like a crafty command line tool, so be prepared um for academic software. Uh but you are welcome to ping me on Twitter or talk to me in the wrap-up room and I'd be happy to help you out. Thanks. Thanks, Chris. We're already at the last tool tech toolbox talk. Um, that's crazy.
You good? Yeah. [Music] So, next up we have Inis Mckendendrick from Hello Games. If you guys ever heard of this game called Nmanski, it's good to practice that. Sorry. Um, yeah. Yeah. is working. Cool. I'm just gonna give it over to Inis Mckendendrick. Let's give him a big hand. Hi. So, I'm Inis Mckendendrick and I'm a programmer at Hello Games. Um, and yeah, we worked on No Man's Sky, which is a sci-fi exploration game. Today, I'm going to talk a bit about the tools that we use for texturing, for procedural texturing, and making the most of our artist textures. But a lot of the things I'm saying are really relevant across the board when we generate content.
They're they're just principles. Um but there are some useful details I hope that you'll pick up as well. So when it comes to content in No Man's Sky, we have a few aims that kind of guide our approach to to creating that. The first is that we have a really large space. So we want to create a variety of interesting content within that. But at the same time, we want to create enough content that we couldn't possibly save it all to disk or have it all in memory at runtime. So we we need to be generating it on the fly which means we need uh generation approaches that are performant and we can do at load time or runtime. Um and the final guiding thing for us is that we're a really small team and I know that might not seem true to some solo indies out there that's maybe an unfair thing to say but compared to AAA team with hundreds of artists we have five and there's no way we can output the amount of content that those people can. So every piece of art that our artists work on needs to really count. it needs to account for a load more um content in the games than you know a single te texture normally would. So in terms of how we texture the
basic overview is that our artists make parts of textures and we just recolor and recombine them in different ways to get a much larger variety of textures. Um and how that looks is something like this. So we start with a base layer there um and then we add different layers over the top and really quickly I think you can imagine the kind of variety that that can get. For example, if I take that stripe texture and swap it out for spots, then suddenly we have a different creature. If I take that sort of underbelly, that light color there, um, and swap it for some fur, then we're going to have another set of textures. And exponentially, we grow the space in which our our textures exist. Um, and this is with a diffuse texture, but we do it matching up with our normal maps and our specular maps. So, we have a complete set of textures for any of the props in our game just by the artist creating a series of these texture parts. And so in terms of how we author that, it's really important to us that our artists use pieces of software that are already out there. We don't want to make a tool that replaces Photoshop because that would be really dumb. Um, we're
not, you know, we're a really small team and our artists like Photoshop. Um, so our artists work like this. They work on a texture as a whole. So this is a head for, I don't know, some rodenty thing, I guess. Um, and they work on all the layers all together there. So they they can see the texture as a whole. they can combine the layers themselves and look at um how that appears and check they're in the correct order and things. And then you can see all the little hashtags next to the the layers there. And that's because we have a script that simply takes all those textures and it exports them to a series of separate files and names our normal maps appropriately for us to load them in the game. Uh and to supplement that we use metadata. And what you're seeing here is our metadata editor, but the data itself is actually just XML. you can edit that in text format as well. And I think that's a really good thing that we use all the time with our generated content. Both so that our artists can provide more information on what they've made, give it context, give it probabilities for showing up, but also so that we can
really easily debug and look through existing data. You know, at any time we can see what's been generated and we can check the input in a really clear and easy to store format and go back to it later. So, it's really handy. Um, so we've got our textures, we've combined them, and the other important step that we do is recoloring them. So looking at this same texture from before, we're recoloring all the layers separately there. And one of the pieces of information that our artist gave on the previous slide was what each of those layers is made of. So if they say that uh a texture part is made of fur, that will determine the types of colors that that layer is allowed to be. But when we say recoloring, that could mean a lot of different things. you know, we could be just hue shifting those textures. Um, so if we have a texture and a color input, we could combine those in a lot of different ways. So for us specifically, uh, the most important thing that you can take away from this today, and I think this has been said at Tech Toolbox before, if you're working with textures, don't work in RGB. Find a nice, friendly texture format that gives you some control over
what you're doing. We tend to work in HSV, but it doesn't have to be. There are other nice color spaces, but just find something that gives you nicer control over your colors when you're working with them. So, then we have this transform. Um, and this is our our super secret code bit. You can kind of copy it wholesale if you want, but the the important thing to think about here is what we're inputting is our texture, which is, you know, our input texture parts, a series of them, the average colors of those, and the color that we want them to become. So in terms of hue, um to give a brief overview, but there'll be more detail on the notes for this slide if you want to come back to it and actually look at how it works. Um our hue is just shifted so that the average color of our input texture becomes the hue that we want the texture overall to be. And the importance from this is that when our artists are creating those textures, they're not creating them in a flat hue. They're not creating uh they're adding detail and we need to do our best to preserve that. And that's why we hue shift in this way
and do separate transforms for saturation and value. So for our saturation, that line's simply saying that we will let our textures become less saturated to match the colors we put in, but not more saturated. So we will let them fade out to whites and grays. Um, but we won't boost the saturation just because it's really ugly. And then that final line, which is a bit of a monster, is basically a curve that came uh from fiddling with things in graph toy. And graphy is my favorite thing whenever you need to deal with curves. Um, and basically all it says is that we want to keep the the dark parts of our input texture dark and the light parts light, but in between we want to try and match the the value of the color that we've chosen for it. Um, so then in terms of fitting all those things together, so that sorry this was a bit of shader code. Um, and we do this all these next steps uh in a shader in the game as we as we load into it. So the basic steps to bring this all together are that our artists create all these bits of textures. They create
these color palettes and in game we select the ones we want. They give us probability data and that lets us choose how rare um individual parts should be. So we we choose a complete set for an individual model. Uh we load all that data in game. We load all those input textures. Uh we then combine and recolor them in in a shader. Um, and then the important part is that we then generate mit maps and compress them and unload all that previous texture data. Um, a big thing when you're working with textures is that it's really easy to end up having a mass of RGB data in your game. So, you need a plan for how you're going to get that into a workable format. Um, and then the results themselves. So, we have a bunch of creatures, plants. Um, we use this texturing technique right across the board. Um, and this shows a creature in context. But a really important thing when you're evaluating your content is that you're seeing things on mass. So we have tools that let artists really quickly see vast amounts of content generated from the their input work. Um and they can quickly call out bugs if
there's a problem. Um they can see if all those creatures show up red without stripes or if something's showing up too much or if there's a texture that they're not able to get enough from if it doesn't look different enough to their other approaches. If there's a space where they haven't made enough content. So being able to evaluate content in a wide way is really important from us. So I know there's not a whole lot of of detail on a tool that you can take away, but the important thing um I want you to go away from with today is that anything your artists make, you can get so much more from. You know, you can take that content, you can boost it, you can manipulate it in ways, and that can be a really approachable and controllable way to look at procedural generation. You know, this is great because our artists have made all the things and they know what what the output is going to be like. So, we have a fairly manageable space, but we're still doing so much more with the textures they've made than if we just used them directly. We have a way broader amount of content. Um, if you have any questions about this stuff,
then just shout me on Twitter. I don't have such a cool email address, but um, you can email me. Um, and we'll all be in a wrap-up room later, I think. So, give me a shout. Uh, thanks Inis and thanks all of the other speakers as well. Uh, look, I fixed a year. I'm great. Uh, just to just to wrap this all up, uh, thanks for listening to a bunch of super varied uh, game developers talk about their games and their tools. um take it yeah just take it seriously and think about the tools you're you're making and especially sharing them with each other because that's basically why we start why we started doing the tech toolbox. Um thanks for coming tell your friends especially tell any anybody you know uh who is who may not uh of out of their own you know uh who who may not normally submit to these type of things tell them to do it anyway especially your diverse friends. We really appreciate that and it's hard for us to to find them. um watch the previous
years in the vaults if you thought this was this was really interesting and please fill out the evaluation and definitely come up uh as soon as we clap one more time to the front of the stage and talk to anybody you have questions about their tool. Thank you so much and I hope to see you again next year.
Auto-generated captions from YouTube — names and numbers may be misheard.
Distilling the key insights…
Game Developers Conference · 2026
Extra Credits · 2026
Comments