Number Guessing Script (GUI) - Feedback for my script? I'm a beginner coder

Hey there Globe here,

  • I’ve recently came into ROBLOX scripting. I’ve been into it like a week now, I decided to make a number guessing script. Tips or Feedback Would help a lot, since I’m not that expierenced yet.

Overview:

  • What does the code do and what are you not satisfied with? The code does a number guessing game, it says “Too Low” If the number is under the target Number and “Too high” If it is above it. The rest of the code you can see yourself. I wanted to know If I should change anything in the script that could make it more efficient.

The Local Script:

local TargetNumber = math.random(1, 100)
local RightOrWrong = script.Parent.ScreenGui.Frame.RightOrWrong
local InsertText = script.Parent.ScreenGui.Frame.TextBox

InsertText.FocusLost:Connect(function(enterPressed) -- FocusLost is that it loses focus as a result of the enter key being pressed.
    if enterPressed then
        local Guess = tonumber(InsertText.Text) -- tonumber checks the text that is inserted

        if Guess == nil or Guess < 1 or Guess > 100 then -- Nil is nothing, if guess is under 1 or above 100 then it will not work
            RightOrWrong.Text = "Invalid guess. Please enter a number between 1 and 100."
            RightOrWrong.TextColor3 = Color3.new(1, 0, 0)
        elseif Guess < TargetNumber then
            RightOrWrong.Text = "Too low!"
            RightOrWrong.TextColor3 = Color3.new(1, 0.5, 0)
        elseif Guess > TargetNumber then
            RightOrWrong.Text = "Too high!"
            RightOrWrong.TextColor3 = Color3.new(1, 0.5, 0)
        else
            RightOrWrong.Text = "You win!"
            RightOrWrong.TextColor3 = Color3.new(0, 1, 0)
            TargetNumber = math.random(1, 100)
        end
        
        InsertText.Text = "" -- To clear the Textbox after each input
        InsertText:CaptureFocus() -- Makes plr automaticly get onto the Textbox

        if RightOrWrong.Text == "You win!" then
            wait(1)
            RightOrWrong.Text = "Refreshing Number . . ."
            RightOrWrong.TextColor3 = Color3.new(1, 0, 0)
            wait(3)
            RightOrWrong.Text = "Successfully Refreshed!"
            RightOrWrong.TextColor3 = Color3.new(0, 1, 0)
        end
    end
end)
1 Like

This is very good, especially from a beginner. I can’t really see any chances of improvement since it is quite a basic concept. I like how you’ve commented your code it makes it a lot easier, even for people like me who have scripted for a while, to read it.

2 Likes

Certainly the comments on what you stated, it helped me a lot too. At the time the lines of code I commented are the lines I didn’t understand myself first. Such as CaptureFocus, tonumber, Focuslost. So it helped me a lot with practicing aswell. Thanks for the compliment of the comments :smiley:

I would make a function to display “Too High” and “Too Low” to reduce the total amount of code on the script, and maybe change the else to an elseif number == number then

Other than that it looks pretty good, and commenting code is a good habit to get in to, makes it easier to fix when something goes wrong, and makes it easier for others to see what it does

1 Like

Here are my comments:

  1. Use task.wait() instead if wait(), wait() is deprecated.
  2. Change your if/else chains to smaller parts like:
if invalidCase then
    -- Change text and do your warnings
    
    return -- stop here, it's invalid, no need to continue doing anything.
end
  1. Use and/or statements to decrease the if/else statements when needed (Idk if this is better for optimization and it could be a personal preference).
RightOrWrong.Text = isHigherBoolean and "Too high!" or isLowerBoolean and "Too low!" or "You win!"
RightOrWrong.TextColor3 = (isHigherBoolean or isLowerBoolean) and Color3.new(1, 0.5, 0) or Color3.new(0, 1, 0)
  1. Naming inconsistencies, ex:

^ All with PascalCase.

^ enterPressed with camelCase.


You could use both PascalCase and camelCase but if you have two things that are the same (aka two buttons, two booleans, etc), it’s better to use same cases.
Personally I use camelCase for everything except for classes, something you will discover when entering OOP, I use PascalCase for them.

^ Personal preference too?


Overall it was really great, especially with the fact that you are a beginner, you did very great, good job!
1 Like

Not sure what you ment by

if invalidCase then
    -- Change text and do your warnings
    
    return -- stop here, it's invalid, no need to continue doing anything.
end

Can you explain a bit more in depth?

Sure, here’s some more explanation, say we have these if/else statements:

if condition1 then
	warn("invalid type.")
	
elseif condition2 then
	warn("this can't be that.")
	
elseif condition3 then
	warn("Muse be in range n1 to n2")
	
elseif condition4 then
	warn("something showing success")
	
else
	warn("Met conditions but you had ______") -- say a high/low guess in ur case
end

You would need to stop after each of the failures as it already failed no way! , so, here is a better way to do this (imo).

if condition1 then return warn("invalid type.") end
if condition2 then return warn("this can't be that.") end
if condition3 then return warn("Muse be in range n1 to n2") end
if not condition4 then return warn("Met conditions but you had ______") --[[say a high/low guess in ur case]] end

warn("something showing success")

I hope this made more sense. Feel free to ask any extra questions.

1 Like

A small note:

return warn(message)

returns nothing as the built-in warn() function returns nothing, this is just a method I do for writing smaller code, other then doing:

warn(message)

return

I just do it in one line.


To understand how the code changed, look at how each condition gets treated in both cases and look at what happens.

the not keyword switches a value so:

not nil -- true
not true -- false
not false -- true
not 1 -- false
not "Hello, World!" -- false

the --[[...]] is a way of writing multi-lined comments:

-- this is a single-lined comment
--[[
	this
	is
	a
	multi-lined
	comment
]]

-- you can have as many `=` between the brackets!
--[=====[
	comment!
]=====]

-- in the example in the first post, I used it to contain a comment that has a keyword (end) after it:
code --[[comment stuff]] code

-- so:
if condition then --[[comment]] return warn("") end

this is normally not good to do as it will make the code look bad but that was just for the sake of giving an example.

1 Like

Here’s an example how you could do it a little better, I changed some things, defined some more variables and functions to make the code look more clean. You should try to code like this to make your code easier to work with. Compare it with your original script and read the comments so you can see the difference.

local TargetNumber = math.random(1, 100)
local RightOrWrong = script.Parent.ScreenGui.Frame.RightOrWrong
local InsertText = script.Parent.ScreenGui.Frame.TextBox

-- Define variables for the color, you can choose to change these later without having to edit a lot of code
local ErrorColor = Color3.new(1, 0, 0)
local WarningColor = Color3.new(1, 0.5, 0)
local SuccessColor = Color3.new(0, 1, 0)

-- Debounce variable for when the player guesses the number and the number has to be refreshed
local Debounce = false

-- Function to update the result, given the text and color to update it to
local function UpdateResult(Text, Color)
    RightOrWrong.Text = Text
    RightOrWrong.TextColor3 = Color

    InsertText.Text = ""
    InsertText:CaptureFocus()
end

-- Revised function that doesn't have any nested if statements to make the code look a little better.
InsertText.FocusLost:Connect(function(EnterPressed)
    if not EnterPressed or Debounce then return end

    local Guess = tonumber(InsertText.Text)
    if Guess == nil or Guess < 1 or Guess > 100 then
        UpdateResult("Invalid guess. Please enter a number between 1 and 100.", ErrorColor)
        return
    end

    if Guess < TargetNumber then
        UpdateResult("Too low!", WarningColor)
        return
    elseif Guess > TargetNumber then
        UpdateResult("Too high!", WarningColor)
        return
    end

    if Guess == TargetNumber then
        Debounce = true

        UpdateResult("You win!", SuccessColor)
        task.wait(1)
        UpdateResult("Refreshing number...", WarningColor)
        task.wait(2)
        UpdateResult("Successfully refreshed!", SuccessColor)

        Debounce = false
        TargetNumber = math.random(1, 100)

        return
    end
end)

Though it’s really good for something you made with only a week of experience, so good job on that.

1 Like

Only thing that I don’t know certain, is returns. Like when do you use returns and for what are they used for.

return well, returns something from a function and stops it from running, ex:

local function sum(a, b)
    return a + b
end

print(sum(1, 1)) -- 2

Here it returned the sum of both numbers, let’s see how it can stop the function from running:

local function foo(stopEarly)
    if stopEarly then return end

    print("Passed!")
end

foo(true) -- nothing gets printed
foo(false) -- Passed!

This is a simple example, return can be used to return anything, even multiple values!


Hope that cleared up your doubts.
1 Like

You can change this to
not Guess
Makes it more neat.