5 Powerful Code Patterns Behind Roblox Games with Quenty, AxisAngle, IntegerUnderflow,and Badcc(RDC)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so we're assuming that you know object-oriented programming services and like single script architecture so if you aren't familiar with these then potentially this isn't the talk for you um but with that being said we think this is going to be a really good talk so i'm james anand and we also are presenting with us trey reynolds alex balfranz and lucy sweet um so with that uh we're going to talk over these five powerful code patterns and with each code pattern we're going to associate it with a roblox game so we're talking about signals maids promises springs and binders and then we'll be taking questions about each of these in the devs code patterns channel in the discord so post your questions as you come up with them and then they'll be selected for the end so why these patterns all of these patterns help deal with asynchronous and dangerous operations in roblox and then problems that we end up creating when we're using these patterns so we have some really tricky problems in roblox that these help solve so like signals help handle user input maids with memory leaks promises with data stores and web requests springs with animating things and binders that streaming enabled and other decoupling of code and inherently all these patterns decouple your code and so the metric that we're looking for is how fast can you delete a module of code from your game and all these patterns help you do that with that being said i'm going to talk about signals for event driven games all of these patterns are used in these top games but we're going to look at whatever floats your boat into an extent when light bay for these signals so first of all you've probably seen signals before you use signals to decouple your code and there's several strong patterns with these signals the caveat with signals is that signals may memory leak so we're going to take a look at these signals here the philosophy behind signals is really simple you should observe the world don't query it observing the world is something that signals do very well so the way signals work is we've got a signal here and for each event we have a notification to each observable and you can disconnect these so if you've written a connect line of code in roblox before you view signals roblox programming is very event driven and this is really good so we use this all the time the contract behind signals is pretty simple when we connect to a signal we give it a callback sometimes this is an anonymous function you'll see it like untouched or on dead or something upon the connection we get a connection object that we can then disconnect so we can cancel the connection and then when we write our own signal wrapper we use a fire event that we write ourselves um but when it fires then the signals will call each callback in its own thread um so signal based code is something that looks a lot like this we connect to the connection and we do work when something changes in the world whereas querying is like a loop based thing and the signal based code has several benefits to it first of all signal based programming reacts immediately so looped-based stuff will take a little bit of time to get around in this case half a second you can also cancel connections at signals which is a really really good pattern so maids are perfect for this we'll have alex be talking about that in a bit and then uh the other thing is like errors don't propagate in signals so in a loop-based code you can have errors that occur and it'll stop your loop from executing but in signals the signal will continue to be connected and fired off even if an error occurs so this helps decouple your code further so in this case here with the humanoid diet event occurring three times we loop and connect three times if this was in a loop we would only get one high here but if uh it's in a signal like we have here it'll actually error out three times and print three times so that's pretty cool and it'll print with this i um so there are some distinguishable signals first of all there's a little bit more indirection this can make stack traces harder to follow they're also a bit more expensive to operate but it's not as expensive as querying the world every frame so you should probably still be using signals and they can memory leak so we want to disconnect all of our events and this is the biggest problem that signals create and maid's help handle that in practice we have several ways we can leverage signals and we're looking at whatever flights you put here so in this case we've got this backput input control and we're listening for the tab added and tab removed these are custom signals we added and what we do is every time this changes we're going to call this update hotkeys method and it's going to loop through all of the tabs which we know just changed and assign the correct shortcut to it if we find a shortcut so and we also the really important thing here is we also call this update thing online 60 when we initialize to make sure we initialize with all the correct values so this helps bind the state of the tab control to this input control here we also have a really common pattern with signals where we pass anonymous functions instead of named functions in so in this tab request activate thing in this backpack to tab adapter we can do work on this anonymous function we're on this backpack item thing in this closure and we just listen to the activate event here and then we do work when it activates so this is also a really good way you can avoid making classes using closures and signals so this is really good um so a custom signal based code is another really common pattern so one thing i really recommend is you use this like signal class here and then when we activate or deactivate signal we can do work on it so in this case this is from one light bay we have basic keymap controls and what we're doing here is anytime the keymap controls are activated we go ahead and uh we add some haptic feedback and a little bit of camera shake and maybe play some music for a sound effect and so what this does is it helps even though we just created a signal here and this class is the one firing just activated it is easier to decouple this feedback and have it only in one place by listening to the signal we expose in this keypap control and these activated and deactivated methods are also exposed for other modules to listen to the 3d structure of the hat and the behavior of the hat so what does this mean what does coding in the metaverse look like fundamentally i don't think we know yet what i don't think it looks like is a text editor suspended in three so we'll talk about remote events first um so a lot of people like to pass things through a single remote event and they think this is a performance improvement or something it really isn't um it is better to structure your code with remote events uh and i really prefer putting remote events underneath um existing objects like this so you can resolve them um it's also really you have a lot more context that way so additionally with remote events i if you have a global remote event for like this reset service um i generate that with a constant so you can see here i'm getting this remote event name and i'm getting the remote event from that constant so retrieving that on a client and constant is usually the best way is what i found but in general remote events for instance are really good and then also you should really use value-based objects for replication value-based objects are really good and attributes will replace these to an extent but they don't exist right now so for now you should prefer value based objects and they expose a changed event they replicate automatically they type check for free and they throttle replication the 60 hertz so all these properties are really valuable and the big thing is even with attributes you can use them without parenting them so you can put them in your own code module and use them and they expose a value that can be changed and it replica and it will debounce all of the changes if it's the same value so avoiding value based objects is like a really bad idea i tried this for several years and it didn't work out so i found it's like really really powerful to just use these the other pattern we have here is bindable events i don't use these directly because they recreate tables so you can see here it's serializing this tablet and we get a different memory address when we pass it through the bindable event so this is really expensive because it has to go through roblox's serialization system instead what we want to do is we want to wrap this in our own custom implementation of it so we don't recreate the table so what we have is a signal class here and what we can do is we can fire off changes so in this case here we have a dialog slider and anytime it changes we fire off the selection confirmed event and one thing i like to do is output the or like comment the values coming out of the signal so i can see what's changing with that being said signals have an issue they can memory leak an anonymous function can keep a signal alive especially if it's connected to a roblox instance that is now parented to something else and so the lua garbage collector will never never collect your stuff so the best practice is to connect disconnect all of your connections you can call disconnect on them there's also a destroy and clear all children method which will disconnect all connections on the instance and then clear all children on all children instances so uh what we do is we use maids to help leverage this and so maids are really good here so with that being said you've seen signals before user input comes from signals other things coming from signals you should use value based objects for replicating like constant values and there are several strong patterns with signals so leverage those and memory leaking is an issue so with that being said here is alex to talk about mates and how we can deal with those thank you james hey everyone this is alex bell fans from jailbreak i'll be talking to you about maids james just talked to you about signals signals are great you should use them everywhere i know i sure do and maids help you use them better so um first summary of maids maids think you make you think about memory leaks from the start they encapsulate cleaning things up it makes state easier to manage and they move cleaning up cleanup code to the constructor rather than destructor so the main philosophy behind maids is a singular object to clean everything up so to create a maid first you'll require the made class and then call made.new on it and this will return a lua class which has a function exposed called give task and to give task you can give functions connections or anything that implements destroy so this can be a roblox instance all of which all of which implement destroy or a custom class anything that has a destroy function um you can give this to a maid um so when you're ready to clean up everything that you've given to a maid so that means you know if it's a connection it'll disconnect the connection if it's a function it'll call the function or if it's an instance or a class it'll call destroy you just call do cleaning on it and this do cleaning has an alias called destroy so you can actually um that's handy because you can just call destroy which means you can give it to other maids you can have a maid clean up another maid because it has a destroy function um so maids in practice let's look at where i use some maids in jailbreak so when you first start using maids the most common use will be cleaning up signals so here i have a region glass which exposes two events on object added and on object removed for whenever for example a player enters some um defined region and i give these events to a maid so that whenever the parent class whatever instantiated this region whenever i clean that up it'll disconnect all those events so that we no longer are waiting for any signals from people entering or leaving the region and then on the right here um same thing we have some signals being created here i'm actually giving the signal instance um or signal class to the maid which as james said is a little overboard but it's good to be paranoid about this because destroying the event will disconnect all the connections it has as well so if you know you're done with the event um and maybe you forgot to put you know add one connection to your maid you can just destroy and they'll clean it up for you it's a good idea to use maids in an object this is where they shine the most so here i have a rocket launcher and this gun.new subclass creates a maid and you see at the bottom i'm using the maid so i have this rocket world class which handles the simulation of all the rockets in the rocket launcher and here's an example of putting cleanup next to construction so immediately when i create the simulation class for the rockets i'm giving it to the maid so that when i call rocket launcher colon destroy this is going to clean up that entire rocket world simulation class so this is an example of using maids within maids because the rocket launcher has made and the rocket world also has a maid and i'm giving the rocket world class to the rocket launcher made you can also use keys to handmade so i talked about give tasks but you can also just index them and this is handy because here's an example in jailbreak where we recently added helicopters which can pick up cargo crates and you can carry them around and i wanted to do certain things like crush the player or make a sound when it hits the ground but for example touching the player or certain other things i wanted to actually know who the player that dropped it was so one way was just to reconnect that touched event every time you drop the crate and so with indexing maids if a connection already exists you see i do self.made.touched if one already exists it'll first disconnect the old one and replace it with this new one so that's super handy and make sure there's only one connection alive at a singular time [Music] maids for deferred action um so this is uh using anonymous functions you can pass to maids so here in the i have a um we have game modes in jailbreak and um this one is the alien game mode when you drop the players it kind of it changes your outfit to an alien does some other things give you some items and so instead of like making sure that i clean this all up um you know when i called destroy i just write away when i drop them into the game this last function where i give an anonymous function to the maid i make sure that i restore their inventory and reset their avatar and so it's really nice just to see that like right when i change their avatar in this drop player function i'm also restoring their avatar so i don't have to worry about forgetting that um you can also do some slightly more complex logic so here you can think about that rocco world class i don't want to stop the simulation of all the rockets in the rocket launcher when i destroy it so you can imagine this code being inside the rocket launcher destroy method um first i wait to make sure all the um like if there's currently rockets flying through the air i wait for that rocket q that queue to be emptied and then i finally finish all the cleanup otherwise i just destroy immediately so maids can give you some really nice complexity for whatever you want to do so maids in summary they make you think about memory leaks from the start they encapsulate cleaning things up and they make you stay easier to manage and they also move your cleanup code to the constructor rather than the instructor and now i'll pass it off to lucy thanks alex uh hi everyone i'm lucy i'm a systems engineer at adopt me um so um a quick bit on uh if i got control i think i do oh no i've gone too far go back one okay cool um yep some assistance engineering adopt me i'm listening as well um so quick bit on uh yielding uh yeah here we go so quick bit on yielding as behavior yielding occurs on roadblocks when you um call a yielding method which needs to get a result but it might not immediately have it so network requests um isn't group http service data store service etc um it's pretty intuitive and easy to sort of hide in the background insofar as it will suspend your current lure thread but it will allow other lure threads that are ready to run to run in the meantime while your one is yielding and getting its result um that can be quite useful and intuitive except um if you don't realize that some of your functions can stop halfway and other code can run in the meantime it can cause some pretty nasty race conditions um and it can actually be quite hard to spot when things are going to yield so for example you may call out to a function that you don't realize is then calling a yielding method or it may be a method that you don't even know yields like izing group for example does not have async after it but it does yield um beyond that um yielding is just a behavior it can't be represented observed interacted with it just sort of happens in the background so that can make um concurrent operations so and other things in that area a bit annoying sometimes i've got a few examples on here so wouldn't it be nice if there's something that did it for you well or sorry gave you these sorts of abilities what there is and it's uh promises um so in in brief uh promises are a way to represent a task that will either um complete or fail at some indeterminate point in the future and by using promises you not only get observability onto that task but you get access to a lot of cool methods and patterns that you can use um so making a promise is pretty simple this is insofar as the library written by ivera that's available on her github there are other libraries available just not as good um that's my opinion though um so that's the one i'm going to be referring to in this presentation um so this promise here simply reached out to http service it downloads the website and then it completes the task by passing the website to this little function called resolve which is pretty ubiquitous to what return would normally do in a lure method um it completes the promise and it sets the returned value to the value passing to resolve um promises make yielding easier to use and harder to misuse so it's important to note that um when a prop when using promises there's no yielding on the main thread unless you cause it somewhere else so you're a reduced risk of accidentally introducing some nasty race condition due to yielding beyond that you can observe the state of your promises in your tasks and you can check if they're finished um as well as deciding multiple callbacks to run for important events in them for example the promise completed successfully the promise failed with some sort of error so you can handle those a lot easier and more intuitively um so yeah as i touched on a bit earlier that promises give you access to useful methods so i'm going to go over a few of them now um and only only a few of them and the rest you can look up in your own time though so promise cancel um gives because we have observability on these tasks we can start to interact with them so promise cancel gives you the ability to cancel a promise before it's completed um it can be really useful for example if you want to preserve resources by not executing code you'll no longer need it anymore so cancellation is best effort and there's no guarantee as to when that as stanators instantly stopping or anything like that but you can say that library will do its best to hold it in the future um so here's some example code it's not really great code but it's an example and then none of this code for the record in any of this talk is used in adopt me um so in this example we have a yielding and pretty expensive function being called um when a player opens a leaderboard we make a load of expensive calls let's say it's like all the data store service but what do we do if the user quickly closes that board it would be a waste of resources to just load the whole ball that nobody's going to be looking at so normally we would end up just wasting our day store quota because the function's been called now you can't stop it but we can cancel the promise in this case and preserve all our resources um so that's cool um promise and then it also takes advantage of the observability it um lets you subscribe certain callbacks to run in response to the promise executing successfully um so exact for example here we've got that um example from before creating a promise that i used where i made one that reached out to a website um and then after that once that completes successfully um we print the content of that website straight out to the output if there was an error here this code wouldn't be executed at all um what would have or sorry the callback wouldn't be executed at all if you want to hook into an error happening on a promise you use catch and if you don't hook in and it does error anyway it produces a warn in the standard output of roadblocks that you can see um so and then calls can also be chained to run one after the other so for example here our original promise is returning one and then we have an and then that uh adds two to that and then we send that to print and you can see i can now put in studio for free so that's quite cool so promised at all um promise to all um is a bit different from the others in that it's not a method on the prompts itself it's uh a method at the top level of the promise library what it lets you do is it creates a um promise that encapsulates multiple promises in and you can treat them then as a single one so when you add a load of promises to promise at all that promise that you've created now that groups them all will complete if all the promises under it do and it will fail if any of the promises under it do so that can be really useful for example if you've got a load of related tasks that you want to basically treat as one big group so for example here i've got some example code of what might it might look like and adopt me where um i have a load of little a load of different tasks i need to do before i can swarm a player into the game loading their house their money and their pets and things like that um and rather than listening to every single one individually and keeping track of all of that which would be a pain i just treat them all as a single promise and i then have code to re to deal with them if it either complete successfully or if it fails with an error um and yeah so in summary promises make dealing with yielding and tasks easier by giving you observability and a load of really useful common patterns and methods some of which i touched on here but some at the bottom of the slides you can see that i've completely missed out but are also really cool because i don't have all the time in the world here so yeah so now i'm going to pass over to uh trey to talk about springs thank you very much lucy okay so hi i'm trev reynolds i'm from solo studios and you might know my work as axis angle uh through phantom forces and other games um and i'm going to give an overview of springs and demonstrate some of the pros and explain some caveats so okay so where are we seeing springs before on the left side we have a roblox spring constraint and it's attached between two parts and that's just out of the box from roblox on the right uh we have an off-road racing truck that uses springs and dampers also known as shock absorbers which is important to help the body glide over the rough terrain and then in the middle uh is a use of springs that you might not have seen before or might not have noticed but definitely seen and we're going to be focusing on this use case so in this case we use springs to apply multiple control forces so when you land on the ground uh the gun goes down but it tries to bring it back up through a spring and then whenever you fire a bullet the bullet will impart some momentum to the gun and the spring tries to return the gun to its original state so what are we really talking about uh springs are a second order differential equation where the acceleration of a function is described by two forces uh one resistance to the velocity and the other towards the goal position and this is kind of confusing so and we don't have the four weeks we need to explain it so we're not going to talk about differential equations instead we're just going to focus on the concepts so springs try to move a point's position towards a target position while limiting the point's velocity and that's that's the big deal and uh this general behavior can be applied to solve many different problems um and for this presentation what we're really talking about is the use of my spring module for artistically tuned physical animation uh this module asynchronously updates itself separate from the rest of your code which makes it really nice to use okay so what makes springs so great uh they're good for twinning and animating and it's intuitive for artists and has a lot of variety behavior the parameters are scale and variant so you can use the same spring parameters to work with really small numbers and really big numbers it just it all looks the same and uh they also work the same in any number of dimensions so numbers vector twos and vector threes or whatever the behavior is the same and we'll talk about c frames later it springs are really only good for linear spaces but you can work around that okay so how do strings work um here we go okay so uh in this picture uh we have a black point mass and at time t equals zero it was at the green initial position uh with the purple initial velocity and then at this point we applied a spring to it and so the spring is trying to pull the black point towards the green goal in the center of the spiral and the spiral is the path that the black point uh will take okay and so again there's two forces acting on the black point and uh we have the blue line which can be thought of well the blue force uh which can be thought of as like just literally a spring that's attached between two points and then the red line is like a wind resistance force okay so um here are some different examples of different spring values the speed damping is the damping parameter and the speed is the spring speed parameter so the initial velocity for all these is the same and as we go to the right we increase damping and as we go down we go we increase speed and you can see that as we increase spread speed the shape of the like the shape does not actually change um so in order to actually change the shape you go you just increase the damping there's more behavior here than uh we show okay so in order to explain the benefits of using springs and show how one might implement them we're going to write a vehicle follow camera and to begin we'll write some really basic code which will keep the camera in the same position relative to the car so at the top we require resources we get the car and we define a camera offset which is just where the camera is relative to the car uh and then we set up our update loop on lines uh nine on line eight and then on line nine and ten we get the car c frame and the camera c frame and then on line thirteen we just set the camera c frame and uh on the right you can see the result of this so uh the camera is definitely functional but it's a little stiff and unnatural and looking at the uh or and then we can make it feel a lot better by placing a spring in between where the camera wants to be and where the camera actually is if that makes any sense okay so looking at our loop we're going to have to make some changes so the problem is uh if we try to directly spring a c frame it won't work very well springs only work in linear spaces and c frames are not a linear space we know that c frames are non-linear because if you try to freely change any of its nine rotation values you don't get a new valid c frame you just get a wonky invalid one so what we can do instead is work with the position and the euler angles yxz which are both linear spaces because any possible position and angles combination will define a valid c frame okay so on line 13 we'll convert camera c frame into camera position camera angles using a conversion function and then after that we'll convert back into a c frame uh to get our final camera c frame and then uh on line 23 we just set the camera c frame again and uh this is still working code the end result is totally unchanged okay so now that we've linearized our space we're ready for a spring we're just going to put it in between so we'll require a spring module and define two springs and when we make a spring we need to tell it what kind of value to expect and since both our position and angles are vector three values we'll initialize both springs with vector threes in the first okay so now we need to make room for our spring code in the middle of our update loop and first of all our camera cream is no longer defined directly with the car so we're going to change these names uh we're going to compute camera c frame goal and then derive the goal position and go angles from that and then quick aside get position in angles from c frame always returns angles within a certain range and this is not what we want because it does not keep track of how many times we've turned around so we include like line 19 to fix this okay and then on lines 22 and 23 uh we say spring.t equals goal and this is setting the target of the spring to the value we give it and then on line 26 and 27 we say value equals string.p and this just gets the current value of this ring and stores it into the to the local variable so now that we have our camera position and camera angles again we're finished and uh one last thing we never set the damping or speed values of the springs and this is because i added some code that will read values from some uh value objects in the workspace so that we can play around with the speed and damping in real time and so now we'll watch a video okay so here's basically the the resulting product uh right now the damping and speed are both set to one but we can increase the speed constant to like 30 and you can see it'll be much more closely coupled with the car and uh so we're gonna set this probably to 15 and then if we or no no sorry 0.1 so now it's really slow and you can see that it has a really hard time keeping up but uh a good value is typically like 15 and then if we play around with damping a little bit if we set it to 0.5 and run off the ramp uh you'll see that uh the camera will have it has a little bit more bounciness and it'll bounce a couple times after the car lands so it kind of uh maintains momentum in the world and then uh yeah so if we set the damping to be really slow or be really low it's gonna it's gonna really wobble a lot and then of course a damping of 50 will be really resistive to change so even though the speed is 15 it's not going to be very coupled with the car but a good value is like typically 0.8 in between 0.5 to 1. okay so springs in summary springs are physically based and feel good they're naturally intuitive to humans and springs are also highly tunable through their speed and damping parameters and also the spring implementation is solved so it only updates when you ask it for a value or try to set a target or value to it and this means that it's performant and stable no matter what numbers you throw at it because it does not require you to update it it's a lot cleaner okay so now back to jameson who will present binders uh cool thank you trey so binders are this really uh less common pattern in roblox um that we we have in games so there's not as many games using this but i think it's a really powerful way to program in roblox the idea behind binders is really simple to bind behavior to roblox's data model and so what we do is we can bind roblox objects or little objects to roblox objects using collection service and we can use binders to program streaming enabled and binders really combined with other code patterns to get really good behavior and the philosophy philosophy behind this is that roblox is our source of truth so why do binders work collection service so if you haven't used this before you definitely should be collection service replicates with instances and we have two methods or two signals that we can listen to that are really valuable we have a get instance added signal and a get instance removed signal and these fire when instance comes in with the tag and comes out of the data model so this also includes when stuff streams in and out the way we interface with this uh because tags are not integrated into roblox studio is we use tiffany's tag editor right now and you can just define tags um so the contract behind binders is really simple it takes two things a tag name so in this case ragdoll and a class to construct our ragdoll class and we have one on the server and one on the client this is just the server binding so every time we tag something with the tag name our class is constructed and every time it's untagged the class is deconstructed when it constructs we call the dot new method the first argument is the class in this case the humanoid and we call destroy just with like no arguments so it gets destroyed so you can see here uh with tags as our source of truth when we tag this humanoid on the client with ragdoll it ragdolls the client and when you untag it it unragbles and a lot of things are changing here so when we ragdoll we change the camera we change the gui showing we show this little thing but our source of truth here is just the tag on the humanoid so this is really an inversion of control back to roblox and this is really good um and you can see here we are on the server we'd be constructing this class and the client would be constructing this class we set up some stuff here so the philosophy behind this is really simple uh we're moving the source of truth back to roblox and this is really good so uh why do we want to use binders uh we want to make it easier to program streaming enabled games we want to query roblox's data model information and we want to make it easier to test and i guess there's an added benefit here too where your builders now have an ability to interface with your game and add more content without a programmer being there so all in all uh there's a lot of patterns with this the first one that's really good is querying roblox's data model so with binders we can search up and down roblox's data hierarchy for bound objects so in this case we have a compass waypoint it's actually an attachment and we first search the attachment just for a value based object for the icon name and if we can't find that we search for a location in the hierarchy and if we're underneath the location like winlight bay which is the game we're looking at here then we can pull the icon key from the location just by calling it icon key and that can do who knows what we don't really care we just get the icon key back another example is this camera drone control so in this camera if you're flying the camera join in with night bay you can go search what we do on the server is we look underneath the camera drone object for any bound camera drone controls and we just destroy them to stop all of the controls and destroying those objects just removes control from the player so this is just a really powerful way to interface with roblox because now that the control isn't there there's just no control it replicates back to the client it gets unbound and we can remove the controls on the client so roblox is our source of truth another common pattern is binder groups so we can add behavior to the game just by tagging it and adding it to a group so what we have here is a trigger this trigger bubble here is typed with trigger and it's kind of pointing back to the atm so we can reuse the same gui everywhere because it's kind of the same and what we do is we add the atm to the trigger list here and then whenever that activates the atm just gets a call and we just bind the atm with an atm tag so this is just a really nice way to interface it and of course the atm has a method called ontrigger activate and this is just a type check to make sure that exists so another really common pattern is updating things that are tagged in the game so just a really simple loop let's say we want to go update all the trees and we're doing this every like 10 seconds or something what we can do is we can iterate over every single tree generator in the game and call update maturity on it and then in the tree generator code we just have a method called update maturity like exactly what we want it to do and then we can do some math on dates and stuff to figure out how much it should have grown and so this is another really strong pattern whereas if you didn't have bound objects you would have to go look up that object some other way and then finding that list could be very expensive so this lets us cache a ton of values and do other things with that another big thing is fast editing in roblox so what we have here it's lagging a little bit but here we go is we've got a flag tag and when you tag stuff in the game it just binds that behavior immediately so when we have builders like messing with flags or something what we can do is we can have them bind the flag while the game is running and see what happens when that tag gets occurred and so by doing this we're able to very quickly iterate and test on different builds and other things that we do in the game so it lets us test quickly both as a programmer and as someone who's making tools for other people in your team to be working on so binders are really valuable in that way other common patterns we can leverage the past patterns that we just discussed to work with binders in really powerful ways so an example here is this model transparency effect we're listening to all the children in descendants and we're saying this model transparency effect is on a model and for each item in the model decals or vase parts we're going to set the transparency on them whenever they get added or removed we're going to remove that transparency modifier and we're also going to update every time it updates and so by using signals here and listening to descendant added and removed we can now have this model always be transparent when we want it to be and we can use this to hide objects in this case to fade objects in and out of the world another really common pattern is using maids all of my bound objects tend to have a made in them just for easy cleanup because destroy is called so this is just the base object i inherit from using object-oriented programming and it has a main and it also has an object that i just give it and that's the object passed in from the bound from the binder.new argument so um these exist for the life the maid exists for the lifetime of the object and it gets cleaned up and that's just a really good pattern promises are also really good so if you remember in the signal talk i was talking about how i parent all my signals to objects well we can use a promise to promise that that signal will that remote event will exist so we promise the remote event we cancel the promise if the object streams out so if the maid gets cleaned up and then we can get the remote event and fire the server only while this is valid so this works really well for one-off instances it doesn't work well for stuff that comes in and out on the fly for that you need to use signals but it's really good for static resources like this remote event here so in summary binders are a really good way to bind lua objects or functions to collection service tags it makes testing easy you can use this for streaming enabled because stuff with binders basically works out of the box with streaming so you don't need more control with streaming all you need is to switch your source of truth to be roblox instead and then you can combine other patterns with binders to get really good behavior with that this is five powerful code patterns um this slide deck will be shared after the presentation hopefully with the uh with links to the code for sure and hopefully with the questions we're about to answer uh with that being said i'd like to transfer this over to hannah to help moderate questions thanks james um we actually don't have any time for questions so i'm going to ask the four panelists to go into the discord channel and answer questions there so please post your questions back in that discord channel they will be there answering any questions again that's dev code patterns in the rdc server but we will see you guys back here in 10 minutes for a talk from sean on building worlds for game performance but otherwise thank you to our four panelists we'll see you at rdc bye guys thank you so much have a good day you
Info
Channel: Zero Man
Views: 3,869
Rating: undefined out of 5
Keywords:
Id: Db3LooLQM1Q
Channel Id: undefined
Length: 40min 2sec (2402 seconds)
Published: Sat Jul 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.