In the case of speech bubbles. I think your solution is functional but needlessly complex. Pooling something that appears something like every other minute is not necessary from a performance standpoint. But I enjoyed the breakdown nonetheless. Cheers
@aarthificial3 жыл бұрын
Thanks! I agree, something like a factory would be enough for this situation. But I wanted my factories to have the same interface as pools, that's why I went an extra mile and implemented this. I'll decide what to use once I'll have some actuall data from the profiler
@rasulseidagul3 жыл бұрын
Well, we could argue with that. Such implementation of pools is around 200~500 lines of code or so. It is not THAT much complex as other people tend to do: custom dependency injection(where you inject pools and other things to objects), object messaging system(when you talk with the world and get a pool you exactly need based on traits/tags/contracts/...).
@Nemofication3 жыл бұрын
@@aarthificial I started following this channel because you fit the "making complex systems so later advanced features will be easier to implement" type of programming style, something I find is relatively rare in the indie dev scene. IMHO skimping out on that mentality results in more spaghetti code and a lower threshold for when a codebase gets too big for a single person to effectively develop. So you can definitely count this as a Yay for more "needlessly" complex systems, keep it up champ.
@NukeCloudstalker2 жыл бұрын
@@aarthificial I know I'm late to the party, but I'm wondering what made you shy away from simply opting to instantiate and customize the speech-bubbles on the spot and as-needed, using a normal asset-reference, given how rarely they are used? Surely the performance isn't the primary concern in this case.
@Dysiode2 жыл бұрын
@@Nemofication Keep in mind, he's not developing them from the beginning, but proofing out the need for them first. It's easy to jump right into building the complex system when you don't know if you'll actually need it
@VoonNBuddies3 жыл бұрын
It's crazy how your able to so effectively explain these high level design concepts in so little time! Thanks for sharing your experience!
@aarthificial3 жыл бұрын
Thank you, too!
@VoonNBuddies3 жыл бұрын
@@aarthificial
@mysterry20003 жыл бұрын
This guy is honestly something else
@aarthificial3 жыл бұрын
Share this video to help fight the Singleton tyranny! Jk, nothing wrong with using singletons. Choose solutions that work for you and have a great day!
@MassimoRough3 жыл бұрын
And monobehaviour as well! Long Live Scriptables!
@ariehuybregts98753 жыл бұрын
What I really like about these more technical videos is that they can really serve to expand the way people think about implementations or structures or whatever. I'd wager a lot of new devs learn a lot from youtube tutorials, which often have a pretty uniform way of doing things and this makes a great change, even if I end up sticking with a singleton or whatever.
@tiredko-hi-3 жыл бұрын
I really liked how the code was shown in the visualizations. Non-coders can still hang along and coders have an easier time to understand how it was implemented. Nice video as always! Questions: Wouldn't it be easier and/or better to make a factory? Create each bubble on demand? That way you wouldn't have to worry about scenes unloading and such, right? And you don't have a bunch of lurking bubbles either. Doesn't a pool create weird and unnecessary limitations?
@aarthificial3 жыл бұрын
Thanks so much! To quote my other comment: "I agree, something like a factory would be enough for this situation. But I wanted my factories to have the same interface as pools, that's why I went an extra mile and implemented this. I'll decide what to use once I'll have some actuall data from the profiler" So yeah, bubbles were just an excuse to implement both
@tiredko-hi-3 жыл бұрын
@@aarthificial Aaa ok I see I see
@NukeCloudstalker2 жыл бұрын
Why even a factory? It's not like speech-bubbles need to be different classes, they just need to contain different texts, and maybe cover some color/size variation.
@Nikola00203 жыл бұрын
Dude I literally just binged all your videos today and you release a new one, fucking sick. Keep it up
@aarthificial3 жыл бұрын
Thanks, glad you're enjoying them!
@NICK....3 жыл бұрын
I pray that the almighty algorithm picks up on your channel
@MassimoRough3 жыл бұрын
Pray is not enough. Share the videos instead.
@FMontanari7093 жыл бұрын
I love the way your graphs make concepts a lot easier to grasp, keep up the good work!
@notanimposter3 жыл бұрын
These videos always get my creative energy up. You always come up with solutions I never would have thought of.
@RugbugRedfern3 жыл бұрын
I've been using Singletons for a long time, and have been wondering about a better solution. Thanks for sharing this!
@aarthificial3 жыл бұрын
Thanks for watching! If you're interested, Unity has a really nice video on how scriptable objects can replace singletons: kzbin.info/www/bejne/jX2nmKeIg7BljKc
@RugbugRedfern3 жыл бұрын
@@aarthificial Thanks! That was a very interesting watch. I'll definitely be experimenting with that architecture.
@holmnerd3 жыл бұрын
I gotta say that I love the short format of your devlogs, concise and entertaining, without wasting everyone's time. Best of luck with your project.
@aarthificial3 жыл бұрын
Thanks so much!
@dibaterman Жыл бұрын
The solution I made leverages multi-scene workflow. It centralizes the pool system to allow for shared pools as well. The benefits here should be obvious but... say you have 5 bubble shooters, instead of making a pool for each bubble shooter you generate a single pool with enough bubbles for all bubble shooters to use as needed. The pool also has a pool cleaner so it purges the bubbles over time if they aren't being used.
@vojtastruhar8950 Жыл бұрын
Great video! Pretty advanced topic. I like it. + The MotionCanvas animations blow my mind every time I see them
@Weckacore2 жыл бұрын
I love these videos, no one explains this type of stuff and I realize so much burn out is from messy architectures. But there doesn't seem to be great tutorials for this stuff, so these are a great resource
@pavelperina76292 жыл бұрын
I somehow like the way this video series (after fast forwarding a lot as it's very late) evolves in terms of production quality. Now it seems nicely animated in similar way such as math videos made in manim&python and it seems that you are quite good at designing nice color schemes.I assume that making of these short videos takes a lot of work.
@DaSquyd3 жыл бұрын
While this is a neat approach, I feel like pooling is a tad overkill for something like this. Usually pooling is used to solver certain performance issues, but you shouldn’t be experiencing any when just instantiating and destroying the bubbles like normal (unless you’re planning on having hundreds spawn in and out in a very short period of time).
@aarthificial3 жыл бұрын
Please read the pinned comment
@elvismd3 жыл бұрын
Nice approach! In the case of speech bubbles I think I would have made only 1 speech bubble that would be customizable for multiple cases (its size, colors, etc) and then would just move it around when needed and placing the right text, the right position, etc (that would kinda works like a singleton of course but also that could be a prefab that is part of a scriptable object that goes around)
@aarthificial3 жыл бұрын
Thanks! This is kinda what I do. Bubbles are customizable like that and, for example, if there's a dialogue with multiple sentences it will borrow only one bubble and reuse it. The problem is that sometimes, when one bubble is fading out, the other may start appearing. So I need at least two of them
@unhearted45103 жыл бұрын
I love your solution, and you explained it very clearly! I was looking for something like this to deal with players disconnecting on photon and the info they contain being lost, you've inspired me,
@whyabadi2 жыл бұрын
I use Scriptable Objects to implement pooling too, but I haven't dealt with the scene unloading situation yet so this was very helpful. I also expose some properties on the pooling SO like max number, and hide flags (to show/hide active or inactive pooled objects in the scene hierarchy). Another small issue I ran into is the need the preload your scriptable objects at an appropriate time or the game can stutter. Love your content by the way. :)
@MrHandsy3 жыл бұрын
This is how I do it, while having a non-static "don't destroy on load" GameObject for management of my pools. Mostly just creation of objects and cleanup, it's never interfaced with from outside code.
@horrornumber3 жыл бұрын
wow impressive
@ArtemDemo3 жыл бұрын
Nice video! What software do you use to create this nice looking presentation? Pls, don't say that you animated it with Unity. And if so - I don't know how you find time for everything :)
@aarthificial3 жыл бұрын
Thanks! I'm currently being held hostage by Adobe. This one was created using Illustrator and After Effects. But using Unity seems like an interesting idea
@Skeffles3 жыл бұрын
Excellent solution & well explained.
@WuchtaArt3 жыл бұрын
aarthificial: does a standing twine aarthificial: 4:32
@logicprojects3 жыл бұрын
Great dev log, beautiful explanations and animations and useful info.
@LutennantLongshot3 жыл бұрын
Super neat and interesting approach to the problem!
@rasulseidagul3 жыл бұрын
Hey man! Your videos getting better and better each time. I really like your work! In my implementations I also have pools inherit from scriptable object, however, I force it to clean up itself after a scene is unloaded because in my case multiple scenes(e.g. menu, battle map) do not use the same type of objects, so it is unnecessary to keep them alive there as "DontDestrouOnLoad" objects. Btw, about why people do not talk about(/share) architecture and clean code: they just don't care. Like they just use some sort of singletons(really bad but working) or have pools as fields in the manager, which is a singleton as well. At least, it is what I think the case from what I saw in companies where I work(ed).
@aarthificial3 жыл бұрын
Thanks so much! It's really reassuring to hear that you also use SO's for pools
@saqibbro52972 жыл бұрын
This is beautiful.
@troidepanhseden45323 жыл бұрын
thank you!
@aarthificial3 жыл бұрын
Thank you too!
@Razofgal3 жыл бұрын
Excellent video as usual - i just wonder - do you make all the graphics (like how you showed off the "code") by hand or do you have a handy app for the graphica creation?
@aarthificial3 жыл бұрын
Thanks! Unfortunately, it's all manual labor in After Effects. I'm actively looking for something better though, so if you know any software for this kind of stuff I'd love to know
@andermium2 жыл бұрын
-4:58-- Those Lego sofas seem cool, really fits with the futuristic vibes- Wait, I realize those are probably the concrete blocks you usually find on the street. Still, such a nice detail!
@aarthificial2 жыл бұрын
Thanks so much! You were right the first time, these are little sofas IIRC I was inspired by the sitting spaces in the middle of this photo: www.pinterest.co.uk/pin/817966351062399834/
@yoctometric3 жыл бұрын
One thing you're missing for referencing the pooling MonoBehaviour is static classes. The usual way I would implement this is to have a MonoBehaviour for pooling and a static class called PoolingManager which would store a reference to the various pools. Then, any object can call PoolingManager.pool1.doShit() whenever they want
@aarthificial3 жыл бұрын
Thanks! Jason Weimann hava a nice video about a similar pattern. I wanted to keep this simple though, so I included only the basic ways of referencing monobehaviours
@Fightitinside Жыл бұрын
It's actually just the same singleton
@mateuszpatua30162 жыл бұрын
i can't stress enough how much i enjoy your content and admire your problem solving!! btw do you have any unity, c# or gamedev courses, books you can recommend?
@NeatGames3 жыл бұрын
Interesting breakdown! I'm using object pooling for things like walking dust step effect in my devlog game :D
@aarthificial3 жыл бұрын
Awesome! It's such a cool little detail, I so wanna add it now
@creo_one3 жыл бұрын
While i don't agree that bubble is good use case for pooling, abstract implementation of this mechanism makes it easy to reuse in other place, so no time wasted.
@kusalg2 жыл бұрын
Once again, scriptable objects have solved the problem!
@hetigamedev18183 жыл бұрын
Good Singleton is a misnomer ;p Nice solution with a scene changes.
@algs54833 жыл бұрын
Just like in most of your other devlogs, I'm hella confused... But I do like your voice so I still watched it...
@docdoc.45002 жыл бұрын
Why was this in my recommended? I'm not learning coding- but heck! This IS interesting! I do admittedly wish I could make my own game someday, maybe this will be the start of learning how
@forcommentingpurposesonly29182 жыл бұрын
JESUS CHRIST. Did I just get object pooling jumpscared? 0:20
@harunakbulut20172 жыл бұрын
Can you tell the name of font that youre using for codes? It feels so soft and nice
@aarthificial2 жыл бұрын
It's JetBrains Mono
@harunakbulut20172 жыл бұрын
@@aarthificial yo thanks
@lordzockt18532 жыл бұрын
ty for asking this. I lost all my stuff and searched for this for at least 10min under his vids just to find this!
@INeatFreak2 жыл бұрын
F Singletons, along with Managers and Controllers. I've been using SO for pools too, it's really convenient for a lot of cases because you don't lose references out of the blue.
@itsME-dc4vm3 жыл бұрын
wow nice ;D
@remy1202 жыл бұрын
0:18 that scared me so bad :(
@fdtdev3 жыл бұрын
I used the same approach as you with scriptableobjects, and get the same fantastic results. But once I had to start using Asset Bundles, happened that each object that was in an assetbundle but was referencing a scriptableobject, ended up duplicating the scriptableobject in memory. So I ended up coming in terms with static classes for this kind of stuff.
@aarthificial3 жыл бұрын
Asset bundles truly were something else. Glad they're no longer relevant
@francoscigliano79153 жыл бұрын
@@aarthificial what do you mean with that? Addressableassets are asset bundles in their insides, so this problem i encountered is still a thing. What i did to fix the scriptableobject events, was to make them share the same identity no matter what instance they where. So duplication in memory wasn't an issue anymore. (I'm the same guy with a different account)
@aarthificial3 жыл бұрын
I'm sorry but I don't understand half the terminology you're using. I'll think about it when I encounter such problem
@francoscigliano79153 жыл бұрын
@@aarthificial I'll check if you have an email and i can send you a better explanation of the problem because it's something that you could encounter and you would be so much better than me doing a video about that xD
@borisvanderhof30282 жыл бұрын
Okay but imagine how funny it would be if a coding error started randomly deleting dialog boxes
@suaveq3 жыл бұрын
Hey, great videos! I just found out about your channel 2-3 days ago and already gone through all of your devlogs up to this one. Could you please tell me, what kind of tool do you use for your graphs presentation like the one in 2:40 ? I need to create something similar, architecture related, for my work and yours inspired me much 😃
@aarthificial3 жыл бұрын
Thanks! I'm not using any specific tool. I create these graphs in Illustrator and then animate them in After Effects
@suaveq3 жыл бұрын
@@aarthificial That is still helpful, thanks! But since I've never used AE I will probably stick with animating everything in Power Point for now, but definitely gonna have a look at AE.
@pandadad883 жыл бұрын
Out of morbid curiosity, any particular reason you didn't let the pool hold on to a reference of the bubble at the same time as the borrower? I have seen pools implemented in a way that store objects (like your bubbles) in two different data structures, one for inactive and one for active. So you have a queue for your inactive bubbles, pop one off, add it to a list (your active bubbles), and then return the same object that's in your active list. That way if the borrower is destroyed, you still have the bubble in your active list. Also, when transitioning scenes and whatnot, you can go through your active list for clean up (dispose of them and add them to the inactive queue).
@aarthificial3 жыл бұрын
That's what I do though. That's what the video is about
@pandadad883 жыл бұрын
@@aarthificial I had to watch this again to see where I missed that. Don't know why I didn't pick that up the first time. Certainly answers my question!
@aarthificial3 жыл бұрын
@@pandadad88 Glad to hear that! I'll try to link the sources in the description this weekend to complement the video
@PeterStrings3 жыл бұрын
As usually, amazing. I've got some specific questions though: without spoiling any details, what's the logic behind having both the "bubble.Dispose()" and the "bubble.OnDisposed()" methods? Where would these two differ? Is there some info that the Bubble needs from the Pool in order to be disposed? Is it because of some sort of ordering between the different stages of the lifecycle of the pooled object, that the logic needs to be split in two stages? Why wouldn't both methods' code simply be within the first "Dispose()" method when called by the Borrower? Also, under what circumstances would you have pooled objects that are assigned to two different Scenes? I find the approach really tidy but in my attempt to try something similar I came to the question that, I didn't know how I would get to a point where I needed to keep track of which Scene an object was borrowed from. It was always by the single previous scene. Is the idea to be able to handle a situation where the game transitions through through Scene 1 -> Scene 2 -> Scene 3, faster than the Pooler can collect those disposed when Scene 1 was unloaded ? Another one would be, if the borrower has to reference the Pooler Scriptable Object asset, then why would the Dispose logic be within the Bubble and not have the Borrower simply call the Pooler to handle the return logic? I'm not arguing against it, I just really want to know which problems you came upon in order to make these design decisions. One last question: what's the general improvement over recycling these dialogue bubbles? This is plain ignorance from my side, but is the issue here not wanting to have all NPCs not reference a DialogueBubble Script component, or not wanting to instantiate a DialogueBubble prefab for every interaction? What are the main benefits you see that pooling provides for dialogue bubbles in particular?
@aarthificial3 жыл бұрын
Thanks! 1. Dispose() only schedules a disposal, OnDisposed() performs it. The former is called by the borrower, and is basically like saying "I don't need you anymore, take your time, finish what you need, and ask the pool to collect you". The latter is called by the pool when collecting an object. This forces it to immediately clean up after itself. It can be invoked as a consequence of calling Dispose() or of the scene being unloaded. 2. Yes, my goal was to make the pool persist as scenes load/unload, instead of destroying and recreating it each time. But if you consider additive scene loading, there's plenty of examples. You could have an open world separated into individual scenes that load/unload additively based on the distance from the player, for instance. 3. If you're talking about the interface, then it's more of a subjective choice. I wanted to recreate how it's done in Zenject, by implementing the IDisposable interface from C#. In terms of usage the difference is insignificant: object.Dispose(); vs pool.Return(object); If you're talking about the implementation, then in my opinion a poolable object should be self-contained. So the disposal logic belongs in its class. This way you can extend it, override said logic, and still be able to use it with the base class' pool. Additionally, the same poolable class can be used with other pool-like constructs, like a factory, or a local monobehaviour pool. If I were to put the disposal logic in the pool, I'd had to duplicate it for each of these. 4. I don't know what's the general improvement. I just wanted a way to create objects from within a script instead of having to manually create them whenever I needed them. I started with a factory but because bubbles had been designed with timelines in mind they were already recyclable. So I went the extra mile and implemented a generic pool as well. As I said in other comments - in my code base, pools and factories share the same interface so switching between them is not a problem. Right now it's more about ease of use and flexibility rather than performance.
@errantwashere3 жыл бұрын
Errant was here
@MrVladoCC3 жыл бұрын
How are you doing all of this cool visual representations of code and such stuff& This looks very neet. Is there au tool or somethink?
@aarthificial3 жыл бұрын
Nope, it's just After Effects and Illustrator
@mystictnediser3854 Жыл бұрын
Are pools the concept of classes in unity? I see no difference between them, I think I missed an important point. Would you explain what the difference between creating a new instance of a class and getting something from a pool?
@PaperBenni3 жыл бұрын
what do you use to create your animated diagrams? It looks really cool
@aarthificial3 жыл бұрын
Thanks! It's After Effects and illustrator
@bluzenkk Жыл бұрын
why not just let it go and give the pool to spawn another brand new pool object when it detects insufficent number of pool object?
@RedLionYTB2 жыл бұрын
I am very curious to know what approach did u take in order to collect the objects when the scene is switched. Did u make a game object with a mono, and then just call a function to collect the objects, or did u subscribe to SceneManager.activeSceneChanged?
@anonymoussloth66873 жыл бұрын
Around 0:49 you mention how serialized fields can't be saved as prefabs. You then explain some more things later. Where can I learnt hese unity specific things? I know how to code in c# but these unity specific things r what confuse me. I tried to read the documentation but that is really hard to understand. Can u recommend any resources?
@aarthificial3 жыл бұрын
Unfortunately, I don't have any specific resources. I usually tinker with things to get the feel of how they work and watch things like Unity Unite and other talks where they tend to explain the inner-workings of Unity
@ciberman3 жыл бұрын
Pros of your video: - The fact that you don't explain how to code and only focus on the ideas and design patterns. - The abstract pool pattern (A mix between an abstract factory and object pooling) - The amazing explainer animations (How do you do make them?) Cons of your video: - As other people pointed out, there is no need to use object pooling for something that you don't create thousands of instances like UI elements. Using a simple factory (with no dispose/returnToPool method) would be better for this case. Normally you use object pooling to reduce memory allocations and GC pressure. But in this particular case, there is no need.
@aarthificial3 жыл бұрын
Out of curiosity - do you know how much time it takes to instantiate one speech bubble?
@someonewithsomename3 жыл бұрын
Video is great. But I have a daunting question: Are you an actual programmer or just like to over-complicate things?
@FMontanari7093 жыл бұрын
"they're the same picture" - engineers, probably
@vladde3 жыл бұрын
2:09 buuble
@ariorick3 жыл бұрын
Why would want to optimize this... There's no way these speech bubbles could ever be a performance issue haha. Solution is intersting of course
@aarthificial3 жыл бұрын
I haven't said a single thing about performance or optimization
@DerClaudius3 жыл бұрын
That's a nice approach, but usually losing a pool member to an unloaded scene isn't a big problem, right? Because it doesn't happen often and the pool will just regenerate members if it doesn't have enough.
@aarthificial3 жыл бұрын
It depends. If you, for instance, want to borrow an object when the scene loads and return it right before unloading, you're always gonna lose said object. Because once the OnDisabled callbacks are invoked, it's already too late to extract an object from the scene. Calling MoveGameObjectToScene or DontDestroyOnLoad won't have any effect. In this case, a pool becomes more of a factory.
@DerClaudius3 жыл бұрын
@@aarthificial Yes, you're right. What I meant by "not often" is not that the losing doesn't happen often, but scene transfers not happening often. I thought of classic uses for a pool where you need a lot of those objects during the lifetime of a scene, because they're short-lived.. like some particles... I wouldn't realy mind if I lose 50 of my 150 particles in a scene transition and need to recreate them later when scene transitions happen a lot less often than using those particles. But I understand the appeal of solving this problem in a clean way.
@aarthificial3 жыл бұрын
Oh, gotcha. Totally agree. It's more just me being pedantic
@ariandannemann45443 жыл бұрын
I don't quite get the point of pooling, like when looking at the circles example it seems 'cleaner' to just instantiate a temporary prefab instead of having 20 copied of it in DontDestroyOnLoad which also clutters the ui
@Mongo2k3 жыл бұрын
In general instantiating and destroying objects can make your frames dip, even just instantiating 5-6 objects at the same time could do it. Keeping them around takes up a bit more memory, but memory isn't really in a shortage nowadays. That said, it very likely wouldn't have mattered in this example, and might be a case of over-optimizing. Also if possible you could just parent all of the pooled objects to the pool itself if you want to avoid cluttering the hierarchy
@egorexw36122 жыл бұрын
Am i die only one who thinks that you could just instantiate a bubble prefab