<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.multitheftauto.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hawk82</id>
	<title>Multi Theft Auto: Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.multitheftauto.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Hawk82"/>
	<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/wiki/Special:Contributions/Hawk82"/>
	<updated>2026-04-21T12:23:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=RU/Debugging&amp;diff=21223</id>
		<title>RU/Debugging</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=RU/Debugging&amp;diff=21223"/>
		<updated>2009-08-24T17:33:58Z</updated>

		<summary type="html">&lt;p&gt;Hawk82: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;При написании скриптов вы обязательно столкнетесь с проблемами, которые не сможете решить немедленно. Цель этой страницы - показать вам основные способыы нахождения ошибок.&lt;br /&gt;
&lt;br /&gt;
==Консоль отладки==&lt;br /&gt;
MTA включает консоль, которая показывает отладочные сообщения, выводимые функциями MTA и скриптами. Вы можете открыть ее введя ''debugscript x'' в консоли, где ''x'' уровень отладки:&lt;br /&gt;
* '''1:''' только ошибки&lt;br /&gt;
* '''2:''' ошибки и предупреждения&lt;br /&gt;
* '''3:''' ошибки, предупреждения и информационные сообщения&lt;br /&gt;
Так, введя ''debugscript 3'', вы будете видеть все сообщения, этот или 2 уровень рекомендуется в большинстве случаев. Рекомендуем держать debugscript включенным всё время, пока вы тестируете свой скрипт, это поможет вам обнаружить мелкие ошибки и исправить их.&lt;br /&gt;
&lt;br /&gt;
===Пример===&lt;br /&gt;
Этот участок кода содержит две ошибки:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (getClientName(player) == &amp;quot;Fedor&amp;quot;)&lt;br /&gt;
	outputChatbox(&amp;quot;Hello Fedor&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
При попытке запуска скрипта, содержащего этот участо кода, debugscript выведет что-то похожее на:&lt;br /&gt;
{{Debug info|Loading script failed: C:\&amp;lt;server path&amp;gt;\mods\deathmatch\resources\myResource\script.lua:15: 'then' expected near ´outputChatbox'}}&lt;br /&gt;
Это означает, что скрипт не может быть обработан из-за синтаксической ошибки. Показывается путь к скрипту, поэтому вы можете увидеть, какому ресурсу он принадлежит, ('myResource' в данном случае) и, конечно же, имя скрипта. После имени файла показан номер строки и информация об ошибке. Теперь проблема легко решается, мы просто забыли написать ключевое слово 'then':&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (getClientName(player) == &amp;quot;Fedor&amp;quot;) then&lt;br /&gt;
	outputChatbox(&amp;quot;Hello Fedor&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Теперь скрипт загрузится нормально и не будет выводить ошибок пока не выполнится для игрока с ником 'Fedor'. Тогда debugscript выведет:&lt;br /&gt;
{{Debug error|C:\&amp;lt;server path&amp;gt;\mods\deathmatch\resources\d\script.lua:15: attempt to call global 'outputChatbox' (a nil value)}}&lt;br /&gt;
Это значит, вызванная вами функция не существует, оно и понятно, ведь правильное название этой функции ''outputChatBox'' (с заглавной буквы ''B''):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (getClientName(player) == &amp;quot;Fedor&amp;quot;) then&lt;br /&gt;
	outputChatBox(&amp;quot;Hello Fedor&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, это просто пример, есть множество других сообщений и сценариев.&lt;br /&gt;
&lt;br /&gt;
==Debug logging==&lt;br /&gt;
Можно также включить режим дебаггера, отредактировав ''coreconfig.xml'' в папке GTA\MTA. Найдите в нем следующий тэг:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;debugfile/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И впишите туда адрес будущего лог-файла (путь указывайте, начиная с папки GTA):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;debugfile&amp;gt;MTA\debugscript.log&amp;lt;/debugfile&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И теперь все сообщения дебаггера будут записываться в этот файл. Если хотите выключить ведение лога, оставьте содержимое тэга пустым:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;debugfile/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Debug strategies==&lt;br /&gt;
{{translate}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Useful functions===&lt;br /&gt;
First of all some functions that may come in handy for debugging.&lt;br /&gt;
* [[outputDebugString]] or [[outputChatBox]] for outputting any information&lt;br /&gt;
* [http://www.lua.org/manual/5.1/manual.html#pdf-tostring tostring()] on a variable to turn it into a string, for example when it contains a boolean value&lt;br /&gt;
* [[getElementType]] to check an MTA Element for its type&lt;br /&gt;
&lt;br /&gt;
===Add debugmessages to check ''if'', ''when'' or ''how often'' a section of code is executed===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (variable1 == variable2) then&lt;br /&gt;
	outputDebugString(&amp;quot;entered if&amp;quot;)&lt;br /&gt;
	-- do anything&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Add debugmessages to check the ''value'' of a variable===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
outputChatBox(tostring(x)..&amp;quot; &amp;quot;..tostring(y)..&amp;quot; &amp;quot;..tostring(z))&lt;br /&gt;
createMarker(x,y,z)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
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 [http://www.lua.org/manual/5.1/manual.html#pdf-tostring tostring()] will ensure that the variables' value can be put together as a string, even if it's a boolean value for example.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
Imagine you created a colshape (collision shape) somewhere and you want a player to stay 10 seconds in it, then perform some action.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
When a player enters the colshape, debugscript outputs the following message:&lt;br /&gt;
{{Debug error|..[path]: attempt to index global 'colshapeTimer' (a nil value)}}&lt;br /&gt;
This means you tried to index a table that does not exist. In the example above, this is done when storing the timer id in the table. We need to add a check if the table exists and if not create it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we still get a warning when a player enters the colshape, waits for the message and leaves it again:&lt;br /&gt;
&lt;br /&gt;
{{Debug warning|[..]: Bad argument @ 'killTimer' Line: ..}}&lt;br /&gt;
&lt;br /&gt;
Except for that (we will talk about that later) everything seems to work fine. A player enters the colshape, the timer is started, if he stays the message occurs, if he leaves the timer is killed.&lt;br /&gt;
&lt;br /&gt;
===A more inconspicuous error===&lt;br /&gt;
But for some reason the message gets outputted twice when you stay in the colcircle while in a vehicle. Since it would appear some code is executed twice, we add debug messages to check this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- add a debug message&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeHit&amp;quot;)&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- add a debug message&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeLeave&amp;quot;)&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we notice that both handler functions get executed twice when we are in a vehicle, but only once when we are on-foot. It would appear the vehicle triggers the colshape as well. To confirm this theory, we check the ''player'' variable that '''should''' contain a player element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeHit &amp;quot;..getElementType(player))&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeLeave &amp;quot;..getElementType(player))&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The debug messages tell us that one of the ''player'' variables is a player, the other one a vehicle element. Since we only want to react when a player enters the colshape, we add an ''if'' that will end the execution of the function if it's '''not''' an player element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- add a check for the element type&lt;br /&gt;
	if (getElementType(player) ~= &amp;quot;player&amp;quot;) then return end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeHit &amp;quot;..getElementType(player))&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- add a check for the element type&lt;br /&gt;
	if (getElementType(player) ~= &amp;quot;player&amp;quot;) then return end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeLeave &amp;quot;..getElementType(player))&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the script should work as desired, but will still output the warning mentioned above. This happens because the timer we try to kill when a player leaves the colshape will not exist anymore when it reached the 10 seconds and is executed. There are different ways to get rid of that warning (since you know that the timer might not exist anymore and you only want to kill it if it is there). One way would be to check if the timer referenced in the table really exists. To do this, we need a little help function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function isTimer(timer)&lt;br /&gt;
	local timers = getTimers()&lt;br /&gt;
	for k,v in ipairs(timers) do&lt;br /&gt;
		if (v == timer) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Which we will use when we kill the timer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (isTimer(colshapeTimer[player])) then&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So the complete working code would be:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- add a check for the element type&lt;br /&gt;
	if (getElementType(player) ~= &amp;quot;player&amp;quot;) then return end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeHit &amp;quot;..getElementType(player))&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- add a check for the element type&lt;br /&gt;
	if (getElementType(player) ~= &amp;quot;player&amp;quot;) then return end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeLeave &amp;quot;..getElementType(player))&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	if (isTimer(colshapeTimer[player])) then&lt;br /&gt;
		killTimer(colshapeTimer[player])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&lt;br /&gt;
function isTimer(timer)&lt;br /&gt;
	local timers = getTimers()&lt;br /&gt;
	for k,v in ipairs(timers) do&lt;br /&gt;
		if (v == timer) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting Concepts]]&lt;br /&gt;
[[en:Debugging]]&lt;br /&gt;
[[it:Guida al Debug]]&lt;/div&gt;</summary>
		<author><name>Hawk82</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=RU/Debugging&amp;diff=21222</id>
		<title>RU/Debugging</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=RU/Debugging&amp;diff=21222"/>
		<updated>2009-08-24T17:33:20Z</updated>

		<summary type="html">&lt;p&gt;Hawk82: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;При написании скриптов вы обязательно столкнетесь с проблемами, которые не сможете решить немедленно. Цель этой страницы - показать вам основные способыы нахождения ошибок.&lt;br /&gt;
&lt;br /&gt;
==Консоль отладки==&lt;br /&gt;
MTA включает консоль, которая показывает отладочные сообщения, выводимые функциями MTA и скриптами. Вы можете открыть ее введя ''debugscript x'' в консоли, где ''x'' уровень отладки:&lt;br /&gt;
* '''1:''' только ошибки&lt;br /&gt;
* '''2:''' ошибки и предупреждения&lt;br /&gt;
* '''3:''' ошибки, предупреждения и информационные сообщения&lt;br /&gt;
Так, введя ''debugscript 3'', вы будете видеть все сообщения, этот или 2 уровень рекомендуется в большинстве случаев. Рекомендуем держать debugscript включенным всё время, пока вы тестируете свой скрипт, это поможет вам обнаружить мелкие ошибки и исправить их.&lt;br /&gt;
&lt;br /&gt;
===Пример===&lt;br /&gt;
Этот участок кода содержит две ошибки:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (getClientName(player) == &amp;quot;Fedor&amp;quot;)&lt;br /&gt;
	outputChatbox(&amp;quot;Hello Fedor&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
При попытке запуска скрипта, содержащего этот участо кода, debugscript выведет что-то похожее на:&lt;br /&gt;
{{Debug info|Loading script failed: C:\&amp;lt;server path&amp;gt;\mods\deathmatch\resources\myResource\script.lua:15: 'then' expected near ´outputChatbox'}}&lt;br /&gt;
Это означает, что скрипт не может быть обработан из-за синтаксической ошибки. Показывается путь к скрипту, поэтому вы можете увидеть, какому ресурсу он принадлежит, ('myResource' в данном случае) и, конечно же, имя скрипта. После имени файла показан номер строки и информация об ошибке. Теперь проблема легко решается, мы просто забыли написать ключевое слово 'then':&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (getClientName(player) == &amp;quot;Fedor&amp;quot;) then&lt;br /&gt;
	outputChatbox(&amp;quot;Hello Fedor&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Теперь скрипт загрузится нормально и не будет выводить ошибок пока не выполнится для игрока с ником 'Fedor'. Тогда debugscript выведет:&lt;br /&gt;
{{Debug error|C:\&amp;lt;server path&amp;gt;\mods\deathmatch\resources\d\script.lua:15: attempt to call global 'outputChatbox' (a nil value)}}&lt;br /&gt;
Это значит, вызванная вами функция не существует, оно и понятно, ведь правильное название этой функции ''outputChatBox'' (с заглавной буквы ''B''):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (getClientName(player) == &amp;quot;Fedor&amp;quot;) then&lt;br /&gt;
	outputChatBox(&amp;quot;Hello Fedor&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, это просто пример, есть множество других сообщений и сценариев.&lt;br /&gt;
&lt;br /&gt;
==Debug logging==&lt;br /&gt;
{{translate}}&lt;br /&gt;
Можно также включить режим дебаггера, отредактировав ''coreconfig.xml'' в папке GTA\MTA. Найдите в нем следующий тэг:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;debugfile/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И впишите туда адрес будущего лог-файла (путь указывайте, начиная с папки GTA):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;debugfile&amp;gt;MTA\debugscript.log&amp;lt;/debugfile&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И теперь все сообщения дебаггера будут записываться в этот файл. Если хотите выключить ведение лога, оставьте содержимое тэга пустым:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;debugfile/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Debug strategies==&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Useful functions===&lt;br /&gt;
First of all some functions that may come in handy for debugging.&lt;br /&gt;
* [[outputDebugString]] or [[outputChatBox]] for outputting any information&lt;br /&gt;
* [http://www.lua.org/manual/5.1/manual.html#pdf-tostring tostring()] on a variable to turn it into a string, for example when it contains a boolean value&lt;br /&gt;
* [[getElementType]] to check an MTA Element for its type&lt;br /&gt;
&lt;br /&gt;
===Add debugmessages to check ''if'', ''when'' or ''how often'' a section of code is executed===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (variable1 == variable2) then&lt;br /&gt;
	outputDebugString(&amp;quot;entered if&amp;quot;)&lt;br /&gt;
	-- do anything&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Add debugmessages to check the ''value'' of a variable===&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
outputChatBox(tostring(x)..&amp;quot; &amp;quot;..tostring(y)..&amp;quot; &amp;quot;..tostring(z))&lt;br /&gt;
createMarker(x,y,z)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
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 [http://www.lua.org/manual/5.1/manual.html#pdf-tostring tostring()] will ensure that the variables' value can be put together as a string, even if it's a boolean value for example.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
Imagine you created a colshape (collision shape) somewhere and you want a player to stay 10 seconds in it, then perform some action.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
When a player enters the colshape, debugscript outputs the following message:&lt;br /&gt;
{{Debug error|..[path]: attempt to index global 'colshapeTimer' (a nil value)}}&lt;br /&gt;
This means you tried to index a table that does not exist. In the example above, this is done when storing the timer id in the table. We need to add a check if the table exists and if not create it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we still get a warning when a player enters the colshape, waits for the message and leaves it again:&lt;br /&gt;
&lt;br /&gt;
{{Debug warning|[..]: Bad argument @ 'killTimer' Line: ..}}&lt;br /&gt;
&lt;br /&gt;
Except for that (we will talk about that later) everything seems to work fine. A player enters the colshape, the timer is started, if he stays the message occurs, if he leaves the timer is killed.&lt;br /&gt;
&lt;br /&gt;
===A more inconspicuous error===&lt;br /&gt;
But for some reason the message gets outputted twice when you stay in the colcircle while in a vehicle. Since it would appear some code is executed twice, we add debug messages to check this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- add a debug message&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeHit&amp;quot;)&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- add a debug message&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeLeave&amp;quot;)&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we notice that both handler functions get executed twice when we are in a vehicle, but only once when we are on-foot. It would appear the vehicle triggers the colshape as well. To confirm this theory, we check the ''player'' variable that '''should''' contain a player element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeHit &amp;quot;..getElementType(player))&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeLeave &amp;quot;..getElementType(player))&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The debug messages tell us that one of the ''player'' variables is a player, the other one a vehicle element. Since we only want to react when a player enters the colshape, we add an ''if'' that will end the execution of the function if it's '''not''' an player element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- add a check for the element type&lt;br /&gt;
	if (getElementType(player) ~= &amp;quot;player&amp;quot;) then return end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeHit &amp;quot;..getElementType(player))&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- add a check for the element type&lt;br /&gt;
	if (getElementType(player) ~= &amp;quot;player&amp;quot;) then return end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeLeave &amp;quot;..getElementType(player))&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the script should work as desired, but will still output the warning mentioned above. This happens because the timer we try to kill when a player leaves the colshape will not exist anymore when it reached the 10 seconds and is executed. There are different ways to get rid of that warning (since you know that the timer might not exist anymore and you only want to kill it if it is there). One way would be to check if the timer referenced in the table really exists. To do this, we need a little help function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function isTimer(timer)&lt;br /&gt;
	local timers = getTimers()&lt;br /&gt;
	for k,v in ipairs(timers) do&lt;br /&gt;
		if (v == timer) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Which we will use when we kill the timer:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
if (isTimer(colshapeTimer[player])) then&lt;br /&gt;
	killTimer(colshapeTimer[player])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So the complete working code would be:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function colShapeHit(player)&lt;br /&gt;
	if (colshapeTimer == nil) then&lt;br /&gt;
		colshapeTimer = {}&lt;br /&gt;
	end&lt;br /&gt;
	-- add a check for the element type&lt;br /&gt;
	if (getElementType(player) ~= &amp;quot;player&amp;quot;) then return end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeHit &amp;quot;..getElementType(player))&lt;br /&gt;
	-- set a timer to output a message (could as well execute another function)&lt;br /&gt;
	-- store the timer id in a table, using the player as index&lt;br /&gt;
	colshapeTimer[player] = setTimer(outputChatBox,10000,1,&amp;quot;The player stayed 10 seconds in the colshape!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeHit&amp;quot;,getRootElement(),colShapeHit)&lt;br /&gt;
&lt;br /&gt;
function colShapeLeave(player)&lt;br /&gt;
	-- add a check for the element type&lt;br /&gt;
	if (getElementType(player) ~= &amp;quot;player&amp;quot;) then return end&lt;br /&gt;
	-- add a debug message, with the element type&lt;br /&gt;
	outputDebugString(&amp;quot;colShapeLeave &amp;quot;..getElementType(player))&lt;br /&gt;
	-- kill the timer when the player leaves the colshape&lt;br /&gt;
	if (isTimer(colshapeTimer[player])) then&lt;br /&gt;
		killTimer(colshapeTimer[player])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onColShapeLeave&amp;quot;,getRootElement(),colShapeLeave)&lt;br /&gt;
&lt;br /&gt;
function isTimer(timer)&lt;br /&gt;
	local timers = getTimers()&lt;br /&gt;
	for k,v in ipairs(timers) do&lt;br /&gt;
		if (v == timer) then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting Concepts]]&lt;br /&gt;
[[en:Debugging]]&lt;br /&gt;
[[it:Guida al Debug]]&lt;/div&gt;</summary>
		<author><name>Hawk82</name></author>
	</entry>
</feed>