ElixirConf 2021 - Digit - Game Programming Patterns in Elixir? - RPG Battles!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] all right uh we're gonna get started wow this is a awesome turnout thanks for coming not only uh is this the first talk i'm giving at elixir conf this is also my first elixir conf so this has been a really fun time so i hope you've all been having a wonderful elixir conf um this is gonna be a bit of a weird talk and a bit of a fun one and something that's gonna be a lot more concerned with the uh how more than the why would you do that um so without further ado allow me to introduce my lovely experimental topic uh game programming patterns in elixir question mark um and specifically talking about uh rpg battle systems all right so the obligatory about me section uh hello i go by digit in the community um i am a senior engineer at a fairly large security company currently i build automated api security scanners about the farthest thing from games at the moment um i am also currently working on ways to aid in the distribution of elixir tools specifically as like packaged up cli apps you can talk to me about that after the talk if you want and i also uh developed teak tex i don't know if anybody's familiar with that but that ended up being cited as one of the inspirations for mix install uh and that landed in the elixir core which is really cool um i am a general attacker who has too many projects for their own good uh i am super curious about basically absolutely everything uh i really really like building developer tools that's probably what i like making the most and i'm a very super wannabe game developer uh you can reach me at twitter and that's my github and that's enough time talking about me okay so a quick background um the idea for this came from i was sitting on the couch with my partner we were playing a ps1 game on the original hardware and we were playing we were playing final fantasy nine uh i don't know if anybody's played that one it's one of my favorites um so i was sitting there and they were playing the game and i was like man this battle system is really cool um i really want to make this an otp that sounds crazy uh so the difference here with this specifically this battle system it was called active time battle abbreviated atb in the game uh and it was introduced in the fourth game is used in the fifth and the tenth i'm sorry the fifth the ninth in the second tenth game thanks uh final fantasy for that um every character in the battle system gets this little gauge called the atv bar and uh when it was full then your character can act so rather than like this person's turn then this person's turn then this person's turn it's kind of like this real time thing where everybody's speed stat is like ticking up this bar constantly in real time and then when it's done it makes a pleasant little sound and you can make your move and the enemies do the same logic their bar is just hidden and that sounded awesome to try and build in something like otp so i submitted this idea uh for a talk it sounded crazy um and then i got an email a week later that said i had a slot so then i had to build it so the rest of this talk is about how i managed to build something like this and both the good and the bad ideas and here's just a screenshot of final fantasy 9. um that green bar at the top there that is the adb bar so like that fills up and then you can just like scroll back and forth between characters if like multiple are ready it's very nice so big disclaimer games are hard they're really hard to make um and there are some really potentially terrible ideas ahead but if that excites you then this talk is for you okay so if you think about it at a high level a game is really just a bunch of assets and some gameplay systems and basically the assets are displayed in accordance to the rules of the gameplay system uh that's like the most abstract way i could describe a game and generally all that sits on top of some kind of high level api that's usually called a game engine and so that could be like unity or unreal or any other kind of game engine and they usually provide you with access to lower level things that you could care about like graphics and input and how to manage entities and how ai works and all sorts of memory management systems and i could stand up here forever listing the amount of subsystems in a game engine and i'm not going to do that instead the ones up here are the ones we're kind of concerned with um and of course all those sit on top of some kind of hardware abstraction layer um great how am i gonna make that work okay well cool we already have the beam so that takes care of all that hardware abstraction it just works on most platforms that we care about this is elixir conf so of course i'm going to use live view for the input and the graphics layer because why not and this over here this is a bit of a question mark i how are we gonna represent these complex uh behaviors because we're gonna have like i'm ambitious i want like i want different weapons and different spells and i want like effects over time and like status ailments and all sorts of crazy how are you going to describe all these things in a way that's not going to make me burn out in five seconds uh well there's a cool pattern that i learned from doing a lot of hobby game dev outside of elixir that's called ecs raise your hand if you know what ecs is okay so a couple people awesome so this is a really common pattern in game system developments so this will be a review for the people who raise their hand but ecs it's an acronym it stands for entity component system and the best thing about it is that it is data driven and that is mainly the reason that i went with it i really like being declarative with my behaviors and ecs lets you do exactly that so the quick overview uh entities they are literally just a lightweight id or a representation of something in the game world could literally be anything could be a rock it could be the player itself they don't have any behaviors on their own they contain components i put that in quotes because in pure ecs implementations uh sometimes just an integer is used and they don't have actual like a list of components that they own it's more so just like a loose collection of components and then an id references those components so if you're catching on the components as a collection make an entity whereas the entity is just this like light container that like references all those components they are the thing that we're going to span all the domains uh domains being your gameplay systems so they're going to be threading in and out of like an input system and the rendering system and whatever system they're going to be called in and out of all of those these are the things that are going to be passed around a lot a component is the easiest part of ecs it is a bag of data and nothing else you don't you maybe put some methods in it to help mutate the error change the values but they do not contain gameplay logic again in pure ecs some engines like unreal and unity have an update method every frame for every component that's not pure ecs pure ecs is just there's just data in the components there are no there's no gameplay logic you can also use them to tag entities so if you don't want to put any data and you just want to use them as like a like a white label just print out a label and stick it on say this is an enemy you could do that too finally the systems these are the fun part uh they are functions if you think about it they're the domains of your gameplay systems and what they do is they query the the storage of entities or the collection of entities in your world uh looking specifically for components they care about so if you have a rock you don't want the input system to look at the rock because why would the rock need to know about what is going on in the input instead you would just want the input system to go to things that have an input component so it's like a lock and key where the components are the key and the system is the lock so how did i map this to otp this is where it gets super opinion land um so entities i really like processes do you like process i love processes uh in in some words of of uh joe armstrong he really liked to think of mapping a lot of things to processes um some i think somewhere he actually was like we could map the atoms in the universe to processes um which i thought was inspiring components we can just make these struts or maps i like structs because they have more type typiness to them and our systems are just going to be functions because what they don't need to be anything else i don't think graphics and input yay live view um and uh for if we need to do things like an observer pattern we're in the beam so we just have message passing out of the box so we don't even need to worry about that awesome okay so we got our concepts mapped uh i like graphs i don't know if you like graphs i like visuals so let's pretend this is what our world is going to look like we know that we're going to have some collection of entities that exist there they are nice little pig cubes and we know we're going to have a live view display and we know that these entities are going to contain some components some kind of data attached to them we know that there's going to be a list of systems that are going to be mutating all of the components data every frame or every tick of this engine and the thing that's going to tick the engine is some kind of timer some kind of consistent time interval so that we can have this simulation evolve over time we're going to have some way to ask for the entities that a system cares about because again brock doesn't need to know about input and we're going to take that information that we get from the entity store and we're going to just pass it to the systems that care about it and this is going to happen every frame we're going to say every frame what's the state of the input mutate the components that care about the input state and we're going to do that for all the list of systems finally our live view is just going to be a portal into the state of the simulation world and then we get to look at that and it looks pretty instead of looking at a bunch of text that's a fun diagram okay so how did i deal with the world so here's a little snippet from the world is a gen server it has a few key components i'd like to point out the first one is the clock ref this internally uses an erlang timer i think it's called or an interval um there's a thing about those where uh it doesn't actually guarantee it'll be exact but it'll be at least the time you ask it to tick at and that's okay because games drop frames sometimes and luckily we have a very simple math trick that we take care of in the update methods it's called delta time we just take the time between the first tick and the next tick and then we integrate that into our math equations then we know that things will be consistent whether or not the tick was the same length or not i have a bunch of casting functions for like pausing and resuming and adding a system and adding an entity to the world so at any time i can just chuck a new entity into the world and it'll start being simulated and uh in this very gnarly looking thing down here i put the tick function so this is what gets called every tick what this does is it goes through all the systems and it executes the system uh in a loop basically it'll just go through all the systems and call this wants function and this wants function like i said will give back what that system wants from the components so a system declares like i want input i want entities that only have input and sprites and so that's what that system will get when it gets called in this loop here it'll just get the entities that have those components here's the entity store i used a weird module i didn't know existed in erlang pg2 i had no idea that this was a thing it's very cool you can just group processes and pids based on an atom which is perfect because i just need a really quick way to query things um and the thing about this is i just kind of stick the world name because i want to have multiple worlds running in my application so i can have multiple people running multiple games at the same time so all everything's name-spaced by the world and i just use module concat to smash those atoms together and i get a like a kind of compound identifier for an entity so i just have a couple methods that you can pass in either a list of components or a single component and you can say i want entities with this list of components or i want entities with at least this component so pretty straightforward fun fact i learned that pg2 is deprecated so that's fun okay so how do i that's great we have an engine i guess uh how do i author content and this is a part that i really care about um as somebody who has a kind of like both parts of my brain and like systems logic and also art um i you're not going to be the only one writing things for your engine or for whatever game you're making you're going to have to hand this to scriptwriters and gameplay programmers and scripters and all sorts of like artists how are we going to provide a nice interface for people to make things in uh what if one of my friends wants to make a new enemy i don't want to have to have them learn elixir to like write all this stuff uh and you know of course i i did what any uh functional you know sane programmer would do and that's to write an entire dsl for it um so here it is this is how you define a component in my dsl it's pretty straightforward you just use the dsl component module and then you can say okay i would like to define a component here is its name and here are the values that this bag of data contains so this is now a reusable component because if you think about it this is not just going to be used for the player this is also going to be used for all the enemies and everything else that might have stats so you just kind of bundle up that data into a component and then you're set and you can just slap this onto any entity speaking of the entities this is how you define an entity you can literally just say i want to define a component so at the top there it's the same component as the previous slide you can just override some of the default values if you'd like or you can just leave them as default you can see i'm defining an entity here i'm giving it a couple components i'm saying it's got an actor stats it's got sprites it's got an actor name it's got a npc brain we'll get more to that later and it's got an active battle component and all the entities are defined like this just all in this little little micro dsl and of course systems are also defined in this so uh the coolest part about this is this wants up here so remember how i said systems need to declare what and what kind of entities they care about this is where you do it you say this is a system and it cares about things that have this component and this component in this component and that's that's all you have to do you just say wants this component and then you define a tick method and in this tick method you're acting on one entity and this is where you would do your mutation for one tick of the game so this is the type of thing that would do the the atb bar filling where it would just try to cap it off at one otherwise it would increment it by one based on the speed and that delta time being that's that's that math trick i told you about how it doesn't matter if the frame is like longer or shorter you just integrate that in and everything will be consistent per frame rather than if one frame takes five seconds instead of one second or something ridiculous oh the other cool thing uh because this is a dsl and macros are ridiculous in elixir i can throw compiler errors when i do dumb things like try to use a component that doesn't exist so that's fun i like when the compiler yells at me it tells me i do bad things okay now on to the next section there's a lot to cover i'm going really fast but hopefully we'll have time for questions at the end so defining gameplay i went about this by basically figuring almost everything could fit into the ecs framework however i did notice that there were some things like graphics like the live view system input and a couple other subsystems needed their own supporting external architecture with the base in place though i could compose basically any kind of entity i wanted in the game once i had the ecs dsl ready i was it took no time to make any new kind of system or component oriented it was just very pleasant to work in all the systems are just going to handle the gameplay logic and uh honestly it feels like magic when it starts working because i just be like here's a player they have poison slap a poison component on them now the poison system suddenly sees them and starts decrementing their health automatically it's like magic it's really fun to watch it work ah this this was a fun part so i don't want the enemies to just sit around doing nothing because that's boring uh so i came up with the idea of attaching a brain component to npcs and uh what this does is it loads an exs script and then caches it and then i have a special scripting system that every tick if it's ready and can act it will read that excess script and execute it so i could define all the brains as just one-off script files so that would let me define more complex behavior without having to write anything you know super good i could just write some some little script um it would execute within the context of the world it was nice and easy it was lovely uh bonus i could hot reload the enemy ai while the simulation was running because it's an exs script um which is phenomenal for uh design iteration that kind of thing in a game design system is like you need that okay so sneak peek that's an enemy um so shout out to my partner who made all of the art um so here is a brain script for this very simple entity uh it's very simple uh there are some common things that get defined in all the brain scripts uh in this case there's a list called player characters which automatically returns a list of pids of things that have input components or things that are under the player's control so they're basically targets for these enemies so i would just basically just pick a random player and then i do a five flat damage across them by doing an action type and we'll talk about the actions in a second but all this does is just set up an action and then executes it immediately all right so building more off that action stuff actions get pushed into an input server which has a system that evaluates it and just like pops the queue and evaluates things in order so that events happen in the correct order a specific system is the one that really like deals with this uh so i think it's called like combat system or something uh this allowed all the input logic because sometimes there's some messy conditionals uh to all be encapsulated in that system and i didn't have input stuff like like spattered all over my code it was all just in one module uh and the other cool thing is all the input code was generic so you clicking a button to attack something and something attacking you all use the same code path because they're all just the same kind of action so here's just some helper functions and some of the types of actions that the engine defines you can just easily define them by making an atom some of them have specific parameters so it's like you can do physical damage or you can do magic damage or you can heal or you can restore mp or you can give a status effect to something and anybody could call these and they would just execute at the next tick hey it's live view time yay all right uh so when you join the live view i start link a new world so i spin up a new world i give it the i give the pid of the live view display to the world so that i can tell it when it needs to draw and really needs to update i kept a back buffer i put that in quotes because it's not really a back buffer that's a real graphics term but it's what i sort of what i treated it like the back buffer is just where i stage all the drawable things in a frame before i'm done and then when i'm done i just say okay swap it and then that's what gets displayed to you so i can work on things in the background because like some things might be in between states and then i flip it to the front that's a real thing that happens in certain graphics programming but i just use i reuse the term i wrote some protocols that handle all the different kinds of drawable components on the front end and input was again using that common code path i just send it into the input server and it's all taken care of so uh in my live view this is not the best live view but it sure did work um i go through all the drawables and i draw them um that facet down there that is the protocol uh so that just takes in a drawable component and the assigns and that's the protocol up there very fancy and down there is an implementation so you'll notice this uh that active battle that's the same name as the component so you if you want a component to be displayable you just go make a protocol implementation for that component name and you can just draw the values here so you can draw them as whatever you want in this case i'm drawing like a span i think it's like a styled progress bar or something for the for drawing the atv bar and there's just a bunch of these there's like some for the sprites there's some for all the different health bars and there's some for like the entity window you'll see it'll be fun um okay so putting it all together um it's cool to watch it in observer because you can actually see like the hierarchy of everything so like there's our live view page and there's our world and below it is the input server and and those are our entities that's it's really fun to like see them all like nicely like in a hierarchy laid out and if if you disconnect of course all of it goes away you could certainly disconnect it and like have a supervisor and like do all sorts of other fancy things to like maintain the persistent state of the world but i did not do that okay it's time to see it in action and this is the this is the this is the part where things go really good or they go really bad so we're gonna see so i'm gonna throw a terminal over on this here all right now fire up the the old front end okay okay so i went with a bit of a retro theme so this isn't the most impressive demo but it is kind of fun uh so i can i can kind of manage some stuff here i'm gonna open up the debugger um this lets me look at a couple different things for example uh here's the live view pit it's telling me i have no drawables and there's no world so i'm going to create a world okay so we have a world now so you'll notice all of those systems listed down there those are all the gameplay systems defined there's like all sorts of fun ones one of my favorite ones is the reaper system which is the one that cleans up dead enemies so i'm gonna unpause the world so now it's ticking in the background it's actually doing like a tick rate uh let's spawn something so remember the whole point of this was to replicate the atv system where like it loads and then you can act right so let's let's spawn let's spawn a guy there he is and he's ready and there he goes and it works but there's so much more we have enemies remember this guy he's back do you remember what his brain does anybody remember five damage you're right how much health does this guy have uh i have bad news for guy we have another kind of cone and it's a little faster he's got a higher speed stays taking damage oh no oh and he's gone isn't that sad you know who else is sad this sad cat let's see what he can do i think he might be able to do more oh he can do much more he can shock and he's frozen their atb gauges that's handy that's a nice little status effect he can do i don't know if that's enough let's give him some more help here's here's here's a little soda dispenser robot let's see what he's got soda bot also a fun fact you can see the pids up here for all of the entities oh he's low on health now he's got it he gets they all have little special and let's get through this guy get out of here he could use some healing let's heal him so he's gonna cast it's gonna take a little bit to cast the spell and he's healed look at that that's nice i love teamwork oh we're gonna get rid of that guy we're gonna get rid of the guys soon i'm doing so good on time this is wonderful i could do this for days uh okay let's just get rid of this guy great wonderful look at that a battle can happen that's wonderful uh i'm gonna go ahead and give a refresh real quick and i'm just going to show off one more thing here and open up the debugger so you can see it i'm going to unpause and i'm going to spawn so the enemies can have way more complex like behaviors so this this guy here i love this guy he uh when he has no friends he um he does this he does this kind of thing where he just he spawns some yeah there he goes so now he has friends he has a bunch of other things where if his health is below half he starts doing crazy i'm not going to have time to go over all of this unfortunately but uh i am going to open source all of this uh in the coming days so you all can check it out okay back to the slides thank you [Applause] okay i have some conclusions because remember this is all some insane experiment um okay let's go over the whoopsies the gotchas and the bugs uh live view um i never opened inspector for a reason but this is good local uh i would not recommend deploying it to a server on the other side of the country and expecting the latency to be good um i didn't spend any time optimizing the wire across the the data across the wire there were definitely ways to do it in fact a lot of things chris mcgurd talked about this morning i was like i wish i had that uh so i might check that out um okay so the entity data store uh pd like i said pg2 is deprecated in otp24 and i did not know that uh pg is the new one but it's missing some things and i'd have to do sets on my own and i just did not feel like dealing with it and it was like a month out so i just kept using pg2 uh i could honestly cache some of the results of asking for what entities have what components because if you think about it in the scheme of a few ticks uh it's not often you're adding or removing components to things so you can really get some some benefits there by caching stuff uh race conditions i ran into only one while developing which i was very happy with uh if you don't know what that would mean here it would mean that something red from a pid and then like in the middle of doing something something else wrote to it and now we have bad data that only happened once and it was because i just did something stupid um yeah uh things that i would do if i had more time to work on this uh i would make a webgl based front end instead of a live view one um live view was just a fast way to get some images on the screen uh i would want a more expressive query language for querying for entities so saying like has this but not that so then you could really have like a really powerful system like definition and saying like i want things that have poison but not this item or like anything like that i want to decouple live view again i really just want to remove live view from i mean don't get me wrong it was awesome to get it working in live view but i really wanted to do the webgl thing i just didn't have the time i wanted to make a more scene graph like tree where i could like define the order of the components um right now they just like draw top to bottom and i'm using a bunch of css hacks to like keep them in the right order uh and i would write a dsl for defining those protocols because i think they could use some some face lift there multi-node multiplayer three question marks two um i yeah i could i have to be careful about more atomic operations on the entities but the cool thing about pg and pg2 is you could actually have those entities scattered across multiple nodes in a cluster and you could still read from them and it'd be great uh so you could totally have like a multiplayer system and all sorts of other fun stuff if anybody wants to figure that out that'd be cool okay so misknotes macros are extremely overpowered and elixir wow i love them they are awesome i almost want to like i want to use that dsl to define gameplay like even outside of this little like toy project but it was just so much fun and so easy to to write um i already have plans for like dsls for things outside of elixir like writing dialogue trees writing proc gen rules all sorts of little dsls to like help aid in game development this isn't the first time that i've heard people using functional language use in in game development a notable example is uh naughty dog one a very large company they use i think it's a scheme dialect they use a scheme dialect for a few different things and one of the reasons they like it is because it blurs the line between functions functional stuff and data they use it as both a data definition language and as a scripting language if you've ever played jack and daxter on the ps2 everything is like a lisp language in that for like the gameplay scripting it's really cool i think elixir has a promising future in some developer tools you know so even if they're not bundled in the engine or anything right i think that they have the ability to have these really great command line tools these great command line scripts dsls for defining data definitions i think there's a lot of potential i initially went in expecting all the async elements to be like in otp to be the big star and it was it was like awesome to have all this working out of the box um but also those other features i just mentioned were a huge like benefit while writing all of this and one of my most wishful things i would love to be able to actually use this in a game engine as a scripting language there's a project called atom vm i forgive me i don't remember who is the author but it's a tiny little c uh beam implementation it's not complete yet um but i i have some back of my head thoughts about how to integrate that into an engine so i'm maybe we'll see we'll see i have some special thanks to give out um my partner for doing all of that character art and the animation they did a fantastic job um the elixir com staff and organizers for accepting this ridiculous idea and all of you for coming that was it means a lot to me that you came to see this so thank you very much i i have some time for questions i think i have like 10 minutes for questions which is great um and if you ask a question i have stickers of the characters from the demo and you will get one oh there's a few okay let's let's start let's see yeah i think it's something like so it's hard because there's not like i had to do some weird math to like figure out the milliseconds but i think it's equivalent to 30 fps constantly you could adjust it to anything really what's the size of that set of like all the atoms that you can concatenate did you run i i didn't run into any issues i imagine you might like yeah so i you could potentially blow up the atom table but um i don't think you would because you probably would only have a few hundred maybe a thousand components in like a large game and there's i forget how many items you can have a lot of atoms in in the beam so i don't think you'd run into that issue um unless you were running like tons and tons and tons and tons and like multi-node stuff maybe then you'd be concerned um and you might want to namespace it a different way yeah it's completely handled out of band the way it works is it just pushes it just throws the drawable things at live view and liveview just takes care of it so you really could swap that out with anything you could you know yank out the live view component it's the simulation world is actually a separate project it's like in a different folder um yeah i mean yeah you couldn't you could do that absolutely um i i just wanted to try and implement like a pure ecs system so like i only use data i actually also only made it so that the data could be uh like one level deep so like you couldn't put maps in components because i wanted like i didn't want to have to do like deep map updates and stuff like that because it can get expensive okay yeah yeah so i just track uh the time from at the beginning of at the end of the last frame i just stole or store away when that frame ended and at the beginning of the next frame i just subtract the timestamps and then you get the delta time between the last frame and the frame you're currently in and so that is what gets passed into all the systems is delta time yes yeah you inform the system every tick here is how much time has passed since your last update so that it knows it can compute correctly to compensate for how long the delay was yeah you can come find me after the target everybody who asked questions can find me i got a logo okay i got a bag of them so yeah yeah there is the only persistent thing in the world is the entities the list of systems and the delta time uh the systems themselves persist no data they are stateless so what they get in is just the the state of the components at that tick they mutate it based on their rules that are defined and then they you know store it away in back into the the component um and then the system just is it's it's it's it's stateless they they have no uh state you could for some things like in a real game engine a lot of time you'll have a system that has state like the controller state and stuff like that you keep that in the input system and then pass that to what you need but in this case they're all stateless yeah what's that what about rayca i don't unfortunately i don't have um like a like a grid for for actually like xy positions you could absolutely do that though there's nothing to stop you like i said that live view like view stuff is like just bolted on so you could view the simulation running but that engine is generic enough where you could make if you have a vector type or you define a vector type and you kind of extend the dsl to accept it you could use it as a component and then just have position and give things positions and now entities suddenly exist in a grid and you can start doing things like raycasting yeah two questions no there's one more question here i was about to ask would you do this again but it seems like you're gonna extend this i i don't know if i'll extend exactly this i'm definitely going to open source it at some point i'll clean it up and open source it uh but i think my next step is definitely i want to do a lot of more like some serious game dev projects and hobby stuff but i definitely want to find ways to use elixir in that pipeline because the whole reason why i did this is i wanted to take elixir from the start of game development to the end like all the way through no matter how crappy the end product was and see where it stood out and that like dsl section was like really where it stood out to me and how you could do the data definition so i think i'm going to find ways to use that um maybe i'll try to like integrate it into unity or something we'll we'll see something crazy i like doing crazy things yes oh it's a change from pg2 to pg i i do not remember exactly but i think there there was just something about the way that the api was exposed through pg that it was lacking a function i'm gonna have to look it up i don't remember yeah i considered using annette's table yeah i just i i liked processes and i thought the idea of modeling them was really elegant as processes and so i just ran with that idea but yeah i think that's a totally valid way to store that data too so everything everything is is in components like that's where all the data gets stored so like if somebody uh if the state of like something changes it's recorded into the component by another system so that another system down the line will pick it up and read it um so it's like the ai system was like if they're ready so like if their atv bar was full execute the script that is defined in their ai component so like the ai system is reading that data yes yeah everything is just reading and writing the components that's all that's all it is it was only in one everything is uh siloed in its systems like only ai logic happens in the ai system um it only does one thing yeah yeah so you just have to you have to be conscious of the ordering of the systems um which is pretty straightforward um you can do some more fancy so unity has its implementation called dots data oriented something and uh it has a way you actually declare dependencies and it tries to actually like pack them into a way where it like parallelizes as many systems as it can while keeping dependency order in check i don't have any fanciness like that so i just have them straight run top bottom i thought about allowing like a parallel like true flag and like how you can do that in tests in ex unit where i could be like this system is safe to run parallel go ahead and parallelize it but i didn't do that but yeah that's a good point you do have to be aware of that all right i think i'm out of time thank you so much
Info
Channel: ElixirConf
Views: 1,215
Rating: undefined out of 5
Keywords: elixir
Id: gQb58bqwDOc
Channel Id: undefined
Length: 41min 33sec (2493 seconds)
Published: Sat Oct 23 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.