Adding levels to my custom game engine (C#/MonoGame)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
previously hi everyone welcome back to another Dev vog about making a c game engine I'm Alex and today we're going to talk about Minecraft chunks my possibly irrational hatred of entity component systems and hacking the level editor that built Celeste let's get started last time I went over how I built out an art Pipeline with aprite and the process of actually getting an image on screen in mono game and while technically we could make the entire game in one long long horrible block of conditionals in our main Loop of code here it'd be nice to compartmentalize things a bit we need a good way to represent all the characters in our game so taking heavy inspiration from gay maker let's tackle actors our actor class is a massive catchall for anything that needs to be created updated and drawn regularly with these three events being represented as their own separate methods the create method fires once and only once when they spawn in for the object oriented minded out there this is effectively their Constructor it's where you chck all the initialization logic that can't be made a compile time constant next is their update event which is called once every frame it handles the bulk of the actor's logic things like movement Collision detection anything which needs to be updated frequently finally there's the draw event which is called every time a frame is rendered to the screen this is where all of our code to actually display the actor goes on the back end will also give each actor a name position and set of colliders not every actor Will necessarily use all of these but in general it saves us from constantly redefining variables and systems that are going to be common across different types of actors colliders are used for Collision test testing it can be square circular or basically whatever the hell you want every collider inherits from a base collider super class where it individually implements how it tests against other colliders allowing rectangles to Bonk circles lines to find polygons Etc of course none of these actually exist right now Beyond The Glorious rectangle there might be a day when we need these other collider types but for now it' just be useless bloat this is a pretty objectoriented approach to actors with each type of actor having its own individual class and that's intentional I know there's a lot of very smart people out there proudly proclaiming the Excellence of other patterns like datadriven design that's where instead of thinking of actors as distinct to spoke entities like am Mario or a Goomba you instead describe them with a series of smaller individual components like a platformer character who can jump shoot fireballs and collect coins and an enemy platform a character who can die I find that unless you're making some crazy game with hundreds of permutations and connections a lot of the time spent making everything data driven is kind of over engineering and future proofing for issues you'll never actually hit I have similar feelings about entity component systems too but that's just an opinion an unfounded opinion thanks for watching rant about the hypothetical data driven bogeyman out of the way we've got actors awesome but uh-oh they're just sitting in a black void of nothingness let's give them some levels to walk around in with tiles usually grouped into larger images called tile sets tiles are tiny images usually grid based which are placed around your level to make a variety of different environments these were super popular and pretty much necessary in the ' 80s and '90s because cartridges had no space consoles had no vram and Mario can't do very much in a level that's only one screen wide though there's somewhat a result of Hardware limitations tiles are still commonly used in new releases a big advantage of a tile-based approach is that when an artist makes a tile set it lets everyone from programmers to level designers work directly on the look and layout of a level without having to constantly bounce back and forth to your artist because a ledge needs to be moved 4 m to the left it also means that if you want to change up the aesthetic of a level edits to one image will populate across the entire thing tiles keep file sizes down and iteration times off there's just one problem it's a lot of draw calls to send to the GPU say our game's resolution is 256x 224 pixels wide and our tiles are 8X 8 pixels wide in total that's almost 800 extra draw calls every frame just to draw the terrain if we want multiple tile layers yes that number increases very quickly and this is just one screen imagine what this would be like if you had to render an entire level in my moment of pity for the GPU I had an epiphany why not just tile tiles since new textures can be created on the Fly within reason we could just create a texture draw the tiles once onto that and then draw that texture over and over again like a giant tile say this texture is about half the size of one screen and we suddenly cut our 500 draw calls per frame down to 500 once and then like four by splitting up our tiles into larger chunks like this like Minecraft chunks sure we get to take advantage of what would have been a benefit of keeping levels on one large texture Quick Draw calls while also having the upsides of tiled rendering which would be speed flexibility and short iteration times hi everyone future Alex here turns out I was a [ __ ] idiot all of this was wrong or at at least the way I implemented it was wrong my implementation of this ended up being the root cause of a bug that has been tormenting me for two years where the game would randomly slow down to 20 FPS I could not reproduce it turns out it was this stupid tile rendering system that I came up with that I thought was so smart and generally what I said was still correct I I just you know maybe don't create that many textures this is looking more and more like an actual game but there's a problem it does doesn't make sense to represent every image we want in a level as a tile set because some of them won't be cleanly divisible by 8 16 or whatever we need some resource that basically represents a PNG so I made a deco class for the backgrounds of levels and oneoff larger static level objects which won't be frequently repeating but pictures which just sit there are really boring we need Parallax the thing that your eyes see when objects at different distances move at different speeds but to do Parallax we need a camera system and confession time I was kind of a dip [ __ ] when I did my first pass at this mono games built-in Sprite batch the thingy which actually start/ ends a draw call has an option to offset SL transform everything it draws with a matrix fancy math word which means a bunch of numbers problem is I hated matrices my first stab at this camera system was taken right at the end of a semester's worth of linear algebra if you've taken linear algebra you might know where I'm coming from the absolute last thing I wanted to think about over my summer was more stupid intersections multiplication translation conversion so I did what any other lazy bastard would do in lie of an actual camera system I simply took the camera's X and Y positions then subtracted that from whatever offset was passed into my raer for model games drawing functions this eventually also started to [ __ ] the bed surprise surprise so I later made a stop Gap with a sort of view Matrix [ __ ] this still sucks okay quick confession the series has been slightly out of order I'm not a patient enough person to cleanly LEAP between topics like this and I'm saying this now today because we're going to break the rules a little bit and I'm going to go through and write a new camera system mid script writing here we go okay so somewhere in this giant camera class is the skeleton of a decent camera system but it's been hacked a bit so let's do a bit of refactoring I'm sure there's hundreds of different ways you can think about what a camera should and shouldn't be responsible for but n of my games are wildly complex we can add fancier camera functionality if and when we cross that bridge from The Game's perspective we want to be able to position rotate and zoom the camera in and out on a point for me this meant breaking a really old habit of having the camera's position be counted by its top left corner it's much nicer to move a camera Matrix around a center than its Edge adding a bit bit of smoothing with linear interpolation that is basically a game development cheat code and huh it's done yeah I I thought the I thought the camera was going to be a much bigger pain in the ass oh God oh God oh dear God okay camera sorted BIM Bam BOS where were we right deal so a static image is pretty boring and with our nice new camera system we can get some parallx in there this can even be applied to foreg Grand Elements which really gives the world a strong sense of depth and perspective in summary we've got actors who get updated regularly responding to input moving around the world tiles and tile sets which we use for making up the basic building blocks of our levels terrain and decal which represent mostly static Sprites which usually act as one-off level elements or backgrounds now how do we actually store all of this we could write it out all by hand but that would be stupid [ __ ] and terrible stealing a bit of film terminology we're going to create a scene class for our purposes we can think of scenes as something like levels or Maps or rooms in a Mario game you might have one scene to represent the title screen individual scenes for individual levels and separate scenes for the credit scroll and game over diving down a little deeper for our purposes a scene will need to store information about which actors tiles and deal are used and where they're all placed this is already much better than the mega loop from hell but reading this all out by hand is a massive waste of time we need a level editor and this is something complex enough where I really shouldn't be Reinventing the wheel [Music] so tiled is super popular and for good reason Shovel Knight axium Verge and carryon all use it as their level editors and I actually used it for a while on a project you'll hear about in the next video but I ended up moving on from it for a couple reasons firstly its handling of tile sets and how it embeds them in data wasn't my favorite parsing that data out of a do TMX and its Associated tile set file while not impossible was kind of annoying secondly I wasn't a fan of its workflow for defining actors everything was a gray box / polygon which made distinguishing actors very difficult while writing this I found out that it's actually had the ability since 2018 to tie actors to Art somehow my brain completely missed this oops I also wasn't a fan of manually adding the properties for every actor whenever a new one was defined in code so after our first release which did use tiled I started looking elsewhere it's a fantastic level editor but just not the right tool for me [Music] specifically not quite as prevalent as tile but what seems to be a growingly popular choice LDK is mildly insane in the amount of flexibility it gives you with how you want your level set up along with providing a lot of nice quality of life features like Auto tiling as well as lots of bells and whistles for how actors are defined and biton Ace loading support but remember how we spent all this time talking about Parallax earlier well LDK at the time of looking at it had no support for something analogous to our decals SL any Parallax image support or multiple background image layers easy I thought stupidly it's open S myself myself I downloaded the source and proceeded to nearly bald and frustration trying to get the damn thing to build I love web Technologies even after that point I promptly stared at the source and nope the [ __ ] out the code wasn't poorly written but inserting something as Central as a new resource type that would change how levels are rendered into the editor was Way Beyond my reach at the time if you're not a celest modder I wouldn't be surprised if you've never heard of this one it started out as extremely okay games internal tool for making celest levels it was eventually open sourced and then later ped to hacks SL web Technologies to become the Community Edition it doesn't have a lot of the fancy features of LDK or tile but when I'm wanting to parse the data it spits out or add new features that's actually a bonus I had a quick play around with it and following my G cloned the source and decided that this would be my level editor of choice so I'd settled on a level editor but one that was pretty Bare Bones so time to start making some tweaks and get this thing doing exactly what I need it to okay time to get building I foolishly thought forgetting how much of an absolute pain in the ass hacks and node projects are to set up after a lot of struggling I managed to make the magical web technology Stars aign install precisely the right versions of hacks and node to get compilation going and finally start making changes it's super pedantic but I thought the editor could maybe use a tiny bit of a redesign so let's overhaul this editor what says aesthetic what says cool what says has a local concert in your area H this entire video all the sides they're all pointing to one thing I've got to go to the Weezer why is my voice still echoing [Music] [Music] [Music] that was pretty [ __ ] great I can't hear and I think my voice is shot no recording videos for a couple days I think I learned a lot at that concert uh like the font Choice much weaser next I wanted to get those Parallax elements in having never touched haacks before I fumbled around a lot in the source bumping into things fortunately agmo already had a deal class so with a lot of trial and error I was able to get some parallaxing level elements woohoo unfortunately I did this in a mildly super terrible way involving just redrawing the same image 100 times in each Direction deal can be placed in a scene and we can get a rough idea of what they'll look like in game with the parallax started I started ripping out stuff I didn't want and tweaking the stuff I was keeping goodbye all these settings we don't need them hello to hotkeys to cycle through entities with that and some other small tweaks out of the way it was time to tackle the big Feature Feature Feature the big Feature Feature was having the list of actors in the game and the list of actors presentent agmo sinking up an unsung benefit of engines like gamemaker unity and unreal is that things couple together nicely if you create a new actor you can easily place it in a room since it's all living under the same program roof thingy unfortunately or unfortunately depending who you ask we're not game maker and we're using an external tool for level design this means that the level editor has no idea who or what your actors are and now you have to waste a fortnite defining all of them each time a new actor is added on the code side okay remember how I mentioned not liking tiled system for defining entities this is why agal already has predefined stuff inside of it for defining entities and their Associated data how all that's represented so modifying this would be a bit more invasive than adding some fields to something that already existed like we did with the Parallax so here's the process first the editor gets pointed at the directory containing all our actor C files it then goes through and creates a corresponding actor representation on the editor side but they're still all red squares how do we actually tell all of these apart well I gave this a good amount of thought and eventually settled on adding a metadata section to all the C actor files as this info had to be defined somewhere and if all of the actor's behavior and other nonsense is defined in the C file this should be too while setting up this metadata system I also decided to throw in support for being able to Define custom variables on individual actors for example if you want to set the direction an enemy is facing or what the text on signs should say it's pretty easy to do I also added an optional flag that would stop certain actors from appearing in the editor for ones that should never be manually placed in a level accidentally this was all topped off with the world's worst parser which is honestly fine since this will only ever get run on development PCS very frequently and after wrestling with a bug where Sprites just weren't loading I love asynchronous processes it was done or as done as the level editor reasonably could be now normally this is where I'd be wrapping up if I hadn't hit my final for now engine architectural snag while working on a yet unannounced project I wanted an enemy that could both interact with platforms and hurt the player doesn't this sound familiar a lot of the time spent making everything data driven is kind of over engineering and future proofing for issues you'll never actually hit never actually hit hm maybe the the rust stations knew something just kidding anyways forgive me for my game maker Tendencies but with my older projects the workflow there would be to give this enemy a generic enemy parent type so the player could check for collisions with it and then call move scripts inside the child enemy if he wanted it to platform thing is C is statically typed meaning you can't easily Define variables on the fly like this so I partially cave to my hatred of data driven design and added a basic component system this is less traditional data driven design and more a thing I want to have act on an object I'm not sure look I made a platformer component which handles 2D platformer style movement and interactions with slope terrain surprisingly annoying every actor that wants this 2D movement adds this component to a list with the platformer component later taking care of the rest then all the actor needs to do is set its horizontal or vertical speed this mildly flexible on a good day component system which took some amount of brain power has been used exactly once I don't know maybe there'll be some more Behavior sharing in the future that'll prove this system's useful ful but for now it's relegated to making sure that both the player and this log can roll up slopes oo on the engine side that's pretty much it to use a very unscientific measurement we now have pretty much everything we need to remake the original Super Mario Brothers with the core engine development mostly wrapped up we could finally start on our next ambitious project a remake of a 4-year-old game Jam game next time the difficulties of expanding a team the difficulties of reimagining something originally made in 48 hours the difficulties of mono game not drawing levels on German laptops true story The difficulty Alex Alex Alex you forgot audio Alex hey it's me uh Henry the sound designer the the game has no audio Alex how will they hear my beautiful beautiful [Music] sound I
Info
Channel: Alex
Views: 19,736
Rating: undefined out of 5
Keywords:
Id: mh_eG-VMeis
Channel Id: undefined
Length: 16min 59sec (1019 seconds)
Published: Fri Sep 29 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.