Modular Upgrades Made Easy Using the Strategy Pattern

แชร์
ฝัง
  • เผยแพร่เมื่อ 17 ต.ค. 2024

ความคิดเห็น • 165

  • @Bitlytic
    @Bitlytic  4 หลายเดือนก่อน +87

    IMPORTANT:
    The GDScript project seems to be broken upon first loading. It complains about some classes missing. Until I can figure out why and push up a fix, you can simply do Project -> Reload Current Project and that should fix the issue

    • @apollyon1311
      @apollyon1311 4 หลายเดือนก่อน +5

      To make the upgrade sprites update in the editor on c# version you must mark the upgrade class and the bullet strategies classes as tools, so before the class it is [GlobalClass, Tool], you build the project then reload it and now it will work as Intended

    • @Mark-ev1ge
      @Mark-ev1ge 4 หลายเดือนก่อน

      Resave the class that it complains about, this fixed it for me

    • @KylerMarkle-p5i
      @KylerMarkle-p5i 4 หลายเดือนก่อน +1

      So I'm looking to expand this to also alter player input. For example, I'm using this for a spell system, where I'd like there to be autofiring spells, single click spells, spells you have to charge, etc
      I can't work out how the referencing should work. I've had to use a resource which holds the bullet (spell) scene and whether it autofires, as I can't reference any of the variables on the packed scene.
      How should I go about this?

  • @dovos8572
    @dovos8572 4 หลายเดือนก่อน +169

    godot really needs more tutorials like this.

    • @c64cosmin
      @c64cosmin 4 หลายเดือนก่อน +1

      I will try my hand at this too, but so happy to see good quality tutorials

    • @dibaterman
      @dibaterman 4 หลายเดือนก่อน +5

      And interfaces.

    • @tkg__
      @tkg__ 4 หลายเดือนก่อน

      @@dibaterman it has interfaces. You can use C#.

    • @dibaterman
      @dibaterman 4 หลายเดือนก่อน +1

      @@tkg__
      He is using GDScript so the context is GDSCript. The idea of having half my project in C# another in GDScript and the next time I want a feature from say RUST then another part of the project in RUST or C++.
      I mean the answer of use C# also isn't really a good one, but it is an answer, I'll give you that.

    • @jackstonverse
      @jackstonverse 3 หลายเดือนก่อน

      It's not really godot specific knowledge, it's rather related to programming in generals. There is a book (free in web format) by Robert Nystrom (developer from EA) about design patterns for games. I'm not sure it's allowed to put links here, but you can easily google it.

  • @maxamillion3437
    @maxamillion3437 4 หลายเดือนก่อน +42

    I understand barely anything, but i have faith that with practice this is gonna be so helpful

    • @naptalky
      @naptalky หลายเดือนก่อน

      It's been 3 months since this comment, have you improved?

  • @acecool_dev
    @acecool_dev 4 หลายเดือนก่อน +38

    Found your channel in the comments section of Brackies, and am blown away at how good your videos are... Keep it up! 💙

  • @MargudnRoboter
    @MargudnRoboter 4 หลายเดือนก่อน +17

    You can even do with less Boilerplate in C# (also kinda in Godot, but less elegantly, cause the first class functions aren't as strictly typed)
    In C# you have the Action and Func and with those you can make types that are functions that take in certain types of parameters and return certain types. And with that you don't need the Class + Polymorhpism Boilerplate.

    • @sheepcommander_
      @sheepcommander_ 4 หลายเดือนก่อน +1

      Wait what?

    • @AdeelTariq0
      @AdeelTariq0 4 หลายเดือนก่อน +1

      But classes are needed here to store member variables like textures or damage modifiers right? I guess if you don't want to reuse code you can do all that in a function too.

    • @MargudnRoboter
      @MargudnRoboter 4 หลายเดือนก่อน

      @@AdeelTariq0 You can do that as well with functions, but it can get a bit convoluted. You can make a specialized function that calls the generalized version with it's parameters and the values you want to have by default (thanks to closures). But I have to say, that I ain't sure how you would go about doing it with variables you want to modify in later calls, but maybe I'm just too tired to think correctly right now.

    • @nubunto
      @nubunto 4 หลายเดือนก่อน +1

      true! but godot 4 has Callables that could be used, too

    • @SeanJMay
      @SeanJMay 4 หลายเดือนก่อน

      @@AdeelTariq0 there's no reason they are required to be stored together on the same object... and possibly some good reasons for not putting them on the same object. If you need to work with the textures, AND _absolutely nothing else needs that instance of that texture, at all, for anything_, then the class is probably fine. But if multiple modules want to share the same data, then having them fight over some private class data (that's what classes are for; hiding data) is not ideal. There's nothing stopping you from having your data stored on its own, in structs (or Nodes), and passing those bits of data into the functions, at appropriate times. It also means that the code for the functions is just completely portable, if they take arguments, and don't assume anything exists. And there would be no instantiation of them; they're just functions.

  • @dibaterman
    @dibaterman 4 หลายเดือนก่อน +12

    Also to note, callables are better than straight up changing the value in more complex games.
    Also the example is using resources which means if you have multiple things that can take a powerup you will want to create a unique instance of these resources.
    You could also have a wrapper class which handles storing data and have the resources that handle the strategy though.
    So for example the apply_update would take 2 arguments (the wrapper and the subject... in this case the bullet)
    So say the effect is to reduce the cool down time until you can fire the next bullet, but that you want that effect to stack 3 times.
    this will increase the stack amount from in the resource and adjust the subject as needed with a callable.
    This then incorporates a mediator pattern which will handle referencing the source of the modifier that way if these modifiers have a duration we can remove its specific effect.
    The use case for this would be say you have a Ring of Vengeance and a Sword of Vengeance which give an effect Vengeance +3 to attack when you attack.
    Lets say you want the effect to stack 3 times and refresh when reapplied.
    You could have the wrapper handle the stacking and duration data, the strategy handle updating that when called and the mediator ensuring the same effect isn't duplicated or throws an exception if you are using a dictionary.

    • @imjust_a
      @imjust_a 4 หลายเดือนก่อน +2

      I'm trying to wrap (hah) my head around this but I'm struggling to understand the first sentence, "callables are better than ... changing the value". Wouldn't a value have to be changed at some point?

    • @dibaterman
      @dibaterman 4 หลายเดือนก่อน

      @@imjust_a
      Callables store values as pointers, they also come with an object reference. In short you can parse more information for separating out information. Further you have much more flexibility when handling the method of updating the value.
      For example if when apply_update is called and a stack increases, we can instead of calling the update across the different strategies involved simply update the stack.
      Assuming the strategy already tracked the wrapper and handled that logic in the original callable we are in turn updating the original value since it is now a pointer.
      So say you have something like this inside the callable:
      return _value * stack
      by increasing the stack the value is updated the next time the previously stored callable is called.
      This is apart from having to change, remove, add a value again, it also simplifies having multiple sources tracking their various injections to the returned value.
      Finally you can easily track which object may be throwing bad values from the object id of the callable.

    • @Dyanosis
      @Dyanosis 4 หลายเดือนก่อน +2

      @@imjust_a What if you change the name of the variable of the value that's being called? What if you want the values to be applied the same way? Say every upgrade is multiplicative but you want it to be additive now. If you use Callables, you'd be able to change that in one place, rather than every single instance that was multiplying.
      Callables are basically a callback function that says "call this function to update some thing when I tell you to". A good way to ensure your code stays more DRY.

    • @imjust_a
      @imjust_a 4 หลายเดือนก่อน

      @@Dyanosis Oh okay, I see what you're saying! I misunderstood the initial post thinking they meant "don't change a value at all" rather than "passing in a function that handles changing the value results in less work"

  • @EmDrive_
    @EmDrive_ 14 วันที่ผ่านมา

    Seeing these practical implementations of things ive been learning about through reading textbooks is really great. Thank you!

  • @arronalt
    @arronalt 4 หลายเดือนก่อน +9

    another useful modular coding pattern to add to our toolset
    these tutorials are very helpful and well planned out, thank you ^^

  • @cryptidpog
    @cryptidpog 4 หลายเดือนก่อน +9

    Hopefully will wrap my head around it with enough practice

  • @sligoman5000
    @sligoman5000 4 หลายเดือนก่อน +3

    I love your Godot videos! I am actually implementing a similar weapon/projectile modifier to a game I'm working on so it's great to see how someone else approaches it.

  • @melpeslier
    @melpeslier หลายเดือนก่อน

    Very good exemples, both, with array sorting, and with bullet upgrades.
    Keep going !

  • @kartopod
    @kartopod 4 หลายเดือนก่อน +4

    Great video! Appreciate the fact that the samples are available to look at to dissect and learn!

  • @LucasFerreira-ek3pr
    @LucasFerreira-ek3pr 3 หลายเดือนก่อน +1

    I was sad that you stopped posting videos for a while because I really like your content on Godot, now I saw this video explaining exactly what I needed for my game, thank you so much, keep uploading pls :)

  • @mrblocklp8701
    @mrblocklp8701 4 หลายเดือนก่อน +1

    Great Video! I really like this kind of tutorials and I’ve understood everything, but I have a question: How did you colorcode your folders inside of the Godot editor?

  • @amosf.2780
    @amosf.2780 4 หลายเดือนก่อน +8

    may I ask how you make the coding animation ?
    they looks so clean and beautiful ! 00:50 to 02:16
    by the way. your videos are one of the best Godot tutorials !! Thank you!

    • @Bitlytic
      @Bitlytic  4 หลายเดือนก่อน +5

      I use MotionCanvas, by Aarthificial. The animations are made using code and you can find out more at motioncanvas.io/
      Thanks for compliment on the visuals by the way!

    • @amosf.2780
      @amosf.2780 4 หลายเดือนก่อน +3

      @@Bitlytic thanks for your light speed response!!

  • @mythrando
    @mythrando 2 หลายเดือนก่อน

    Very nice exploration of using the pattern. Thank you!

  • @Psydle_
    @Psydle_ 2 หลายเดือนก่อน

    I'm applying this sort of modifier to a game right now with GRScript and got a little stuck by not being able to make abstract interfaces. This cleared it up for me quickly and even included the confusing GUI part of Godot, so thank you!

  • @DropCGamestudio
    @DropCGamestudio 4 หลายเดือนก่อน +1

    fantastic explanation! I'll definitely use this for my game, thanks!

  • @kieran1229
    @kieran1229 3 หลายเดือนก่อน +1

    Super informative video, really appreciate it! Thanks!

  • @GuitarBreakOut
    @GuitarBreakOut 4 หลายเดือนก่อน

    I just started learning godot and you have some of the best tutorials out there. thank you so much

  • @magnuspedersen5751
    @magnuspedersen5751 4 หลายเดือนก่อน +2

    this is actually so good it's insane

  • @LandonDevelops
    @LandonDevelops 2 หลายเดือนก่อน

    This is some top-tier genius level content right here and in less than 7 minutes. You explained this so well and succinctly

  • @Evitrea
    @Evitrea 4 หลายเดือนก่อน

    I remembered struggled for a few weeks and came to a solution like this
    Not sure how I feel now a better solution lays before me lol, keep up the good work

  • @JackAllpikeMusic
    @JackAllpikeMusic 4 หลายเดือนก่อน

    I'd love to see more videos like this as someone just getting into Godot. But even for people not using Godot, these are very helpful in just breaking down common ways of handling problems that we may not have heard of. I hadn't considered nor heard of this way of doing things before.

  • @LocherYT
    @LocherYT 2 หลายเดือนก่อน

    this is insanely useful for games whose content is built on modular upgrades.
    For example, for a card battler game (akin to Slay the Spire) you never know what kind of crazy effect you have to implement at a later date.
    By making the points of applying the changes more modular (and by use of fitting signals) you can plug in modular effects at any given stage of the game (during draw phase, initiate combat, after combat, on damage taken, on turn end, etc) while the actual base code remain untouched.

  • @Theo-sf8qn
    @Theo-sf8qn 4 หลายเดือนก่อน +6

    Awesome i love design patterns in godot

  • @ColinBeauregard
    @ColinBeauregard 4 หลายเดือนก่อน

    You have the best videos on these coding topics that I have ever come across in my 6+ years of coding. Seriously, thank you.

  • @runemonger1284
    @runemonger1284 4 หลายเดือนก่อน +1

    This is incredibly useful information. Thank you for sharing.

  • @nick-brooking
    @nick-brooking 3 หลายเดือนก่อน

    This is a really great video. Thanks for putting in the effort to lay it out so clearly! I really appreciate the two halves of sample code at the beginning and real world example later on. I have personally found this technique to be an interesting tradeoff. When you have a good idea of the ways your game will be extensible then it's really valuable. Just like in your example, things like weapon upgrades are quite predictable. I've run into issues however when I've incorrectly predicted the ways I'll want to change the code and have wished I hadn't engineered an extra layer of abstraction. Thanks again for the vid, looking forward to more!

  • @chrissmith5371
    @chrissmith5371 4 หลายเดือนก่อน

    Your tutorials are simple, coherent, and extremely helpful! You're a great teacher.

  • @TrizZzle
    @TrizZzle 4 หลายเดือนก่อน

    Thank you! Very useful, nice explanation and presentation! I was wondering for a long time how you would implement upgrades in a game.

  • @CosmicEntity-pp2ok
    @CosmicEntity-pp2ok 4 หลายเดือนก่อน +1

    amazing video, and thanks for including the source code it makes it so easy for us to experiment on these concepts and learn!

  • @Alexanderserenus
    @Alexanderserenus 2 หลายเดือนก่อน

    great videos , wish you would post more often, your videos are very easy to understand for a complete beginner like me, i need mooore

  • @brockcotterill
    @brockcotterill 4 หลายเดือนก่อน +8

    "Sorry cant make it new Bitlytic video just dropped!!"

  • @r.e.4873
    @r.e.4873 3 หลายเดือนก่อน

    @bitlytic I can tell you're talented and a good teacher. Are you gonna make a full tutorial playlist for a game? I feel like that's a really good way to learn a lot and tie it all together. Even if it's a small project.
    Just a thought, thanks for the great videos!

  • @yakdoggames
    @yakdoggames 4 หลายเดือนก่อน

    Great video, thanks. What do you use to edit you videos, the code examples look really neat.

  • @R8Spike
    @R8Spike 4 หลายเดือนก่อน +3

    I'm having problems using stragety patterns atm so this came at the perfect time!
    I'm right now using c# and Trying to use a Stratgey pattern to make bullet patterns be handeled inside a strategy pattern instead instead of a switch statement, but having trouble firing the bullets when handled using a strategy pattern

  • @purrrparker9864
    @purrrparker9864 หลายเดือนก่อน

    Hi Bitlytic, really helpful video. I have one question: Why do you reparent the BulletParticles to the root node instead of the Bullet? I thought it will be better if the particles disappear when the bullet disappears.
    Anyway, thank you for the video!

  • @youcefbou8078
    @youcefbou8078 3 หลายเดือนก่อน +1

    You are literally the best!

  • @lemonlimelychee
    @lemonlimelychee 4 หลายเดือนก่อน

    hi, your video tutorial about finite state machines and node composition helped me a lot with my game development, this tutorial is actually also applicable to my game and gave an idea, hope you make a inventory system tutorial

  • @dayronalfaro9461
    @dayronalfaro9461 2 หลายเดือนก่อน

    The tutorial that I need, thx man this help me a lot

  • @alexxander7289
    @alexxander7289 4 หลายเดือนก่อน

    you sir are a scholar and a gentleman and a freaking awesome teacher ! thank you !

  • @Akrob55555
    @Akrob55555 4 หลายเดือนก่อน +3

    Doesn't the Simple list example make you skip numbers? The elements shift but it continues at the same index. So if you have two elements after each other that should be removed it will only remove the first one.

  • @aerialsnack
    @aerialsnack 3 หลายเดือนก่อน

    You helped me fix a problem I didn't know I had!

  • @keithwinget6521
    @keithwinget6521 2 หลายเดือนก่อน

    Oh wow. I created a whole separate node script that has the class_name Stat, and I have it store a dictionary of modifiers with the keys being a combination of the modifier type with the source name concatenated to the end so that I can remove modifiers via finding them from their source name using .ends_with(source_name). My "supports" and "spirits" as I'm calling them, can also attach modular components to entities (each component of which contains it's own logic for how to integrate with an entity's other components).
    You gave me some ideas for improving on this, so thanks!
    If I had to do it over, Stat wouldn't be a node, it would be a resource and each thing that needed to care about a stat, would either have individual Stat resources, or it's own child node containing a specific package of Stat resources designed for use together. I have this all working, btw, and I can't wait to finally iterate enough on the game to make it presentable.

  • @VaporCode
    @VaporCode 4 หลายเดือนก่อน +5

    Are you using motion canvas for your video presentation?

    • @Bitlytic
      @Bitlytic  4 หลายเดือนก่อน +4

      Yep, I absolutely love it

    • @sethikablip8607
      @sethikablip8607 4 หลายเดือนก่อน

      Pls continue your tutorials. They are awesome.

  • @r2d2meuleu
    @r2d2meuleu 4 หลายเดือนก่อน

    Thank you for this, I had a clunky and cumbersome implementation of this, now I can go back and upgrade it ! ;)

  • @w1-w2-w3
    @w1-w2-w3 3 หลายเดือนก่อน

    Your videos are so good. I just set my notification on now.

  • @ProrokLebioda
    @ProrokLebioda 4 หลายเดือนก่อน +1

    Damn, that's a good tut! Would've been really useful when I begun work on roguelike :D

  • @bloodcc5168
    @bloodcc5168 4 หลายเดือนก่อน

    this really helps me a lot, thank you

  • @jugibur2117
    @jugibur2117 4 หลายเดือนก่อน +2

    Really great, thanks! Even if I had to slow it down to .75 speed :-)

  • @BocBaBox
    @BocBaBox 4 หลายเดือนก่อน

    Do you plan on making any Motion Canvas tutorials in the future? I was looking around but couldn't find many tutorials :p

  • @alexxander7289
    @alexxander7289 4 หลายเดือนก่อน +1

    For Those who are completely new/lost after downloading - you need to setup The input map for
    "move_up" "move_down" "move_left" and "move_right". AND "primary_fire".
    I downloaded the project and the could not move my player.
    Looking in "player_movement" Script - I saw that the input map(s) for moving were not created.
    Looking in "player_weapon" Script - I saw that "primary_fire" was not in the Input Mappings.
    Once I mapped all of the above, the project worked normally.

  • @piousthepious
    @piousthepious 4 หลายเดือนก่อน +1

    Man I love your stuff.

  • @yosef908
    @yosef908 4 หลายเดือนก่อน

    Great video clear and concise.
    I have a question unrelated to the strategy pattern. I'm a bit confused about the move_toward and lerp functions in Godot.
    i want to convert the velocity.move_toward(direction * MAX_SPEED, (1.0 / acceleration_time) * delta * MAX_SPEED) function to use lerp instead should it be like this velocity = velocity.lerp(direction * MAX_SPEED, (1.0 / acceleration_time) * delta) ?

  • @kruth6663
    @kruth6663 4 หลายเดือนก่อน

    Thank you for making this tutorial!

  • @fvhaudsilhvdfs
    @fvhaudsilhvdfs 23 วันที่ผ่านมา

    is it good practice to be looping through an array each time a bullet is fired? i mean in terms of performance. like what if you have a high rate-of-fire weapon and the array is quite large?

  • @Joan-kr1jo
    @Joan-kr1jo หลายเดือนก่อน

    This is cool. Thank you!

  • @grbrigsted
    @grbrigsted 4 หลายเดือนก่อน

    This is essentially the open/closed principle from the SOLID principles (en.wikipedia.org/wiki/SOLID), but it makes so much sense to apply it here.

  • @jbfelix_
    @jbfelix_ 4 หลายเดือนก่อน

    Great video. I am a software developer, but new to game dev. I have a question: why not use the decorator pattern? It sounds a bit more adequate to this situation since you are adding multiple changes to the object

    • @Bitlytic
      @Bitlytic  4 หลายเดือนก่อน

      I've seen a couple recommendations for the decorator pattern and the simple answer is a gap in my knowledge, any resources you'd recommend for learning more about it?

    • @nouveu1
      @nouveu1 4 หลายเดือนก่อน

      ​@@Bitlytic there is plenty of resources about it, if you want example without UML diagrams mess search for example "baeldung decorator pattern". Example is in Java (C# predecessor so syntax would be familiar for you).
      But in short, if your bullet would be immutable (no setter for damage) then you would need to create wrapper over bullet which calls damage getter on wrapped bullet and adds bonus to it. In such case original bullet damage won't be changed but wrapped (outer) bullet will return increased damage.
      It doesn't make sense in Godot because your bullet is not immutable, you don't have real "private" keyword, and in general immutability is not a thing in game dev industry where you already spawning thousands of bullets and can't afford to double that number. Contrary to IT systems where we don't have a lot of allocations but we have dozens of interconnected components - in such systems immutability is crucial because one component changing some variable can break stuff in other components.

    • @xDRaymanxD
      @xDRaymanxD 2 หลายเดือนก่อน

      @@Bitlytic I've seen it's explained inside the book "Design Patterns" by the so-called "gang of four". Haven't read it myself (yet), but as far as I know it's quite popular. Even though it's not gamedev oriented, it might be a good resource.

  • @SGI077
    @SGI077 4 หลายเดือนก่อน

    So if i understand this correct you just make 1 base bullet scene with a script and then for each other upgrade you make different scripts that extend the base bullet script? Sorry im a noob but im trying to wrap my head arround it. Awesome video!

    • @Rattja
      @Rattja 4 หลายเดือนก่อน

      No, he makes 1 base bullet scene, then when spawned a reference of that bullet is passed to the resources which changes the parameters of that bullet. It does not extend the bullet class, it changes it.

  • @KylerMarkle-p5i
    @KylerMarkle-p5i 3 หลายเดือนก่อน

    So I'm trying to extend this and I'm running into a problem I can't figure out a way around.
    I'm using it for a modular spell system. If I use packed scenes, I can't reference their variables as they aren't created yet.
    For example, different kinds of spells will autofire, some will charge to cast, etc. So instead I tried to store the spell as a resource, and then the resource can hold all the variables as well as the packed scene. But then in the packed scene, the script can't reference the variables as they're in that resource object.
    Any way around this?

  • @quellusdev
    @quellusdev หลายเดือนก่อน

    Love a good Bitlytic video

    • @Bitlytic
      @Bitlytic  หลายเดือนก่อน +1

      Dude I know this guy!

  • @lisoan123
    @lisoan123 26 วันที่ผ่านมา

    I do get this type of composition. But when I would like to add for example triple shot, how would I go about it? I think I would have to somehow change the way bullets are spawned so there are tree different instances instead of one but how would I make it work?

  • @junba1810
    @junba1810 หลายเดือนก่อน

    Great tutorial!

  • @palmpixiplus
    @palmpixiplus 4 หลายเดือนก่อน

    This is ingenious! I had been trying to figure out how to do something like this but wasn't even able to articulate it in a search.
    The main thing that I had been getting hung up on was how to dynamically add upgrades instead of checking the Player for every possible upgrade. Using an array is such an elegant approach.

  • @ERKEK2000
    @ERKEK2000 หลายเดือนก่อน

    love modular stuff

  • @grzegorzpedrycz2630
    @grzegorzpedrycz2630 4 หลายเดือนก่อน

    I can watch this whole day ... :)

  • @miodev5833
    @miodev5833 4 หลายเดือนก่อน

    I love this video presentation, i see you use canvas motion, how you get the style code gdscript?

  • @MrSerikos
    @MrSerikos 4 หลายเดือนก่อน

    Crazy coincidence for me to be working on exactly this. I see you built piercing into your base bullet class, is there a good way to have an upgrade override a default behavior like hitting a wall or enemy? For instance in my project i made an upgrade where the bullet sticks to an an enemy, which would replace the default on_hit_destroy_self, but piercing would also replace it, but should stack with the sticking ability...
    I had an idea to split on_hit into two separate events, on_hit and on_hit_final, or something, but I'd love to get some input on how you might structure this, and when to put things in the base class or not.

  • @ElNightmareYT
    @ElNightmareYT 2 หลายเดือนก่อน

    What I keep struggling with is Multishot and having all the bullets properly carry the properties. (What about multiple.multishots?).
    Or modifiers that also change the bullets trajectory (homing for example).
    Is there anywhere where I could read about this?

  • @michaelkimball3401
    @michaelkimball3401 4 หลายเดือนก่อน +1

    I think the decorator pattern may be a better fit for this particular use case. Strategy is better for replacing logic where as decorator adds on top of existing logic.

  • @HunterxGatherer
    @HunterxGatherer หลายเดือนก่อน

    is this close to component composition but a different flavor ?

  • @longuemire748
    @longuemire748 หลายเดือนก่อน

    thank you, very intersting.

  • @redestroyer7994
    @redestroyer7994 4 หลายเดือนก่อน +1

    I was thinking about a way to make an upgrade that has other upgrades' functionallity, like a firework that has the particles and an explosion hit. I thought of something like a `CompoundUpgrade` thing that you can just insert multiple upgrades in it and make it use each one of the upgrades.

  • @Ignawesome
    @Ignawesome 4 หลายเดือนก่อน +2

    Isn't this pretty much like the command pattern? Im not sure I see the difference.

  • @Weeb1367
    @Weeb1367 4 หลายเดือนก่อน

    Please keep up with C# inclusion if possible, a cool guide!

  • @Crax1415
    @Crax1415 หลายเดือนก่อน

    What if we want to apply an upgrade that is not directly related to the bullet? Like a "burst shot" that shoots 3 bullets in quick succession.

    • @qingxian3870
      @qingxian3870 หลายเดือนก่อน +2

      the weapons that need to be upgraded, not the bullets.

  • @brandonjacksoon
    @brandonjacksoon 4 หลายเดือนก่อน

    Thanks mate!

  • @haxking2
    @haxking2 4 หลายเดือนก่อน

    I'm new to godot, so have I understood this correctly?
    What I understand: Basically a resource holds values, in this case a class object, which is appended to an array in the player when it is picked up.

  • @ArksDigital
    @ArksDigital 4 หลายเดือนก่อน

    Pretty interesting stuff

  • @saveriov.p.7725
    @saveriov.p.7725 7 วันที่ผ่านมา

    bruh did you just remove elements from the list while iterating over it?

  • @merovingen4546
    @merovingen4546 2 หลายเดือนก่อน +1

    at the beginning it truly was a strategy pattern, but in the project example it's decorator )

    • @Utamaru56
      @Utamaru56 หลายเดือนก่อน

      yeah I was like "cool, a decorator. so when are we going to apply a strategy? oh, video ended"

  • @moonnight9474
    @moonnight9474 4 หลายเดือนก่อน

    wow, thank you !

  • @dawidkotlinski
    @dawidkotlinski 15 วันที่ผ่านมา

    Isn't strategy pattern obsolete when you can pass functions around as arguments to other functions? It doesn't seem like there's a point to creating a class, especially with closure functions which can capture variables in outer scope.

  • @AvrumKline
    @AvrumKline 4 หลายเดือนก่อน

    THANK YOU

  • @Olixis
    @Olixis 4 หลายเดือนก่อน +1

    welcome back!

  • @fmilioni
    @fmilioni 4 หลายเดือนก่อน

    Wow, that’s cool

  • @tiggerbiggo
    @tiggerbiggo 3 หลายเดือนก่อน

    This pattern can be made much simpler by using Callables instead of explicit classes. Instead of writing an entire class just to hold a function, just pass in a Callable and store all of your "common" ones somewhere as variables. This means you don't need new classes for every new type of "strategy", you just make a new function and pass it in.

  • @Big_Dai
    @Big_Dai หลายเดือนก่อน

    Dude! Can you make a tutorial on using Dice for Dice-Placement purposes?

  • @mirijanyavo6532
    @mirijanyavo6532 หลายเดือนก่อน

    I'm just watching this randomly browsing on youtube, don't know much about Godot or GDScript, but does it not just have callbacks/first class functions?
    Rather than all this boilerplate, wouldn't it just be easier to make an array of functions and just call them 1 by 1 or compose them?

    • @Bitlytic
      @Bitlytic  หลายเดือนก่อน

      It does have callbacks, and that's totally a valid way to do it here. This is just a more object-oriented approach to it, totally based on preference

    • @mirijanyavo6532
      @mirijanyavo6532 หลายเดือนก่อน

      @@Bitlytic But you'd have to write the functions anyways, I don't see how it affects performance what so ever.

  • @istemann
    @istemann 4 หลายเดือนก่อน

    Thank you

  • @steffa5821
    @steffa5821 4 หลายเดือนก่อน +1

    im here from brackies!!!

  • @Freek314
    @Freek314 4 หลายเดือนก่อน

    So why shouldn't we just use instanced scene nodes for this? One node with funcs to handle all of this in one place without any unnecessary layers of abstraction. Put it under whatever you need the functionality in, then call it from the parent node when needed.

  • @JamesSully
    @JamesSully 4 หลายเดือนก่อน +3

    GDScript has first class functions, so you don't need a whole class with a method to do this.
    The number filter example can be written like this:
    ```
    func is_odd(x):
    return x % 2 != 0
    # return a new list containing only the elements of the input
    # for which the filter function returns true
    func filter_list(list, filter):
    var out = []
    for x in list:
    if filter.call(x):
    out.append(x)
    return out
    var list = [-4, -2, 0, 4, 5]
    print(filter_list(list, is_odd))
    ```
    Similarly with the upgrades, you can make the strategies functions instead of classes, then replace strategy.apply_upgrade(bullet) with strategy.call(bullet). Admittedly you don't get all the cool editor integration though. But it's nice if you want a simple, low boilerplate solution.

  • @dibaterman
    @dibaterman 4 หลายเดือนก่อน +1

    It should be stated, that 99% of using this pattern is reliant on FIRST HAVING A STRATEGY.
    Spend the time to draw out the interactions between your logic and then go ahead and run with this, you'll thank yourself later that week/month.

  • @cloudseer
    @cloudseer 4 หลายเดือนก่อน

    Smooth video. The first half was interesting but then everything after that did not have enough context for me.

  • @romainguegan5280
    @romainguegan5280 หลายเดือนก่อน

    I'm sorry, I don't understand the purpose.
    You can simply pass the variable to the bullet directly (well to the weapon rather).
    Let's say your item does +1 attack damage.
    on_body_entered():
    weapon.attack_damage +=1
    assuming your weapon handles the bullet's spawning damage of course

  • @Kantrul
    @Kantrul 4 หลายเดือนก่อน +68

    Isn't this just polymorphism?

    • @Bitlytic
      @Bitlytic  4 หลายเดือนก่อน +64

      Pretty much, I wanted to explain it in a way that applies to games

    • @mpmedia6735
      @mpmedia6735 4 หลายเดือนก่อน +18

      Yes, but this is particularly an object oriented programming pattern, which, you guessed it, incorporates oop principles.

    • @vil-mo
      @vil-mo 4 หลายเดือนก่อน +10

      ​@@mpmedia6735 Literally the same thing can be done in functional languages like haskell

    • @ultimaxkom8728
      @ultimaxkom8728 4 หลายเดือนก่อน +15

      It's not _particularly an object oriented programming pattern._ OOP is not even a necessity here. If anything, strategy pattern uses composition over inheritance.

    • @apollyon1311
      @apollyon1311 4 หลายเดือนก่อน +16

      ​@@ultimaxkom8728 Wait till you learn that composition is, in fact, also part of OOP and that OOP is not only inheritance

  • @kunai9809
    @kunai9809 3 หลายเดือนก่อน

    honestly, the most important thing I took from this video is that you can COLOR YOUR FOLDERS IN THE FILE SYSTEM!?!?