Functional Game Engine Design for the Web - Alex Kehayias

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody my name is Alex Caius and welcome to my talk about functional game engine design for the web so we have two talks that are gonna happen one which is gonna be more focused on how you actually design and implement a functional game engine and then Bryce covert is also going to be giving a talk about specifics of solving problems in actually implementing implementing an adventure game enclosure so before we begin I just want to talk about where this all comes from so I like many of you guys have spent several years building back-end systems with closure having to deal with very large data sets lots of plumbing lots of ETL sticking things in the right places and there's a lot of things that I've learned along the way about data oriented design and solving problems with data enclosure and using some of those ideas now to apply it to something that I have as a pet project which is games and game engines as a result so to start off what is a game how do I actually define what a game is and really it's actually state so one of our you know most feared but also most revered things about anything related to a program is actually state and in games we can think about it as state transitions that are happening 60 times per second they tend to be pretty complicated that's a it's a multimedia interactive experience that has lots of moving parts and a lot of times the moving parts tend to be intertwined so there's some complexity inherent in building and expressing games so if I were to sum all that stuff up I would basically put it into this one chart which is state and time or you know to borrow something from the physics world state time so as we can see each box is a state at any particular point in time and we're always moving linearly across time so don't think of as like minutes seconds or hours think about it as like ticks that are always moving forward and progressing and the state of the game world is what it is at any particular point in time is the truth so just a quick justification why would we even want another game engine aren't there plenty of other options and of course there are quick shout out to the people who are working on Arkadia on top of the closure seal are Tim's and Ramsey have done some amazing work on allowing closure to be built on top of the udemy 3d game engine there's other tools in the JavaScript land for building game engines also but why now why do we need something else and it really comes down to the timing of closure and closure script so the appeal of being able to bring the entire toolkit of closure and it's amazing work with dealing with data and being able to program the way that I want to program games that I'm going to be spending my free time on is a really great time to do it because we can also use all of our functional programming techniques to start dealing with some of that complexity start trying to think of simpler models and use some of the things we learned from the rest of our closure work to apply it to a new domain and who doesn't like building games or dabbling with games and game programming so I found it extremely fun to build for the past two and a half years I've been working on a game and game engine that I've written rewritten many many times and really the fun is just been building this universe and building on top of it so let's start with a quick example and I don't mean to you know point any fingers or pick on anything related to object-oriented programming but this kind of showcases a few things of problems that I want to solve so let's quickly try and digest what's going on here we have a couple of objects we have a player object we have a game object we have an enemy object and inside this game we have a method called run which is going to run our game and essentially what we're gonna do is iterate over these entities these objects and we're going to start manipulating their state we're gonna start calling methods and quickly notice how we are actually coupling players and enemies together where both of their states maybe need to be known in order to alter the state of the other we're also gonna handle other things like input and we're gonna end up with an orchestration in our run method where we're gonna have lots of different objects that they're playing together so this might be a really great way to start and especially in simple games it's an obvious place to start but what happens when we start to add more things in what happens when the complexity starts to go up the kinds of games that I'm really interested in tend to be more about content so think about like Diablo or like Zelda 2d games that have lots of content and experience by what's in the world and the behaviors that you can actually create so in that example we've coupled things together at the code level and that's one thing that I found to be a little bit difficult especially when you want to start adding more functionality and one thing that is kind of obvious this too with using objects is we've actually intermingled state and the methods that change that state so that's fundamentally how classes and objects work but we can change that assumption and separate those two and have a different way of expressing our games or functionally so what are some ideas that we can now apply to how we might want to express a game a few things that are on my short list I want modularity I want to be able to add new things without breaking other things I want it to be declarative and I mean that in the sense of I want to be working on what the game does rather than how it is going to accomplish and do it so the separation of those two things I want to say okay game engine you figure out how to run this game I'm going to tell you all the pieces that you need to account for to express the behaviors that I want and I want to do it with data I want it to be functional because I like to be able to test things with data I can reason about data pretty easily and I have a lot of tools in closure especially to deal with data I also have a vendetta against global state I don't like the idea of having a singleton I don't know who's gonna have to be accessing it and I want to minimize what all of the functions in my execution strategy are going to have access to at any particular time and of course I want to wrap this all up in a nice interactive development environment where I can get instant feedback about the game that I'm creating so it could be more fun so let's talk more about the modularity aspect of this so bringing back our object example we might try to express a game that has let's say a space fighting game we might express it with an object tree that looks a little bit like this we'll have an eye hierarchy where let's say we're trying to create three different kinds of missiles heat-seeking the Sidewinder missile and then we also decide we want a heat-seeking Sidewinder missile so how might we go about expressing this in a more of a hierarchical sense we can take our missile object and say okay a heat-seeking missile is gonna inherit the missile object the Sidewinder missile is gonna inherit the missile object and then as soon as we want that heat-seeking Sidewinder all of a sudden we're gonna start to run into a little bit of trouble we either need to rewrite our object hierarchy to remove this deadly diamond of death or we have to deal with the consequences of how we're gonna know what methods are actually going to be called especially if they share the same methods within this tree so you can see imagine if you multiply this by a hundred or a thousand right into content-based games or there are so many different things going on you can quickly end up with a very rigid structure that's gonna take one a ton of planning up front and two that's typically not what happens you're gonna want to change an experiment with the functionality of your game for maximum fundis so this leads us to entity component systems this is something that's been popularized in about 2007 Dungeon Siege was really the pioneer of this Scott Billis gave a great talk about it and basically what we want to do is D couple those really strict hierarchies and think about it more as a collection of aspects components so essentially the way we describe things is as a collection of things that it can do its behaviors and we want to separate the means for iterating over it from how we describe what the things actually are so if you do it in this particular way which lends itself nicely to the games that I want to create that are more related to content we can easily add remove create new things from our existing pool of components without having to deal with a really upfront rigid hierarchies of classes and I found that it tends to pair really well with functional programming so what does this look like now if we were trying to describe that same you know missile Sidewinder heat-seeking Sidewinder with components we're gonna end up with little buckets so heat-seeking missile can move it can explode and can heat seek our Sidewinder missile can move it can explode and it can have a sidewinding component our heat-seeking Sidewinder is the exact same thing but it has both the heat-seeking and Sidewinder components and then just to cap it off how might we create new novel things in our game world like a bomb it can't move it's not sidewinding it's not heat-seeking it's stationary it's static so all it has is the explosive component so that's all well and good but how might we express this now in data so we're gonna build up this framework so to speak by looking at data and trying to build it off of data first so that we can achieve some of the declarative parts that I really wanted for this type of approach so here we have an entity and entity component systems are described in many different ways here I'm gonna take the most functional way that I have thought of to express it an entity being a label so player one and a collection of component a abel's so notice there's no implementation there's nothing in here it's just data all it's saying is that the entity has those three components that it's going to participate in next we have components and a component is pretty simple it's a label and it's a function of component statement so we're introducing a new concept here component State and component State belongs to an entity okay so what it's going to do it's a function take some phone of state returns the next component state next we have a system a system like we said before is in charge of the means of iterating over these entities so here we are going to say a system is actually just a label so if we're gonna take the movement system it's a label it's a function of the overall game State and it's going to iterate over all of the components all the entities that have that particular component and it's going to be in charge of calling the component function with the component state that for each entity right so each component State belongs to a particular entity it's iterating over all of them and it's going to stick them back into the overall game state so you can think of it as a lens a system function is lends to the component function what we want to do is take wider inputs pull out just what we need and then recombine everything at the bottom another concept that I want introduce which is not often covered is a scene a scene is a little bit higher level where it has a label but it's also a collection of systems of system labels and the reason why that's important is because order of execution is sometimes important maybe we need to get input from our controller before we calculate movement so the order of execution of our system functions can be specified up front without code again we're using data here to describe how I want the game engine to actually execute the game lip so what is the pattern here the key takeaway is if we model in this way we're dealing only with data and if we're dealing with data we're dealing with values and we kind of have these new properties that come along with it so in some words in some ways you can think of it as kind of this game Icona City the game is actually data the data is actually the game which means at game time we can alter how the game actually works entirely by declaring different behaviors or changing things so that allows us to do a lot of things at development time but also as the game is running so we've seen how we can describe entities components systems and a scene using this data and functions but we need something that's actually going to put it all together right so what is the actual game has actually run how is it how do we put it together so if we were to describe our game state as being a hash map in which we described our entities or components our systems and our scene using data what we want to do is we want to take all of the system functions out of our game state and we can do that very easily by mapping over it in the order in which we defined the scene to be and we're just gonna complement again which is going to return a new function and it's gonna take a single argument game state and it's going to return the next game state so when we talked about state time remember it's just different snapshots of state and we're just going to transform it over time so this is going to return the next game state we're gonna take the result of that I'm gonna stick it at the again and we're going to recur so essentially our game live is a recursive function in which it's getting the instructions of how to execute our game loop from the data itself so quick summary of what that execution model looks like we have the game state it gets passed through a bunch of different system functions until it recurs all over again if we were just pull out one system we can see we start with the state we're going to provide a lens to it we're gonna pull out each entity that's participating in that particular system we're going to get the next component state for each of those entities then we're gonna stick it all together again into the game state okay I'm just gonna pass it through so this looks very much like a linear pipeline that we would create in our other closure work that we would do in plumbing a bunch of data so some good things that emerge as a result of this we've got pure functions the data itself is a flow of data that's linear right we can see exactly how we specified what's gonna happen in what order and it's predictable so we can also parallel eyes this if there are no dependencies between systems and each system returns a state as long as we can separate them without any dependency we could put those on different threads and combine them again at the bottom if we wanted to to get some parallelization it avoids Singleton's the data is actually just in a recursive loop and just being passed in so we're not having to swap bang in in a global state bar side effects can be isolated we're building layers of functionality so if we describe everything in data and then our last system is the rendering system we've actually prevented a whole bunch of side-effects from happening through the rest of our data pipeline until points where we can actually isolate them it's super dynamic components can change their own state only and nothing else they only have access to what they need all the benefits obviously of immutability and it's super easy to add new things in order to add new functionality we add new systems or new components and we can express this very declaratively using data of course there are some bad things that come along with anything that we're gonna try and do so you know I kind of said let's minimize what you have access to you if I'm writing a component and I am in charge of returning the next components date let's say I just have to calculate the next position sometimes I'm going to need more than just my last position to tell me where I need to go right so this thing that I just showed you kind of breaks down there how are we going to express that it's great to keep things that are really clean and really pure but at the end of the day things interact and that could lead to some bad things like fat components you guys have heard of things like a god object or a blob object before where it kind of has knowledge about all of these different things and it doesn't separate concerns and it becomes really brittle and hard to change we didn't talk about performance or probably morphism yet or tooling those are things we're gonna have to address - and one thing for those who are looking at the system functions they can actually seem really boilerplate right they're parsing a whole bunch of gamestate they're pulling out things or calling functions they're recombining it that sounds like a lot of boilerplate if I want to add new layers of functionality I have to go rewrite all that stuff over and over so that's something that's not good either it's not strict at all it's a data structure which means it's probably the loosest thing which means what happens if I accidentally returns nil right I forgot to return something all of a sudden my game is going to break on the next loop through in unexpected ways and then we'll talk about tooling - so we have to we have to settle how we're going to actually share state sharing state as dirty as it is has to happen because games tend to have things that interact I can't think of any game where no interaction happens so we do have to figure that one out we want to share this stuff without really tightly coupling it the tightest place you can couple it is in code next we want to make it read-only we don't want to have anybody arbitrarily changing our state pal from underneath us because we're gonna end up with really weird bugs as a result so we want to keep our flow of data in one direction and we want to minimize what people have access to so kind of think of it as least privilege of state so what does coupling look like at the code level this is a blob component so if a component is in charge of just giving me the next component State for a particular entity here I'm calculating where this thing should be moving based on collision detection whether or not they took damage by colliding with an enemy where they should be where they should be positioned and moved to in this frame and you can see we're mixing a lot of different concerns and we're ending up in a very and this is a clear smell here we're ended up in a nested conditional so this is gonna be really brittle if you want to introduce something else right like Oh what if there's invincibility what happens if you don't get hit every single frame what happens if it was it cool down how do I do that now you end up bolting things on there it becomes really really hard so let's use some of our knowledge from our other domains enclosure and say how might we separate the sender from the receiver to keep it in a single directional flow but decouple those two things together from each other all right so component a and component B we don't want them to know anything about each other it shouldn't matter we do this with conveyance so we would typically stick an event Q between things and we can do something similar here instead of directly altering each other State or having to put them all in one component we can say here's an event and here's just an example where we can create kind of this mock messaging system and I'm gonna subscribe to collisions for player one and I can get the message out all right so here anybody can create a message someone's gonna have to handle it downstream so we're pushing that down to the handler rather than to the person who's gonna create it and if we do that we can now separate those things nicely into separate components so we can really have a collision component a movement component position component health component and they're going to be loosely coupled on the message format rather than the implementation of say a blob component or having to know everything about the entire state of the world in order to do what it needs to do what might be another solution to this we can also declare things upfront just shove this stuff into the system the system is in charge of how we're going to call it component functions well what if I tell it that I'm always going to need player ones position okay maybe I'm an enemy thing right and I always just need to know where the player is so I can go hunt them down if I know I'm always gonna need that up front why don't we just declare that and hey whenever you call this component function give me this other component state okay so we're pushing that to the game engine hey game engine you figure out how to run my code I'm just gonna focus on one aspect which is the component so how can we continue to make this thing really declarative in order to make it really truly declarative we want to be able to capture what we want to happen all in one place and we want to be explicit we want to be able to use our full our full inventory of all the tools we have to deal with data in closure so that we can manipulate the language of our game using closure functions and we want our game engine to interpret the stuff for us do the right thing for us and it shouldn't matter how this data gets generated doesn't matter where this game spec came from our game engine should just figure that out and for now we can just avoid macros we're gonna keep it all at data and that's gonna be our DSL so here's a quick example what this might look like a game state function that takes some initial states this in this case a hash map and we're gonna say here's a bunch of specs I want you to read those specs so much you figure it out the nice thing about this is we're capturing all of the rule we're capturing the essence of what we want the game to be and letting the game engine figure out how to run it so if you think about the original example we looked at with objects we were actually describing all that stuff in one giant run method so it was all described in code here we're describing it in data and we're letting the game engine figure out how to actually execute it so if we were to zoom in on one thing we can see we've now described the behavior with data instead of code here we have an entity called a one and it has a position on the XY of 20 and 20 on a 2d plane all right so we've been able to capture this with data rather than with code or objects having to construct this ahead of time or in a more rigid fashion with let's say objects in hierarchies how could we interpret this we can reach right into multi methods and we can say let's just dispatch off of the kind of spec that it is and we're gonna reduce it right it's just a reducing function we're gonna end up with a hash map it's gonna figure out how to stick this stuff into the game state for us that shields us from having to know the innards of how the game engine is going to organize our data for us and we can just focus on specifying our specs also this allows us to now remove some of that boilerplate I talked about before where maybe there is just a default system that's gonna automatically figure out how to call all of your entities with the correct component state so that you can focus on just writing your component and we can have a new declaration here where we say I'm gonna define a system called s1 it's going to operate on a component called c1 using this component function let the game engine figure out how to call that component I can move on to my next thing all right so we've removed a whole bunch of boilerplate as a result of that so next we have tooling you know last time I checked things like unity have like really awesome tooling amazing experience we've seen how we can do things really nicely close to data and we have all the environment set up for us enclosure to do that with data but there are things that we can get now on top of that really close to our text editors and to our development environment one of them is obviously the browser repple so the implementation I'm thinking about in the web means that we can connect to our repple into the browser evaluate our code see the results immediately one thing that always comes up is going to be like well if I'm testing this aspect of a game does that mean now that I have to construct the whole game in order to experiment with this one thing it's weak it what I found to be a good solution is to use something like dev cards so dev cards is this little this little program that lets me visually test things in the browser so I can create little cards I can share them with people and I can view isolated functionality and it's kind of a mixture between documentation testing and a nice visual way of inspecting things speaking of inspection how can we now abuse the properties of the fact that our game State is actually this hash map it's a data structure to automatically build the tooling that we want so here we have it just a little gift of something that I threw together which is just going to auto generate a UI for our game state that allows us to inspect it this is just react show us in real-time what all the data looks like at any frame and if we want to manipulate and change it have a two-way so that we can alter it and it can change things on the fly this means while we're playing the game we can also alter the game how can you achieve that with something like closure well let's just extend our data types we're gonna implement a new protocol which is going to have a single method called inspect and it's just going to return a react component and we're gonna recursively evaluate our nested data structure and we're just gonna tell closure how to how to invoke what to return when we call inspect on it so we can create recursively a UI now that is our inspector so really really nice and we're just using the the fact that we can extend closure and it's data types to do everything for us so very little code we didn't have to specify everything up front it just figures it out because this was a pure function a recursive function sometimes you really do want to get things out right what happens if you want to monitor frames per second what happens if you want to be able to inspect that state in your repple and not just in the visual inspector well one way you can do this is borrow a lesson from ring and use middleware so since this is a function and we have access to the game loop as a function we can just wrap that function as middleware so here we're gonna create a little bit of tooling that's going to allow us to inspect in a read only way our game state using our repple and the way I'm gonna achieve that is by specifying an atom that I'm gonna copy the latest data into for that frame and make that available so all it's going to do is take our game loop function it's going to grab whatever state happened it's gonna stick it into a place that I can inspect it and return the next function so we're borrowing a lesson from middleware so you can implement your own tooling very very simply because you do have access to everything you can do all the side effects you want at that layer and it won't matter another thing that often comes up when I talk to people about functional and game engines and JavaScript is immediately performance right where's performance look like you know the games are not really interested in our 2d sprite content based game so just keep that in mind but there are a lot of lessons that were learned just by looking at the profiler just see what it does and the fact that you can look at the closure and closure scripted core code means that you can see all the things that it's doing and the biggest lesson that I got using things like the CPU profiler the CPU charts to look at the call stack is that you want to do you want to figure out where you're doing lots of work and rather than trying to make everything faster try and make your program do less if you can make your program to you less you will as a result go faster and by being able to view your source code very easily and handy through you know things like a dev environment you can actually see when it's gonna be doing lots and lots of work so that kind of led me to a couple of different lessons that I want to pass along and trying to create more of a higher performance gameloop think about it sixty times per second we're trying to trying to update this data structure over and over and over in non non trivial ways one way one thing that was immediately found and I'm sure you guys have seen this before is very attic functions do come with the penalty it's gonna do more work because it needs to dynamically dispatch your code so in JavaScript terms and v8 it can't actually optimize it so it can't create the hidden class to optimize the calling of that particular function so instead use multiple era T's you probably already know how you're going to call your function and if you do just use multiple era T's alright and specify all of them upfront you'll get the performance boost v8 can now optimize that and pretty much every JavaScript engine can do that next partials same concept has to do more work in order to call your code so don't use partials you should know how you're gonna call your code or trying to reread a rearrange it in a way that you can avoid using that more examples of doing extra work empty pretty innocuous but it does a lot of things under the covers you look at the source of how it deals with all the different data structures in closure and everything that participates in the different abstractions that empty is going to work on we can also use something it's a little bit simpler seek which is going to do the same thing in this case but avoid extra work for data structures we don't care about another great example keyword equality huge performance boost if you just say instead of using equals keyword keyword used you word identical it will skip all the extra work that it does to have especially with JavaScript to figure out the whole equality thing and take a shortcut make it do less work therefore higher performance runtime polymorphism you're going to want to avoid multi methods again it does extra work because it's so dynamic and everything instead my advice in in actually you know trying to implement things in a high-performance way and close your script is you could probably get away with for a while with cond P granted it can't be extended from outside of your code so you're gonna make decisions based on that as soon as you know more about your problem domain you might want to actually start implementing you know def records or def types or protocols because that is gonna be the fastest ways that you can dispatch another lesson this is a contrived example but if you're gonna keep calling the same exact function inside of another function and it's always gonna same to return that same result just def it alright skip the extra function calls don't worry about it just def inside of your function instead laziness is a thing obviously enclosure in games and and tight loops like this we don't actually care about laziness we're not going to deal with infinite sequences so we don't necessarily want the cost of having to build up you know lazy sleep when it's lazy sequences and pay for that abstraction so we want to favor things like reduce over map maybe loops instead don't be ashamed of loop in closure because you can avoid creating all this intermediate stuff which also has a penalty to pay and when it comes to garbage collection so biggest thing avoid intermediate collections there's a lot of tools and closures to help avoid this but it does make a huge difference because you think about you're gonna create a whole bunch of things and just throw them out to build up something procedurally then you probably want to rethink what you're what you're doing in that particular function and in a lot of ways sometimes just break out into a loop create your own accumulator use transients if you're isolating that mutable state inside function doesn't matter right so here I would also advise just using you maybe even a JavaScript array if you need to bang away it's something an accumulative result and you're gonna do multiple steps to each one of those things instead of creating those intermediate collections create a loop use a transducer but avoid all of those intermediate collections in a procedural way some other closure scripts specific things garbage collection is actually really good I just want to throw out up just in profiling this implementation I've been working on roughly seven to ten percent of your time is going to be spent doing GC could that go lower sure is it right now worth the price of entry yes does the Google closure compiler help in overall frame rate immensely so it's it's worthwhile to take some of those penalties but be aware that you are generating more garbage as a result and JavaScript has to do something about it javascript boolean czar a mess if you know something is going to be a boolean there is an actual type int in the google and in the closure script compiler to skip all the extra checking again make it do less work use arrays and transients when you need to to build up intermediate states and then use the advanced compiler options static functions does amazing things you'll get a solid 30 to 40 percent speed boosts if you implement it in a similar way to what we described by being able to in line the function invocations take a quick look at it it makes a really big difference and then one thing that people often ask is like well is immutability really slow I've tried to re-implement all the stuff right with mutable state and like oh I'll just create my own data structure typically it's not that and you can find a lot more low-hanging fruit and in the lessons that I've learned the slowest part is usually something else to do with my implementation and not really functional programming or the closure tools that I'm using so just keep that in mind there's probably lower hanging fruit that you should be tackling and while we have a little bit of time I just want to show you you know what this stuff can look like just to prove that you know it actually does stuff so here we're looking at this is dev cards by the way so kind of mixture of documentation and so we're just gonna mock out a quick little game here we have some middleware that's running and I have my player1 we have enemy AI we have tile Mastiff collision detection there was a hunter game objects on there and we have attacking hit points stuff like that so if I want to just show how we can move around we have animations too and then I'm just gonna kill some bunnies so when we attack them with our fireball they'd have hit points and they eventually die so that's all well and good but you know some of the other promises that we have about this was like well maybe I should be able to change the behavior of this so let me go into the state and this is just Auto generated code let me go see what the state is for attacking for player 1 and it has this fireball attack as part of its attack component and maybe I want to change its you know its damage to 30 hit points ok so now when I attack things it's gonna take 30 hit points away and maybe I want to you know increase the speed so it's a lot faster across the game or I want to make it really really really really slow just because I want to fine-tune the experience of it and I can do this visually and I can see the representation of that inside of my inspector and I didn't have to write any of that code at all so what am I doing with this I've taken this implementation and I've been working on something called the chocolatier it's kind of a game slash game engine about exploration and content and been able to get this up to 60 frames per second using the advanced optimizations in the Google closure compiler actively in development and it's really all the things that I want to have when I'm spending my free time in building games and lastly let's continue to push what we believe to be the right way different tools for tackling games and things that are really complex using functional paradigms using closure we have an amazing tool set to do it and in closing hopefully you guys have seen how we can apply entity component systems to this problem domain using functional programming data oriented declarative that figure out how to do the things that we want to do it so we can focus on what we want to do and lastly speaking in front of you guys it's been a dream of mine for you know starting closure 4 years ago so you know literally a dream of mine so thank you for sharing that with me and hope you guys learned something thank you all right so we have a few minutes I believe for questions sure so luckily in the java world there are a ton of tools for doing it like your kid and things like that just to see exactly what's being created from the objects or the classes that are being generated in java lands so yes there's there's good tooling there anything related to job of profiling memory CPU etc exist the main focus so the main my main focus has been on building this for the web so targeting the JavaScript environment as you can see in there we didn't actually touch anything with rendering I kind of have a rule not to try and write my own rendering code and let the high performance libraries that exists for your environment do the work so that particular example is using html5 well using WebGL and then degrading to html5 it doesn't if it doesn't exist so I'm not actually touching anything other than to canvas except for the inspector that was that is the Dom that's react yes I'm not sure I haven't looked at it residue oh sure so the question was there's a thing called co-routines in unity in the unity engine have I thought about something like that here got it the way that I've been doing it is uh I use counters a lot and so for animation especially I'll just keep counters as part of component state to figure out what frame it should be on so it's literally the entire thing is literally state to state rather than any anything that might be non-deterministic in the middle so for animations and everything that's it's literally locked with time you can change that if you wanted to but that's how I approached it to just make it simpler so there's in the web environment that's requestanimationframe will match to the refresh rate of your monitor there are two ways of creating event loops all right not have been loops game loops one which is like every single tick is actually the next frame and there's also fixed fixed time fixed time step loops where it will try and call your code and if it's too slow it will run your game loop and number of times to catch it up so you'll have the game will run at the same speed but it will actually be frame skipping in the rendering part of it so that's that's two ways of handling it especially if like so in this particular implementation if it was like really dragging the entire game would move slower so if I know if you've experienced that with like older games but the way to solve that is with fixed step time loops to where you can actually catch it up yes there's a lot of tooling on the JavaScript side if you wanted to use physics engines or things like that in this example for collision detection I'm actually just bringing in a JavaScript library for arteries to do the to do spatial indexing easier than me having to implement it oh I would recommend it just make sure you isolate and wrap those libraries because they tend to be a lot more stateful in JavaScript but there are plenty of options for physics too the challenge might be in wrapping it in a somewhat functional way yes have I thought about using deforestation as an optimization that would be awesome so javascript is pretty aggressive in its optimizations to do garbage collection one thing that I haven't profiled a lot is what the memory is actually doing during the game loop so I think to your point there's probably other ways to manage intermediate things that might get generated as a result some of them might be opaque to me it might be implementation details of the language or in some case like the JavaScript render the JavaScript engine itself but I have not taken the step yet in memory land to go figure that stuff out yes so yes it is a penalty and so his point was if you are spending so much time in GC land you know definitely something to take a look at and old you know just a lesson from the list world in making sure you hand all memory and everything so you can be as efficient as possible great well thank you so much for your time appreciate it
Info
Channel: ClojureTV
Views: 12,587
Rating: undefined out of 5
Keywords: clojure, programming
Id: TW1ie0pIO_E
Channel Id: undefined
Length: 41min 6sec (2466 seconds)
Published: Sat Apr 16 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.