I want to improve this really bad framework of my (IMO), how would I go about it?

Hello!

I’m an aspiring dev, just taking it open step at a time. I have been working on combats for a while, just fooling around but I finally steeled myself to take the step of creating something such as an Absolver-like Combat System, but I felt like it was very… Messy.

image
image
image

A lot of things were split when I look at it. I feel like it could be a lot more compact overall. If you would like to see the communication between the scripts, I can also provide that if you need further insight.

I feel like that would be a LOT more important as a consideration that compactness of code. You should ideally make code as readable and organized as possible. If splitting code into 50 different modules makes it more organized, then go with that. If putting code all into one module reduces organization, then don’t do that.

I don’t think I can show all of the code, but I’ll show the setup of the combat at the very least + Stance System

Local Script for Combat:

-- \\ Player-Related Variables // --

local Players = game:GetService("Players");
local Player = Players.LocalPlayer;
local Character = Player.Character or Player.CharacterAdded:Wait();


-- \\ Services // --

local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Dict = require(ReplicatedStorage.Modules.CombatModules.StunHandler.DictionaryHandler)

-- \\ Variables // --

local Debounce = false
local DodgeDebounce = false

local CDS = {

	1,
	2

}


local CurrTime = 0

local PrevTime = 0

local Count = 0

local DodgeCooldown = 10
local DashCooldown = 4

local NearbyPlayer

local LastDash,LastDodge = os.clock(),os.clock()
local LastPressed = os.clock()

-- \\ Functions & Events // --

local function Can(Action)
	if Action == "Dodge" then
		
		return os.clock() - LastDodge >= DodgeCooldown
	elseif Action == "Dash" then
		return os.clock() - LastDash >= DashCooldown
	end
end


UserInputService.InputBegan:Connect(function(Input, Processed)

	if Processed then return end
	
	if Dict.find(Player, "Stunned") then
		return
	end
	
	if Character:FindFirstChildOfClass("Tool") then

		return
	end
	
	if UserInputService:IsKeyDown(Enum.KeyCode.F) then

		return
	end
	
	if Character:WaitForChild("StatusFolder"):FindFirstChild("Dazed") then

		return
	end
	
	
	if Input.UserInputType == Enum.UserInputType.MouseButton1 and not UserInputService:IsKeyDown(Enum.KeyCode.F) then


		if Debounce == false then
			Debounce = true
			CurrTime = os.clock()
			
		
			local PT = CurrTime - PrevTime
			if PT < 1.2 then
	
				Count += 1
				if Count > 4 then
					
					Count = 1
				end
				
			else
				Count = 1
			end
			
			ReplicatedStorage.RemoteEvents.CombatEvents.Hit:FireServer(Count)
		end
	end
	
	
end)

ReplicatedStorage.RemoteEvents.CombatEvents.Hit.OnClientEvent:Connect(function(bool)	
	PrevTime = CurrTime

	if bool then 
		wait(CDS[2])
		
		Debounce = false
	else
	
		Debounce = false
	end
end)

Stance System Local:

local CountChanger = function()
	
	if Count <= 3 then
		Count += 1
		
	elseif Count == 3 or Count >= 3 then
		Count = 1
		
	end
	
end

local CountReverser = function()
	
	if Count == 0 then return end

	if Count >= 2 then
		Count -= 1
	end
	
end

local BlockCountChanger = function()
	
	if BCount <= 2 then
		BCount += 1
		
	elseif BCount == 2 or BCount >= 2 then
		BCount = 1
	end
	
end

-- \\ Main-Script // --

UserInputService.InputBegan:Connect(function(Input, GPE) -- Count Increaser
	
	if GPE then return end
	
	if Debounce == true then return end
	
	
	if UserInputService:IsKeyDown(Enum.KeyCode.F) then
		return
	end
	
	if Input.KeyCode == Enum.KeyCode.T and not UserInputService:IsKeyDown(Enum.KeyCode.F) then
		if Debounce == false then 
			if Boppin.Parent == Players.LocalPlayer.Character.Head then
				Debounce = true
				Boppin.Star:Emit(1)
				Boppin.Circle:Emit(1)
				Boppin.StarAfterImage:Emit(1)
				Boppin.CircleAfterImage:Emit(1)

				CountChanger()
				print(Count)
				Stances:FireServer(Count)
				task.wait(0.7)
				print("Dang")
				Debounce = false
			elseif Boppin.Parent ~= Players.LocalPlayer.Character.Head then
				Debounce = true
				Boppin.Parent = Players.LocalPlayer.Character.Head
				
				Boppin.Star:Emit(1)
				Boppin.Circle:Emit(1)
				Boppin.StarAfterImage:Emit(1)
				Boppin.CircleAfterImage:Emit(1)
				CountChanger()
				
				Stances:FireServer(Count)
				task.wait(0.7)
				
				Debounce = false
			end			
			
		end
	end
end)

UserInputService.InputBegan:Connect(function(Input, GPE) -- Reverse your Count/Stance

	if GPE then return end

	if Debounce == true then return end


	if UserInputService:IsKeyDown(Enum.KeyCode.F) then
		return
	end

	if Input.KeyCode == Enum.KeyCode.Y and not UserInputService:IsKeyDown(Enum.KeyCode.F) then
		if Debounce == false then 
			if Boppin.Parent == Players.LocalPlayer.Character.Head then
				Debounce = true
				Boppin.Star:Emit(1)
				Boppin.Circle:Emit(1)
				Boppin.StarAfterImage:Emit(1)
				Boppin.CircleAfterImage:Emit(1)

				CountReverser()
				
				Stances:FireServer(Count)
				task.wait(0.7)
			
				Debounce = false
			elseif Boppin.Parent ~= Players.LocalPlayer.Character.Head then
				Debounce = true
				Boppin.Parent = Players.LocalPlayer.Character.Head

				Boppin.Star:Emit(1)
				Boppin.Circle:Emit(1)
				Boppin.StarAfterImage:Emit(1)
				Boppin.CircleAfterImage:Emit(1)
				CountReverser()
			
				Stances:FireServer(Count)
				task.wait(0.7)
			
				Debounce = false
			end			

		end
	end
end)

UserInputService.InputBegan:Connect(function(Input, GPE)
	
	if GPE then return end
	
	if Debounce == true then return end

	if Input.KeyCode == Enum.KeyCode.U then
		if Debounce == false then 
			if BlockingBoppin.Parent == Players.LocalPlayer.Character.Head then
				Debounce = true
				BlockingBoppin.Star:Emit(1)
				BlockingBoppin.Circle:Emit(1)
				BlockingBoppin.StarAfterImage:Emit(1)
				BlockingBoppin.CircleAfterImage:Emit(1)

				BlockCountChanger()

				Stances:FireServer(BCount, true)

				task.wait(0.7)

				Debounce = false
			elseif BlockingBoppin.Parent ~= Players.LocalPlayer.Character.Head then
				Debounce = true
				BlockingBoppin.Parent = Players.LocalPlayer.Character.Head

				BlockingBoppin.Star:Emit(1)
				BlockingBoppin.Circle:Emit(1)
				BlockingBoppin.StarAfterImage:Emit(1)
				BlockingBoppin.CircleAfterImage:Emit(1)

				BlockCountChanger()
			
				Stances:FireServer(BCount, true)
				task.wait(0.7)

				Debounce = false
				end			
		end
	end
end)

Server Script (I would like to state I attempted to handle everything combat related here. I just don’t like the way it’s setup)
Combat:

Hit.OnServerEvent:Connect(function(Player, Count)
	
	local Action : AnimationTrack
	local Length
	
	local Character = Player.Character

	
	if DictionaryHandler.find(Player, "Stunned") then end
	
	if DictionaryHandler.find(Player, "ParryFail") then end
	
	if DictionaryHandler.find(Player, "Dazed") then end
	
	if DictionaryHandler.find(Player, "SwingStun") then end
	
	if not DictionaryHandler.find(Player, "Stunned") or DictionaryHandler.find(Player, "ParryFail") or DictionaryHandler.find(Player, "Dazed") or DictionaryHandler.find(Player, "SwingStun") then
		
	if Stances == 1 then
		Action, Length = AnimationHandler.getmultipleAnimation(Character, Count, Animations.StanceOne)
			
	elseif Stances == 2 then
		Action, Length = AnimationHandler.getmultipleAnimation(Character, Count, Animations.StanceTwo)
			
		elseif Stances == 3 then
		
		Action, Length = AnimationHandler.getSingleAnimation(Character:FindFirstChild("Humanoid"), Animations.StanceThree[1])	
			local UppercutRecorder =	Action.KeyframeReached:Connect(function(keyframename)
				if keyframename == "ChargeOne" then
					Action:AdjustSpeed(0)
				end

				if Count == 2 then
					Action:AdjustSpeed(1)	
				end

				if keyframename == "ChargeTwo" then
					Action:AdjustSpeed(0)
				end

				if Count == 3 then
					Action:AdjustSpeed(1)
					CMHandler.BaseCombat(Player, Length, 4)
					if Count < 3 then
						Hit:FireClient(Player, false)

					else
						Hit:FireClient(Player, false)
					end
				end
			end)
			Action:Play()
		return
	end

if Action then	
			
		
	
	Action:Play()
		
	Action:GetMarkerReachedSignal("HitboxSummon"):Connect(function()
		CMHandler.BaseCombat(Player, Length, Count)
	end)
	
	
	task.wait(Length)
	
	if Count < 4 then
		Hit:FireClient(Player, false)
	else
		Hit:FireClient(Player, true) --Resets their cooldowns
		
			end
		end
	else
		Hit:FireClient(Player, false)
		
	end
	
end)

Stance System (In the same script):

-- \\ Functions & Events // --

StanceSwitch.OnServerEvent:Connect(function(Player, Count, Blocking)
	if Blocking ~= true then
	
		Stances = Count
		
	StanceSwitching.Switches(Player, Count)	
	end
	
	if Blocking == true then
		BStances = Count
		
		StanceSwitching.BlockSwitches(Player, Count)
	end
end)

If you really need to see more, I’ll provide the module, but not the modules that work a long with it cause it’s just overall a lot.

Oof. Maybe you can create another module directly in replicatedstorage to find and require the libraires for you, but that would make typechecking disabled unless you add even more code.

Honestly, I think the way that it is currently is fine. No changes needed.

But I’m going to look at the code itself now.

1 Like

Can easily be simplified into:

if Blocking then
	
		Stances = Count
		
	StanceSwitching.Switches(Player, Count)	
	else
		BStances = Count
		
		StanceSwitching.BlockSwitches(Player, Count)
	end

What is this for? Why do you have the same thing twice with the first set of if statements and then the second?

1 Like

Just a second check to see if any of those things wore off before continuing the script.