Client-side utilities

What I dislike more than anything in programming is having to copy & paste similar pieces of code across multiple places. For example, I have dozens of tools that need to access a humanoid from the client. Copy-pasting them all would be terrible. Having to find a module script would be less terrible but still. Rather, I created a script that runs immediately that populates the shared table with some utility items, to avoid boilerplate in my tools.

What do you guys think?

assert(script.Parent.ClassName == "ReplicatedFirst")
shared[-3] = Vector3.new(nil, -3)
do
	local Slash = Instance.new("StringValue")
	Slash.Name = "toolanim"
	Slash.Value = "Slash"
	shared.Slash = Slash
end
local Player = game:GetService("Players").LocalPlayer
local Anim = Instance.new("Animation")
local Max = Vector3.new(6e4, 6e4, 6e4)
local Humanoid
local Root
local function Added(Char:Model)
	local Humanoid = Char:FindFirstChildOfClass("Humanoid")
	if not Humanoid then
		repeat
			Humanoid = Char.ChildAdded:Wait()
		until Humanoid.ClassName == "Humanoid"
	end
	return Humanoid
end
local function RootAdded(Humanoid:Humanoid)
	local Root = Humanoid.RootPart
	if not Root then
		Humanoid:GetPropertyChangedSignal("RootPart"):Wait()
		return Humanoid.RootPart
	end
	return Root
end
shared.HumanoidAdded = Added
shared.RootAdded = RootAdded
shared.Mouse = Player:GetMouse()
function shared.CharacterAdded()
	return Player.Character or Player.CharacterAdded:Wait()
end
function shared.BodyPosition(Time, Position)
	local Pos = Instance.new("BodyPosition")
	Pos.Position = Position or Root.Position
	Pos.MaxForce = Max
	Pos.Parent = Root
	task.wait(Time)
	Pos:Destroy()
end
function shared.Animation(AnimId)
	Anim.AnimationId = "rbxassetid://"..AnimId
	local Track = Humanoid:LoadAnimation(Anim)
	Anim.AnimationId = string.char()
	Track:Play()
	return Track
end
Player.CharacterAdded:Connect(function(Char)
	shared.Character = Char
	Humanoid = Added(Char)
	shared.Humanoid = Humanoid
	Root = RootAdded(Humanoid)
	shared.RootPart = Root
end)

So a couple of things

Firstly, in regards to shared and _G, a lot of people say not to use them and I do in part agree. Using a module script and referencing it within your code will help maintainability down the line. Assuming you define the module require at the top of your script, you’ll be able to see what dependencies your script uses instead of shared which any script can modify at any time. Like if you want to copy and paste your scripts maybe months down the line (after you’ve forgotten how they were scripted), it makes the process easier.


Secondly:

That can be simplified down really easily

local Players = game:GetService("Players")
local character = Players.LocalPlayer.Character or Players.LocalPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

Also, it’s good practice to use WaitForChild instead of the entire repeat loop stuff (that’s an old school way of doing things)

WaitForChild gets the first child of name Humanoid. What I did gets the first child of classname Humanoid.

The humanoid name is always going to be “Humanoid” under a character, are you using that function for npcs / zombie rigs where the humanoid name is something different?