Hey everyone! Both Mediator and Blackboard are good patterns to know before diving into Behavior Trees, GOAP and State Trees. If these kinds of topics interest you, let me know in the comments and hit the 🔔!
@ryaz47048 ай бұрын
Yes
@ragerungames8 ай бұрын
Yesssss behavior trees and state trees
@carlwong19198 ай бұрын
GOAP please
@TChrisBaker8 ай бұрын
all of those sound interesting. I would be curious on your take on how to implement a Blackboard as well
@drewalkemade37158 ай бұрын
Seeing your implementation of GOAP would be great!
@git-amend8 ай бұрын
Alrighty! One vote for a GOAP video!
@PetersExcapades8 ай бұрын
@@git-amendmake it 2!
@PetersExcapades8 ай бұрын
yes thats 2 factorial
@Fitz0fury8 ай бұрын
Also voting for goap.
@fear_ctpax7 ай бұрын
@@git-amend +, me too!
@danny-g43288 ай бұрын
I thought this thing was facade pattern. I guess as soon as components need to know of / communicate with each other, it turns from facade into mediator pattern. Thanks for making this video, I tend to use this pattern a lot and this video really helped me with improving on it :))
@git-amend8 ай бұрын
That's a great observation, thanks for sharing that. Cheers!
@silchasruin44878 ай бұрын
GOAP, GOAP! You're a fantastic teacher, I'm busy working on enemy AI that uses the Observer pattern to update randomly assigned weights based on the players actions. So if the player is looking in their direction and shooting them, an enemy with a lower Courage weight will run, where as one with a higher weight value will rush the player. Just to add a bit more dynamic behavior. Im still working on the implementation but I don't know if GOAP would simplify things or make it unnecessarily complicated. We all want F.E.A.R. type AI in our games haha
@git-amend8 ай бұрын
Ok another vote for GOAP. I’ll start working on that soon!
@silchasruin44877 ай бұрын
@BornToTroll-it5ju that's pretty cool to think I've got a similar idea to a 15 dollar asset since I can't afford it at the moment
@TChrisBaker8 ай бұрын
Great video ! Your timing with these videos is amazing . I was just trying to make a central "EnemyManager" class this week but I wasn't sure if there was a more sophisticated way to do it. I will give this a try
@git-amend8 ай бұрын
Glad it was helpful!
@_stephenhubbard7 ай бұрын
Great stuff I've always struggled with some of these practices in the past. Was pretty recently I was looking for a good explanation of the mediator pattern and couldn't find one! Super helpful :D
@git-amend7 ай бұрын
Right on, glad to hear that!
@PurpleDaemon_8 ай бұрын
The first part with the AI chat was very cool! But I didn't catch the essence of the mediator in the second part. What prevents us from making private fields and public interface-methods in the hero class itself? Btw, this is exactly the problem I'm currently trying to solve as my character class consists of a dozen public systems, which causes problems when one system must influence another, so I'm going to make them private and expose public methods instead.
@git-amend8 ай бұрын
Thanks for the comment! Nothing is preventing you from exposing/using field and properties on the Hero class itself - but any class that calls them directly will also need a reference to the Hero. That's not necessarily a bad practice, but consider a UI that exists in a 2nd scene. Beyond the issue with having to 'tunnel' into the sub classes of the Hero for information, you also can't reference it directly. So, consider the Mediator just another tool in your toolkit for when the need arises!
@PurpleDaemon_8 ай бұрын
@@git-amend I just realized that may be in my approach I already use some type of mediator as all my logic live in non-MonoBehaviour classes while MonoBehaviours simply subscribes to these class events , which makes it much simpler to write tests. I just never thought about this as a sub-type of mediator pattern, closer to a model - view decomposition. Thank you for making me think more about such things!
@Fitz0fury8 ай бұрын
I had not even heard of this pattern. Ill have to play with it this week. It might solve for a problem i have actually..
@git-amend8 ай бұрын
Nice, that's what I like to hear!
@franciscooteiza3 ай бұрын
Hi Adam, I’d love to hear your thoughts on using MediatR for implementing the mediator pattern. What do you think?
@git-amend3 ай бұрын
I haven't actually used it myself, but that has been suggested as a topic before, or just request/response in general. I'll give some thought to making a video about it. Personally, I think it's a good choice, but I'd have to look and see if there are any gotchas.
@DuckeryDoo7 ай бұрын
I often wonder with more "complex" implementations like these patterns, there is often creating new instances involved, that only serve temporary (e.g. Payload or Builder here). Is this something that one should "worry" about (e.g. performance/GC-wise) and try to avoid creating new instances or build stuff like pools on top of that (especially when having lots of entities communicating)?
@git-amend7 ай бұрын
That is a valid concern. For me, I usually add concerns for performance later on. It wouldn't be difficult to add pooling these kinds of resources.
@SunSailorАй бұрын
@git-amend, which application did you use to create this nice node graph illustration with the hand drawn look at the beginning of the video?
@git-amendАй бұрын
That's Excalidraw for Obsidian, though you can use it without Obsidian too. kzbin.info/www/bejne/pWHIqX5jrauDac0
@anasmostefaoui30277 ай бұрын
can't wait for the GOAP video :D
@git-amend7 ай бұрын
Coming soon!
@bartekwoszek2337 ай бұрын
God damn, that is awesome, never seen solution like that. Im gonna jump on another level with your videos. Thanks
@git-amend7 ай бұрын
Thanks! Welcome aboard, join the Discord too if you like.
@connorjagielski67607 ай бұрын
Great video as always! Unrelated to the code, what software do you use for the diagrams? I’ve been looking for something super simple for drawing them
@git-amend7 ай бұрын
Thanks! I'm using ExcaliDraw (with the plugin for Obsidian) excalidraw.com/ kzbin.info/www/bejne/pWHIqX5jrauDac0
@AstralNostalgia8 ай бұрын
thanks ! however I Notice all the game pattern needs to be addapted to unity monobehaviour ? or non-unity monobehaviour right?
@git-amend8 ай бұрын
The patterns can be applied to both. The main issue with MonoBehaviour is that you can't use constructor injection. Otherwise, it's all very similar.
@atherissquamigera74252 ай бұрын
To me, the first implementation is the same as EventBus, and the second use case is like Facade pattern. Can you tell me the difference?
@bgt79118 ай бұрын
Hi, i love your videos because you work as professional. Can you make a video about game dev roadmap. I really need it please
@git-amend8 ай бұрын
Not a bad idea!
@votranduy88362 ай бұрын
Hi! I come from the future of this video @@, really appreciate every content in this channel!! So far I have implemented and used several techniques you have taught us and they're pretty powerful! I would like to ask in regards of this pattern, we have a Message method which will direct a message from a source to a specific target, I would like to ask what is the best way to do it? because if we want to message to a specific object, we have to know or keep a reference to it, the way I am doing is to use service locator to store the target reference and use it inside the source! Looking forward to your response! Happy coding time!
@git-amend2 ай бұрын
My intention with the message was not to keep a reference, but only to be able to send messages when two agents were close enough together in the game that they could see each other, for example within range of a trigger collider. Just like in the real world, you can only talk to someone directly if they are close enough.
@votranduy88362 ай бұрын
@@git-amend Alright I understand now, actually my case is a bit different as the implementation's not used for chat room agent, but acting as mediator between UIs, then it's more appropriate to use broadcast then the UI agent will determine what to do with the message! I have another question regarding to the visitor pattern used here, generally speaking visitor will handle the logic of visitable object with their passing data right? that's what I understand, but do you think it's viable to "reverse" the action back to the visitable? Like the visitor come, visitable objects accept, then the visitor (right now it's the payload) will pass the necessary data of the broadcast back to the visitable and they decide what to do with it!
@git-amend2 ай бұрын
@@votranduy8836 Yes, the Vistor can be implemented in either direction.
@votranduy88362 ай бұрын
@@git-amend Thanks a lot!! Learn something new today from you again!!!
@crazyfox558 ай бұрын
A visitor with a generic visit method is a code smell. What do you think?
@git-amend8 ай бұрын
Labeling a visitor with a generic visit method as a code smell can be context-dependent. If the generic method overly complicates the interaction between visitors and visitable objects or leads to type checking and casting that defeats the purpose of using patterns for clean and maintainable code, it might be considered a code smell. However, in scenarios where such a design significantly simplifies the implementation by reducing boilerplate code or enhances flexibility without sacrificing clarity and type safety, it could be justified.
@crazyfox557 ай бұрын
@@git-amend Yes I think I follow what you're saying here. I would agree it's not a code smell.
@AtmosMr4 ай бұрын
Hi, I am a hobbyist coder but am looking to improve. I have created a few projects which suffer from all the basic errors but work... I am sure you would laugh your head off at my code. Can you tell me what Visual Studio addons you are using? Or rather what would you recommend? Any tips/videos aimed at amateurish intermediates, who make all the classic mistakes, would be great. A lot of your code is very sophisticated and a bit over my head. Thanks!
@git-amend4 ай бұрын
Well, I don't use VS Code very often to be honest, I mostly use JetBrains Rider as my IDE, which you can get for free right now if you want to try the early access version: www.jetbrains.com/rider/nextversion/ Next week's video is going to be about Plugins and Assets, and the setup script that I use in all my projects, so hit the bell and you'll get the notification next Sunday!
@rechnight7 ай бұрын
Hey Adam! I just finished watching your latest video, and as always, it was fantastic. I did notice one thing though: in the Message method, the T source parameter doesn't seem to be utilized. I was wondering if it was intended to ensure that the source of the message isn't the same as the target, or should be removed? Great job overall, looking forward to your next video! One more vote for GOAP!
@git-amend7 ай бұрын
Thanks! In the Message method, you might want to be able to send a direct message to another entity if you happen to have a direct reference to it. So, for example if one AI Agent comes into contact with another one in the game world, it might want to deliver a Payload/message just to that specific entity instead of a Broadcast to all agents, similar to a DM in a normal chatroom.
@rechnight7 ай бұрын
@@git-amend That part, I understood, but there's something bothering me: public void Message(T source, T target, IVisitor message) { entities.FirstOrDefault(entity => entity.Equals(target))?.Accept(message); } We have the T source that is not being utilized... So just wanted to make sure what's its purpose here.
@git-amend7 ай бұрын
@@rechnight Oh I see. I'm sure I probably had something in mind, but by the time I recorded maybe I wasn't necessary for the video anymore. An oversight on my part I guess.
@MarushiaDark3167 ай бұрын
What's the difference, if any, between Mediator and Bridge patterns? Is it just a different name or is there some meaningful distinction like there is between Builder and Factory?
@git-amend7 ай бұрын
The Mediator pattern is designed to simplify communications between multiple objects or classes in a system by having them communicate indirectly through a central mediator, thereby reducing direct dependencies between them. In contrast, the Bridge pattern separates the interface (abstraction) of an object from its implementation, allowing both to be modified independently without affecting each other, aiming to enhance scalability and manageability. Perhaps a video about the Bridge pattern should go onto the list, though I'll have to think of a good example use case.
@pstudioDOTtk8 ай бұрын
As usual your videos are very interesting. I do have a few questions regarding the second example. First the HeroMediator to me might as well be called HeroFacade. The class hides away object dependencies and instead offers simplified methods to interact with those underlying objects. What do you see as the differences between the Mediator and Facade patterns in that example? Or is it more about intent? Mediator is concerned about decoupling dependencies whereas Facade is about simplifying interaction with dependencies. Second it is not quite clear to me what you are trying to solve or prevent, when you introduce a separate Mediator object to modify stats etc. rather than having those methods on the Hero object itself? If you are using a ServiceLocator or other method of retrieving dependencies, why not just retrieve the Hero object or the specific sub-object I need? E.g. what benefit would a UI Healthbar gain from retrieving the mediator over getting a direct reference to the Health object? Anyways, thank you for the videos. They are in my opinion the best regarding game development in Unity on KZbin.
@git-amend8 ай бұрын
You bring up some interesting points. First, the distinction between the Mediator and Facade patterns does largely hinge on intent and context; the Mediator pattern aims to reduce coupling between classes by centralizing complex communications and control logic, whereas the Facade pattern typically offers a unified, simplified method/interface that encapsulates multiple steps or operations, like changing the hero stats and health with one method call. Second, introducing a separate Mediator, like HeroMediator, is about centralizing the interaction logic between different components (HeroStats and HeroHealth) to manage their relationships and interactions in a decoupled way, enhancing modularity and maintainability. Using a Mediator over direct object retrieval, such as through a ServiceLocator, can offer clearer encapsulation of the interaction logic and potentially simplify changes to the system's behavior without altering the individual components or their consumers. That being said, there is nothing wrong with either approach. Thanks for your comment!
@MarushiaDark3167 ай бұрын
I understand the value of chaining all these systems and patterns together and showing that such a thing is possible at an advanced level; and maybe teaching is a side benefit whereas the primary concern is that you're actually building something useful to you like a specific game you want to eventually publish. However, I'm starting to feel that this format does make it a bit nebulous and difficult to follow any individual pattern if you don't have a decent grasp of all the other ones already. So in order to follow along in THIS tutorial, it's not enough that I know the Mediator pattern. I have to know Visitor, Service Locator, GOAP, generics, and many other things. As opposed to the first patterns in your series about Builder and Factory where I don't have to have prior knowledge, I can just learn about builder and factory. In my case, I was still stuck on the Visitor and Service Locator, so I can't get as much value from learning the Mediator, even though it's definitely something I conceptually get would be really useful as a central command center. So if you do make a GOAP vid - and I really would love it if you did - can you please make it a stand-alone thing that just focuses on that system as if it were the first in the series? Or maybe going forward, a better approach might be to show an introductory implementation for beginners and then finish with the flair of, "Now here's my advanced use case tying into everything else we learned so far." As always, I really appreciate your content.
@git-amend7 ай бұрын
Thanks for sharing your feedback. I can understand how integrating multiple concepts can make it difficult to grasp new patterns without prior knowledge of related systems and patterns. At the same time, it's my intent to create intermediate and advanced Unity content. I appreciate your input and I'll take it into consideration.
@MarushiaDark3167 ай бұрын
@@git-amend By no means am I saying don't do advanced integrated stuff. That's an important niche. All I'm suggesting is maybe do the intro stuff first and THEN tie it into existing systems. So you learn beginner things then graduate to intermediate and advanced things later in the video.
@TheKr0ckeR6 ай бұрын
Sometimes i feel that way too, for example, we have used ServiceLocator, but i generally prefer other solutions like DI or Singleton maybe. But since I dont really grasp the concepts of Service Locator, or i dont prefer; It makes me feel like i am "obligated" to use Service Locator here to make this work. But I know know those concepts are prefer to use and you are showing them to make them work together which is great. Combining Locator, visitor and mediator is great it might be hard to grasp. But THE IMPORTANT PART HERE is you have already shown those concepts in previous videos. So that means as you soon as you have grasped those concept, you will be fine to follow up this tutorial. So i recommend going back and learn those concepts.
@Hovrawl7 ай бұрын
More votes for a GOAP video please 🙏
@mertakbulut2417 ай бұрын
Hello sir, Thanks for the video again. Waiting a video for your code editor.
@git-amend7 ай бұрын
You're welcome
@martin.m.kloeckener8 ай бұрын
Very interesting, haven't heard about this pattern before.
@git-amend8 ай бұрын
Glad to hear that!
@omeryilmaz10215 ай бұрын
can we use this pattern to manage UI system to solve complex relations between buttons and popups etc., or do you have any other solution for ui management because I think its a big issue to get rid of drag and drops, using many components for each buttons and popups, deciding which pop will be front or not and etc..
@git-amend5 ай бұрын
Yes actually that is a very common use of the Mediator pattern. You can see an example of that here: refactoring.guru/design-patterns/mediator
@omeryilmaz10215 ай бұрын
@@git-amend Thank you very much!
@franciscooteiza8 ай бұрын
I know there is no right or wrong answer but what would be the best pattern to apply in a UI? Thanks for another great video.
@git-amend8 ай бұрын
You're welcome. Yes, there is no right or wrong answer, but if you keep the Mediator approach in mind, you'll have a lot easier time reusing similar elements like buttons and toggles. Of course, the Observer pattern is also very useful.
@Efim1418 ай бұрын
Depending on what you want you can either look into Data Binding (simpler approach) or Model-view-presenter pattern (more sophisticated). For starters here's a good playlist to learn about Unity's UI 'intended' architecture: kzbin.info/www/bejne/fpiwf51_j9OEnq8
@franciscooteiza8 ай бұрын
@@Efim141 Thanks for sharing!
@puretrack067 ай бұрын
Any thought on how you would implement this in unity entities api ?
@git-amend7 ай бұрын
Haha... well that's a question with a complex answer. I don't think I can tackle that one in a comment, but maybe that's a good idea for a video when we start talking about DOTS/ECS more.
@puretrack067 ай бұрын
@git-amend would definitely watch as this is something I need with my utility ai implementation
@Multizauri8 ай бұрын
GOAP, let’s go!
@git-amend8 ай бұрын
Another vote! I’ll start working on it!
@kutanarcanakgul55333 ай бұрын
I really like this pattern but I think too much complexity for 1 Pattern, If someone wants to watch this video. It has to know Visitor and Builder Pattern, What is ServiceLocater mean and how it works, Complete Understanding Over Generics etc. Does Mediator Pattern must need a complex system to work? Or Can we purify the workflow of this pattern?
@truman56524 ай бұрын
We just have to remember that each new abstraction = more resources. If game has many entities and logic, then it could be critical and in performance optimization time - it will be antipattern time) - get rid not only from abstractions, but reflection, complex types, any additional logic which needs resources.
@git-amend4 ай бұрын
While abstractions can introduce some overhead, they generally help manage complexity without significant performance costs, unlike reflection, which can be more resource-intensive and should be used sparingly in performance-critical code.