Okay. So, let's can we talk really quick before you dive in so that there's a nice segue here? I like a good segue. When it comes to your lighting, it's not baked because it's a single directional light. Is that correct? That is correct. It's a single directional light and we only have real time realtime shadows. Yep. So, if you were to take that directional light and rotate it, can I can I see it really quick? Yep. Let's find it. I want to see how important lighting is to the game. Wow. Okay. And you got very low poly meshes. That's why it's being kind of sticky because it's the low poly meshes. Um, cool. Cool. Look at this. You got one, two, three, four, five, six different planes. Yeah. Like it's exactly goodness. Exactly the kind of jankiness you would expect from a game project. Okay, so Jonas is full of He's I'm just
kidding, by the way. No, this is great. I love this is this helps game developers so much, man, because they It's nice for them to know, you know, oh, he's just throwing planes on the on the ground. Yeah. You have kind of two options, right? Either you write a fancy shader that kind of darkens the edge of the screen or or you just throw in a gradient sprite, obviously. So, why why not just use Go ahead. I'm sorry. Why? Why? Why not just try and Why not just do one big quad? Why do you have to slap those all over? Uh the Yeah, why do you have them all rotated around like that? Why not just It's It's to get the shape that we wanted, right? So, it's a You can see the map is a sort of specific shape. It's not perfectly round or something. It's like a Are those angled up? Are those quads angled up? Yeah, they're angled up. Are they kind of angled up? Like what? They are angled up. So it says 00
0. The rotation is 00 0. Let's let's only look at a single one. I'll show you what we're working with. So we have these uh gradients here, right? Yes. Yes. And as you can see, one of them is not enough to cover the entire edge of the map. I see. So what we cheekily did is we just duplicated this and put it on every side of the map so that all of the outside area of the map is blacked out. And I understand this is this is this is a actually is fantastic that you picked up on this immediately because this is exactly one of thoseam examples where it's like this is not at all performance optimized. This is a horrible way to do this. But in this specific case, it really doesn't matter because it's only like one, two, three, four, five, six, seven of them or so. So, Right. Right. If you have like seven giant sprites floating around in the scene, it's kind of not that big of a problem. Mhm. So, it's
it's worth the speed trade-off. And so, so the idea with these gradients is to give the player an idea of the boundary of the the map. Yeah. Yeah. Yeah. Actually, this does compile. So, we can just run it. Yeah, I'd love to see it. If Unity wants to. So, this is the overhame. [Music] Uhhuh. If it kind of gets a little darker at the edges here. what you want. Trying to think of a better way to do that and the only thing I could think of is a cookie with like a light a cookie on the directional light, but I don't even know if that would do it. Yeah, that would do it. But, you know, it's also during early access, we changed the shape of the map quite quite often. So, it's in a way it's also beneficial to stick with something that you can change very quickly. And one of the advantages of this solution is that you can change
it quickly. If you ever change the shape, you just drag these around a bit. And then can you change the camera to be nonorthographic for us? I can. I would love to see how bad or good it looks. [Music] Um, so I can either navigate this or I can see if we Do you forget about your project uh already? It's been a while. It's been a while. So So there we go. This is Yeah. Let's Yeah, this is perspective cam. It looks so much cheaper to me. You know, it's not as beautiful and clean. So, that's so funny. Let's see if I can Where's Where's the full screen button in See, I even forget these. Go to game. All right. You have to You can only change it. So, play focus is right there and then you go to play play max. Yeah, that's the one. Thank you. Exactly. So yeah, this looks very dumb.
Yeah, it does. And also, one of the problems you can see here is that the UI camera is still Yeah. Um, so don't accidentally change it to perspective before you upload a build to Steam. Commit uh what I what I show you here. Yeah, I guess it kind of it looks nice in a way, but it's also as you said, it looks looks more cheap. Oh, sure. I've always had trouble being okay with doing an orthographic camera because like my game Brave Boy, I could do an orthographic camera for that game, but there's something about sacrificing depth that really it's really hard for me to do to be willing to do. And but there is something beautiful about an orthographic screenshot, you know? It's just there's something really cozy about it. I don't know. Um so that's cool, man. I mean, for for
strategy games, it's obviously very easy to get away with it because it's kind of the standard perspective for for strategy games anyway. So also helps players to uh quickly see what the game's about, right? Exactly. So, what's the uh can you tell me about the uh the hierarchy of this scene? Like your naming conventions and how you're using prefabs and all that stuff. So, this is of course the level select scene. So, this is a bit different from the typical throne for level, but usually the hierarchy looks something like this. So, you can see it's relatively cleanish if you collapse everything there. There a couple of random stuff floating around here. For example, the ground is just plain, but uh other than that, we have uh all of the levels nicely sorted into um categories here so that whenever you want to edit or move a specific level to
a different place, you can just grab the whole thing and how are those, by the way, how are those pieces are they meshes or are they sprites? like this the pieces of the board. They are meshes that we just quickly made in Blender. Uhhuh. And they have edge they have an edge painted on there. A black edge or you pick up on all the details. So actually the um the edge lines that you see here uh are a custom geometry script that we wrote for Thronefall. And essentially what it does is it just has a couple of children that are empty game objects and you can just move them around and change and use them to change the geometry. So we can just draw simple lines and shapes like this. I love that you wrote something custom for that. But for the fade quads, you're just like, ah, screw it. So you know why we have something custom for that is
because we actually need that in a lot of different places. We don't just need it for drawing lines. We also use it for actually building entire levels are just built using this tools. And um I I'll while we're at it, I'll show you. Let's go to one of the levels that uses this quite heavily. Dude, that's crazy. The levels are named Durstein. Like you you you picked a name and you named it that. In my head, I'd call this Blue Mountain scene because I change the names of my levels every week, you know? I'm like, "Ah, no, I don't like that name." And I'll change it. So, I I try and make all my scenes super basic names that are descriptive, but you guys committed to a name and you stuck with it, right? Yeah. Um, sometimes I think it happened once or twice where we changed the name of the level uh after the fact and that was a bit annoying. Either we renamed it or often times we also just don't rename it and then it has the wrong name but it's kind of like whatever, right? Um, so the entire level, this entire
level is also built using the exact same tool. Everything's made of these paths here. Not sure you can see it. So, I'm just going to move this out of the block a little bit. Whoa. Path measure. This is our little script. It's It's essentially a spline. They're That's wild. They're readym made scripts on the asset store that you can uh just grab that do the same thing. So instead of begging us to give us the script, just look on the asset store. I'm not sure why we rewrote this stuff like this. Wait, you made it? Yeah. No way. Are you charging for it on the asset store? It's not on the asset store. I'm just saying other people have made tools like this that you can use if you want want something like this. Yeah. But yeah, the idea is just that you have like a a little path and you can just draw around or move move the individual points kind of even change their thickness if you
want to. And is there a is there a mesh collider on the the parent object? It does have a mesh collider so that you can walk on it. Okay, that is correct. So it's creating a mesh at real time. Yes. How is that with performance? Because it can't be static. Actually, meshes creating meshes in real time is not that big of a problem. It's like you can just um you know there there are only a couple hundred vertices that you need to connect. So yeah, doing that in real time is is it at real time in play mode if you were to change a spline would it adjust the mesh? Uh, it's I think it would. But let's give it a go. Cuz that means you can't bake lights. I think I think you if you wanted to bake, you couldn't bake. I could be wrong, but yeah, we we don't need to bake.
That's the benefit of exterior scenes. For anyone's listening, exteriors are great because there's one directional light. interiors, it's really tough because everything's lit by like a billion, you know, lamps and windows. So, you have to bake a lot. Actually, I can't change this during runtime. Okay. Cause I think because one of the performance optimizations we made. Yeah, you can you can see here in play mode whenever I click one of these rocks, I select an entire group of rocks. So, these have all been combined into a single mesh. Mhm. Whereas if I um check this out in normal edit mode, then you can see that these are all individual rocks that we can move around. So this is also one of our uh optimization scripts that kind of merges these meshes to reduce straw holes. Would you be able to, if you don't mind, can we see what the rocks look like without stylized shading instead or and make it smooth? I'd love to see what happens to the game style if
you were to smooth that out. Is that possible? We do have some levels with smooth rock. So, I think I just need to go to a different level for wind. So, this one does have smooth rocks as you can see here. No, I mean the uh the shading of it. Exactly. These have smooth shading. Or do you mean get rid of the cell shading? It Well, it you can still have cell shading that's smooth. So like um in the material there flat kit stylized surface does it have a smoothness option? So you want to blend between the areas a little bit. Yeah. Yeah. Yeah. Blending. That's really what shadow edge. Yeah. Yeah. Yeah. I wanted to see what it looks like. And then also the uh the color the dark green. Can I see what that looks like? I don't think we can change that because that's um the just
the shadow color. It looks so bad. Um I see I see why you made it look really crisp, you know? It's a great It was a great decision. I love it. And that's Paul, right? Is Paul sort of the the visual guy? I I would say Paul is the mastermind behind all of the art stuff for for the most part. Yeah. So, go ahead. I guess the main trick we we got away with for Thronefall is we made or or what you what we're trying to get away with as a as an indie developer always is you're trying to get away with making very crappy assets look very good. That that's your objective cuz then you can then you can fill your game with crappy assets and it still looks good. That that's the dream. That's right. And that's definitely something I think we achieved with Thron because we look at all of the 3D models and like they're like very amateurish, you know, very very basic modeling skills required to make something like this. Well, and
and lighting is a huge part of that. Like if you were to hit play for me, I would love to see this. If we were to move the directional light in a in a imprecise or a a bad position, I'd love to see how bad the game looks, if you don't mind, with just a bad directional light. Um, no, my controller is not plugged in. Okay. Um, yeah. So, I guess we'll purchase some stuff and then uh change the direction. Yeah, let's see how bad it looks with with a different directional light. like move it in a bad position where it's like all shadows, you know, maybe do something horrible. Yeah. All of a sudden, the game doesn't work, you know? It just doesn't look good. Oh my Why, Thomas, why are you making me do this? Yeah, don't push this to get um that would be bad. It's It's cool though. It it it definitely has a a
moody look, but it's it's it's unworkable, you know. Um, it kind of looks okay at night, surprisingly. Yeah, because you got that point light. Um, that's so funny. Yeah, lighting. The problem with using bad assets is that typically with bad assets, what makes them look good is a very precise set of shaders and lights. And if you in color theory, good color theory. So when you go in there and you you you me tweak it slightly. Let's say somebody's like, "Well, I'll just go in and tweak the color." Suddenly it all doesn't work, you know, like if those yellow rocks were a or if the grass wasn't that nice teal grass, it wouldn't work, you know, it wouldn't look stylish. Um, so color theory is super duper important, right? Yep. We have a a color manager here where we can tweak all of the colors in the scene.
Bro, I love that. Can you show us some changes? Sure. Can, for example, grab the ground color here and just make it a different color or something. It looks great though, even with different Yeah, like Oh, no. Make it red or something. But yeah, you can get get away with surprising very surprising things sometimes. Wow, that's amazing. Really kind of cool. That's a really smart tool to make. Um, you can unify a level's theme really quick, right? And then the cool thing is we can also very easily swap these out. So I can, for example, also make this one uh look like a different level. So you're swiping out the color scheme and the color scheme is a scriptable object. Exactly. I can make this look like winter and so on and so forth. So, does did you create some of these color schemes or is this all Paul?
Uh, it's a mixed effort. Like Paul did all of the fine tuning on these. Um, but I created the the rough drafts for a lot of them cuz I did the the initial level design and then Paul did a polishing pass on them. So, usually it was like me doing like a dirty draft of how I would imagine the colors to look like and then Paul usually did some fine tuning and sometimes the fine tuning was entirely different from what I envisioned but was usually better than than my version. Yep. Now, how often are you instantiating things Jonas or using object pooling? So, there there is no object pooling. None. Zero. And um not saying do that. Shame on you. At least that's what my live stream audience would tell me. I think um we're barely getting away with it with the amount of objects we have cuz we do have I don't know, we have like a limit of 200 300 enemies spawning per
night. And with like 200 300 enemies spawning per night, you can kind of get away with them not being pulled. And then one of the things that we should really should have been pulled is uh visual effects. So arrows that are being shot through the air, destruction effects and so on. We should have done pooling for that. We don't. Mhm. And uh yeah, we barely get away with it. Hey, are the are the I'm just going from one thing to another here. Uh are the shadows opaque because of the shader or are they opaque because you've set them to be opaque with the directional light? What are opaque shadows? What do you mean exactly? All of your shadows are completely blue. They are not There's no fade or opacity shift. Yeah. Is it possible to make them less dark? Um, yes, it is possible, but I'm not sure if it's a it's a one click kind of
thing. I can check it out. I can try on the ground material. Let's see. The reason I ask is I'm curious why you decided to do that um or like what it would look like. I guess what I'm saying is I think it unifies the theme. It it unifies the style and it's a brave decision because you've got to you got to make sure there's not too many shadows. Um because then it can ruin the gameplay, right? So, okay, I can't figure it out, but Oh man. Yeah, you're working on another game right now. There there are too many sliders. That's great. Uh and then another question I had was um are there any really cool tricks that are just like that you you want to tell us about that just like are almost magic tricks visually that you're using? I think you I think you should have been asking probably Paul and also
Freedom about this because Freedman worked on this. No, no, he doesn't. But he's also a very very good uh artist actually. I see. I see. Hey, are you using post-processing? We are using some very minimal post-processing, but if you turn it off, you're almost not going to see any difference whatsoever. Like it's I think it's very No, no tone mapping. I think it's very tiny amount of chromatic aberration. And that's pretty much it. Really? Why did you do that? I I I think I could see it actually. It's very subtle. Yeah. What was the goal there? to make it look retro. I guess I guess that's a question for Paul. I honestly I I like it with or without. It looks almost identical. Doesn't really I don't need this, but if you think it looks good, let's keep it whatever. Um what uh how how what's the point of a local manage manager versus a global manager? And for for the record, I do know the answer, but I want my audience to kind of get an idea.
So these two here, right? The it's not it's not just a manager, it's managers. It's like these are all of the single team. What? It looked so pretty when it was collapsed or closed. Now y um these are all individual manager objects with different tasks in the game. These are all singletons. And I know like your stream audience would murder you for something like this because you know typically every if you like if you want to do ideal code architecture then you want everything to be as modular as possible. You don't want interdependencies where one script depends too much on on another one. You you kind of want everything every script to be like a Lego piece that you can just plug together. that that's not how Thronfall that's not how thronfall's architecture works. We have lots and
lots of uh centralized managers that all have interconnected dependencies and all depend on each other to do various things. Yeah. Um and I think it would have been difficult to get away with this with with a bigger project but for thronefall it was just fine actually. So let me ask you this. Singletons in my mind are for global stuff. Yes. So why did you do it with local stuff? Local, I would assume local means it's local to the scene. It is local to the scene, but you can So why do you need it to be a singleton? You can you can still do a local singleton. There maybe uh very very small Mhm. misunderstanding on your end. Singleton just means that there's just one object of this type. So typically do something like static instance blah blah blah singleton whatever. Yeah. And then the the advantage of that is just that you can reference that script from wherever you want and you you don't have to do the find component of type thing which is
correct. Correct. Which is slow. Yeah. The the reason I say that is I I just always um I only ever use singletons for global stuff. Um but I guess I guess you're right. I guess it makes sense to use singletons for for local stuff. So that's cool. Yeah. So I guess the the rule of thumb is if there's only if you already know there's only ever going to be one of a particular thing then just make it a singleton by default then whenever you can access it whenever you want without doing get component. Exactly. Ah yes. Okay. Sweet dude. Uh are there really quick are there naming conventions here that don't follow like some things have spaces some don't? Yeah. No there are no naming conventions. It's a if you're two person team, I think you sort of naturally converge on some things. So, it's not a complete mess just because over the time we kind of develop similar preference and that kind of thing, but we're not
like, "Oh my god, this this uh this object in the scene has doesn't have a space here and it should be camel case or whatever." It's like, yeah, whatever. This match fusion. Okay, I guess it needs some spaces here, but this is not something we we waste our time on. Like we have more important things to do. I always have I always have this like fantasy of starting a new project and that the the naming conventions are perfect, you know, everything's clean uppercase like uh or what do you call it? What do you call it when only one is uppercase in the in the word? um the first letter type case or something. I don't know what it's called. No, whatever. But I have a fairy tale fantasy about this where and I and everything's spaced out clean. All of my classes are uppercased. You know, all of my variables have the exact same naming conventions. Um but then you get a team involved once you once you get the project rolling. You get a team involved and then invariably every once in a
while someone pushes without you knowing they push a variable that uses an underscore. when I don't use underscores. I I never ever use underscores and then somebody puts an underscore in my variable or in the project's variables and then slowly it just starts to degrade the naming conventions, you know, and the syntax. So, it's just what happens and naming conventions are easy to maintain if you work alone. Oh, yeah. Relatively easy. If if you work on a team, good luck. Let me ask you about variables. Can we take a look at some of your variables? Um, are you do you are you descriptive with your variables or are you as indescriptive as possible and you want your variable names to be very clean and short? Uh, I have a very definitive answer on this. I'll I'll I want to I want them to be as descriptive as possible. So I'm on the I I I literally make variable names that
are half half the line in they're like comments, right? Yeah, exactly. Yeah, I do that sometimes. I'm like I really don't want to forget what this variable is for later. So just try to come up with a good name. But then also on the other side, um often times shorter variables uh are are enough to describe what you what you want to say. Mhm. Like health for example. Exactly. Cool, man. Let's Let's have a look at some scripts. Let's maybe an enemy script or something. Let's pick something. Uh have a look at the at the mole man or whatever. Let's let's see. So, this is this is not a class. This is a this is a scriptable object. Scriptable object. You do you want to explain to the audience the difference? So scriptable objects are just
essentially meant to hold pure data. Another thing you can do if you want to write very clean projects is that you can is that you try to separate your data and your game logic as much as possible so that if you want to extend the game later on all you need to do is add data and you don't need to write any additional code. Correct? So, for example, if you add an additional weapon or something, then you can just put in another entry into your weapons database and everything already works perfectly. And essentially, scriptable objects are that they are data entries. You can you can um the way that we do it, for example, with weapons in our game, all of the weapons in our first person controller are, and I'm not telling you this, I'm telling the audience because you already know this, but we've got like a pistol, we've got a magnum, we've got a automatic, we've got a chain gun, we've got a rocket launcher. all of that data associated
with each weapon, like the shoot speed, the shoot power, the reload speed, all that stuff, the sprite for the for the crosshair, all of that stuff is in one scriptable object called the weapon manager. And if we need to adjust the balancing of the game, we can adjust the balancing in that single scriptable object. We don't have to go into each prefab for each weapon and adjust it. Do you feel like that's a valid case for the a scriptable object? Yeah, of course. Okay, totally cool. So, as you can see here also with our enemies, they look very silly sometimes up close. Like this one. I I have actually haven't even seen this one up close. Wow. I don't even know what I'm looking at. Yep. Yep. Yep. But then when you zoom out, it kind of starts looking like something. Yeah. Very nice. That's awesome. Okay, but let's um for example have a look at a script here for
examp the the kind of variables I would write cooldown duration cool down after after spawn uh cooldown randomization. Mhm. So, mostly very self-explanatory variable names. Um, yeah. And then I guess it looks relatively normal. It doesn't look super clean. Doesn't It's not overly commented like most It's also not overly complicated. It's not like you're doing I'm sure I'm sure you're very clever, but I'm not seeing anything that's super clever here. That's right. Yeah. Trying I like that. I mean I I like my scripts to be very very very like layman simple and and normal. Nothing crazy. You know the the trick of writing clean code I think in theory is uh not writing simple code. It's just hiding away the complexities. For example, what what for
example a beginner maybe would have done here is they would have inlined the entire on attack function here like okay whenever we attack we just write all of everything that's that happens right here in the update function. But obviously the the cleaner way is to just have it in mind. Well, and for for people who are just starting to code who are listening, anytime anytime you write the same code twice, obviously slam that into a single function. Um, and you and then you can use that function multiple times. Um, yeah, obviously. Right. Even for stuff like this one here, this would be one example where where I could have done a little bit better, I guess, cuz we have find auto attack target. And then we also have find auto attack target with um with I guess various settings. I wonder if I could have just done something like this where in in this simpler function I call the other function with some
default with some defaults like uh Mhm. Mhm. Like something like this. Yep. And this also would have made it a bit cleaner, I guess. Well, you know, that's the nature of gamedev is you look at your old projects and it's like looking at an old photo of yourself from high school. Yum. Yum. Yum. It is. That's That's also I'm not not sure if it's cringe. It's also sometimes like this script is already so simple and so short. Why bother optimizing further? It's like I agree. I've gotten to the point with my project, dude, where I'm at the end of it and I don't care what kind of band-aids I'm slapping on the code. I don't care. I'm just like, get it done. Um the the the clean code that's out the door for me for for for my latest project. So,
you know, it it as always, it depends on what you're trying to build. the the bigger the project that you want to build, the more attention you need to pay to clean code because um spaghetti code just doesn't scale as well into bigger projects. Well, that and that's kind of my point though is that I'm we're not scaling the project anymore. Yeah, it's it's reached its max capacity. So, I'm just like spaghetti code all day to get it done. That's exactly and I'm not going to reuse the system. Y uh hell no. Yeah, I'm I don't know if you've ever reused one of your code bases before um for another project, but I I can't bring myself to do it cuz I'm like I don't want to live in this code anymore. I need this code. Yeah. You know, I think what's the main problem with reusing code snippets is exactly what you're saying. You're like the next time you need something like this, you're like, I'm start I'm building it from scr scratch and I'm going to do it two times better than than I did last time. That's right. That's right. So you you never really
get to the point where where it makes sense to reuse something. You can just do a better job building it from scratch. And by the way, if you're anything like me and you've always dreamt of getting paid to make your indie games, I have a super cool gift for you. It's a webinar below, totally free, and it's about how to turn a simple 15-minute demo into an actual paycheck. I've secured six figures multiple times with just a demo, ensuring I was able to go full-time indie, pay the bills before even finishing my game. Believe it or not, over 15,000 devs have checked out this free webinar. Now maybe it's your turn. Click the link below to enroll for free, and you can save it for later, use it as a resource, and watch it whenever you want. I'll see you there.
Auto-generated captions from YouTube — names and numbers may be misheard.
Distilling the key insights…
Thomas Brush · 2026
Thomas Brush · 2026
Comments