GUIDE TITLE: Don't Panic: Debugging Tutorial
COMPLETION TIME: 30 Minutes
SUGGESTED PREREQUISITES: some knowledge of Lua and Core Editor
TUTORIAL SUMMARY:
a practical guide to the bug fix workflow in Core Environment.
EXPECT TO LEARN:
- how to analyze errors in Event Log and Script Debugger
- how to fix Lua compilation and runtime errors
- how to fix Core contexts errors
Introduction
In this tutorial you will explore some techniques for fixing bugs in Core projects. You will open a project with several pre-planted errors and you are going to fix them
Prerequisites
-
Create a new Core project by downloading the "DontPanicTutorial" community project.
CORE -> CREATE -> COMMUNITY PROJECTS
-
It’s recommended that you install vscode editor with Core Lua API for VS Code extension.
Error01
After you open the project in the editor, hit Play
(hotkey =
). A few error messages will pop up in the Event Log. Don’t worry, it is expected. Our goal here is to find the source of those errors and fix them. Hit Stop
(hotkey =
).
The first error message will be the following:
Error running Lua task: [E432E9A363446C25] Error01:3: attempt to perform arithmetic on a table value (local 'y')
Let’s have a look at the code of the Error01
script.
local function add(x, y)
return x + y
end
local function wrongCall()
local num = add(1, {2})
return num
end
wrongCall()
The error message corresponds to line 2 that is inside the add
function. This function is so simple that there couldn’t possibly be any mistakes in there, but it does expect to receive arguments of certain data types that support the addition operation, and it seems that someone has called it with the wrong arguments. Unfortunately, the error message doesn’t tell us that. We are now dealing with a very simple example, but in a real project a function could be called from a hundred different places. To let us see the whole chain of calls that had led to an error, Core provides us with a built-in script debugger.
Let’s turn it on.
- Open the Script Debugger (
Window -> Script Debugger
). - Make sure that you have the
Pause on Error
option activated ((1)
at screenshot). - Hit
Play
in the Core Editor.
You will see:
-
Pause on Error
On (button turned orange). - Second stack frame selected.
- Code line corresponding to the selected stack frame.
To the right is the stack frames column. By clicking on a stack frame, you can see from where in your script the function has been called and what arguments have been passed.
To fix the “wrong argument” error you need to:
- Look at the topmost stack frame and see what arguments have been passed.
- Move up along the stack to the call site and correct the wrong arguments.
In our case the error resides in line 7 that passes a table {2}
(that does not support the (+)
operator) as a second argument. Let’s fix it - for instance, as follows:
-- Correct line 2 of Error01.lua
local num = add(1, 2)
PickUp Template
There is an instantiated PickUp
template in the project’s hierarchy. It is full of errors! Let us fix them by relying on common sense, using the Script Debugger
and carefully reading error messages in the Event Log
.
We are going to make changes to the template, so it would probably be a good idea to deinstance it in the hierarchy.
- Right-click on the
PickUp
template instance in the hierarchy. - Choose
Deinstance This Object
from the menu. -
Optional: after you finish working on a template, select
Update Template From This
.
Syntax Error
Our next error seems to be rather cryptic:
Error compiling Lua script (API_Rewards):
[E96F95B81540514B] API_Rewards:14: '(' expected near '.'
<...>
Error compiling Lua script
means that there is a syntactic error somewhere that prevents Lua from compiling the script.
Those errors are pretty easy to fix, but their error messages can be rather hard to interpret. A good idea would be to use an external editor vscode that can indicate such errors even before you compiled the code. Error messages usually make more sense, too.
Line 14 contains an incorrect keyword local
. If the name of a function is a field of an API
table, this function can not be local
- or, in other words, local function can only use identifier as name
.
INFO: [Names (also called identifiers)][3] in Lua can be any string of letters, digits, and underscores, not beginning with a digit and not being a reserved word. Identifiers are used to name variables, table fields, and labels.
To fix this error you need to remove the local
keyword from line 14 of the API_Rewards
script.
-- corrected line 14 of `API_Rewards.lua`
function API.giveReward(player, rewardAmount)
Context Error (client)
Our next error:
Error running Lua task: [FB27BF9E0F0840F6] PickUpRewardClient:6: Server script attempted to access a client-only field in a namespace. Field: Game.GetLocalPlayer
PickUpRewardClient.lua
is a client script, it calls client functions of Core API, like Game.GetLocalPlayer
, so it should be placed inside a client context. Core editor has a very convenient option to correct this error: New Client Context Containing This
. Don’t forget to deinstance the template if you haven’t already.
- Right-click on the
PickUpRewardClient
. - Choose
Create Network Context
from menu. - Choose
New Client Context Containing This
.
Now PickUpRewardClient
is placed correctly: in a client context.
Error in the Module API Call
By now, if everything is done properly, the game will start without errors. But this doesn’t mean there aren’t any! To see that, come up to the Ball
and press F
(interact). We got a new error.
Error running Lua task: [E96F95B81540514B] API_Rewards:17: attempt to call a nil value (method 'GetResource')
If we look closely at the stack frame where the error took place, we will see that: player
is of type table
, and rewardAmount
is of type Player
. This is very suspicious. It is one of the most common mistakes in Lua programming: (:)
instead of (.)
in a function call.
API method giveReward
defined in line 14 of API_Reward.lua
module:
function API.giveReward(player, rewardAmount)
But we call this method at line 19 of PickUpRewardServer.lua
as:
APIREWARDS:giveReward(player, REWARD_AMOUNT)
-- ^- here we used `:` instead of `.`
Colon (:)
call is a syntactic sugar for a regular call with an implicit self
as a first argument.
In other words, what we have is:
APIREWARDS.giveReward(APIREWARDS, player, REWARD_AMOUNT)
To fix the error, we should replace (:)
with (.)
in the call to giveReward
:
-- corrected line 19 of `PickUpRewardServer.lua`
APIREWARDS.giveReward(player, REWARD_AMOUNT)
Error in a Field Name
Now an interaction with a Ball gives us another error:
Error running Lua task: [E96F95B81540514B] API_Rewards:39: attempt to perform arithmetic on a nil value (field 'Up')
Here we mistype Vector3.UP
at the line 39 of API_Rewards.lua, there is no field Up
in Vector3
.
-- corrected line 39 of `API_Rewards.lua`
local position = LOCAL_PLAYER:GetWorldPosition() + 150*Vector3.UP
Error of Object Networking
Our next error:
Error running Lua task: [75E602123F51FA46] PickUpRewardServer:22: Attempted to modify a field on a non-networked object. (Try marking the object as Networked or move it into a Client Context or Server Context to fix this problem.) Field: isInteractable, Object: Trigger
There is no error in our code, we do want to modify the field of the Trigger, and for this we should make it Networked
.
- Right-click on the Trigger.
- Choose
Enable Networking
from menu.
No More Errors
Congratulations! We did it. There are no more errors in our code. But is it actually so?
In fact, there is at least one more error in our code, but it is not that easy to find. If we carefully read the code of PickUpRewardServer.lua
we will see that after the interaction with the Ball
, a prompt for a new interaction must not appear within the next 3 sec, but this doesn’t happen. Try to find this error (Hint: it is very similar to one of those we have already analyzed).
Consclusion
In this tutorial you have explored some essential techniques for fixing bugs that may emerge during developing games in Core.