How a clicking system is made?

How a clicking system is made?

Like what’s the math behind it. Player clicks it move the bar and it constantly moving the bar from boss side. So how exactly is calculated how much to move the bar from player and from the boss side?

can anyone give a overview?

3 Likes

What do you exactly mean by “boss side”? Can you give an example?

1 Like

I mean how do you calculate how much to move when player clicks and how much and how fast to move the bar for the boss.

There is health value let’s say, and constant loop that changes bar’s size with math, there is green bar (you resize it) and red bar (static one), you make that every click this health value grows, and you update the bar’s size, if health is bigger than 1, then you win

EDIT: use this to calculate size:

local percent = health/maxHealth
bar.Size = UDim2.new(percent,0,1,0)
1 Like

It goes down too where do you calculate it? On the server right?

So like when player clicks fight, it fires a event telling the server that this player is fighting with that Boss and then server updates the player score on each click but what about the Boss where does it get calculated?

Inside a loop i can think, like you have a table and you put each boss there and updates their’s score in like every .1 or .2 seconds then resize the bar accordingly on the client side.

Idk this what i thinks can be done. I can make it but is it really the way it done?

Ok so each bar would prob have a set amount of power needed e.g. 400 power. So the click power of the player would increase according to their level. I’ll put it in your perspective here
In the picture, you have 602 strength while the ‘boss’ has 100 strength, so the amount the bar moves with each click will vary according to your strength

local mainbar = script.Parent.BossBar
local clickbar = mainbar.PlayerClickBar
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local TS = game:GetService('TweenService')
local maxpower = mainbar:GetAttribute('Power')
local TI = TweenInfo.new(.1,Enum.EasingStyle.Linear,Enum.EasingStyle.Out)
local recordedpower = 0
function FightBack()
   local rann = math.random(0,100)
   if rann < 50 then -- 50% chance, change this to what you want
      recordedpower -= workspace.MiniBoss:GetAttribute('Power')
      TS:Create(clickbar,TI,{Size = UDim2.fromScale(math.clamp(recordedpower/maxpower,0,1),1}):Play()
   end
end
game.ReplicatedStorage.StartMiniBoss.OnClientEvent:Connect(function()
   local t = task.spawn(FightBack)
   mainbar.Visible = true
   mouse.Button1Down:Connect(function()
      if clickbar.Size < mainbar.Size then 
         recordedpower += player:GetAttribute('ClickPower') -- This could be the strength, idk
         TS:Create(clickbar,TI,{Size = UDim2.fromScale(math.clamp(recordedpower/maxpower,0,1),1}):Play()
         if clickbar.Size >= mainbar.Size then
             mainbar.Visible = false
             task.cancel(t)
             recordedpower = 0
             print('Boss defeated!')
             return
         end
      end
   end)
end)
1 Like

On client, health is shared value that server changes, clicks are sent via remote and checked if there is cooldown or smth, then when let’s say number value changes you update your bar’s size

It’s overcomplication, why would you use tween service? there is better option


Client:

--[[Player]]
local player = game:GetService("Players").LocalPlayer
local mouse = player:GetMouse()

--[[Important objects]]
local remote = game:GetService("ReplicatedStorage").ClickRemote
local HealthValueObject = player.BossFight.Health -- example folder

--[[Gui]]
local Gui = player.PlayerGui.BossFightGui
local Indicator = Gui.Frame.Indicator -- red bar
local Bar = Indicator.Bar -- green bar

--[[Update bar's size]]
local function OnUpdate()
    local percent = HealthValueObject.Value
    Bar.Size = UDim2.new(percent,0,1,0) -- Bar is parented to indicator, soo we can use percents
end

--[[Send info about clicking to server]]
mouse.Button1Down:Connect(function()
    remote:FireServer()
end)
HealthValueObject:GetPropertyChangedSignal:Connect(OnUpdate)

Server:

local remote = game:GetService("ReplicatedStorage").ClickRemote
local debounce = {}
local clickCooldown = 0.05 -- cooldown
local clickStrenght = 0.1 -- how many percent one click adds

local function OnServerEvent(player: Player)
    if not debounce[player] then debounce[player] = 0 end
    if tick() - debounce[player] >= clickCooldown then
        debounce[player] = tick()
        player.BossFight.Health.Value += clickStrenght
    end
end

remote.OnServerEvent:Connect(OnServerEvent)

NOTE: This script will update bar when player clicks it, you have to add loop that decrease the same value by some percent every second or soo, i wanted to show that @MysteryX2076’s script could be done better

Im using tween service here to smoothen the green bar size increasing and decreasing, thought it would be appropriate :confused:

If it changes few times per second, then there is no need to smooth it out, but i appreciate this idea

@0786ideal @MysteryX2076

Client Handling is easy. He clicks, the server changes his progress. I was thinking about boss as the game will have multiple players so is multiple bosses.

So do i need to handle them all in some separate loop for each or Can i do this?

function Main.Fight(player,Enemy)  -- add a fight in the active table whenever a player starts a fight
	table.insert(ActiveFights,{player,Enemy,true})  ---{player,enemy,isFighting}
end

	
	while task.wait(.1) do
		
		for i, fight in ipairs(ActiveFights) do
			task.spawn(function()
				local player = fight[1]  --get the player from the active fights
				local enemy = fight[2]--get the Boss from the active fights
								
				wait(EnemiesInfo[enemy.Name].Cooldown)  --- a cooldown for the boss, different boss have different fightback speed
				
				fight[3]-=EnemiesInfo[enemy.Name].Strenght  -- boss fight backs and reduces player progress
				
				if fight[3] == 100 or fight[3] == -100 then  -- if player had to reach the goal first or boss have reach it first fight ends 
					FightEnds(fight)
				end
				
			end)
		end
	end

the Fight[3] is the progress of the fight.

Which changes when player clicks and also when boss fight backs.

The goal for the player is to make the progress reach to 100, so like he add some value in the progress according to his strenght.

And the goal for the boss to make the progress reach to -100, so he subs some value in the progress according to his strenght.

After reaching, the goals fight ends and according to the progress it decides the winner.

Handling client is easy, I’m just thinking about a best way to handle all the bosses.

idk why there is -100, if you can use one of our methoods that are far better than this, also don’t use wait(), use task.wait() instead as it’s faster and better

Can you explain how are you making the boss fight back?

local rate = 1/10
local BossDamage = 0.08
local victory = false
local function BossFight(player: Player)
    repeat
        player.BossFight.Health.Value -= BossDamage
        if player.BossFight.Health.Value >= 1 then victory = true end
        task.wait(rate)
    until victory
end
-- some event such as button click or smth to connect this event to boss fight

Im sort of doing what you are doing now, subtracting the boss power from progress of the player with a 50% chance. While what you are doing works now, it takes a toll on your performance so I recommend running the fight on the client. You can take a part from @0786ideal’s code, sending a remote function to the server every click to modify the master player progress and have the boss fight back, and if the boss dies there give the rewards and stuff to the fighters

Yea. this is my concern. Also there’s some cooldown like .1 and not the true. I’ll change it in the code.

Isn’t handling it on client side make it easy to exploite?

I thought about this but what if player isn’t clicking that mean the boss is not fighting back either. But if you play these games, the boss is constantly fighting back even if player is not.

I was also thinking about this a bit. What about bindable events? Every time a player clicks you can fire it and other players fighting the boss will receive the change. Smth like this

local bossfightevent = game.ReplicatedStorage.MiniBossBindable
game.Players.LocalPlayer:GetMouse().Button1Down:Connect(function()
   bossfightevent:Fire()
end)
bossfightevent.Event:Connect(function()
   -- damage the boss
end)

You could activate this once the boss fight remote event is fired then you could spawn the function for the boss to fight back

1 Like

TBH, this could be a good way. If no one is fighting then there will be no useless processing goin on but also if there’s only one player fighting the boss then again it goin to depend on him if the boss goin to fight back or not.

I think, this is reliable more reliable.

Thanks for the suggestions.

Happy to help, topic really broadened my mind to modify code to suit multiple players

cooldown should be with use of tables&numbers instead of true/false, this allow you to add debounce for many players in one script