Hibakeresés

From Multi Theft Auto: Wiki
Revision as of 13:10, 5 August 2007 by Driver2 (talk | contribs)
Jump to navigation Jump to search

While scripting you will often come across problems that are not immediately apparant. This page tries to point out some basic strategies to locate the error.

Debug console

MTA features a built-in debug console that shows debug messages created by MTA or the scripter. You can open it with by typing debugscript x in console, while x is the debug level:

  • 1: only errors
  • 2: errors and warnings
  • 3: errors, warnings and infos

Thus, by typing debugscript 3 all messages are visible, that or level 2 are recommended for most occasions. You should have debugscript enabled most of the time you are testing your script, this will help you to detect typos or other simple to solve errors easily.

Example

For example this snippet has two errors:

if (getClientName(player) == "Fedor")
	outputChatbox("DISGRACE")
end

When the script this piece of code is in is tried to be loaded, debugscript will output something similiar to this:

INFO: INFO: Loading script failed: C:\MTAServers\server8\mods\deathmatch\resources\d\script.lua:15: 'then' expected near ´outputChatbox'

This means the script could not be parsed, because there was a syntax error. It shows the path of the script, so you can also see what resource it is in ('d' in this case) and of course the name of the script. After the filename it shows the line number and again after that what was wrong. Easy to solve now, we just forgot the 'then':

if (getClientName(player) == "Fedor") then
	outputChatbox("DISGRACE")
end

Now the script will load fine and also don't output an error, until a player with the name 'Fedor' enters this section of the script. Then debugscript will output:

ERROR: ERROR: ..rvers\server8\mods\deathmatch\resources\d\script.lua:15: attempt to call global 'outputChatbox' (a nil value)

This means the called function does not exist, which can be easily explained since the functions' name is outputChatBox (capital Box):

if (getClientName(player) == "Fedor") then
	outputChatBox("DISGRACE")
end


This is of course just an example, there are plenty of other messages and scenarios, but you should get the idea.

Debug strategies

There are several strategies that support finding errors, apart from going through the code of course. Most of them include outputting debug messages, with differing information depending on the situtation.

Useful functions

First of all some functions that may come in handy for debugging.

Add debugmessages to check if, when or how often a section of code is executed

A typical example would be verify whether an if-section is executed or not. To do that, just add any message you will recognize later within the if-section.

if (variable1 == variable2) then
	outputDebugString("entered if")
	-- do anything
end

Another application would be to check when variable values are modified. First search for all occurences of the variable being edited and add a message just beside it.

Add debugmessages to check the value of a variable

Let's say you want to create a marker, but it doesn't appear at the position you expect it to be. The first thing you might want to do is check if the createMarker function is executed. But while doing this, you can also check the values being used in the createMarker function in one run.

outputChatBox(tostring(x).." "..tostring(y).." "..tostring(z))
createMarker(x,y,z)

This would output all three variables that are used as coordinates for the marker. Assuming you read those from a map file, you can now compare the debug output to the desired values. The tostring() will ensure that the variables' value can be put together as a string, even if it's a boolean value for example.

Example

Imagine you created a colshape (collision shape) somewhere and you want a player to stay 10 seconds in it, then perform some action.

function colShapeHit(player)
	-- set a timer to output a message (could as well execute another function)
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,"The player stayed 10 seconds in the colshape!")
end
addEventHandler("onColShapeHit",getRootElement(),colShapeHit)

function colShapeLeave(player)
	killTimer(colshapeTimer[player])
end
addEventHandler("onColShapeLeave",getRootElement(),colShapeLeave)