Reading What Went Wrong
The Output window names the script, the line, and the exact object that was nil, and most people close it. Read three real Roblox errors and find the single word in each that identifies the problem.
Worth reading first: Where Code Goes, and Where It Runs
The Output window names the script, the line, and the exact object that was nil, and most people close it. Read three real Roblox errors and find the single word in each that identifies the problem.
The Output window is the whole instrument
Roblox has a debugger, a script analyser, and a performance profiler, and you will use all three eventually. You will use the Output window every single session, and almost every problem in a first obby is solved there.
Open it from View → Output and leave it open. A closed Output window is the reason a beginner believes their script did nothing — the script threw an error on line four, said so clearly, and nobody was listening.
print, warn, and error are three signals
They look similar and they mean quite different things. Using the right one is how your own messages stay readable at a glance six months later.
Plain white. Information you wanted to see. Does not stop anything.
Orange. Something is not right but the script can continue. The correct level for 'this part was missing so I skipped it'.
Red, and it stops the current thread immediately. Use it when carrying on would produce nonsense.
local platform = workspace.Obby:FindFirstChild("Platform") if not platform then warn("No Platform found in Obby — check the name in the Explorer") returnend print("Platform script armed on", platform:GetFullName())There is also assert(condition, message), which errors when the condition is false and does nothing otherwise. It is the shortest way to state an assumption in a line that would otherwise silently proceed on nil.
Output
Laser armed
Workspace.Obby.Laser.KillScript:5: attempt to index nil with 'Humanoid'
Stack Begin
Script 'Workspace.Obby.Laser.KillScript', Line 5
Stack End
The words that matter: index nil
Something on line 5 was nil and you asked it for a child. Almost always hit.Parent came back as something without the child you wanted — a falling brick, or a hat. The fix is the `if humanoid then` guard, not a different way of writing line 5.
attempt to index nil is the one you will see
If you learn to read one Roblox error properly, make it this one. It accounts for the clear majority of crashes in beginner code, and it is precise about everything except the thing people look at first.
Workspace.Obby.Laser.KillScript:5: attempt to index nil with 'Humanoid'Read it in three pieces. The path and number say where: line 5 of KillScript, inside the Laser. attempt to index nil says what: something was nil and you asked it for a child. And 'Humanoid' is the name you asked for.
The trap is that Humanoid is not the thing that was missing. It is the thing you wanted from the thing that was missing. In otherPart.Parent.Humanoid, the nil is otherPart.Parent — and once you read it that way, the fix is obvious and it is a guard, not a spelling correction.
Three errors and what each means
- →attempt to index nil with 'X' — the expression to the left of .X was nil. Guard it.
- →attempt to call a nil value — you put () after something that is not a function. Almost always a misspelled method name.
- →Infinite yield possible on 'WaitForChild("X")' — a warning, not an error. The script is still waiting, and X probably has a typo.
Breakpoints beat scattering print statements
Prints are excellent and they have a ceiling. Once you are adding a fourth one to work out which of six values is wrong, you are rebuilding a debugger badly, and Studio already has one.
Click the gutter to the left of a line number to set a breakpoint. When execution reaches it the game pauses, and the Watch window shows you every variable in scope at that instant — not the ones you thought to print.
laser.Touched:Connect(function(otherPart) local character = otherPart:FindFirstAncestorOfClass("Model") local humanoid = character and character:FindFirstChildWhichIsA("Humanoid") -- Breakpoint here shows otherPart, character, and humanoid at once. if humanoid then humanoid:TakeDamage(100) endend)Client and server log separately
This one costs people hours. In a multi-client test, the server and each client have their own Output. A print from a server Script does not appear in the client's window, and vice versa.
In single-player Play mode there is a Client / Servertoggle in the Test tab that switches which context you are inspecting. A large fraction of "my script printed nothing" is the other side being selected.
When a script appears to do nothing
- ✓Is the Output window open, and filtered so your message could appear?
- ✓Are you looking at the right side — client or server?
- ✓Did the print at the top of the script run at all? If not, the problem is placement, not logic.
- ✓Is the script's parent a container that starts that class? Seven common placements start nothing.
- ✓Is the part named what the script thinks it is named?
- ✓Is the script Disabled? It is a property, it is easy to set by accident, and it produces perfect silence.
Key takeaways
- Keep the Output window open. A closed one is why a beginner thinks a script did nothing when it reported an error clearly.
- print is information, warn is a problem you survived, error stops the thread. Use the right one and your logs stay readable.
- assert(condition, message) states an assumption in one line instead of letting a nil proceed quietly.
- attempt to index nil with 'X' means the expression LEFT of .X was nil. X itself is spelled fine.
- attempt to call a nil value is almost always a misspelled method name.
- 'Infinite yield possible' is a warning, not an error — the script is still waiting, and the name probably has a typo.
- Breakpoints show every variable in scope, not only the ones you thought to print — but pausing inside a physics event distorts the physics.
- Client and server have separate Output. Checking the wrong side is a common cause of 'it printed nothing'.
- A Disabled script produces perfect silence. Check the property before rewriting the logic.
Quick check
Answer these to unlock the next chapter — 3 of 4 to pass. You can retake it anytime.
Answer every question to check.
Make a free account to read on
Every chapter is free — an account is how your progress, XP, and streak follow you from your laptop to your phone, and how you show up on the leaderboard. No payment, no trial.