How to make an OOP-Structured NPC in Roblox Studio ep. 1

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

КОМЕНТАРІ • 49

  • @Knineteen19
    @Knineteen19  7 місяців тому +6

    Because I've been getting some complaints about this system being complicated, I wanted to make a bit of a disclaimer. Please read this before continuing this series!
    This tutorial is NOT meant as a beginner "how to make an NPC with pathfinding" tutorial. If all you want is a single NPC with basic functionality, other tutorials do the same thing in simpler ways.
    The point of this tutorial is instead to show how to create an object-oriented NPC base class from which you can inherit behaviors in various subclasses. In other words, you could have a "BaseNPC" class, which has general NPC functionality like following parts and walking to locations. Inheriting from that BaseNPC class, you could then have maybe an "AggressiveNPC" class that attacks players on sight. Inheriting yet again from that, you could have a class for a specific NPC, such as maybe a "Bandit", that maybe has special moves and patterns of behavior that add onto the regular AggressiveNPC.
    This structure of setting up an NPC is only really useful in the case that you will have a wide variety of NPCs that need to inherit logic from one another in object-oriented ways. Apparently I didn't do a good job at making that clear in this series, since I've received a number of complaints from other experienced scripters.

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

      Hey! you probably won't respond to this but where in the explorer tab did you put your script that requires the module script and makes the npc's pathfind? and also, why are you using that framework?

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

      @@mars48379 Assuming you mean the BaseNPC module, then all modules are automatically required by the ModuleHandler module in ReplicatedStorage.Modules.BLU, which is required both from ServerStorage.Server and StarterPlayer.StarterPlayerScripts.Client.
      I'm using the framework because it helps me streamline a ModuleScript-only workflow, which allows functions to be usable from other modules, and basically completely removes the need for anything like BindableEvents for server-server or client-client communication. It also adds some additional quality-of-life features like built-in functions for connecting to common events, such as PlayerAdded, CharacterAdded, the various RunService events, and more.
      I think there should be a link to the framework in the description, which has more information on how the framework works as well. You don't necessarily need to use this framework for this system, if you know how to modify it to work without, but I decided to because I think it makes things easier and quicker to work with.

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

      @@Knineteen19 Thanks for th explanation man!

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

    It's astonishing how little videos there are out there covering more heavy topics like this while keeping it cohesive and interesting. This is also a very interesting framework I've never seen before so I'll definitely have to look into it at some point. Keep up the good work, love to see it.

  • @Jaypiasco
    @Jaypiasco 8 місяців тому +4

    just letting you know that you're doing a great job! Your content has very high value and quality. Much appreciated!

    • @Knineteen19
      @Knineteen19  8 місяців тому +1

      Thanks! I'm glad you're enjoying it.

  • @Obsidian_9
    @Obsidian_9 8 місяців тому +3

    Amazing, cant wait for part 2

  • @ShadowClaw_Dev
    @ShadowClaw_Dev 9 місяців тому +4

    I also made an OOP structured NPC for my game from scratch 👍

  • @Ss-ft3vr
    @Ss-ft3vr 9 місяців тому +4

    Just gotta say adding all those tabs before variables is frowned upon and is insanely hard to read. There's really no point in doing it

    • @Knineteen19
      @Knineteen19  9 місяців тому +3

      I don't know, I find it easier to read, but I always go back and forth on whether or not I should do it. Realistically though, I work on all of my projects alone so it hasn't really mattered too much how I organize my code, but if I wasn't working on my own, I probably wouldn't do it since it would just make things inconsistent. But for just me, it makes it easier for me and feels nicer.

  • @falcon4991
    @falcon4991 9 місяців тому +1

    Make a complete like NPC spawning system with following, attacks, abilities and other features like a Npc has in those big games like Blox Fruits

    • @Knineteen19
      @Knineteen19  9 місяців тому +2

      This system will include spawning and following, but won't include too much along the lines of complex attack patterns and abilities, mostly because I figured it was already going to be long just with the basic set up. However, I can confirm that it's pretty easy to add onto this system (the complete system anyway) to do more complex things, but it would take knowing how to do that, and I may as well make an updated combat tutorial if I was going to show how that.

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

    should use state machines for ai

  • @Spooky.Studios
    @Spooky.Studios 9 місяців тому

    you can set the whole model's Network owner to nil instead of looping through the parts! also the jittering issue probably was because of the pathfinding updating with delays or updating too quickly without a reason to update

    • @Knineteen19
      @Knineteen19  9 місяців тому

      Ah okay, I wasn't sure if doing the model would work or not so I just looped to be safe. Honestly the jittering, when it was happening, would only happen after a fair bit of gameplay, so I wondered if it was just like a memory leak that was building up or maybe just me using pathfinding too intensively. What ended up making it better was when I changed a part later on (with following parts) so that it uses a straight path whenever possible rather than pathfinding a straight line and creating unnecessary lag.

    • @Spooky.Studios
      @Spooky.Studios 9 місяців тому +1

      @@Knineteen19 yeah you may also try the EasyPathfinding module someone had created they also offer stuff like tracking and i believe they already have a method to optimize the pathfinding but i'm not sure
      also i got an idea for you, in your next tutorial for this system you may also try to make NPCs with Weapons (mostly guns and melee)

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

    Il be honest. Sounds like bloat. But maybe its just me coming from a C background lol.
    I noticed the best way to do Roblox is to not treat it like regular languages. Just treat it like how a noob would.

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

      yeah thats how they simplified the game engine lmfao

  • @b3lowtoonatural524
    @b3lowtoonatural524 9 місяців тому +2

    You should use state machines

    • @Knineteen19
      @Knineteen19  9 місяців тому

      I'm not too sure what you mean by that to be honest.

    • @b3lowtoonatural524
      @b3lowtoonatural524 9 місяців тому +1

      a state machine models the system's behavior that uses states and transitions to respond to events
      In the NPC we can set 2 states for walking and attacking.
      When the walking state is entered

    • @thecolorblue7427
      @thecolorblue7427 9 місяців тому

      @@Knineteen19it’s very useful for baked ai sort of projects like these, highly recommend looking into it

    • @b3lowtoonatural524
      @b3lowtoonatural524 9 місяців тому +1

      ​@@Knineteen19it would walk to different waypoints but when the attacking state is entered it would turn aggressive and attack the player

    • @Spooky.Studios
      @Spooky.Studios 9 місяців тому +1

      @@Knineteen19 he basically wants to toggle if something is hostile or not.

  • @devAmos
    @devAmos 9 місяців тому

    I have a question about OOP: how do i make sure that i cleared everything so that there are no memory leaks? I'm just do self.Model:Destroy() and disconnect all connections from self.connections table. Besides this there are other tables, do i need to set all keys or a table to nil?

    • @sqldrop
      @sqldrop 9 місяців тому +1

      LuaU has built in GC, no need to worry about that.

    • @Knineteen19
      @Knineteen19  9 місяців тому +1

      That's what the Janitor object is for inside the NPC object. You can add any connections or functions or anything, and those will all be taken care of when the npc's :Destroy() method is called. If you're worried about memory leaking in any particular way, just add it to the janitor to be taken care of when the NPC is destroyed.
      Although I will make some notes:
      - Connections are automatically disconnected when objects are destroyed (the player events are an exception, such as CharacterAdded, which doesn't disconnect when a player leaves and can cause memory leaks).
      - Like sqldrop is saying, Luau has a built in garbage collector, which basically means that anything that no longer has a reference to it will be removed from memory. For example, if you defined a table in a variable (such as an instance of an NPC), and anything that needed to use that table was done running and there were no references left to it, then that table would be taken out of memory I believe. I could be wrong though, but that's just how I've understood it.

    • @devAmos
      @devAmos 8 місяців тому +1

      okay, ty for advice!

    • @itsnotloveitslust
      @itsnotloveitslust 6 місяців тому

      This is only partially true. It only garbage collects normal lua code. For example, it would clean up a table after it's done being used. But event connection​s, instances, and a few other native roblox values will not be automatically cleaned up. @@sqldrop

  • @isosta2373
    @isosta2373 9 місяців тому

    Why is your constructor a method? Thats where you should be *creating* self, not inheriting it as a parameter.

    • @Knineteen19
      @Knineteen19  9 місяців тому +1

      It's set up that way so class inheritence is easier to do, since self, in the case of the :new() function, is the module itself. For example, later on in this series, we'll be creating an "AggressiveNPC" class that inherits from the "BaseNPC" class. We want to run all of the same code from BaseNPC:new(), but with the values from the AggressiveNPC module, and using a colon was the best way I found to set it up, and so it's how I set up my plugin. Unless you know of a better way to do class inheritance.

    • @isosta2373
      @isosta2373 9 місяців тому

      You should pull the base class into the module and do@@Knineteen19
      function SomeInheritedClass.new(args)
      local self = setmetatable(SomeBaseClass.new(args), SomeInheritedClass)
      return self
      end

    • @isosta2373
      @isosta2373 9 місяців тому

      Having players/npc's run the same code is essential, and actually what I used this protocol for, conveniently enough.@@Knineteen19

  • @ИльдарИсмагилов-х7я
    @ИльдарИсмагилов-х7я 9 місяців тому

    if there will be 2nd episode?

    • @Knineteen19
      @Knineteen19  9 місяців тому +1

      Yes there will be, I just need to edit it and whatnot. It seems like this series is doing well so far so I'd be glad to continue it.

  • @rileybelleville
    @rileybelleville 7 місяців тому

    How do i make an inventory😂😂

  • @sadge6430
    @sadge6430 9 місяців тому

    dsa

  • @shortplayz195
    @shortplayz195 9 місяців тому

    give me a model please i beg you its so hard iv been crying 😭

    • @Knineteen19
      @Knineteen19  9 місяців тому

      You can become a member for $2.99/month on either UA-cam or Patreon and join the Discord for access to all of my files from my tutorials to download. And that means the completed files, since I've been completing them in advance and recording and explaining them after the fact.
      But you can also just join the Discord to ask questions or anything for free if you just want some help.

  • @sadge6430
    @sadge6430 9 місяців тому

    u

  • @sadge6430
    @sadge6430 9 місяців тому

    v

  • @ARandomChad
    @ARandomChad 9 місяців тому

    clash royale