Building games with Typescript a short retrospective

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
um okay uh hi everyone i am craig fisk um yeah i'm here to talk to you about building games in typescript um i'll go over very shortly about myself um as i don't like to talk to myself that much um web developer for 11 or so years now currently working at barclays as a senior front-end developer um i like to build everything in the front end because i'm a masochist maybe um but yeah uh so i've been building games since i was like 14 or something using various game engines like um game maker and things and um yeah over the years worked at various different companies including some um web game development companies um worked for a company called legendary games over in nottingham building kind of strategy games uh their latest thing building uh more time for the um the game's workshop license um it's very cool but um so i've been uh yeah building web games uh in my own personal time ever since then and i always build them with html css and javascript which uh to most people when they talk about building video games sounds like crazy talk but i'm gonna try and convince you that it's not um and it is possible um so i'll show you uh the first game which uh that i uh kind of commercially released um although it's now uh defunct uh on the google play store it's um with it being uh just built in html javascript it just runs anyway so i'll just run a http server on oh it died now that's because i have another server running somewhere else on this one stop that one let's try that one again there we go okay um so yeah so this was uh my first game that i released apologies it's probably gonna run like absolute garbage because it was built to run uh on the web at least five years ago um and as we know technology technology in the front end moves fast enough that that's um ancient technology but um it's not not the best demo of web games running but it works um you can uh yeah make your little character jump and all the animation works et cetera et cetera so this i uh bundled up and released as a android application so if we just have a little look under the hood all of my games uh start with a index.html file it's very simple um with not an awful lot inside it uh just a few scripts um um yeah i mean let's not we won't look into this file too deeply because it's deeply embarrassing how badly i was coding but i was just coding for myself so you know i i bundled it all into one very very big file um and left myself all sorts of horrendous notes and things inside to try and keep it um keep myself understanding it thankfully i've got better at building games since so um we'll move away from that one now quickly um so i then released last year a uh newer game um which currently is working on the android app store um again i bundle these up uh these i'm building mobile i was building mobile games um this could easily be released on the ios store as well um but the simple fact of that i didn't want to pay 150 quid a year to be an ios developer when there was no guarantee of making any money on a personal side project um i decided just to go with um android so um that's just this one across there we go so this one obviously being built uh more recently runs an awful lot smoother and better in the web i do not know if you can hear the sound but it's particularly obnoxious but it's a fluffy bird style game where as you tap on the screen or click on the screen it makes the character go higher and lower and if you bash into any of these things you hit an end end state um now um this although uh slightly better organized where are we uh this one again starts with just an index.html file slightly more complex we have some css built in here just to set some styles of the web page then we have very simply the most important element when building games for the web is this canvas element so the canvas element uh is a html element that um essentially gives you an empty box on the screen and then gives you a javascript api that you can hook into that and in that javascript api you can draw um that there are a number of apis for drawing either images directly to the screen to that box or to various pathing uh svg style pathing syntaxes so you can draw things onto it but the most important thing about it is that it's optimized to run very fast or especially if there's a gpu available on the system you're running so this allows us to uh clear and redraw the screen really really fast using this api just like a game would do in whatever language you care to look at um so this thankfully is broken down into some more um usable chunks rather than just being one big file um using some um es6 import syntax here um so the unfortunately the the main engine of it is still a class of 500 lines long which is not the best practice ever but again this is just a just a coding project of myself but the core idea behind the game engine is that you split your code into two different loops you have a rendering loop and you have a logic loop the rendering loop you want to run as fast as possible so the the player never drops any frames you get a nice smooth result whereas the logic runs at a fixed interval so in my case i usually code with it being at 30 frames a second or 30 ticks as or 30 runs of the code every second which gives you uh from web in general web performance you get a nice stable game at that sort of thing that obviously depends on how busy you make it but um so let's go to um where are we going we're going to okay so the yeah here we are so we have uh our two loops in the game engine we have a render loop and we have a logic loop uh as i said so the render loop uses a um api built into the browser built into all modern browsers now called request animation frame so this allows you to essentially before the browser does a redraw of the screen you can actually get it to execute code and then um force the the redraw of the screen so this is perfect to basically allow us to get ahead of the logic that's going to be running on the main thread it allows us to kind of skip um that queuing system that javascript would normally calls and get the render to happen really quickly so it's actually if we look this function is actually it's one of these apis that you um recall itself to continue its execution um so it just continually re-renders um and it's very simple um so this context object here is our main api for drawing on the canvas and we are just clearing the screen using the clear rectangle uh api and then we are we have a an array of things that we want to draw on the screen and we just call their render function um and i will show you an example of one of those render functions very simple i try and break these down as simply as possible in this case for the main player character we are just draw using the draw image um we have the the image defined um and then you can actually just draw a certain portion of an image rather than just the whole image if you want to and you can get it to scale up and down as you want to so um that is uh so and again that's how we get the animation to work so i have a for example um this uses uh sprite sheeting let me know so the unicorn for example uh just has a series of animations so the x and y coordinates in the code here just correspond to these places so um again to save on the loading of the images etc we just draw we have one image that we just draw portions of over and over again and there's some simple logic to iterate through those um so as you can see this is all written in just pure javascript um using standard javascript class syntax uh and import export syntax and that was that was a great improvement over what i was doing beforehand of just bundling it all into one massive file but we could do better um so the so that game is actually out on the play store it has a small amount of downloads but that wasn't the point it was more the point of showing that i could release a game out on android um so let me kill this one um i've moved on to a bigger project now um so i've decided um instead of just proving that i can build a game in html and launch it on android as well as the web um i my next plan is to check that sound off is to release a desktop based game so something with an installable um exe um and um ship a a wholly bigger game than uh what a small simple mobile game is like that so that brings us to this project so this was the time so when i started this project in october of last year i decided to switch over to typescript because it provides every all the simplicity and wonderfulness of javascript that i like um but i build uh games and i think most games are built in a very classical programming style where you have um object inheritance um you're building on top of classes etc so typescript just lends itself massively to that so um give you a quick demo of the game that i've got so far um we'll start a new game quickly so we have some exposition and story very simple and then we hit the big load um as it builds all of the images and composites everything together get there in a minute here we go so as you can see it's a very um pixelated um you know snes legend of zelda style pixel art um game and lots of exposition to begin with um but then we launched into the world here so um yeah currently i have a bit of a world a a large open area you can i've made it so you can walk into buildings walk around things um you can interact you get pop-ups you can do things like going to sleep um and this game in particular is um based on the loose pitch i'm going for if anyone's seen the film kiki's delivery service uh about young witch um in training it's meant to be that combined with a game like stardew valley or harvest moon kind of a life sim type thing so if i hit spacebar in this game you can turn and you can get out your witch's broom and start flying around and as you can see that that the world is a lot larger than it looks from up there but that's the idea um so this is obviously very very much work in progress there's not an awful lot here to do at the moment um there's just a couple of buildings that you can go into and an npc that you can interact with um nothing too crazy at the moment but it's taken an awful long time just to get to this far there's an awful lot of working parts behind it um so um i will show you kind of some of those working parts oh that was the other thing that the big thing that's taken quite a long time is there's an internal game clock um that's running on the particular day that changes the lighting in the in the in the um in the world depending on what time of day it is and eventually if you stay up too late you eventually pass out and fall asleep um also have loading and saving of data um so you can reload from your original position i'll jump into that in a little bit of how i do that because that's quite interesting from a web point of view um but yes so um what should we talk about um so uh what i've done being um as i've built um several of these games over the years i've kind of rewritten my game engine every every time i start a new game um and to try and avoid wasting so much code and throwing it all away every time i've started to build a separate library for the core game engine which i've released on npm so there's a i don't necessarily expect other people to use it although they can use it i've created some very simple documentation to show you how to use it that needs more filling out but i have separated that out into a separate library so i can just not have to throw away so much code every time so that houses the core game mechanics um there's all my uh preloading of images preloading of sounds handles key and key up and keep down inputs etc and then again the beauty of the typescript language um you then get these type definitions for all of your classes so it looks kind of like gibberish here a little bit but this is highlighting all of the properties of that class and all of their types so that when i come to import and use that inside my game engine sorry inside the game i'm building um i know that for example a game config object here has to have all of these various properties and if i remove one um i'm gonna get an error thrown just straight away up in visual studio code here saying that the width width is a missing property um in in that type um so i'm getting the benefits of of compile ahead um type checking without having to uh whilst keeping all the simplicity and powerfulness of javascript um so um so yeah we see here we have a the game object let's create our game so again from um just using uh the fact that we have typescript all these type definitions i get intellisense already straight away from all with all the typings and everything that are defined in the in those type definitions um which makes it massively powerful massively useful um when we're doing development rather than just trying to rely on our own memories um especially especially this time i'm going for such a larger project it's making a world of difference especially as this is a side project and i'm working only part-time evenings weekends whenever i can find a spare hour to work it um stops me having to have such so much of a cognitive overhead um again more more power of the um um more power of the typescript language we get extending of classes again with uh more more intellisense um so for example that the one uh mpc the unplayable character i have in the game extends a base mpc class uh which has all of its typings etc and all the complexity which all gets inherited nicely [Music] so that yeah when i come to write new npcs here so i can make another mpc that just extends this base class and it's going to make it a hell of a lot quicker for me to scale up the development of this game um so let's talk about uh interesting point um so the levels that i'm building obviously very large and i'm using this uh application called tiled um that allows you to kind of get an overview of the maps that you want to build and allows you to use tile sets so these tile sets you can see here on the right hand side they are these are the images that are actually getting loaded in um to the game so i'm not actually loading this base level in as a whole i'm loading it in as an individual tile set um so we can see here this is this is just the all the individual tiles uh into in one single uh map and then this application that allows us to have various layers of thing of um of tiles but we can just kind of literally get hold of them and paint on top by default this all this data is stored as xml but it has the wonderful ability to export as a json format which is what i use to consume inside the game so [Music] i'll look in our data um so as we can see we we get a um essentially what is essentially a series of arrays for the light for each layer with numbers that corresponds to which tile they are on the tile map as well as we can pass in a set of extra objects um so all of the collision boxes so you see all of these uh squares that are highlighted uh these are all on a separate layer called colliders so all of these boxes are what the player collides into and can't walk through um so uh when i process this data in i can easily just create on the fly um all of the objects that the player collides into so it gives me a lot of power to be able to to build up lots and lots of levels very quickly using these um repeating tile sets so as we can see we have same for the same thing for inside um one of the houses here and i'm starting to set up extra objects here with particular types that then have custom properties assigned to them so for example when the player is colliding with one of these it doesn't stop them from colliding with it but it's going to i've configured it so that it has a sleep dialog attribute so i know that when i hit enter and i'm colliding with this object the sleep the do you want to go to sleep a dialogue pops up same with these purple ones these are set these are doors so you see this goes to the this particular door goes to the stage name of main world it sets the the player coordinates as well as the stage coordinates the correct place and the same within the world the world has corresponding doors that then have the same data but for going inside the houses and so it's a great tool for building these sort of things for this particular game i'm sure there are lots of other uses you could probably put to this um to to build sprites and things up and and of that kind but for this particular type of game this tool is perfect um what else do we talk about oh yeah so the again being building this in web tech allows us to take advantage of really really simple apis that are just built into all browsers so for example the saving of data i don't need to have any web server actually running to get the save data i don't have to have cloud say you know a cloud infrastructure to save and pull data down i can just use um the built-in uh the built-in apis that um we have is the we can use the session storage as well here we go the session storage as well as the local storage so all of the uh configuration data um for saving and loading all gets stored as a sim as a simple key value pair um and as you can see here the json data just says when we were saved you know that the string with the name of the world we have our our time we have our npc's and all their coordinates their x the y what screen they're currently on uh and it's really really simple there's a really simple api just to pull this data down convert it to json and vice versa convert convert it back to a string and save it here so i just run a polling script every 30 seconds this data just gets written automatically so you get an autosave kind of feature going on um for really really simple um yeah with with very little overhead i'm not saying this this data couldn't then be um persisted um saved out of here put onto servers etcetera because again it's only a very simple uh key value pair store of string data that i'm storing here um but um for now um the plan is to yeah continue just using this this local storage um which the user can can wipe so if you hit that nasty button that says clear all your browsing data and cookies this data goes as well but because i'm not going to be launching this as a standalone website i'm going to be wrapping this up into an application using something like node webkit or electron if you've heard of those tools they what they do is essentially take chromium in most cases as it's an open source browser and wrap that up with a node server that runs when you launch the application uh so you can actually bundle that up as an executable that will just launch the chrome browser with whatever configuration so you can make it full screen etc like you would want for a video game and you can stop people launching developer tools etc there's loads of configuration for that but so because this is going to be a separate instance of a chromium browser rather than your chrome browser you'll never run into those issues of having that data cleared not to say that i couldn't potentially release this as a browser this is the beauty of writing games in this way in typescript and javascript i can release this anywhere this can go into steam stalls this can go there are games written like this that are um being put out on the nintendo switch xboxes etc they they can go anywhere um which is what i really like um with this it's it's a code once release anywhere kind of thing as long as you can write the wrapper to wrap it up as long as you can get a web browser launched and an index.html file served up you can make this run anywhere um i guess that's probably enough of me waffling all about this um so i guess i'll just open up to questions that's really cool mate um where does one start with this what's what's like supposed to make tic-tac-toe or something yes so i actually um a new tablet launched um i actually uh i started writing a uh tutorial series for how to do this um but um it can just start in a codepen to be honest um that's how uh that's actually how i um started off all of these games they've all started off as a code pen um that i've then just eventually exported and turned into a proper project but um if i watch this so eventually you can get to something like this but i'll show you the the initial crux of it side by side so this is a simple platforming game again all written in the exact same technology stack um but it runs as a codepen it's literally one single javascript file and you can get something like this running in 171 lines of code so not an awful lot um let me see i can show you quickly this the a few that you know the early stages here so the first thing is obviously getting the rendering happening so again you create canvas element in your html you get a reference to that canvas element you create a context which gets you the api to draw to the canvas element and then you can start drawing to the screen so for example just filling in a rectangle that then leads to now great okay i can start making some class like functions that creates uh multiple objects so i can make blocks i can make heroes i know that everything needs a width for height an x and a y and a fill and then we start creating render functions for them that render their x y width heights then you start getting into building loops etc so it's it's it's not overly complex code to actually uh get started really um as long as you uh kind of split um split your code into these two kind of loops i render i have this idea of a red loop and a logic loop um it's pretty easy to get started with i there are plenty of tutorials out there that get into this um eventually i'll have one written uh eventually um but on top of that if you're not into writing your own game engine which not everybody is everybody some people want to just get going there are a number of engines built out there for you already um phaser being one of the main ones phaser.iio they yeah have a million tutorials and a million examples of games that are built with it their docs are very good their examples are very good so yeah that's a phaser is a very good place to start if you don't want to get into writing your own engine but you just kind of want to play around with this sort of thing how do you find typescript versus javascript um so in in this particular project writing such a large game uh i think it's an absolute no-brainer i find it um far better to write in than javascript just for the fact that you get all the inheritance and everything built in easily although that now is is true of javascript you can write classical style with classical inheritance um but the fact that you just get all of the built-in inherited uh all the built-in typings you get the um at code time errors throwing up whereas um showing that you're you know if you're not passing in the right thing into functions etc you can make it strict uh as strict or as loose as you want but it yeah it just it makes me not make so many mistakes when i'm building a a project as big as this um so i mean for for example you know how how do you know when you've written your game engine you know i i wrote this game engine now october last year how am i going to remember uh what a config file for a new game looks like you know um whereas as soon as i put this typing in saying it's game config i immediately get the the red squigglies and it tells me exactly what i need to fill in here um it's yeah it's kind of a no-brainer what was the learning curve like going from javascript to typescript um i wouldn't say it's so much of a learning curve because you are still writing javascript at the end of the day the main syntax is still javascript and you don't have to write any typings for it to then still be valid typescript so all javascript is valid typescript because it's a superset on top um but the more you lean into writing typings for everything the more you get out of it so for example when i was initially working in it i hardly wrote any interfaces for things um i just allowed typescript to kind of infer a lot of my typings for me but then the more and more i've used it the more use i found out of writing interfaces for everything so if i show a quick example of um in the base game engine um uh yeah i have a a folder full of um interfaces now that they're really simple to write but you get so much power out of it by you know for example in this case 99 of everything in the game engine uses this gaming uh game entity interface um and you can get kind of three or four abstractions deep um inheriting this this type and if i wasn't using this in this interface and i wasn't using typescript it would be so easy just to miss off one of these one of these properties and then the whole thing will fall over and i'll spend an hour trying to debug where i've missed a single property um so the more i found definitely the more you lean into it the more use you get out of it um for a less complex project from i think it becomes it can become cumbersome it can feel like you're writing a lot of extra code that nobody's going to see at the end of the day because all these interfaces and things are of absolutely no use to the end user at the end of the day they're only useful for me deving i know and for the fact that i'm building such a large project it makes sense to spend that extra 10 uh work effort to write all the extra code because it's going to help me in the future but if i'm writing a small project i i i wouldn't i wouldn't go for typescript right are you missing a semi there uh [Music] yeah now see yeah i've missed a semicolon they are optional and that's upset me that i've missed it i'll be honest um because i like to put them everywhere and being javascript and typescript they are optional in in a lot of places and that's upset me so i am going to be saving that because i hate semis i have prettier take all mine away okay yeah we can get into that argument for a long time no i hate semis it's just an extra type but a button that you don't need to press well if you have pretty deal but you don't have to type it yeah but then you don't have to look at it if you don't put them in i suppose you should just use python if you really hate things like semis and so yeah i guess this sort of interface here kind of shows um you know you're getting into some slightly more complex typings which um again trying to remember all of this you know for example even just down to entities okay great in javascript land this would just be an array um but the fact that i'm typing as it's an array of game entities and i know that the game entity interface is there and it's got all of these potential optional properties and stuff when i'm when i'm typing when i'm writing this this stuff out it um yeah it saves you so many headaches and debugging in debugging in the browser which you know nobody really likes to debug brow the javascript in the browser really right um where so when you get those graphics load them in them and put them onto the canvas are you doing that in your own code or using a library to kind of blit that onto the oh so this is all in so this is all my own code um so yeah so the main game engine um its render loop is very simple it clears the canvas so you go back to a white screen then it looks for what the current stage is so what the current level is it grabs its cube of things that it needs to render and it calls its render method and passes in the context for the canvas for the game so the court passes in the api to use so then for example um let's look at the players render function so this is what we'll get called bottom here somewhere um so it's very simply using um the base api so the canvas get the context gets passed in again we're just drawing we get the image we draw the image it's really simple in this case itself has that of that facility built in then it does yeah yeah so again this is just drawing a portion of the player image um because it's a sprite sheet of animation how powerful is the basic the drawing facility does it have things like um transparencies and yeah yeah it does it does so this so this is the main one i use uh drawer image but as you can see these commented out ones here are for debugging purposes so if i turn these on for a second um so we set the fill style um using an rgba so it's got the alpha setting to 50 and then we're drawing a rectangle over the top of the drawn image [Music] to build so the code actually gets built that i've just changed um and this is the good thing as well um the old times are not particularly slow either 9.2 seconds to build um is pretty reasonable in my opinion for a complex game load in here fingers crossed it will be working here we go so yeah you can see there's a there's a box drawn over with the transparency and everything um so it's not just rectangles you can draw there's a full api for drawing lines with with uh borders um you can draw arcs bezier curves uh kind of anything you want really there's a full full library there to take use of it's just for the fact that i like to have the the pixel art style that i use drawer image to draw everything out um so you could use that if you to generate lighting effects and things like that yeah yeah so the way i'm doing with lighting effects so this current time of day um uh everything's a bit brighter because it's it's closer to midday so um all of the graphics are um pre-rendered so the whole level is built up in um into a large image using cam uh using an off-screen canvas and then that off-screen canvas is what's then drawn onto the main canvas but i uh pre-generate three different versions with three different sets of lighting on which is again because it's all off screen um is relatively cheap to do you do it at load time so you don't have to do it and then just as the clock goes by you just switch between the different images so that works really nicely how many entities do you think you can probably throw around on the screen well it depends on how much complexity you're doing with them so again you can see here on the um uh in the uh dom here there's there's next to nothing um in the dom there is the one canvas element there's a text box for us you know a span for that clock in the top corner and another span with a couple of bits in for that uh power bar up there so there's next to nothing going on in the dom it's all going on in the canvas and if you know do you have like an idea of how many of those you can get on the canvas in the time well i haven't hit um i haven't hit a performance issue with it yet um but if we look in here for example um look at current stage so we can see the render queue is very limited because we're only drawing we're drawing the player we're drawing these these boxes and we're drawing um the background and the foreground for the for the level however if we look at um the entities queue here there's 222 different entities so these are all different collision boxes for the various uh things that you can collide into and we're running collision testing on all of these in the background to see if the player is colliding with them for example on this fence and there's no slowdown that happens from colliding into these yet anyway i'm sure there will be a limit that gets hit eventually yeah um but uh as it stands currently there's not and maybe that's because i'm yeah not overloading it with extra draw calls because i've got it very simply drawing just a foreground on the background um it's working quite nicely so for example you can go behind this tree so there's a foreground set that goes above the player and there's a background that the player walks on top of um so i get some layering like that but i'm sure there will be limitations eventually and it's also going to be dependent on the system that it's running on um so you define those different layers in the tile editor what um yes so in the tile editor um anything that gets put in this top objects layer here um if i toggle that on and off you'll be able to see see it goes around the trees around this well here and if i toggle it off that's stuff that gets drawn on top of the player whereas everything else gets drawn behind the player takes a long time to do the art as well doesn't it yeah so i i actually uh thankfully i started out with um some pre-built our assets um that were that i got from a humble bundle from my game dev store basically um that are these kind of very painterly effect um tiles but i am essentially retracing over them with pixel art and um and i see the difference the toggle um which there gives me that gives me the power to kind of change change it um going forward but yeah it takes a long time to to redo all this and again same with the um player sprites those uh i'm building up in sections as well so there's actually a base um skin that all of the players and the npcs use for animation and then they have various layers that go on top of them such as the witch's robes have a separate animation set and all the hair has a separate animation set so that means in the future when i when i eventually get there i can allow you to do player character customization um by just choosing these different images and just layering them on top of each other and it gives me a lot more options for the npcs that i can mix and match different images uh different hair and clothes to build up different um different characters it's amazing how much these details matter in the end and how much work it takes to do all the little things especially if you're working on your own because yeah i've developed the list is never ending i wrote myself an initial uh minimum viable product list which i thought seemed quite good and then as soon as i started ticking a couple of things off it more stuff got added and more stuff got added and i realized yeah that that wouldn't be enough for the minimum viable product even so that good list keeps growing but i do keep taking stuff off it so eventually i will get to a minimum viable product that i can ship out onto itch.io to get some people have some hands on with it and get some feedback with it and then that gives me scope to just keep building and keep building yeah keep going yeah very patient man craig thank you i think all that pixel stuff would drive me mad this particular game all started off because i was bored stuck in a hospital bed without being out without being able to leave the ward for a couple of weeks so it um yeah when you haven't got anything else to do it um it very quickly seems perfectly rational to start such a very large project which bit do you enjoy the most crafting the engine or crafting the game um hard to say it used to be crafting the engine i think um the fact but that was very much when the engine was kind of the same thing as the game but i did get a lot of um yeah satisfaction out of building all these different systems but now um yeah now i've kind of separated them off into two separate projects i'm finding i'm enjoying i'm staying more in the game area so i know i've got um utilities and things that i'm using in the game that need to be ported back to the engine and i will get around to reporting them back to the engine eventually but that the idea of doing that is far less fun than continuing to add more stuff to the game
Info
Channel: Chester Devs
Views: 98
Rating: undefined out of 5
Keywords:
Id: LC9210uTJoU
Channel Id: undefined
Length: 48min 48sec (2928 seconds)
Published: Fri Sep 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.