<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>https://game.etao.net/w/index.php?action=history&amp;feed=atom&amp;title=StendhalScripting%2FLua</id>
	<title>StendhalScripting/Lua - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://game.etao.net/w/index.php?action=history&amp;feed=atom&amp;title=StendhalScripting%2FLua"/>
	<link rel="alternate" type="text/html" href="https://game.etao.net/w/index.php?title=StendhalScripting/Lua&amp;action=history"/>
	<updated>2026-05-06T00:13:48Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://game.etao.net/w/index.php?title=StendhalScripting/Lua&amp;diff=182&amp;oldid=prev</id>
		<title>183.129.118.43：​创建页面，内容为“{{Navigation for Stendhal Top|Playing}}  &lt;span style=&quot;color: red; font-style: italic;&quot;&gt;this page is a work-in progress&lt;/span&gt;  Stendhal supports [https://www.lua.org…”</title>
		<link rel="alternate" type="text/html" href="https://game.etao.net/w/index.php?title=StendhalScripting/Lua&amp;diff=182&amp;oldid=prev"/>
		<updated>2023-06-01T21:43:04Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“{{Navigation for Stendhal Top|Playing}}  &amp;lt;span style=&amp;quot;color: red; font-style: italic;&amp;quot;&amp;gt;this page is a work-in progress&amp;lt;/span&amp;gt;  Stendhal supports [https://www.lua.org…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Navigation for Stendhal Top|Playing}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: red; font-style: italic;&amp;quot;&amp;gt;this page is a work-in progress&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Stendhal supports [https://www.lua.org/ Lua scripting] via the [https://sourceforge.net/projects/luaj/ LuaJ library].&lt;br /&gt;
&lt;br /&gt;
Lua scripts end in the &amp;lt;code&amp;gt;.lua&amp;lt;/code&amp;gt; extension &amp;amp; are stored in the &amp;lt;code&amp;gt;data/script&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
= Lua Basics =&lt;br /&gt;
&lt;br /&gt;
For more detailed information, see the [https://www.lua.org/docs.html Lua reference manual].&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Lua uses double dashes (&amp;lt;code&amp;gt;--&amp;lt;/code&amp;gt;) for single line comments &amp;amp; double dashes followed by double square brackets (&amp;lt;code&amp;gt;[[&amp;lt;/code&amp;gt;) &amp;amp; closed with double square brackets (&amp;lt;code&amp;gt;]]&amp;lt;/code&amp;gt;) for multi-line comments:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- a single line comment&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
a multi-line comment&lt;br /&gt;
]]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
By default, Lua variables are set in [https://en.wikipedia.org/wiki/Global_variable &amp;#039;&amp;#039;&amp;#039;global&amp;#039;&amp;#039;&amp;#039; scope] (meaning it is exposed to the entire Lua engine). To create a variable in [https://en.wikipedia.org/wiki/Local_variable &amp;#039;&amp;#039;&amp;#039;local&amp;#039;&amp;#039;&amp;#039; scope], the &amp;lt;code&amp;gt;local&amp;lt;/code&amp;gt; keyword must be used:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- a global variable&lt;br /&gt;
var1 = &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- a local variable&lt;br /&gt;
local var2 = &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data Types ==&lt;br /&gt;
&lt;br /&gt;
Some common data types in Lua are &amp;#039;&amp;#039;string&amp;#039;&amp;#039;, &amp;#039;&amp;#039;integer&amp;#039;&amp;#039;, &amp;#039;&amp;#039;boolean&amp;#039;&amp;#039;, &amp;amp; &amp;#039;&amp;#039;table&amp;#039;&amp;#039;. Type names do not need to be declared when setting variables.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- string variable&lt;br /&gt;
local var1 = &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- integer variable&lt;br /&gt;
local var2 = 11&lt;br /&gt;
&lt;br /&gt;
-- boolean variable&lt;br /&gt;
local var3 = true&lt;br /&gt;
&lt;br /&gt;
-- table variable&lt;br /&gt;
local var4 = {}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Strings ===&lt;br /&gt;
&lt;br /&gt;
==== String Concatenation ====&lt;br /&gt;
&lt;br /&gt;
String concatenation is simple, much like Java uses a plus operator (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) to join strings, Lua uses two periods (&amp;lt;code&amp;gt;..&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- create a string variable&lt;br /&gt;
local var = &amp;quot;Hello&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- append another string&lt;br /&gt;
var = var .. &amp;quot; world!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
print(var) -- prints &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tables ===&lt;br /&gt;
&lt;br /&gt;
A Lua table is a data type similar to a Java list or map. Tables can be indexed or use key=value pairs.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;IMPORTANT NOTE: Lua table indexes begin at 1, not 0&amp;lt;/span&amp;gt;)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==== Creating Tables ====&lt;br /&gt;
&lt;br /&gt;
An empty table is initialized with a pair of curly braces (&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mytable = {}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can add values to indexed tables at initialization or with the &amp;lt;code&amp;gt;table.insert&amp;lt;/code&amp;gt; method:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- create a table with values&lt;br /&gt;
local mytable = {&amp;quot;foo&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
-- add value&lt;br /&gt;
table.insert(mytable, &amp;quot;bar&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a key=value table, any of the following methods can be used to add values:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- all of these do the same thing, that is, assigning &amp;quot;bar&amp;quot; to mytable.foo&lt;br /&gt;
local mytable {&lt;br /&gt;
	foo = &amp;quot;bar&amp;quot;,&lt;br /&gt;
	[&amp;quot;foo&amp;quot;] = &amp;quot;bar&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
mytable.foo = &amp;quot;bar&amp;quot;&lt;br /&gt;
mytable[&amp;quot;foo&amp;quot;] = &amp;quot;bar&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Accessing Table Values ====&lt;br /&gt;
&lt;br /&gt;
Square brackets (&amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt;) enclosing an index number are used to access values in indexed tables (&amp;#039;&amp;#039;remember that Lua table indexes start at &amp;quot;1&amp;quot; not &amp;quot;0&amp;quot;&amp;#039;&amp;#039;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mytable = {&amp;quot;foo&amp;quot;, &amp;quot;bar&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
print(mytable[1]) -- prints &amp;quot;foo&amp;quot;&lt;br /&gt;
print(mytable[2]) -- prints &amp;quot;bar&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a key=value table, values can be accessed by either enclosing the key string in square brackets or concatenating the key member using a &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mytable = {foo=&amp;quot;bar&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
-- using square brackets&lt;br /&gt;
print(mytable[&amp;quot;foo&amp;quot;]) -- prints &amp;quot;bar&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- using concatenated member&lt;br /&gt;
print(mytable.foo) -- prints &amp;quot;bar&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Iterating Tables ====&lt;br /&gt;
&lt;br /&gt;
Tables can be iterated in a &amp;lt;code&amp;gt;for&amp;lt;/code&amp;gt; loop using the &amp;lt;code&amp;gt;pairs&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ipairs&amp;lt;/code&amp;gt; iterators. Loops are terminated with the &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; keyword:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mytable = {&amp;quot;foo&amp;quot;, &amp;quot;bar&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;indexes:&amp;quot;)&lt;br /&gt;
for idx in pairs(mytable) do&lt;br /&gt;
	print(idx)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nvalues:&amp;quot;)&lt;br /&gt;
for idx, value in pairs(mytable) do&lt;br /&gt;
	print(value)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
indexes:&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
&lt;br /&gt;
values:&lt;br /&gt;
foo&lt;br /&gt;
bar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using a key=value table:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local mytable = {&lt;br /&gt;
	[&amp;quot;foo&amp;quot;] = &amp;quot;hello&amp;quot;,&lt;br /&gt;
	[&amp;quot;bar&amp;quot;] = &amp;quot; world!&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;keys:&amp;quot;)&lt;br /&gt;
for key in pairs(mytable) do&lt;br /&gt;
	print(key)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nvalues:&amp;quot;)&lt;br /&gt;
for key, value in pairs(mytable) do&lt;br /&gt;
	print(value)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keys:&lt;br /&gt;
foo&lt;br /&gt;
bar&lt;br /&gt;
&lt;br /&gt;
values:&lt;br /&gt;
hello&lt;br /&gt;
 world!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also: [http://lua-users.org/wiki/TablesTutorial Lua Tables Tutorial]&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
&lt;br /&gt;
Like normal variables, functions can be declared as &amp;#039;&amp;#039;&amp;#039;global&amp;#039;&amp;#039;&amp;#039; or &amp;#039;&amp;#039;&amp;#039;local&amp;#039;&amp;#039;&amp;#039; &amp;amp; must be terminated with the &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; keyword.&lt;br /&gt;
&lt;br /&gt;
There are two ways to define functions with the &amp;lt;code&amp;gt;function&amp;lt;/code&amp;gt; keyword:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local function myFunction()&lt;br /&gt;
	print(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local myFunction = function()&lt;br /&gt;
	print(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functions can also be members of a table:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local myTable = {}&lt;br /&gt;
function myTable.myFunction()&lt;br /&gt;
	print(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local myTable = {}&lt;br /&gt;
myTable.myFunction = function()&lt;br /&gt;
	print(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local myTable = {&lt;br /&gt;
	myFunction = function()&lt;br /&gt;
		print(&amp;quot;Hello world!&amp;quot;)&lt;br /&gt;
	end,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- execute with&lt;br /&gt;
myTable.myFunction()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Comparison Operators ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Logical Operators&lt;br /&gt;
! Operator !! Description !! Java Equivalent&lt;br /&gt;
|-&lt;br /&gt;
| and || logical &amp;#039;&amp;#039;and&amp;#039;&amp;#039; || &amp;amp;&amp;amp;&lt;br /&gt;
|-&lt;br /&gt;
| or || logical &amp;#039;&amp;#039;or&amp;#039;&amp;#039; || &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| not || logical &amp;#039;&amp;#039;opposite&amp;#039;&amp;#039; || !&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Relational Operators&lt;br /&gt;
! Operator !! Description !! Java Equivalent&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt; || less than || &amp;lt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt; || greater than || &amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;= || less than or equal to || &amp;lt;=&lt;br /&gt;
|-&lt;br /&gt;
| &amp;gt;= || greater than or equal to || &amp;gt;=&lt;br /&gt;
|-&lt;br /&gt;
| == || equal to || ==&lt;br /&gt;
|-&lt;br /&gt;
| ~= || not equal to || !=&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Stendhal Application =&lt;br /&gt;
&lt;br /&gt;
== Zones ==&lt;br /&gt;
&lt;br /&gt;
=== Setting Zone ===&lt;br /&gt;
&lt;br /&gt;
To set the zone to work with, use the &amp;lt;code&amp;gt;game&amp;lt;/code&amp;gt; object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
game:setZone(&amp;quot;0_semos_city&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create New Zone ===&lt;br /&gt;
&lt;br /&gt;
It is recommended to create new zones in the XML configurations in {{StendhalFile|master|data/conf/zones|data/conf/zones}}.&lt;br /&gt;
&lt;br /&gt;
Currently creating new zones via Lua is not supported.&lt;br /&gt;
&lt;br /&gt;
=== Add Zone Music ===&lt;br /&gt;
&lt;br /&gt;
Music can be added to zones with the &amp;lt;code&amp;gt;game:setMusic&amp;lt;/code&amp;gt; function. It supports the following arguments:&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:darkgreen; font-style:italic;&amp;gt;filename:&amp;lt;/span&amp;gt; Basename of the OGG audio file to use stored in {{StendhalFile|master|data/music|data/music}}.&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:darkgreen; font-style:italic;&amp;gt;args:&amp;lt;/span&amp;gt; A table of key=value integers.&lt;br /&gt;
* Valid keys:&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:darkblue; font-style:italic;&amp;quot;&amp;gt;volume:&amp;lt;/span&amp;gt; Volume level (default: 100).&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:darkblue; font-style:italic;&amp;quot;&amp;gt;x:&amp;lt;/span&amp;gt; The horizontal point for the source of the music (default: 1).&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:darkblue; font-style:italic;&amp;quot;&amp;gt;y:&amp;lt;/span&amp;gt; The vertical point for the source of the music (default: 1).&lt;br /&gt;
** &amp;lt;span style=&amp;quot;color:darkblue; font-style:italic;&amp;quot;&amp;gt;radius:&amp;lt;/span&amp;gt; The radial range at which the music can be heard (default: 10000).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if game:setZone(&amp;quot;0_semos_plains_n&amp;quot;) then&lt;br /&gt;
	game:setMusic(&amp;quot;pleasant_creek_loop&amp;quot;, {volume=85, radius=100})&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adding Entities ==&lt;br /&gt;
&lt;br /&gt;
=== Signs ===&lt;br /&gt;
&lt;br /&gt;
Signs can be created with &amp;lt;code&amp;gt;entities:createSign&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;entities:createShopSign&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local zone = &amp;quot;0_semos_city&amp;quot;&lt;br /&gt;
if game:setZone(zone) then&lt;br /&gt;
	-- create the sign instance&lt;br /&gt;
	local sign = entities:createSign()&lt;br /&gt;
	sign:setEntityClass(&amp;quot;signpost&amp;quot;)&lt;br /&gt;
	sign:setPosition(12, 55)&lt;br /&gt;
	sign:setText(&amp;quot;Meet Lua!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	-- Add it to the world&lt;br /&gt;
	game:add(sign)&lt;br /&gt;
else&lt;br /&gt;
	logger:error(&amp;quot;Could not set zone: &amp;quot; .. zone)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NPCs ===&lt;br /&gt;
&lt;br /&gt;
Use the &amp;lt;code&amp;gt;entities:createSpeakerNPC&amp;lt;/code&amp;gt; method to create an interactive NPC:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local zone = &amp;quot;0_semos_city&amp;quot;&lt;br /&gt;
if game:setZone(zone) then&lt;br /&gt;
	-- Use helper object to create a new NPC&lt;br /&gt;
	local npc = entities:createSpeakerNPC(&amp;quot;Lua&amp;quot;)&lt;br /&gt;
	npc:setEntityClass(&amp;quot;littlegirlnpc&amp;quot;)&lt;br /&gt;
	npc:setPosition(10, 55)&lt;br /&gt;
	npc:setBaseSpeed(0.1)&lt;br /&gt;
	npc:setCollisionAction(CollisionAction.STOP)&lt;br /&gt;
&lt;br /&gt;
	local nodes = {&lt;br /&gt;
		{10, 55},&lt;br /&gt;
		{11, 55},&lt;br /&gt;
		{11, 56},&lt;br /&gt;
		{10, 56},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	npc:setPath(nodes)&lt;br /&gt;
&lt;br /&gt;
	-- Dialogue&lt;br /&gt;
	npc:addJob(&amp;quot;Actually, I am jobless.&amp;quot;)&lt;br /&gt;
	npc:addGoodbye();&lt;br /&gt;
&lt;br /&gt;
	-- Add to the world&lt;br /&gt;
	game:add(npc)&lt;br /&gt;
else&lt;br /&gt;
	logger:error(&amp;quot;Could not set zone: &amp;quot; .. zone)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Adding Transitions ====&lt;br /&gt;
&lt;br /&gt;
A simple example of adding a chat transition can be done without any special functionality:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local frank = entities:createSpeakerNPC(&amp;quot;Frank&amp;quot;)&lt;br /&gt;
frank:add(ConversationStates.IDLE,&lt;br /&gt;
	ConversationPhrases.GREETING_MESSAGES,&lt;br /&gt;
	nil,&lt;br /&gt;
	ConversationStates.ATTENDING,&lt;br /&gt;
	&amp;quot;Hello.&amp;quot;,&lt;br /&gt;
	nil)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This simply adds a response to saying &amp;quot;hello&amp;quot; &amp;amp; sets the NPC to attend to the player (equivalent of &amp;lt;code&amp;gt;frank:addGreeting(&amp;quot;Hello&amp;quot;)&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
For more complicated behavior, we need to use some helper methods. If we want to check a condition we use the &amp;lt;code&amp;gt;conditions:create&amp;lt;/code&amp;gt; method. The first parameter is the string name of the ChatCondition we want to instantiate. The second parameter is a table that contains the values that should be passed to the ChatCondition constructor.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frank:add(ConversationStates.IDLE,&lt;br /&gt;
	ConversationPhrases.GREETING_MESSAGES,&lt;br /&gt;
	conditions:create(&amp;quot;PlayerHasItemWithHimCondition&amp;quot;, {&amp;quot;money&amp;quot;}),&lt;br /&gt;
	ConversationStates.ATTENDING,&lt;br /&gt;
	&amp;quot;Hello.&amp;quot;,&lt;br /&gt;
	nil)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this scenario, the NPC will only respond if the player is carrying &amp;lt;item&amp;gt;money&amp;lt;/item&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A NotCondition instance can be created with the &amp;lt;code&amp;gt;actions:notCondition&amp;lt;/code&amp;gt; method:&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local condition = conditions.notCondition(conditions:create(&amp;quot;PlayerHasItemWithHimCondition&amp;quot;, {&amp;quot;money&amp;quot;})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To add a ChatAction, we use the &amp;lt;code&amp;gt;actions:create&amp;lt;/code&amp;gt; method. Its usage is identical to &amp;lt;code&amp;gt;conditions:create&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frank:add(ConversationStates.IDLE,&lt;br /&gt;
	ConversationPhrases.GREETING_MESSAGES,&lt;br /&gt;
	conditions:create(&amp;quot;PlayerHasItemWithHimCondition&amp;quot;, {&amp;quot;money&amp;quot;}),&lt;br /&gt;
	ConversationStates.ATTENDING,&lt;br /&gt;
	&amp;quot;Hello.&amp;quot;,&lt;br /&gt;
	actions:create(&amp;quot;NPCEmoteAction&amp;quot;, {&amp;quot;looks greedily at your pouch of money.&amp;quot;, false}))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Lua tables can be used to add multiple conditions or actions:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
frank:add(ConversationStates.IDLE,&lt;br /&gt;
	ConversationPhrases.GREETING_MESSAGES,&lt;br /&gt;
	{&lt;br /&gt;
		conditions:create(&amp;quot;PlayerHasItemWithHimCondition&amp;quot;, {&amp;quot;money&amp;quot;}),&lt;br /&gt;
		conditions:notCondition(conditions:create(&amp;quot;NakedCondition&amp;quot;)),&lt;br /&gt;
	},&lt;br /&gt;
	ConversationStates.ATTENDING,&lt;br /&gt;
	nil,&lt;br /&gt;
	{&lt;br /&gt;
		actions:create(&amp;quot;SayTextAction&amp;quot;, {&amp;quot;Hello.&amp;quot;}),&lt;br /&gt;
		actions:create(&amp;quot;NPCEmoteAction&amp;quot;, {&amp;quot;looks greedily at your pouch of money.&amp;quot;, false}),&lt;br /&gt;
	})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this scenario, the NPC will respond if the player has money &amp;amp; is not naked.&lt;br /&gt;
&lt;br /&gt;
Nested tables are supported as well:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local conditions = {&lt;br /&gt;
	conditions:create(&amp;quot;PlayerHasItemWithHimCondition&amp;quot;, {&amp;quot;money&amp;quot;}),&lt;br /&gt;
	{&lt;br /&gt;
		conditions:notCondition(conditions:create(&amp;quot;NakedCondition&amp;quot;)),&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
frank:add(ConversationStates.IDLE,&lt;br /&gt;
	ConversationPhrases.GREETING_MESSAGES,&lt;br /&gt;
	conditions,&lt;br /&gt;
	ConversationStates.ATTENDING,&lt;br /&gt;
	nil,&lt;br /&gt;
	{&lt;br /&gt;
		actions:create(&amp;quot;SayTextAction&amp;quot;, {&amp;quot;Hello.&amp;quot;}),&lt;br /&gt;
		actions:create(&amp;quot;NPCEmoteAction&amp;quot;, {&amp;quot;looks greedily at your pouch of money.&amp;quot;, false}),&lt;br /&gt;
	})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Adding Merchant Behavior ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;merchants&amp;lt;/code&amp;gt; object is used for adding merchant behavior (buying/selling) to an NPC.&lt;br /&gt;
&lt;br /&gt;
Example of adding seller behavior to an NPC:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if game:setZone(&amp;quot;0_semos_city&amp;quot;) then&lt;br /&gt;
	local frank = entities.createSpeakerNPC(&amp;quot;Frank&amp;quot;)&lt;br /&gt;
	merchants:addSeller(frank, merchants.shops:get(&amp;quot;shopname&amp;quot;), true)&lt;br /&gt;
&lt;br /&gt;
	game:add(frank)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a custom shop list, you can use a Lua table (there are multiple ways to add elements to a Lua table):&lt;br /&gt;
&lt;br /&gt;
Method 1:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local priceList = {&lt;br /&gt;
	meat = 50,&lt;br /&gt;
	[&amp;quot;ham&amp;quot;] = 70,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local priceList = {}&lt;br /&gt;
priceList.meat = 50&lt;br /&gt;
priceList[&amp;quot;ham&amp;quot;] = 70&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The helper methods have special handling for underscore characters as well (the following are all the same):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
local priceList = {&lt;br /&gt;
	smoked_ham = 100,&lt;br /&gt;
	[&amp;quot;smoked ham&amp;quot;] = 100,&lt;br /&gt;
}&lt;br /&gt;
priceList.smoked_ham = 100&lt;br /&gt;
priceList[&amp;quot;smoked ham&amp;quot;] = 100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the seller behavior using the custom list:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
merchants:addSeller(frank, priceList, true)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== System Properties ==&lt;br /&gt;
&lt;br /&gt;
Java&amp;#039;s system properties are exposed to Lua with the &amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt; object.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- property state&lt;br /&gt;
if properties:enabled(&amp;quot;stendhal.testserver&amp;quot;) then&lt;br /&gt;
	print(&amp;quot;Test server enabled&amp;quot;)&lt;br /&gt;
	if properties:equals(&amp;quot;stendhal.testserver&amp;quot;, &amp;quot;junk&amp;quot;) then&lt;br /&gt;
		print(&amp;quot;Junk enabled&amp;quot;)&lt;br /&gt;
	else&lt;br /&gt;
		print(&amp;quot;Junk disabled&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	print(&amp;quot;Test server disabled&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- property value&lt;br /&gt;
local prop = properties:getValue(&amp;quot;stendhal.testserver&amp;quot;)&lt;br /&gt;
if prop ~= nil then&lt;br /&gt;
	print(&amp;quot;Test server enabled&amp;quot;)&lt;br /&gt;
	if prop == &amp;quot;junk&amp;quot; then&lt;br /&gt;
		print(&amp;quot;Junk enabled&amp;quot;)&lt;br /&gt;
	else&lt;br /&gt;
		print(&amp;quot;Junk disabled&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	print(&amp;quot;Test server disabled&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Misc ==&lt;br /&gt;
&lt;br /&gt;
=== Typecasting ===&lt;br /&gt;
&lt;br /&gt;
Lua does not support typecasting (as far as I know), but if the class you want to cast to has a copy constructor, achieving the same functionality is quite simple.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- &amp;quot;entities:getItem&amp;quot; returns an instance of Item&lt;br /&gt;
local bestiary = entities:getItem(&amp;quot;bestiary&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- in order to use the bestiary&amp;#039;s &amp;quot;setOwner&amp;quot; method, we must convert it to an &amp;quot;OwnedItem&amp;quot; instance by calling its copy constructor&lt;br /&gt;
bestiary = luajava.newInstance(&amp;quot;games.stendhal.server.entity.item.OwnedItem&amp;quot;, bestiary)&lt;br /&gt;
bestiary:setOwner(&amp;quot;Ted&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= See Also =&lt;br /&gt;
&lt;br /&gt;
* [[StendhalScripting/LuaAPI|Lua API]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Stendhal]]&lt;br /&gt;
[[Category:Documentation]]&lt;br /&gt;
[[Category:API]]&lt;br /&gt;
[[Category:Scripting]]&lt;br /&gt;
[[Category:Lua]]&lt;/div&gt;</summary>
		<author><name>183.129.118.43</name></author>
	</entry>
</feed>