Did I write good comments?

I am practicing to write good comments, so that the code is easily understandable. I can never be too sure if the comments are actually good without other developers reading it…

--[[

    Made by: GiantDefender427

    Devforum Post: https://devforum.roblox.com/t/movementhandler-crouch-sprint-slide-prone/1539379

    Accelerator Framework version

]]

-- Service dependencies

local RunService = game:GetService("RunService")

local ContextActionService = game:GetService("ContextActionService")

local TweenService = game:GetService("TweenService")

----------------------

-- MOVEMENT HANDLER --

----------------------

local MovementHandler = {}

-- Properties

-- Reourses

MovementHandler.ReplicatedStorageDirectory = game.ReplicatedStorage:WaitForChild("MovementHandler")

MovementHandler.AnimationFolder = MovementHandler.ReplicatedStorageDirectory:WaitForChild("Animations")

MovementHandler.MovementState = MovementHandler.ReplicatedStorageDirectory:WaitForChild("MovementState")

MovementHandler.HumanoidState = MovementHandler.ReplicatedStorageDirectory:WaitForChild("HumanoidState")

-- Local player

MovementHandler.Player = nil

MovementHandler.Character = nil

MovementHandler.Humanoid = nil

MovementHandler.Animator = nil

-- Camera offset tweens

MovementHandler.CameraOffsetTweens = {}

MovementHandler.CameraOffsetTweens.Default = nil

MovementHandler.CameraOffsetTweens.Crouch = nil

MovementHandler.CameraOffsetTweens.Prone = nil

MovementHandler.CameraOffsetTweens.Slide = nil

-- States

MovementHandler.States = {}

MovementHandler.States.Sprinting = false

MovementHandler.States.Crouching = false

MovementHandler.States.Proning = false

MovementHandler.States.Sliding = false

-- Configurations

MovementHandler.Configurations = {}

MovementHandler.Configurations.WalkSpeed = 16

MovementHandler.Configurations.SprintSpeed = 30

MovementHandler.Configurations.CrouchSpeed = 6

MovementHandler.Configurations.ProneSpeed = 4

-- Animations

MovementHandler.Animations = {}

MovementHandler.Animations.CrouchIdle = MovementHandler.AnimationFolder.CrouchIdle

MovementHandler.Animations.CrouchWalk = MovementHandler.AnimationFolder.CrouchWalk

MovementHandler.Animations.ProneIdle = MovementHandler.AnimationFolder.ProneIdle

MovementHandler.Animations.ProneWalk = MovementHandler.AnimationFolder.ProneWalk

MovementHandler.Animations.Slide = MovementHandler.AnimationFolder.Slide

-- Animation tracks

MovementHandler.AnimationTracks = {}

MovementHandler.AnimationTracks.CrouchIdle = nil

MovementHandler.AnimationTracks.CrouchWalk = nil

MovementHandler.AnimationTracks.ProneIdle = nil

MovementHandler.AnimationTracks.ProneWalk = nil

MovementHandler.AnimationTracks.Slide = nil

-- Functions

-- Lerp

function MovementHandler:Lerp(a, b, t)

    return a * (1 - t) + (b * t)

end

-- Assemble the profile for functionality

function MovementHandler:Initiate()

    -- Saftey measures incase character has already loaded

    self.Character = self.Player.Character

    self.Player.CharacterAdded:Connect(function(Model)

        self:onCharacterAdded(Model)

    end)

    self:GetPlayerInput()

end

-- On character added

function MovementHandler:onCharacterAdded(Model)

    self.Humanoid = Model:WaitForChild("Humanoid")

    self.Character = Model

    self.Animator = self.Humanoid:FindFirstChildOfClass("Animator")

    -- Reload animations for new Humanoid

    self:LoadAnimationTracks()

    -- Reset humanoid event listeners

    self.Humanoid.StateChanged:Connect(function(OldState, NewState)

        self:onHumanoidStateChanged(OldState, NewState)

    end)

    self.Humanoid.Running:Connect(function(Speed)

        self:onHumanoidRunning(Speed)

    end)

    self.Humanoid.Jumping:Connect(function(Jumping)

        self:onHumanoidJumping(Jumping)

    end)

    -- Reset camera offset tweens for new Humanoid

    self:ResetCameraOffsetTweens()

end

-- Load animations

function MovementHandler:LoadAnimationTracks()

    self.AnimationTracks.CrouchIdle = self.Animator:LoadAnimation(self.Animations.CrouchIdle)

    self.AnimationTracks.CrouchWalk = self.Animator:LoadAnimation(self.Animations.CrouchWalk)

    self.AnimationTracks.ProneIdle = self.Animator:LoadAnimation(self.Animations.ProneIdle)

    self.AnimationTracks.ProneWalk = self.Animator:LoadAnimation(self.Animations.ProneWalk)

    self.AnimationTracks.Slide = self.Animator:LoadAnimation(self.Animations.Slide)

end

-- Reset camera offset tweens

function MovementHandler:ResetCameraOffsetTweens()

    self.CameraOffsetTweens.Default = TweenService:Create(self.Humanoid, TweenInfo.new(0.1, Enum.EasingStyle.Sine), {CameraOffset = Vector3.new(0, 0, 0)})

    self.CameraOffsetTweens.Crouch = TweenService:Create(self.Humanoid, TweenInfo.new(0.1, Enum.EasingStyle.Sine), {CameraOffset = Vector3.new(0, -1, 0)})

    self.CameraOffsetTweens.Prone = TweenService:Create(self.Humanoid, TweenInfo.new(0.1, Enum.EasingStyle.Sine), {CameraOffset = Vector3.new(0, -3, 0)})

    self.CameraOffsetTweens.Slide = TweenService:Create(self.Humanoid, TweenInfo.new(0.1, Enum.EasingStyle.Sine), {CameraOffset = Vector3.new(0, -2, 0)})

end

-- Humanoid events

function MovementHandler:onHumanoidStateChanged(OldState, NewState)

    -- Data to be used by external scripts

    self.HumanoidState.Value = tostring(NewState)

end

function MovementHandler:onHumanoidRunning(Speed)

    -- Crouching

    if Speed == 0 then

        self.AnimationTracks.CrouchWalk:Stop()

    elseif self.States.Crouching then

        -- Play animation only if it isnt playing, to avoid restart of animation

        if not self.AnimationTracks.CrouchWalk.IsPlaying then

            self.AnimationTracks.CrouchWalk:Play()

        end

        -- Adjust the speed of animation to match Character WalkSpeed

        self.AnimationTracks.CrouchWalk:AdjustSpeed(Speed / self.AnimationTracks.CrouchWalk.Length)

    end

    -- Proning

    if Speed == 0 then

        self.AnimationTracks.ProneWalk:Stop()

    elseif self.States.Proning then

        -- Play animation only if it isnt playing, to avoid restart of animation

        if not self.AnimationTracks.ProneWalk.IsPlaying then

            self.AnimationTracks.ProneWalk:Play()

        end

        -- Adjust the speed of animation to match Character WalkSpeed

        self.AnimationTracks.ProneWalk:AdjustSpeed(Speed / self.AnimationTracks.ProneWalk.Length)

    end

end

function MovementHandler:onHumanoidJumping(Jumping)

    if Jumping then

        if self.States.Crouching then

            self:StopCrouching()

        end

        if self.States.Proning then

            self:StopProning()

        end

    end

end

-- Sprint

function MovementHandler:StartSprinting()

    if self.States.Crouching then

        self:StopCrouching()

    end

    if self.States.Proning then

        self:StopCrouching()

    end

    if not self.States.Sliding then

        -- Player is sliding, don't overwrite the MovementState

        self.MovementState.Value = "Sprinting"

    end

    self.States.Sprinting = true

    self.Humanoid.WalkSpeed = self.Configurations.SprintSpeed

end

function MovementHandler:StopSprinting()

    self.States.Sprinting = false

    self.Humanoid.WalkSpeed = self.Configurations.WalkSpeed

    if not self.States.Sliding then

        -- Player is sliding, don't overwrite the MovementState

        self.MovementState.Value = ""

    end

end

-- Crouch

function MovementHandler:StartCrouching()

    self.MovementState.Value = "Crouching"

    self.States.Crouching = true

    self.AnimationTracks.CrouchIdle:Play()

    self.CameraOffsetTweens.Crouch:Play()

    self.Humanoid.WalkSpeed = self.Configurations.CrouchSpeed

end

function MovementHandler:StopCrouching()

    self.Humanoid.WalkSpeed = self.Configurations.WalkSpeed

    self.MovementState.Value = ""

    self.States.Crouching = false

    self.AnimationTracks.CrouchIdle:Stop()

    self.AnimationTracks.CrouchWalk:Stop()

    self.CameraOffsetTweens.Default:Play()

end

-- Prone

function MovementHandler:StartProning()

    self.MovementState.Value = "Proning"

    self.States.Proning = true

    self.AnimationTracks.ProneIdle:Play()

    self.CameraOffsetTweens.Prone:Play()

    self.Humanoid.WalkSpeed = self.Configurations.ProneSpeed

end

function MovementHandler:StopProning()

    self.Humanoid.WalkSpeed = self.Configurations.WalkSpeed

    self.MovementState.Value = ""

    self.States.Proning = false

    self.AnimationTracks.ProneIdle:Stop()

    self.AnimationTracks.ProneWalk:Stop()

    self.CameraOffsetTweens.Default:Play()

end

-- Slide

function MovementHandler:StartSliding()

    local HumanoidRootPart = self.Character.HumanoidRootPart

    local JumpPower = self.Humanoid.JumpPower

    local JumpHeight = self.Humanoid.JumpHeight

    local num = 0

    self.MovementState.Value = "Slide"

    self.States.Sliding = true

    self.AnimationTracks.Slide:Play()

    self.CameraOffsetTweens.Slide:Play()

    self.Humanoid.JumpPower = 0

    self.Humanoid.JumpHeight = 0

    -- Slide the character

    while math.abs(num - 5) > 0.01 do

        num = self:Lerp(num, 5, 0.1)

        local rec = num / 10

        HumanoidRootPart.CFrame = HumanoidRootPart.CFrame * CFrame.new(0, 0, -rec)

        RunService.RenderStepped:Wait()

    end

    self.Humanoid.JumpPower = JumpPower

    self.Humanoid.JumpHeight = JumpHeight

    self.MovementState.Value = ""

    self.States.Sliding = false

    self.AnimationTracks.Slide:Stop()

    self.CameraOffsetTweens.Default:Play()

    if self.States.Sprinting then

        -- Sprinting state is still true, start sprinting

        self:StartSprinting()

    end

end

function MovementHandler:ProcessInput(ActionName, InputState, InputObject)

    if InputObject.KeyCode == Enum.KeyCode.LeftShift then

        if InputState == Enum.UserInputState.Begin then

            -- Shift button pressing, start sprinting

            self:StartSprinting()

        else

            -- Shift button not pressing, stop sprinting

            self:StopSprinting()

        end

    end

    if InputObject.KeyCode == Enum.KeyCode.C and InputState == Enum.UserInputState.Begin and self.States.Sliding == false then

        if self.States.Sprinting then

            -- Tried to crouch but player is sprinting

            self:StartSliding()

        else

            if self.States.Crouching then

                -- Player is crouching, stop crouching and start proning

                self:StopCrouching()

                self:StartProning()

            else

                -- Player is proning, stop proning and start crouching

                self:StopProning()

                self:StartCrouching()

            end

        end

    end

end

-- Get player input

function MovementHandler:GetPlayerInput()

    local function PlayerInput(ActionName, InputState, InputObject)

        self:ProcessInput(ActionName, InputState, InputObject)

    end

    ContextActionService:BindAction("Sprint", PlayerInput, true, Enum.KeyCode.LeftShift)

    ContextActionService:SetTitle("Sprint", "Sprint")

    ContextActionService:SetPosition(("Sprint"), UDim2.new(1, -90, 1, -150))

    ContextActionService:BindAction("Crouch", PlayerInput, true, Enum.KeyCode.C)

    ContextActionService:SetTitle("Crouch", "Crouch")

    ContextActionService:SetPosition(("Crouch"), UDim2.new(1, -160, 1, -60))

end

return MovementHandler
5 Likes

The comments are fine. Thou you can do something like --//COMMENT//--

What I do not like is the spacing between each reference. I only separate them in order to categorize them like

--//SERVICES//--
local replicatedStorage = game:GetService("ReplicatedStorage")

--//VARIABLES//--
local player = game.Player.LocalPlayers

local event = replicatedStorage.Remotes.Events.Event
local event2 = replicatedStorage.Remotes.Events.Event2

local hasMoney = false

Something like that

1 Like

I wouldn’t obsess over comments. As long as you use them here and there to clarify blocks of code and it’s understandable + grammatically correct then your fine.

2 Likes

In my opinion comments should only be used to describe parts of your code that aren’t understandable at first glance, ie. complicated math, quirks with your code and hacky bits of logic.

You should aim to write code that is self-documenting and doesn’t need an absurd amount of comments to understand. Good variable & function names along with thoughtful abstraction should be used to make the purpose of your code tacit.

Comments reduce the readability of your code when you don’t moderate their usage. Comments like

----------------------

-- MOVEMENT HANDLER --

----------------------

are especially bad as they contain unnecessary characters and take up large portions of the screen.

One place where overbearing comments are fine is if you are writing them to generate documentation with something like Moonwave for an open source/team project, but I’m assuming this is not the case.

10 Likes

I think adding unnecessary characters in your comments decreases readability and introduces more complexity to your style guide. Keep it boring and simple to digest.

4 Likes

First of all, I would highly reccomend cutting down on the spaces, it can be quite difficult to find a perfect combination between using too many and having to use more spaces, although it’s possible, and the way you’re handling it can be quite confusing. For instance, the GetPlayerInput function. Rather type it like this:

function MovementHandler:GetPlayerInput()
    local function PlayerInput(ActionName, InputState, InputObject)
        self:ProcessInput(ActionName, InputState, InputObject)
    end

    ContextActionService:BindAction("Sprint", PlayerInput, true, Enum.KeyCode.LeftShift)
    ContextActionService:SetTitle("Sprint", "Sprint")
    ContextActionService:SetPosition(("Sprint"), UDim2.new(1, -90, 1, -150))

    ContextActionService:BindAction("Crouch", PlayerInput, true, Enum.KeyCode.C)
    ContextActionService:SetTitle("Crouch", "Crouch")
    ContextActionService:SetPosition(("Crouch"), UDim2.new(1, -160, 1, -60))
end

Now about the comments. Try to not over-do it. Only use comments where the code isn’t too clear at first moment, using comments at obvious points in your code doesn’t have any usecase. I would also reccomend removing the following style of comments:

----------------------

-- MOVEMENT HANDLER --

----------------------

Even though I understand that it might look more clear at first, it actually creates more confusion. Roblox has published a whole guide for the reccomended lua style. It might be interesting to take a look at it.

https://roblox.github.io/lua-style-guide/

Other than that, the code looks neat!