Roblox Weapons Kit Fix

Wow thanks for speedy replies! Can confirm that the creator store has the files now! Gun works great, if you reset (and I assume die in general) with gun out you will have the camera lock and cursor. Assuming you’re aware and it’s not an issue with your newest version.

P.S. I’ve also been cooked by the roblox moderation before so I def hear your case. But that’s neither here nor there.

1 Like

I was just able to have my friend scrape the code of this asset from the game that I had the up-to-date version in. After reverse engineering some of the obfuscated code, I’ve now updated the marketplace version to it. It should have all of the fixes, but let me know if any of you find anything!

Here is the downloadable version too:
RobloxWeaponKitFix-Backup_v1.1.0.rbxm (143.3 KB)

EDIT:
I just created a GitHub page for this asset! If you have any issues, you can now use GitHub’s Issue creation tool instead of posting them on this forum (or do both, I don’t mind!).
GitHub/JustAT0rtoise/Roblox-Weapon-Kit-Fix

1 Like

You rock!! Good idea making a GitHub and your friend is goated (so are you). This works like a charm. Will be making games with these!

1 Like

v1.1.1 has been released:
RobloxWeaponKitFix_v1.1.1.rbxm (143.8 KB)
Release v1.1.1 · JustAT0rtoise/Roblox-Weapon-Kit-Fix

It was brought to my attention that shooting while scoped into a sniper/railgun was not possible, and it showed your crosshair while scoped in too. This was due to 2 very small and simple things that I didn’t do reimplement lol. The fixes done are explained in the asset README and also in the GitHub release.

Continue to send me any issues you guys find or features you guys want!


EDIT because it’s a small fix:
v1.1.2 has been released today also:
RobloxWeaponKitFix_v1.1.2.rbxm (144.4 KB)
Release v1.1.2 · JustAT0rtoise/Roblox-Weapon-Kit-Fix

There was a bug of where if you were using a controller, had a weapon equipped, and were looking around with the right analog stick, then unequipped the weapon or swapped to a non-weapon, and then reequipped a weapon, your camera would keep on spinning at the speed you unequipped the weapon at. The fixes done are explained in the GitHub release.


EDIT2 because it’s another small fix:
v1.1.3 has been released:
RobloxWeaponKitFix_v1.1.3.rbxm (145.8 KB)
Release v1.1.3 · JustAT0rtoise/Roblox-Weapon-Kit-Fix

This re-fixes an old bug discovered by @KoromaruLlM in August 2024, along with a new fix for a small zoom issue when equipping weapons that were previously zoomed into.

2 Likes

With latest 1.1.3 release i am getting this error in the console with the base version AR you included in the file

  14:10:34.058  RunService:fireRenderStepEarlyFunctions unexpected error while invoking callback: Unable to assign property C0. Property is read only  -  Studio
  14:10:34.075  Unable to assign property C0. Property is read only  -  Client - ShoulderCamera:540
  14:10:34.076  Stack Begin  -  Studio
  14:10:34.076  Script 'ReplicatedStorage.WeaponsSystem.Libraries.ShoulderCamera', Line 540 - function applyRootJointFix  -  Studio - ShoulderCamera:540
  14:10:34.076  Script 'ReplicatedStorage.WeaponsSystem.Libraries.ShoulderCamera', Line 513 - function onRenderStep  -  Studio - ShoulderCamera:513
  14:10:34.076  Script 'ReplicatedStorage.WeaponsSystem.Libraries.ShoulderCamera', Line 233  -  Studio - ShoulderCamera:233
  14:10:34.076  Stack End  -  Studio

gun works fine but this is spamming alot making it very annoying and possible performance issues?

Also hands do not return to normal, Can test it here: Zombie Tycoon [Coming Soon! - Roblox

What are you doing at the time that you get this error? Are you able to reproduce and record it? When I put the asset with the base AR into an empty game, it works with no errors, which makes me think it could be something else in your game or something specific causing the glitch.

EDIT: While playing your game for a bit I did not find any issues in console or with my hand, so I’ll definitely need you to show me what you were doing to cause this error.

all i did was equipped the gun to get the error, no special modifications and the game is basicly “Vanilla” besides some blocks and testing a Zombie AI system + topbarplus script.

Maybe its specific to R15 charaters?

Just tried it in game, no error, Maybe it is studio specific when using studio testing.

The base kit is built to support ONLY R15 characters, so that wouldn’t be the case. Very weird though how it works for you now, must’ve been some weird build issue when testing in studio. Thank you for this though as it reminded me to make a fix to allow R6.

v1.1.4


The base kit did not support R6 players and would error out and break. I have added a fix to prevent this and to finally allow R6 users to use the weapons (only issue so far is that the kit’s R15 animations don’t work on R6, but not much we can do there for now).

Not sure what the security side of things look like here but I edited the shoulder cam to stop sprinting while aiming.

Shoulder camera script at line 364 - 369

	if self.sprintEnabled and self.zoomState then
		self.sprintEnabled = false
	else
		self.sprintEnabled = true
	end

This will work smoothly when zooming in and out while holding shift. The premade code already handles all that stuff for us which is handy :]

What is this meant to solve? When you aim with a weapon, the base weapon kit already stops the player’s sprinting and slows them down.

not from my testing it doesn’t. I have the latest version too I am sure.

Import the kit to a new baseplate and try sprinting while aiming; it will not work. I just tried it and it brings my character into AimSpeed and not to SprintSpeed.

I am not sure then I have no clue why it doesn’t replicate the same way mine does. :man_shrugging:

1 Like

I added an extra security method that was inspired by the CG gun kit or whatever its called that is used by prison life (it is posted in the resources section)

All you need to do is the following:

CLI Remote name spoofing

-- edit with your own algo
local function generateID(seed) 
	
	return "" .. game:GetService("HttpService"):GenerateGUID(false) .. "" .. Random.new(seed):NextNumber()
end

and for the lines to modify, do not edit the server code only the client code:


-- 182 -> 214

for _, remoteEventName in pairs(REMOTE_EVENT_NAMES) do
			coroutine.wrap(function()
				local remoteEvent = networkFolder:WaitForChild(remoteEventName, math.huge)
				local callback = NetworkingCallbacks[remoteEventName]

				if callback then
					WeaponsSystem.connections[remoteEventName .. "Remote"] = remoteEvent.OnClientEvent:Connect(function(...)
						callback(...)
					end)	
				end
				
				remoteEvent.Name = generateID(1e2)

				WeaponsSystem.remoteEvents[remoteEventName] = remoteEvent
			end)()
		end

		for _, remoteFuncName in pairs(REMOTE_FUNCTION_NAMES) do
			coroutine.wrap(function()
				local remoteFunc = networkFolder:WaitForChild(remoteFuncName, math.huge)
				local callback = NetworkingCallbacks[remoteFuncName]

				if callback then
					remoteFunc.OnClientInvoke = function(...)
						return callback(...)
					end
				end
				
				remoteEvent.Name = generateID(1e2)

				WeaponsSystem.remoteFunctions[remoteFuncName] = remoteFunc
			end)()
		end


Packet flood defence

I have also added anti packet flooding measures to my version of the code too.

Code to edit, this is for the server:


-- 112 - 161

for _, remoteEventName in pairs(REMOTE_EVENT_NAMES) do
			local remoteEvent = Instance.new("RemoteEvent")
			remoteEvent.Name = remoteEventName
			remoteEvent.Parent = networkFolder

			local callback = NetworkingCallbacks[remoteEventName]

			if not callback then
				--Connect a no-op function to ensure the queue doesn't pile up.
				warn("There is no server callback implemented for the WeaponsSystem RemoteEvent \"%s\"!")
				warn("A default no-op function will be implemented so that the queue cannot be abused.")
				callback = function() end
			end
			WeaponsSystem.connections[remoteEventName .. "Remote"] = remoteEvent.OnServerEvent:Connect(function(player, ...)
				if PacketLimiter:Check(player, networkFolder:FindFirstChild(remoteEventName..""), 100, remoteEventName.."Remote") and ... then
					callback(player, ...)
				else
					print("kicking for flood")
					player:Kick("packet flooding")
				end
			end)
			WeaponsSystem.remoteEvents[remoteEventName] = remoteEvent
		end

		for _, remoteFuncName in pairs(REMOTE_FUNCTION_NAMES) do
			local remoteFunc = Instance.new("RemoteEvent")
			remoteFunc.Name = remoteFuncName
			remoteFunc.Parent = networkFolder

			local callback = NetworkingCallbacks[remoteFuncName]
			if not callback then
				--Connect a no-op function to ensure the queue doesn't pile up.
				warn("There is no server callback implemented for the WeaponsSystem RemoteFunction \"%s\"!")
				warn("A default no-op function will be implemented so that the queue cannot be abused.")
				callback = function() end
			end
			remoteFunc.OnServerInvoke = function(player, ...)
				if PacketLimiter:Check(player, networkFolder:FindFirstChild(remoteEventName..""), 100, remoteEventName.."Remote") and ... then
					return callback(player, ...)
				else
					print("kicking for flood")
					player:Kick("packet flooding")
					return nil
				end
			end
			WeaponsSystem.remoteFunctions[remoteFuncName] = remoteFunc
		end

		networkFolder.Parent = WeaponsSystemFolder
		WeaponsSystem.networkFolder = networkFolder

PacketLimiter module:

Place in server storage please.


local PacketLimiter = {}

local Packets = {}

function PacketLimiter:Check(Player_Object, Remote, RatePerSec, Unique_Identifier)
    local Rate = RatePerSec or 10
	local Identifier = Unique_Identifier or "Identifier"
	
	if not Packets[Player_Object] then
		Packets[Player_Object] = {}
		local connection
		local function PlayerLeft(player)
			if player == Player_Object then
				Packets[Player_Object] = nil
				connection:Disconnect()
			end
		end
		connection = game.Players.PlayerRemoving:Connect(PlayerLeft)
	end
	if not Packets[Player_Object][Remote] then
		Packets[Player_Object][Remote] = {}
	end
	if not Packets[Player_Object][Remote][Identifier] then
		Packets[Player_Object][Remote][Identifier] = {}
	end
	
	if Rate > 1 then
		if Packets[Player_Object][Remote][Identifier]["Count"] then
			local TimeElapsed = tick() - Packets[Player_Object][Remote][Identifier]["StartTime"] 
			if TimeElapsed >= 1 then
				Packets[Player_Object][Remote][Identifier]["Count"] = 1
				Packets[Player_Object][Remote][Identifier]["StartTime"] = tick()
				return true
			else
				Packets[Player_Object][Remote][Identifier]["Count"] = Packets[Player_Object][Remote][Identifier]["Count"] + 1
				return Packets[Player_Object][Remote][Identifier]["Count"] <= Rate
			end
		else
			Packets[Player_Object][Remote][Identifier]["Count"] = 1
			Packets[Player_Object][Remote][Identifier]["StartTime"] = tick()
			return true
		end
	end
	if Rate <= 1 then
		if Packets[Player_Object][Remote][Identifier]["LastTime"] then
			local TimeElapsed = tick() - Packets[Player_Object][Remote][Identifier]["LastTime"]
			if TimeElapsed >= (1/Rate) then
				Packets[Player_Object][Remote][Identifier]["LastTime"] = tick()
				return true
			else
				return false
			end
		else
			Packets[Player_Object][Remote][Identifier]["LastTime"] = tick()
			return true
		end
	end
end

return PacketLimiter

1 Like

Camera Swapping:

This will not bug out when aiming in or out.

Add functionality to register key inputs to swap or however else you want to handle this.
Define the self.LeftCam your self as a boolean

-- LINE 617 - 621 (MIGHT BE DIFFERENT AS MY SCRIPT IS MODIFIED)
if self.LeftCam and not self.zoomState then
		local newCFrame = self.currentCFrame * CFrame.new(-4, 0, 0)
		print(newCFrame)
		self.currentCFrame = newCFrame
	end


All you need to do for this to happen is the following:

if self.LeftCam then -- and not self.zoomState then
		local newCFrame = self.currentCFrame * CFrame.new(-4, 0, 0)
		print(newCFrame)
		self.currentCFrame = newCFrame
	end

-- PUT ABOVE THE BELOW LINE:

-- Move camera forward if zoomed in
	if self.zoomAlpha > 0 then
		local trueZoomedOffset = math.max(self.zoomedOffsetDistance - self.lastOcclusionDistance, 0) -- don't zoom too far in if already occluded
		self.currentCFrame = self.currentCFrame:lerp(self.currentCFrame + trueZoomedOffset * self.currentCFrame.LookVector.Unit, self.zoomAlpha)
	end
1 Like

@L_Moments Where and what requires the BulletWeapon I have not a clue how this is being used. I can read the code of the module but doesn’t help if I cannot access the scripts that use it or find its reference.

Wrote this at 2am do forgive if I am missing something.

1 Like