Attempting to decipher the script of the Linked Sword (default sword)

I’m currently in the process of making a melee weapon from scratch, and I thought there would be no better reference for how to do that than the most popular sword on Roblox, the Linked Sword. For that reason, I’ve been pouring through the code of the sword in Studio attempting to figure out how it works, and I’d say I’ve gotten 90% of the way there. There are several parts, however, that I need help understanding:

  1. At the top of the script there is a “BaseUrl” variable that seems to be meant to used to concatenate URLs, but that is never used in the script. Why is it there?
  2. In the script, there are two functions for “tagging” and “untagging” the humanoid of the player being attacked. It’s not clear to me why this is in the script, though I think it might have to do something with awarding kills because it places the attacker’s player in the humanoid via an ObjectValue.
  3. During the two functions which spell out what happens when the player slashes and lunges respectively, they create a StringValue called “toolanim” and place it inside the tool. I have no idea what this does.
  4. There is a “RightGrip” that is made reference to during the function for dealing damage, but I can’t figure out where it’s initialized. Is this just something that is automatically placed into the right arm whenever any tool is equipped?

Below is the commented code. Let me know what those problem areas could mean, or if I misunderstood a different part of the code.

--Rescripted by Luckymaxer

Tool = script.Parent -- assigning the tool to a variable
Handle = Tool:WaitForChild("Handle") -- grabbing the handle
Mesh = Handle:WaitForChild("Mesh") -- grabbing the mesh of the handle

Players = game:GetService("Players") -- retrieving players service
Debris = game:GetService("Debris") -- retrieving debris service
RunService = game:GetService("RunService") -- retrieving run service

BaseUrl = "http://www.roblox.com/asset/?id=" -- assigning a placeholder string for creating urls (???)

Grips = { -- assigning the grips to different positions
	Up = CFrame.new(0, 0, -1.5, 0, 0, 1, 1, 0, 0, 0, 1, 0),
	Out = CFrame.new(0, 0, -1.5, 0, -1, -0, -1, 0, -0, 0, 0, -1),
}

DamageValues = { -- assigning the damage dealt by different attacks to different values
	BaseDamage = 5,
	SlashDamage = 10,
	LungeDamage = 30,
}

Damage = DamageValues.BaseDamage -- setting a placeholder damage value as the base damage

Sounds = { -- assigning all the sounds to a table
	Slash = Handle:WaitForChild("Slash"),
	Lunge = Handle:WaitForChild("Lunge"),
	Unsheath = Handle:WaitForChild("Unsheath"),
}

LastAttack = 0 -- initializes the time of the last attack

ToolEquipped = false -- creates a placeholder variable to determine whether or not the tool is equipped

Tool.Enabled = true -- sets the tool as enabled by default (debounce)

function SwordUp() -- function for setting the sword into the upright position
	Tool.Grip = Grips.Up
end

function SwordOut() -- function for setting the sword into the outward (lunging) position
	Tool.Grip = Grips.Out
end

function IsTeamMate(Player1, Player2) -- function for determining whether or not the target being attacked is on the same team as the attacker
	return (Player1 and Player2 and not Player1.Neutral and not Player2.Neutral and Player1.TeamColor == Player2.TeamColor) -- if player one and two exist, are both not neutral, and their team colors are the same, return true
end

function TagHumanoid(humanoid, player) -- function for tagging a humanoid (???)
	local Creator_Tag = Instance.new("ObjectValue") -- creates a new object value
	Creator_Tag.Name = "creator" -- names it "creator"
	Creator_Tag.Value = player -- gives it a value of the passed-in player
	Debris:AddItem(Creator_Tag, 2) -- sets it up for deletion in 2 seconds
	Creator_Tag.Parent = humanoid -- parents it to the passed-in humanoid 
end

function UntagHumanoid(humanoid) -- function for removing a tag from a humanoid (???)
	for i, v in pairs(humanoid:GetChildren()) do -- for all of the objects in the humanoid
		if v:IsA("ObjectValue") and v.Name == "creator" then -- if the object is the tag created in the previous function...
			v:Destroy() -- destroy it
		end
	end
end

function Attack() -- function for slashing
	Damage = DamageValues.SlashDamage -- sets the damage to slash damage
	Sounds.Slash:Play() -- plays the slash sound
	local Anim = Instance.new("StringValue") -- creates a new string value (???)
	Anim.Name = "toolanim" -- names it "toolanim" (???)
	Anim.Value = "Slash" -- sets its value to "slash" (???)
	Anim.Parent = Tool -- parents it to the tool (???)
end

function Lunge() -- function for lunging
	Damage = DamageValues.LungeDamage -- sets the damage to lunge damage
	Sounds.Lunge:Play() -- plays the lunge sound
	local Anim = Instance.new("StringValue") -- creates a new string value (???)
	Anim.Name = "toolanim" -- names it "toolanim" (???)
	Anim.Value = "Lunge" -- sets its value to "lunge" (???)
	Anim.Parent = Tool -- parents it to the tool (???)
	local Force = Instance.new("BodyVelocity") -- creates a new bodyvelocity (force)
	Force.velocity = Vector3.new(0, 10, 0) -- sets the velocity to a slight upwards velocity
	Force.maxForce = Vector3.new(0, 4000, 0) -- sets the max force to 4000 upwards
	Debris:AddItem(Force, 0.5) -- sets it up for deletion in half a second
	Force.Parent = RootPart -- parents it to the humanoidrootpart of the attacker
	wait(0.25) -- waits a quarter of a second
	SwordOut() -- sets the sword position to be out
	wait(0.25) -- waits another quarter of a second
	if Force and Force.Parent then -- if the force still exists and the the force has a parent...
		Force:Destroy() -- destroy it
	end
	wait(0.5) -- waits half a second
	SwordUp() --sets the sword position to be up
end

function Blow(Hit) -- function for dealing damage
	if not Hit or not Hit.Parent or not CheckIfAlive() then -- if hit is nil or it's not parented to anything or the attacker isn't alive...
		return -- exit out
	end
	local RightArm = (Character:FindFirstChild("Right Arm") or Character:FindFirstChild("RightHand")) -- find the right arm or hand of the attacker
	if not RightArm then -- if it doesn't exist...
		return -- exit out
	end
	local RightGrip = RightArm:FindFirstChild("RightGrip") -- find the right grip in the right arm (???)
	if not RightGrip or (RightGrip.Part0 ~= RightArm and RightGrip.Part1 ~= RightArm) or (RightGrip.Part0 ~= Handle and RightGrip.Part1 ~= Handle) then -- if it doesn't exist or the two parts being linked aren't the right arm and the tool handle...
		return -- exit out
	end
	local character = Hit.Parent -- assign the parent of the hit part to a variable
	local humanoid = character:FindFirstChild("Humanoid") -- find its humanoid
	if not humanoid then -- if the humanoid doesn't exist...
		return -- exit out
	end
	local player = Players:GetPlayerFromCharacter(character) -- get the target's player from players service
	if player and (player == Player or IsTeamMate(Player, player)) then -- if the target's player exists and it's the same as the attacker's or the target is on the same team as the attacker...
		return -- exit out
	end
	UntagHumanoid(humanoid) -- delete the tag in the humanoid (???)
	TagHumanoid(humanoid, Player) -- create a new tag in the humanoid (???)
	humanoid:TakeDamage(Damage) -- deal the appropriate damage
end

function Activated() -- function that plays when the tool is activated
	if not Tool.Enabled or not ToolEquipped or not CheckIfAlive() then -- if the tool isn't enabled, equipped, or the attacker isn't alive...
		return -- exit out
	end
	Tool.Enabled = false -- disable the tool (debounce)
	local Tick = RunService.Stepped:wait() -- assigns the amount of time passed since the start of the game
	if (Tick - LastAttack) < 0.2 then -- if the difference in time between the current and last attack is less than 0.2 seconds...
		Lunge() -- lunge
	else -- otherwise...
		Attack() -- perform a normal attack
	end
	Damage = DamageValues.BaseDamage -- reset the damage value to the base damage
	LastAttack = Tick -- set the last attack time to the current attack time
	Tool.Enabled = true -- enable the tool (end debounce)
end

function CheckIfAlive() -- function for determining whether or not the attacker is alive
	return (((Character and Character.Parent and Humanoid and Humanoid.Parent and Humanoid.Health > 0 and RootPart and RootPart.Parent and Player and Player.Parent) and true) or false) -- if the attacker's character exists, it's in the workspace, the attacker's humanoid exists and it's in the character, the humanoid's health is greater than 0, and the rootpart and player both exist and have parents that aren't nil, then return true, else return false
end

function Equipped() -- function that plays when the tool is equipped
	Character = Tool.Parent -- assigns the attacker to the character variable
	Player = Players:GetPlayerFromCharacter(Character) -- assigns the player of the attacker to the player variable
	Humanoid = Character:FindFirstChild("Humanoid") -- assigns the humanoid of the attacker to the humanoid variable
	RootPart = Character:FindFirstChild("HumanoidRootPart") -- assigns the rootpart of the attacker to the rootpart variable
	if not CheckIfAlive() then -- if the attacker is not alive...
		return -- exit out
	end
	ToolEquipped = true -- sets the toolequipped boolean to true
	Sounds.Unsheath:Play() -- plays the unsheathing sound
end

function Unequipped() -- function that plays when the tool is unequipped
	ToolEquipped = false -- sets the toolequipped boolean to false
end

SwordUp() -- sets the default pose of the sword in the up position

Handle.Touched:connect(Blow) -- when the handle is touched, run the appropriate function

Tool.Activated:connect(Activated) -- when the tool is activated, run the appropriate function
Tool.Equipped:connect(Equipped) -- when the tool is equipped, run the appropriate function
Tool.Unequipped:connect(Unequipped) -- when the tool is unequipped, run the appropriate function

The url is the endpoint where assets are fetched from. A lot of gears have it but don’t use it (I don’t know why)

I believe you’re correct; it’s a common method for games to tag a player in order to award kills/points

This interacts with the default Animate script that’s placed inside the player’s character. It will listen for this value and play the appropriate animation

Unless your game has custom characters, default Roblox characters will have objects created inside them at runtime when the game starts.

RightGrip is exclusive to R6 rigs however, as R15 rigs use a wider range of attachments instead

It used to be the official way. Roblox would actually track kills/deaths on your Roblox profile. Dark, dark times. That horrendous system would never be recommended by anybody these days.

There still seems to be a “RightGrip” in my R15 rig when I test it that gets added whenever I take out the sword and removed whenever I put it away. I would imagine it’s some carry-over from R6 rigs so that R15 rigs wouldn’t break when using the sword.

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