ClientCast - A Client-based, Idiosyncratic Hitbox System!

Your UpdateAttachment calculation is a ray from the current position to the last position, but if the projectile is moving too fast and there are 2 parts between the current position and the last position, it will count as it hit the part near the current position , which made it look like the projectile would throw the first part in the player’s field of view and hit the second part. So I changed the UpdatedAttachment() function slightly, which makes it more suitable for quick projectile:

local function UpdateAttachment(Attachment, Caster, LastPositions)
	local CurrentPosition = Attachment.WorldPosition
	local LastPosition = LastPositions[Attachment] or CurrentPosition

	if CurrentPosition ~= LastPosition then
		--local RaycastResult = workspace:Raycast(CurrentPosition, LastPosition - CurrentPosition, Caster.RaycastParams)
		local RaycastResult = workspace:Raycast(LastPosition, CurrentPosition - LastPosition, Caster.RaycastParams)

		UpdateCasterEvents(Caster, RaycastResult)

	LastPositions[Attachment] = CurrentPosition

I hope this helps you and thanks for the ClientCast system, it helped me a lot : )

Hey, yeah this behavior makes more sense - ClientCast seems to currently raycast from the current position to the old position, when it’d make more sense to raycast from the old position towards the current position (same vector, but opposite directions).


  • Raycasts now start from the old position and go towards the current position, rather than starting from the current position and going towards the old position. cc @ProHandsomeGod
1 Like

Every time I unequip my weapon I get this error.

I have no code written that does anything to the caster when unequipping. I’m completely clueless on how this happens.

Hey! thanks for showing this. I have updated the script, could you update your ClientCast module to the latest version and see if this error has been fixed? Thanks!


Updated to the latest version. It works now. Thanks!

1 Like

How to use module, please help

This text will be blurred

1 Like

Is there anything specific you are stuck on? I can’t help much if you don’t explain your issue.

1 Like

I am making a fists tool with this that has a left and a right punch. I want to make this so there are two different hitboxes depending on which punch animation is being used, so I’ve created two casters and I start and stop an individual one when they’re needed. However, both casters seem to start when I intend to start only one. Is the module not supposed to be used like this, or is there a workaround?

This seems like an issue with your code. I’m not able to help you further without seeing a decently large snippet of code, but from the information at hand, it shouldn’t be an issue with the module.

What are the benefit’s for me switching to this module? Is it better for the user experience if its client side instead of server? For example, this is my current server side code for hitboxes. It might be bad but it does the job alright.

local ServerSideHandler = coroutine.wrap(function()
	while task.wait(0.009) do
		for i,v in pairs(AllRunningHitBoxes) do
			local player = v.player
			local playercharacter = v.player.Character
			for i,v in pairs(workspace:GetPartsInPart(v.hitboxpart)) do
				if not v:IsDescendantOf(playercharacter) then
					if (tick() - PlayerStates[player.Name].M1Frame) > 0.4 then
					PlayerStates[player.Name].M1Frame = tick()


Your questions are already answered in the thread, please be more specific as to what issues you have with the module.

I found a workaround to my issue. However, an error pops up randomly and I’m wondering what it means.

Did you set AutoSetup to false in the Settings table by any chance? This error should only be happening if you set it to false.

Nope, I’ve never changed the AutoSetup value. Disregard the first edit I made.

That error shouldn’t be occurring if you haven’t changed the AutoSetup value. If possible, could you provide a minimal place file in which this error occurs? It would help greatly in fixing the issue.

Updates -

  • Added checks for if a descendant connection exists before disconnecting it.

  • Added a one-second debounce for disconnecting a remote-event connection, in order to prevent potential remote packet exhaustion. Thank you @Bizarre_Amar for the help in recognizing the issue!

  • Added a check to make sure the Caster is still enabled at the time of receiving the remote packet data.

If the Caster Owner is set to the client, you’d use this for anti-cheat.

    if (Data.Position - Caster.Object.Position).Magnitude > 5 then
        return print("very likely an exploiter")

Is there a way to send the HitHumanoid directly to the Server since the server does the calculations to prevent exploiters? Because people can just call the remote function that sends the Hit Humanoid to the server.

Yes, hence the need for a distance-check. An exploiter could send false hit data from the client to the server, which is unwanted behavior.
If you want to also have the humanoid which was hit sent to the server, see Caster.HumanoidCollided.

I’d like to clarify on a few matters:

  1. Minimizing exploitability is a pipe dream as it stands now anyway - even if you calculate hitboxes on the server, what prevents a client from simply teleporting their character around instead? If teleported at small distances around a target mob, the server won’t be able to detect it as a speed exploit.

  2. As mentioned in the original post, this trades security for client responsiveness & UX, creating for more visually-accurate hitboxes.