EASY Stats and Modifiers in Unity | Broker Chain Pattern

Поділитися
Вставка
  • Опубліковано 4 жов 2024

КОМЕНТАРІ • 135

  • @git-amend
    @git-amend  5 місяців тому +24

    Hi everyone! Hope this implementation of the Broker Chain pattern sparks your creativity! Smash that like button and join us on Discord! 👍

  • @nathan5694
    @nathan5694 5 місяців тому +21

    The biggest challenge I think a good stat modifier system faces probably could be an addendum video. Making your modifiers order of operation independent and also performant. You might have a modifier debuff that is designed to Clamp a stat, but if its applied first and then other modifiers are added you wont have consistent behavior. This is also extremely important with equipment modifiers where you might have things that multiplicatively buff Attack, so equipping add modifiers either before or after would have different results. Usually I solve this by creating a priority flag for any modifiers and then just iterating through that way, but I've never been super happy with that solution.

    • @git-amend
      @git-amend  5 місяців тому +12

      Yes, you bring up an excellent challenge. I will give this some thought, because it's definitely a problem many people face.

    • @UmbraGlobe
      @UmbraGlobe 5 місяців тому +1

      I personally solved this by creating more stat modifiers (add, increased, more, raw, override)

    • @crazyfox55
      @crazyfox55 5 місяців тому

      Addition, subtraction, multiply, divide, and clamps applied in that order still result in the largest stat bonus, so for your example, there is a simple solution of sorting, and the mediator can easily do that. Is there a modifier that breaks this? Stat ^ 2 can come after division. A non-increasing or wavy bonus would not fit with sorting but who should design a sign wave stat?

    • @nathan5694
      @nathan5694 5 місяців тому +1

      ​@@crazyfox55 Sorting is nlogn, so you do lose performance on that which may or may not be a problem depending on scope of the system, you can break it down to O(1) if you want to implement separate collections instead of one collection, but that loses extensibility, which could also be fine. There are solutions to this problem that will fit an individual games use case, but I like modularity in my systems and there is nothing I've been too happy with.

    • @drewvananne1796
      @drewvananne1796 5 місяців тому +1

      One optimization could be to only sort when a modifier is added and cache the value of the stat with the currently active modifiers. Instead of sorting and iterating across every modifier every time the stat property is accessed. This way if you only had a permanent attack buff from an equipped sword, it’d just have to calculate once upon equipping.
      But really I’d be surprised if this system was ever much of a performance bottleneck unless a game plans to have thousands of modifiers active at one time on a single character. Don’t worry too much about performance if these kinds of things aren’t updating every frame and aren’t allocating any memory. Sorting even several hundred modifiers by their enum value for operation type would be very fast.

  • @FireGmr3
    @FireGmr3 5 місяців тому +22

    Dude. Keep it up not only is this a great resource for learning game dev things but really good for seeing patterns in action

  • @GTZ-98
    @GTZ-98 5 місяців тому +10

    Man it‘s always the same with your videos…
    I see a topic that I have some experience with, then after watching your video I feel like I have no idea what I was even doing before.
    Your code quality compared to other game dev channels is insane!
    Keep up the good work! :D

    • @git-amend
      @git-amend  5 місяців тому +1

      Thanks! I hope you like the next video about Refactoring as well, which builds on this video!

  • @prometheus1100
    @prometheus1100 5 місяців тому +16

    Amazing stuff. I FINALLY found a unity content creator aimed at developers that aren't complete beginners.
    Safe to say I subscribed immediately. Personally I'd love to see some roguelike specific content like random dungeon generation, loot systems, etc.. Thanks!

    • @git-amend
      @git-amend  5 місяців тому +5

      Welcome aboard! You'll probably like the Discord too!

  • @Thomas-yz3ny
    @Thomas-yz3ny 5 місяців тому +6

    That's the first time I see pure quality code in a game dev related video. Thank you! I'm quite advanced and it's a breeze and refreshing to follow you through!

    • @git-amend
      @git-amend  5 місяців тому +1

      Great to hear!

  • @MrOfearos
    @MrOfearos 5 місяців тому

    Many things I could say, bottom line is: you're a legend and I hope u know how much we appreciate you and your content

    • @git-amend
      @git-amend  5 місяців тому

      Thank you so much! Very encouraging to hear that!

    • @MrOfearos
      @MrOfearos 5 місяців тому

      @@git-amend sure! You fill a gap that was sorely missed in the game dev toturials world and you do it in such a great quality

  • @umapessoa6051
    @umapessoa6051 5 місяців тому +1

    Hi, thanks for the video, i have a almost identical system in my Steam game and i didnt knew this had a name 😂
    One thing about the Timer, i also have a custom one implemented, you can have a static event when they start and a monobehaviour manager class that listen and is responsible for ticking and disposing of them, this makes easier to use them on non-monobehaviour class like FSMs 😊

    • @git-amend
      @git-amend  5 місяців тому

      Nice! You might find this interesting, something that came out of a conversation on Discord the other day: gist.github.com/adammyhre/68a4c14f4478a9f64adc0759f7e4f402

  • @lonbpalmer
    @lonbpalmer Місяць тому

    I still get shudders when I think of the last time we implemented a Visitor pattern in a big project. That's one pattern I'll never use again. PS: I love this series, thanks for making it!

    • @git-amend
      @git-amend  Місяць тому

      Thank you! Sounds like a good story about the pattern implementation...

  • @DMIyce
    @DMIyce 5 місяців тому +1

    Man i love your stuff and presentation. I was looking for more advanced topics. I may not understand everything right away but these help me push myself and my knowledge further. Thank you so much!

    • @git-amend
      @git-amend  5 місяців тому

      Awesome, thank you!

  • @andreasmetz2438
    @andreasmetz2438 5 місяців тому +1

    Fantastic video as always. In a few weeks I'm at a point where I've got to implement a stat-system too and it will most certainly be inspired by this :)
    Keep up the amazing work!

    • @git-amend
      @git-amend  5 місяців тому

      Great, glad to hear that!

  • @PurpleDaemon_
    @PurpleDaemon_ 5 місяців тому +1

    Very cool implementation, thanks for sharing! I definitely can improve my buff system with some ideas from this video.
    Two small things im not sure about:
    1) I would avoid using a linked list for modifiers, since it's not cache-friendly for iterating by, and you still can remove from a normal list in O(1) by simply swapping the desired element with the last one before the actual deletion, since the order in which modifiers are applied should not affect the final result.
    2) I really dont like that we have to check the type in Visit method. Unfortunately, I myself don’t yet know how to avoid this, other than to create a more specific IVisitable interface that has stats.

    • @git-amend
      @git-amend  5 місяців тому

      Thanks for the comment. You are correct, the actual list in the video doesn't matter in regards to order, since that isn't what's applying the modifiers. As for the Type, yeah I'm not sure what an elegant solution to that is yet either. It's on the diffuse brain now.

    • @Soraphis91
      @Soraphis91 5 місяців тому +2

      > 1) I would avoid using a linked list for modifiers, since it's not cache-friendly for iterating by, and you still can remove from a normal list in O(1) by simply swapping the desired element with the last one before the actual deletion, since the order in which modifiers are applied should not affect the final result.
      I also oppose the linked list, but if you have things like multiplicative modifiers order might inded play a role. I'd probably store a List and flag the objects as dead (as even the skipping over a few dead entries is probably way faster than dereferencing the linked list entries), and shrink it whenever the last element is flagged as dead (since that is an O(1))
      > 2) I really dont like that we have to check the type in Visit method. Unfortunately, I myself don’t yet know how to avoid this, other than to create a more specific IVisitable interface that has stats.
      the visitor pattern seems here a bit over-engineered. As the Powerup could also just `ApplyPickupEffect(GetComponent())` in the OnTriggerEnter. Number of GetComponent calls stays the same, type check in visit is gone, visit is gone alltogether and Accept method is also gone.
      alternatively making IVisitor generic (IVisitor where T : IVisitable) so you have to implement a concrete method for every IVisitable the Visitor can accept.
      this would be in-line with the idea of the visitor pattern: having few/a fixed amount of different IVisitables (since adding visitables would be a lot of code change) to receive the benefit of adding Visitors being not that much work.
      3) Retrieving stats is a query.
      changing the stats can only happen if a buff is added/removed so the resulting value can be pretty easily cached and the query only executed once per change in the mediators list.

  • @bluzenkk
    @bluzenkk 5 місяців тому +1

    thankyou , i learn alot from this.

    • @git-amend
      @git-amend  5 місяців тому

      Glad to hear that!

  • @kevin41307
    @kevin41307 5 місяців тому

    THANK A BILLION. That's what I am looking for.

  • @MTweedC4
    @MTweedC4 5 місяців тому

    Git! I love your videos. Also the quizzes

    • @git-amend
      @git-amend  5 місяців тому

      Glad to hear it!

  • @LuizMoratelli
    @LuizMoratelli 5 місяців тому

    Your videos are amazing! Really important stuff to learn and not just a bunch of simple tutorials.

    • @git-amend
      @git-amend  5 місяців тому

      Glad you think so! Thanks!

  • @SuperTungbi
    @SuperTungbi 5 місяців тому

    Shit, I am enlightened every time your video release, thank you so much for the beautiful work ❤

  • @shukarullahshah
    @shukarullahshah 5 місяців тому

    Thank you so much, i was working on this task

    • @git-amend
      @git-amend  5 місяців тому

      You're welcome 😊

  • @littleowlgaming-unity-tutorial

    ive watched all your videos like a dozen times. i enjoy learning the different techniques. then trying to alter them and run them in a slightly different way. such as, taking the GOAP video and converting it into a city manager, that feeds priorities to multiple AIs. i do that type of stuff lots. but if you could, at some point, could you do a inventory video? more so on the focus. of the database. how do you generate a masterlist of items, and access them. how would saving work for a players inventory? right now, i normally make a singleton, that grabs all the SOs/or monos) of that type, and stores them into a list, each having a unique ID from guid in the master list. items can get complex, if not only can they add to a player to change stats, or are required for some quests. or perhaps some are usable. where perhaps the video from the decorator pattern or the video of the stat modifier might come into play.

    • @git-amend
      @git-amend  4 дні тому

      Yes, I've been thinking about revisiting some topics such as Inventory and Stats in the near future, especially since the now experimental App UI will soon be released.

  • @ragerungames
    @ragerungames 5 місяців тому

    Amazing content as always! One of the best youtube channel!

    • @git-amend
      @git-amend  5 місяців тому

      Glad you think so! Thanks!

  • @bbrainstormer2036
    @bbrainstormer2036 5 місяців тому

    Now this is helpful!

  • @skyswimsky1994
    @skyswimsky1994 5 місяців тому

    Haven't heard of this pattern before even in passing. Reminds me somewhat of the Decorator pattern, though doing some research on the topic of "Broker Chain/Chain of Responsibility and Decorator" I'm not the only one. As a ignorant blanket statement I wouldn't say apples vs oranges as much as the Broker Chain being another level of abstraction for more potential control.

    • @git-amend
      @git-amend  5 місяців тому +1

      Absolutely! While the Broker Chain pattern is more common in enterprise applications, the context of video games is often used to teach the pattern because they provide a dynamic and relatable context for understanding how responsibilities can be distributed and managed across different objects.

    • @8BitsPerPlay
      @8BitsPerPlay 5 місяців тому

      @@git-amend Just checking is the Broker Chain pattern and the Chain of Responsibility pattern the same. It seem like one started with more generic and goes to more detailed logic classes. Just wondering if they are considered the same on a technical level.

    • @git-amend
      @git-amend  5 місяців тому +1

      @@8BitsPerPlay They are a little bit different. While both patterns deal with distributing requests among a set of handlers, the Broker Chain uses a central broker to manage communication, which reduces coupling between handlers, unlike the more linear and direct chaining of handlers in the Chain of Responsibility.

    • @8BitsPerPlay
      @8BitsPerPlay 5 місяців тому

      @@git-amend Okay that makes a lot more sense. When trying to find more about the Broker Chain pattern I only kept finding information about Chain of Responsibilities.

  • @정동우-n2x
    @정동우-n2x 5 місяців тому +1

    I think you're really good at coding.

    • @git-amend
      @git-amend  5 місяців тому +1

      Thanks!

    • @정동우-n2x
      @정동우-n2x 5 місяців тому

      ​@@git-amend If you don't mind, why don't you teach me an assembly definition definition next time? Your code is concise and beautiful, but I think modularization should also have an assembly definition.

    • @git-amend
      @git-amend  5 місяців тому +1

      @@정동우-n2x Sure, Assemble Definitions is on my TODO list!

    • @정동우-n2x
      @정동우-n2x 5 місяців тому

      @@git-amend It's a rude and annoying question, but thank you for answering

  • @rofu8096
    @rofu8096 5 місяців тому

    perfection

  • @SetZor666
    @SetZor666 5 місяців тому

    It's great, I woke up this morning pondering some ways to handle my game's player/enemy stat modifiers and this video pops up a day after i subbed to the channel. what i would love is an addressables tutorial that shows more than just loading the stage or static objects. can't seem to find one anywhere. what if i want to have a character model selection (multiplayer game) and all those models are addressable, what would be a good strategy/pattern to handle this.

    • @git-amend
      @git-amend  5 місяців тому

      Thanks for the comment! An Addressables video about loading things on the fly might make for a good video. I'll put it on my list.

  • @williamedwards3911
    @williamedwards3911 4 місяці тому

    @git-amend - thank you for a great video - just getting wise to your channel. Presumably I could swap out the enum (StatType) for a Type And SubType maybe as ScriptableObjects?

    • @git-amend
      @git-amend  4 місяці тому +1

      Seems like something that is not too hard to change, and might make it a bit more user friendly.

  • @codeperson3475
    @codeperson3475 5 місяців тому +1

    Hi! Why did you chose EventHandler approach for PerformQuery? Instead of while loop that sums all modifiers results?

    • @git-amend
      @git-amend  5 місяців тому +3

      By choosing an EventHandler approach, the design adheres to principles of object-oriented design such as encapsulation, loose coupling, and separation of concerns, making the system more maintainable and flexible to changes. This approach typically results in a system that can evolve more easily over time as new requirements emerge or existing functionality needs to be adjusted. This is why the Broker Chain pattern evolved from a basic Chain of Responsibility pattern that you are describing.

    • @codeperson3475
      @codeperson3475 5 місяців тому

      @@git-amend thank you for your content and detailed respone ❤❤❤

  • @charboa531
    @charboa531 5 місяців тому +1

    Hi, I really like your tutorials and game design pattern videos in particular. It has been 3 years since I started game development and I was thinking I am at a level that I can develop and ship a game with my current knowledge of object oriented programming and Unity. I am probably junior-mid level considering you are a senior, and every time I watch one of your tutorials I try to implement that design pattern to my workflow and it kinda creates an endless cycle of learning and applying new things to my code. And this led me to think my eager to learn new design patterns and new programming concepts puts a barrier to my ability to finalize a product. What would you suggest to a fellow junior, should I learn and practice as much design patterns as I can to enhance my workflow or should I focus on finishing my games even though they are developed in less efficient way?

    • @git-amend
      @git-amend  5 місяців тому

      The learning never ends! Keep working on your projects… if you stop creating and just learn, you’ll be learning forever. It’s best to always do both!

  • @Fitz0fury
    @Fitz0fury 5 місяців тому

    How dare you release this AFTER i closed out my stats and modifiers todo list literally this morning... 😂

    • @git-amend
      @git-amend  5 місяців тому +1

      Awww sorry! Hope it was helpful nonetheless!

    • @Fitz0fury
      @Fitz0fury 5 місяців тому +1

      ​@@git-amend Unfortunately it is LOL. I doubt you remember but my first thread on the discord was about this exact issue. i was relatively close to having the solution you have here, but couldn't figured it how to make it more generic. the best i could do needed hand made event channels for every characters individual stats. you and amaree said something to the combined equivalent of "just do it how you know you can for now, and refactor later if you need to..". i literally just decided to retackle it on Saturday night. I had everything done except for accuracy and evasion by 7:37am Sunday. accuracy and evasion commit was 10:05am. i took my phone off focus mode and got my subscriber alert for " stats the easy way". the sheer odds of you dropping this video THREE MONTHS LATER exactly as i finish my stat rework! it literally made me drop a few curse words and laugh the second i read the alert. 😅

    • @git-amend
      @git-amend  5 місяців тому +1

      @@Fitz0fury Well, perhaps ironically, I think next week's video is going to be on the subject of Refactoring 😁

  • @crazyfox55
    @crazyfox55 5 місяців тому

    Doesn't the func kinda defeat the purpose of the stats modifier? Only the specific type is determined by the class.

    • @git-amend
      @git-amend  5 місяців тому +1

      The use of Func provides flexibility by allowing dynamic definition of operations without multiple subclasses, though it might make the relationship between operation and stat type less explicit. Perhaps in a future video we can enhance clarity by incorporating more specific modifier classes or adopting a strategy pattern.

    • @crazyfox55
      @crazyfox55 5 місяців тому

      @@git-amend I would love to see a video about balancing pickups. Because this is a good system so far but I'm not sure how full it would become once lots of pickups and stats are added.

  • @halivudestevez2
    @halivudestevez2 5 місяців тому +1

    the more tutorial I watch from you, the more I feel we get some overcomplicated stuff, which is easy to create bugs and errors.

    • @git-amend
      @git-amend  5 місяців тому +3

      While some content may appear complex, it often aims to demonstrate practices like type safety, encapsulation and separation of concerns, which actually lead to less bugs in the long run and facilitating scalability in more complex games.

    • @28082989
      @28082989 5 місяців тому

      Is either overcomplicating things or the Broker Chain Pattern is awful, and for me is the second one.
      He might be implementing the Broker Chain Pattern correctly, but just imagine adding more StatTypes to this system... no thank you!

  • @DamageSoftware
    @DamageSoftware 5 місяців тому +1

    This looks great! Thanks for sharing.
    One thing is bothering me though.
    I might be missing something, but don't you think it will be better if you somehow cache the calculated value so you don't need to calculate it each time that you access the property getter ?
    What if you need to access the Attack or Defense property getter each frame ? This means that the calculation will happen every time, even though it might not need to.
    What I am personally doing is I do the calculation only when I change the list of modifiers.

    • @git-amend
      @git-amend  5 місяців тому +1

      Thanks for the comment! Yes, a cache would be a good idea if you were concerned about performance, and easy to implement.

    • @crazyfox55
      @crazyfox55 5 місяців тому

      I asked UA-cam for a router example, and it says the stats need to be calculated in each frame if you add a stat modifier that increases or decreases over time. I bet there are still some calculations which could be chached.

    • @publiclag
      @publiclag 5 місяців тому

      @@crazyfox55 I'd probably add an event for modifiers to flag a stat type "dirty". If a stat is dirty when queried, it'll be recalculated, otherwise the cache is used.
      So a modifier that changes over time can mark its stat dirty each update.
      Worst case you'll get one recalculation per frame, which is still a win if the stat is used more than once per frame, and no loss if less often.

  • @silchasruin4487
    @silchasruin4487 5 місяців тому

    I'll have to experiment with this more if I need modifiers and stat changes during runtime for my game but I'm interested in testing it out by creating a simple implementation using Sphere colliders set as triggers which could potentially adjust enemy behaviours or damage/speed stats. On a seperate note, I'm trying to look into a type of Director type AI. Similar to the Director from Left 4 Dead. What I'm thinking about is reducing the overhead from multiple smarter individual enemies and have a director that can take the number of enemies, types of enemies and see what the player is doing or even what weapon the player is holding and come up with strategies such as flanking, taking cover, and more. I'm starting small by monitoring where the player is looking, where player is not, where the player cant see and so on and working from there.

    • @git-amend
      @git-amend  5 місяців тому +1

      Sounds like a very interesting idea, a little bit similar to what I want to do with the Mediator and GOAP videos but with a unique twist. Let me know how you get along with it!

    • @silchasruin4487
      @silchasruin4487 5 місяців тому

      @@git-amend I'll have to DM you on Twitter once I have something functional, I'm still working out the systems for cover and flanking now that I have the FOV stuff out the way. I'll do a test with the Mediator pattern to test if working with 200 enemies on screen is more performant than having each enemy use its own complex logic.

    • @git-amend
      @git-amend  5 місяців тому

      @@silchasruin4487 Sounds good, I look forward to it.

  • @aynotation5202
    @aynotation5202 5 місяців тому

    Good channel to learn thins

  • @adek445
    @adek445 5 місяців тому

    Really great video. I've got kinda lost on Queries but will watch again, implement and figure this out.
    The thing I wonder is that here in this implementation of broker chain pattern we will have to add multiple components of StatModifier if we want to change couple of stats at the same time. I probably would see a little change to have stats modification maybe as a SO and have them as a list in stat modifier, or as some serializable type also in list.
    How would you approach such problem - items could change multiple stats? :)

    • @git-amend
      @git-amend  5 місяців тому +1

      I think you could add an overload to accept a list, seems straightforward

  • @littlerookey5466
    @littlerookey5466 3 місяці тому

    Hi, what is the name of website you're using to plan before code? The one ur using to make diagrams. I really like it. Also your workflow of building system is so helpful! My goal as a programmer is you!

    • @git-amend
      @git-amend  3 місяці тому

      Thank you! That's Excalidraw for Obsidian (ua-cam.com/video/o0exK-xFP3k/v-deo.html). You can use it standalone too at their website.

  • @rechnight
    @rechnight 5 місяців тому +1

    Hey Adam, do you have psychic powers? Just started writing up a CharacterStat class and wondering how to deal with modifiers and your video was uploaded! 😂

    • @git-amend
      @git-amend  5 місяців тому

      Nice! I do not have psychic powers, I don't think, but this was a much requested video!

  • @andrewpullins8817
    @andrewpullins8817 2 місяці тому

    Would you make skill trees be "equipable items". If you have enough XP to upgrade a skill, then "Equip" that skill?

    • @git-amend
      @git-amend  2 місяці тому +1

      That's a good question, and probably has multiple answers. You certainly could do something like making it "equipable", but that might not be my first choice. I'm going to give this more thought, because I'd like to do an entire video about the combination of skill or ability trees with stats and modifiers.

  • @damonfedorick
    @damonfedorick 5 місяців тому

    nice

  • @ryaz4704
    @ryaz4704 5 місяців тому

    I have just unknowingly created a stat system very similar to this. Except the modifier in mine has 2 types, the permanent one and the temporary one

    • @git-amend
      @git-amend  5 місяців тому

      Nice! I had considered separating them; in some cases it might affect gameplay a little bit because of the order they were applied. Something to consider anyway.

    • @ryaz4704
      @ryaz4704 5 місяців тому

      Oh wait, no. It's different. Hmm... I could use your "MarkForRemoval"

    • @ryaz4704
      @ryaz4704 5 місяців тому

      @@git-amend I have a "Priority" property in my stat modifier. It's so that I can calculate the ones with multiply operation first

    • @ryaz4704
      @ryaz4704 5 місяців тому

      @@git-amend Oh also, I made the something similar to MarkForRemoval in my code be virtual and separate the timer logic to stat modifier classes that are temporary

  • @MrHussain99x
    @MrHussain99x 5 місяців тому

    Could this pattern be used in coherence with the strategy pattern? E.g. my player has ability strategies that are called when I press a button. They have cool down times and animations that play. And some of them have buffs/debuffs for stats, whilst others spawn in projectiles etc.

    • @git-amend
      @git-amend  5 місяців тому +1

      Oh yes, absolutely. It's a good idea!

  • @FyresGames
    @FyresGames 5 місяців тому

    Look like a pretty good base to start. For example I got a really long debuff, but I find a potion to remove it immediatly, how could I do that?

    • @git-amend
      @git-amend  5 місяців тому

      Managing cancellation of specific debuffs would likely involve adding a bit more flexibility to the StatsMediator and StatModifier structure. We could add an identifier or use a specific characteristic (like a tag or type), then remove the first matching debuff that matches. We'll probably delve into these kinds of scenarios in next week's video.

    • @FyresGames
      @FyresGames 5 місяців тому

      @@git-amend Nice. Will watch for sure how you expand that Stats modifier.

  • @Guywiththetypewriter
    @Guywiththetypewriter 4 місяці тому

    how do you feel about replacing the get methods with a Dictionary

    • @git-amend
      @git-amend  4 місяці тому

      I think it's a good idea and a natural next step as the system evolves. In fact, I'm using a dispatch table in today's video for just that reason, but it's a Dictionary by Type to Action. Same concept and for the same reason.

    • @Guywiththetypewriter
      @Guywiththetypewriter 4 місяці тому

      @@git-amend brill thought so.
      As a point btw I am currently starting work on a top down tycoon game in a tavern and was wondering if you have any suggestions for handling the logic for entities moving around.
      Gonna need a system where entities can move of their own decision making but also be influenced to do things by player input.

    • @git-amend
      @git-amend  4 місяці тому +1

      @@Guywiththetypewriter I think I might start with either a behavior tree or finite state machine for entity decision-making, which would allow the entities to perform actions based on their state and could also handle player inputs dynamically. Additionally, using the Nav Mesh could allow entities to navigate your environments autonomously as well as under player direction. I've been using the Nav Mesh Agents a lot lately for this reason - even in my last few videos - the agents can move using the nav mesh and behaviour tree AI to get around, but I can just add a simple point and click too with just a few lines so I can set destinations myself.

    • @Guywiththetypewriter
      @Guywiththetypewriter 4 місяці тому

      @@git-amend cheers!
      So also something else which, I'll preface with the fact I'm a university lecturer for engineering before I come off too entitled 😅
      I don't know if it's cause I've spent too much time in Java but I have swapped out quite a few of the implementations in the mediator with interfaces, that then things like the modifiers inherit.
      I do this out of habit as I like to do my logic before my implementation. But thinking about it, it could be a unique way to teach these concepts
      I.e. define interfaces for all the major aspects of the technique first, dive straight into the mediator and have it handle just the interfaces, then build the components.
      That way for viewers there is full context as to how each individual part fits into the overall architecture.
      It comes from something I noticed through teaching a few years back, which is when you explain how each indvidiual brick is made, before showing the blueprints, it can be hard for students to see the house, if you get my meaning?
      Would love your thoughts on this approach.

    • @git-amend
      @git-amend  4 місяці тому +2

      @@Guywiththetypewriter All I'm going to say about that is that a) I agree it is the preferred approach in a classroom or workplace to help students and junior developers think in terms of systems. In my work as a software engineer, of course implementation always begins with interfaces. b) I've come to realize that UA-cam is not a traditional classroom or workplace, and the audience is not a group of aspiring software engineers who have implicit trust in me, the presenter. What resonates with my audience and keeps them from switching to watch something else is something that continues to evolve as I do as a creator, based on analytics and feedback, yours included of course!

  • @Xezner
    @Xezner 5 місяців тому +1

    Hello, what app are you using when you create the diagrams you present in your videos?

    • @git-amend
      @git-amend  5 місяців тому +1

      ExcaliDraw for Obsidian
      ua-cam.com/video/o0exK-xFP3k/v-deo.html

    • @Xezner
      @Xezner 5 місяців тому

      @@git-amend Thank you mate!

  • @SantaGrapa
    @SantaGrapa 2 місяці тому +1

    And what about making a stat depend on other, like health depending on maxHealth. i could make stats have a maxValue but i want maxHealth to be a sepparate stat with its own modifiers. Also maxHealth makes no sense if health is not present, so then i find myself coding stat dependencies. Maybe im making this more complex than it has to be, im just wondering how do big games like diablo manage this.

    • @git-amend
      @git-amend  2 місяці тому

      To make health dependent on maxHealth with separate modifiers, you could implement a method in your Stats class to query maxHealth before applying modifiers to health. This ensures health is always capped by maxHealth. In large games like Diablo, dependencies are often managed by hierarchical stat calculations or a dependency graph ensuring all related stats are updated accordingly.

  • @Diequissom
    @Diequissom 2 місяці тому

    NICE! i couldnt help but notice you're not using scriptable objects... I use them a lot, is there a reason for you to avoid them?

    • @git-amend
      @git-amend  2 місяці тому +1

      SOs are excellent for data-driven design and decoupling data from behavior. However, in this example, I'm focusing on a more traditional C# approach to demonstrate the Broker Chain pattern. You could easily adapt this system to use Scriptable Objects instead.

  • @yanch.965su
    @yanch.965su 5 місяців тому

    Is it okay to not unsubscribe on event after subscribing on it

    • @git-amend
      @git-amend  5 місяців тому

      It is generally not okay to neglect unsubscribing from an event after subscribing because it can lead to memory leaks by keeping the subscribed objects from being garbage collected. Always ensuring that subscriptions are appropriately removed when no longer needed helps maintain optimal performance and resource management in your game.

  • @lizkimber
    @lizkimber 5 місяців тому

    where does ivisitor/ivisitable come from?

    • @git-amend
      @git-amend  5 місяців тому

      It was from an earlier video - I've added a copy to this repository for you:
      github.com/adammyhre/Unity-Stats-and-Modifiers/blob/master/Assets/_Project/Scripts/Stats/Visitor.cs

    • @lizkimber
      @lizkimber 5 місяців тому

      @@git-amend awesome thanks - i did search your git but couldnt find it there.. so appreciate it

  • @gameplay_factory
    @gameplay_factory 2 місяці тому

    Amazing work thanks for that just a question is there a way to aviod while loop in here while loops are realy stops unity on any unexpected error

    • @git-amend
      @git-amend  2 місяці тому +1

      You probably want to watch the following video about refactoring where we take this code and improve it.
      ua-cam.com/video/ZJI6USyLtLo/v-deo.html

  • @arnesso92
    @arnesso92 5 місяців тому

    Which asset are those trees and rocks ?

    • @git-amend
      @git-amend  5 місяців тому

      I think most of them came from BK Mountains, though I was messing around with Highland as well. I'll find both the links and add them to the description in a minute here.