Help making a skill framwork

So I’m working on a skill system, and i need a reliable and easy-to-work-with framework. I have a module script (in ReplicatedStorage called MoveData) that defines everything about the move. I want every move to be activated from tools that have the corresponding name. Please help me I’ve been trying for the past 5 hours and I’m really starting to get very disappointed because this is literally my dream game. If anyone could help create a framwork that would mean the WORLD to me. Thank you!

(MoveData):

local assets = game.ReplicatedStorage:WaitForChild("Assets")

local MoveData = {
	--test move
	Fireball = {
		Damage = 5, --self-explanatory
		StunTime = 1.5, --how long the user cannot use moves
		UserStuckTime = 1.2, --this determines how long the user is stuck while using the move
		UserStuckSpeed = 7, --this determines how much WalkSpeed the user has while stuck
		RagdollTime = 1.5, --amount that user is ragdolled for (to ragdoll/unragdoll a player, just do RagdollModule.RagdollCharacter(charactertoragdollgoeshere) and the same thing to unragdoll only instead of saying RagdollModule.Ragdoll it is RagdollModule.Unragdoll)
		MoveFireTime = 1.1, --this is how long it will take before the move fires (example: if its a projectile, it will fire the projectile towards where the cursor is at the time of this firing. Also, right when the move starts, BEFORE this fires, i want the users body to constantly be rotating towards the mouse postion)
		KnockbackForce = 10, --force of the knockback
		KnockbackOrigin = "Center", --could be either center or a specified knockback origin for somthing like a push move
		Animation = "rbxassetid://132127577863396", --the animation the move playes
		Cooldown = 4, --cooldown of the move in seconds
		MoveType = "Projectile", --can be either Projectile, Beam, AoE, Dash, or Continued (for context, continued is if someone stays in the hitbox they will get continued damage and stun.)
		HitboxSize = 3, --calculated in studs
		HitboxType = "Explosion", --can be either Explosion, or Beam (beam will allow me to shape the size in specified directions)
		HitboxOrigin = "Right Arm", --where the hitbox comes form. For example, if its a projectile it will fire from the arm of the player
		VFX = assets.Fireball.Explosion, --VFX that will play for the move
		Projectile = assets.Fireball, --for if the move is a projectile type move
		ProjectileExplodes = true, --for if the move is a projectile type move
		TickDamage = nil, --for continued type moves
		TickTime = nil --for continued type moves
	},
}

return MoveData

:heart: To anyone who helps.

“Easy-to-work-with” is quite subjective, so my suggestion to use object-oriented programming might not work for you. Nevertheless, I’ll still give you a basic idea of what it is, because I am a very strong advocate for it.

Object-oriented programming (commonly abbreviated to OOP) is a programming paradigm where we create classes and use them to represent things in our games. These classes can copy the same variables and functions as other classes through inheritance, making it very easy to adhere to DRY. It’s other advantage is that it can keep everything organized by grouping together functions and variables into one block. While OOP isn’t quite as integrated in Luau as other languages, (eg. C++ and Python), the inheritance features and organization are still very much achievable. You can think of OOP classes as less tangible versions of Roblox objects (eg. BaseParts and Cameras) in that they have properties and methods that you create.

Creating classes involves creating a module script and starting it out with

local Class = {}
Class.__index = Class

return Class

Once we have this set up, we can fill it up with functions like we do with module scripts, but with a few caveats. First is that we need to have what is called a constructor function. This allows us to set some variables and do things when we first create the object.

function Class.new(inFoo)
    local self = setmetatable({}, Class)

    self.foo = inFoo

    return self
end

The constructor function sets up a metatable for the class and is the main strategy for keeping all the functions and properties grouped together.

For any other functions, you’ll need to use a colon instead of the usual dot in order to make use of the self keyword.

function Class:PrintFoo()
    print(self.foo)
end

The self keyword allows you to access and manipulate variables that are stored within the class.

As for the inheritance thing I mentioned, there are a couple of extra steps. The subclass should end up as

local Superclass = require(script.Parent) -- Make subclass a child of the script it is supposed to copy variables from

local Class = {}
Class.__index = setmetatable(Class, Superclass)

return Class

The constructor also needs a minor change. Instead of setting self to a blank metatable, it will need to be set to setmetatable(Superclass.new(), Class) instead.

When using the class, you’ll want a driver script (ie. script or local script) to have

local class = require(ModuleScript) -- The module script holding the class
local object = class.new()

Now, designing a framework for your game is, frankly, something you should do yourself. Designing frameworks are half, if not most, of the game development process. And with how much you’ve already planned out, I’d need to create so much of the framework that you’d have one heck of a time trying to learn the framework. Best I can offer is to type “object-oriented programming luau” into Google and watch those tutorials. Or, if you’re willing to wait and learn an entire framework, just give me the word and I’ll see what I can come up with.

1 Like

Ok thanks. I’ll keep trying to make on on my own.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.