How Thinking in Systems Can Improve Your Code

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] if you haven't already you should check out the player class of the popular indie game celeste at 5 400 lines it is a monolithic behemoth that handles anything and everything to do with the player including animations state input handling movement and even audio in software development there's actually a term for code that's written like this code that touches a lot of systems and has to keep track of multiple elements of state is often referred to as spaghetti code in a nutshell spaghetti code is code that lacks the structure that's required to be maintained and scaled effectively now i'm not trying to dunk on celeste here it's an incredibly impressive game but some devs may point to its massive player class and say why should i spend time structuring my code so s-code isn't structured it was a huge success well celeste was created by two people who accomplished something truly remarkable but i'm willing to bet that their relatively unstructured approach worked for them at least in part because they didn't have to worry about stepping on each other's toes or doing a whole lot of knowledge transfer during development but if you've ever worked on a team you'll know that the more unstructured a project is the harder it is to collaborate and the harder it is to onboard new developers i mean imagine trying to get a team member up to speed on a class that's over 5000 lines long and that's just one class at the end of the day whether you're solo working with a partner or developing on a team of any size i believe that more game projects fall apart as a result of spaghetti code and go on to become smash hits let alone make it to market still there are many out there that would argue that you shouldn't overthink or try to over engineer your code that the most important thing is that it just works well to them i say you can have it both ways because there are a few techniques that you can use to give your code the structure it needs to thrive one of those techniques is to use a systems approach when developing new features and mechanics and that's exactly what we're going to cover in this video but first if you're interested in content like this you should sign up for our monthly level 2 game dev newsletter level 2 is all about helping you develop the skills you need to take your game dev hobby or career to the next level once a month we'll send you an email with curated content that's designed to help push you on your game dev journey and help you keep your finger on the pulse of what's going on in the industry if that sounds good to you and to have a chance to sign up for the beta of our upcoming course visit the link in the description to sign up now to help us illustrate the system's approach i've created a player class that's responsible for way more than it should be taking a moment to scan through it we can see that it has logic for handling movement managing the player's inventory and allowing the player to pick up items in the world in terms of picking up items the logic is relatively simple on start the player class runs a co-routine that constantly searches the scene for the item that's nearest to the player then when the player presses the interact button on their input device the nearest item is added to the player's inventory and destroyed the code works fine but if you aren't already sweating looking at this class just imagine how you'd feel if a new requirement came in for example let's say we needed to track the player's health the player class is a reasonable size at the moment but i'm working on a big rpg so if i continue down this path it'll easily surpass celeste 5 000 plus line count now to address this we could do a little bit of refactoring but i think it'd be more valuable to backtrack a bit and explore how using a systems approach could help us avoid this problem in the first place because our current approach of just tacking features on as they come up definitely isn't going to scale let's roll back the clock to before we implemented item pickup our initial approach was to again tack it on to the player class which makes sense because the player's the one who'll be picking up items at least as far as we're concerned for the time being but if we take a systems approach we can think about the problem in another way instead of thinking that we need to write code to allow the player to pick up items we can say we need to develop a system that'll allow items to be picked up now the word system can take on a lot of different meanings depending on the context especially in software development in our case when i say system i'm referring to one or more classes that when organized and working together facilitate a mechanic or some piece of functionality another important distinction is that each system should be able to operate independently of other systems and systems should be able to interact with one another only at key points which we will explicitly define it's a subtle shift in thinking but taking a systems approach can help you write code in a more structured way that'll ultimately help you avoid writing spaghetti code let's jump into the editor and see the system's approach in action so if we're going to treat adam pickup as its own system we'll need to implement a component to represent the actor that will be picking up the items right now that actor is our player but we're developing a new system so let's create a mono behavior called interactor i'm using a generic name here on purpose because picking up items is just one way to interact with the environment and since i know the scope of my game already i know that there will eventually be other ways for the player to interact with the environment as well of course there are many ways to approach this so i could have just as easily named this class item picker or something more specific like that that being said taking a more generic approach will allow us to support more functionality down the line as we'll see in a moment okay the next step will be to create a component to represent the things that our interactor can interact with let's create a monobehaviour called interactable instead of interacting directly with items we're going to completely isolate our interaction system from the rest of the code by having our interactor class collaborate with this new type of object called interactable and we'll make it abstract because we want to be able to implement what happens on interaction based on the context of the feature that we're trying to implement now we can extract the logic that we had originally shoehorned into the player class except we'll modify it so it can support our more generic implementation it's the same logic as before which search the scene for the item that's nearest to the player but instead i'm refactoring it so that it now looks for the interactable that's nearest to the interactor finally we can implement an interactable that represents an item that the player can pick up this is the explicit point that we've defined where our isolated interaction system can talk to the rest of the code we've created an invisible boundary between the interaction system and everything else and we're using our implementation of interactable to cross that boundary which leaves our player class much cleaner than it was before and more focused on what it's responsible for now which is just managing movement and the player inventory although i think i'd like to move this inventory logic out of the player as well and maybe that could be another system all right let's wire everything up in unity and see it in action as you can see our new code isn't all that different from the original we essentially just plucked the original logic out of the player class and stuck it into its own set of classes the biggest difference was in our mindset and our approach when new features arise it's much easier to just graph them into your existing logic but that can lead to tightly coupled monolithic classes that are difficult to work with and really hard to scale effectively on the other hand when you think of your code in terms of individual systems that work together across well-defined boundaries you can get ahead of spaghetti code and even avoid it altogether when you work this way you'll find that your code ends up being much easier to maintain test and even scale in the long run of course as with everything there are a few caveats to keep in mind when taking a systems approach for one it's possible to overdo it to the point where your code base becomes a bunch of tiny micro systems that are really hard to get working together this typically happens when you over generalize and over genericize your logic early on something to keep in mind is that your game is unique and will require unique code in other words don't try to create each system as if you're going to put it on the asset store you're not developing general purpose solutions that can work and support any type of game instead you need to create solutions that can work and support your game there's no correct size when it comes to a system and your game will require its own level of system granularity the best way to determine what that granularity is is to practice the more you approach your code in this way the better you'll become at discerning how to create and organize your systems finally at the end of the day the idea of just getting your code to work and not overthinking it is a valid one the more you develop though the better you'll become at judging when it's time to think about and structure your code and when it's more important to just get it working and move on let me know what you think about using a systems approach by leaving a comment below do you do this already or is this a completely new concept for you if you enjoyed this video and want more content like this use the link in the description to sign up for our monthly level 2 game dev newsletter and of course be sure to like this video and subscribe to this channel thanks for watching and as always i'll catch you in the next video thank you to all of my patrons and a special shout out to nicholas monter datwell jennifer irwin yarizer alan kuravila uma sarin dustin petrio bungo and usaf ali castle thank you so much for your support
Info
Channel: Infallible Code
Views: 12,705
Rating: undefined out of 5
Keywords:
Id: uITOjsZFzyc
Channel Id: undefined
Length: 10min 16sec (616 seconds)
Published: Fri Nov 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.