scripting
scripting
Pitsu
Layout
Robenhagen
Scripting your maps is a way to make them more interesting, per- writing: the syntax, how to build a function and set triggers prop-
sonal and control the game course better. The Heroes of Might erly. But even with this guide and other materials at hand, be
and Magic V Editor (game patch . or later required) allows you ready to lose some nerves when doing you first scripts? Luckily on
to build such scripts. In your game folder you even have docu- online forums other people can help you in your darkest hours.
mentations for editor handling and the script commands. Yet, it I must admit that without people asking for help and without
is easy to get lost when opening the script editor window and see- other mapmakers demonstrating their neat solutions, this piece
ing the blank white page. What and how do write in there? of manual would not have been written. My thanks to all the
This little pdf is meant as a supplementary material for the regulars of the Round Table Mapmaking Guild!
official editor documentations. It does not describe all the indi- Oh, and an important warning before you start to work with
vidual commands for instance, since they already are quite well scripts: be aware that Heroes V scripts works only on single player
covered in official materials. It is just about the trivial of SCRIPT maps!
2. Functions ........................................................ 3
2.1. Defining functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2. If … then, while … do etc. blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3. How many “end”s does there have to be? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.4. Function fname() or function fname(parameter) . . . . . . . . . . . . . . . . . . . . . . . . 3
2.4.1. Function fname(hero_name) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.5. Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3. Variables ......................................................... 5
3.1. Variable types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.1. Global variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.2. Local variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1.3. Game variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
4. Triggers .......................................................... 6
4.1. Instant triggering of functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
4.2. Binding functions to map events and objects . . . . . . . . . . . . . . . . . . . . . . . . . . 6
4.3. Triggering fname(parameter) type of functions . . . . . . . . . . . . . . . . . . . . . . . . . 6
4.4. Removing a trigger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
5. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.1. Are empty lines, semicolons and number of spaces important? . . . . . . . . . . . . 8
5.2. Case sensitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.3. Quotation marks and their use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.3.1. USE NO QUOTES WHEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.3.2. USE QUOTES WHEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.4. How to refer text message files, map objects and heroes . . . . . . . . . . . . . . . . . 9
5.5. Meaning of some symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Example
VARIABLES
TRIGGERS
Note the text color code. It helps a bit to avoid spelling and other mistakes. When it is green (comment), you can write anything, it
is ignored by the game. When it is blue, it is a number or has a certain meaning for lua programming language. When it is red, it is a
properly spelled Heroes V specific command. Text between quotation marks (parameter names) is orange. The rest is black.
SYNTAX
DEBUGGING
2
Functions
2. Functions if boolean test then
FUNCTIONS
function give_it_a_nice_name() until boolean test
commands_that_run_every_time_when_the_
function_is_triggered ;
if boolean_test then
commands_that_run_only_if_boolean_test_ 2.3. How many “end”s does there have to be?
returns_true ;
end; An “end” is required for each “block” that is started with:
again_commands_that_run_every_time_when_the_
function_is_triggered ; · function
end; · if … then
VARIABLES
· if … then … else
· while … do
You can have blocks within other blocks: · for … do
function function_name() Everything that is between an above listed command and respec-
commands_that_run_always_when_the_ tive “end” statements forms a block and are run together or none
function_is_triggered ; is run. See examples under general description of functions.
if boolean_test then
commands_that_run_only_if_boolean_test_ One block that does not require “end” is:
returns_true ;
TRIGGERS
if boolean_test2 then repeat
commands_that_run_only_if_boolean_test_and_ commands;
boolean_ test2_BOTH_return_true ; until boolean test;
end;
end;
end; 2.4. Function fname() or
function fname(parameter)
NOTE: Clicking on the script editor <Check> button gives you Imagine situation where you have several objects which trigger
SYNTAX
an ERROR “function xxx not defined” for every function. This is similar scripts. For example several towns that upon capture are
meant only to confuse and scare you … Ignore it. converted to another town type. You could write a separate script
for each town, but you can use the possibility to write a general
2.2. If … then, while … do etc. blocks function and specify the town that has to be changed in the trig-
ger. For that is the possibility to define variables in parenthesis
The basic most common types of blocks are briefly described be- after function name. You can have more than one such variable
low. But in fact lua, the language that Heroes uses, is more power- there, separated by commas, if needed.
ful than that, but in order to learn other possibilities of the same
DEBUGGING
3
Functions
2.5. Threads
SCRIPT FILE LAYOUT A
function transform() often you do need the opposite: commands are hold back until a
TransformTown(“town2”, TOWN_ACADEMY); certain requirement is fulfilled. For that use the following:
end;
function funcname()
In the following example “townname” variable is not used for while boolean test do
anything. The variable is defined, but always town is converted. if boolean test2 then
Thus “function transform()” is more appropriate to use than commands;
“function transform(townname)”. end;
sleep(10);
Bad example end;
VARIABLES
end;
function transform(townname)
TransformTown(“town2”, TOWN_ACADEMY); If you have problems defining the first boolean test which deter-
end; mines how long the thread lives, give it eternal life with “while
do”. Official maps use this statement quite often.
... Function fname(hero_name)
Heroes have a special relationship with functionname(parameter) sleep() – why that? This is to save your CPU. If you forget it or
type of functions. Namely, one does not need to specify the hero misplace it so that it is not effective, you force the thread to run
to which the generic function applies. If not specified, the cur- without pauses, causing game lags. The higher the number the
rently selected hero, who triggered the script is chosen. more time you give for other processes. is a good value, but
TRIGGERS
function message2(lollu) -- without defining Triggering threads goes via startThread(functionname) com-
the parameter here, HasArtefact returns an error mand. Triggering them in other ways basically blocks access to
if HasArtefact(lollu, 2) then -- tests whether other scripts as long as the (infinite) thread runs.
selected hero has artifact number 2
SetRegionBlocked(“passage”,0,3); Example script: You want a script that gives the player an instant
end; win when he accumulates . gold.
SYNTAX
end;
function checkgold()
while 1 do
This function can be called up without specifying the hero name if GetPlayerResources(PLAYER_1, 6) >= 100000
like : then
win();
message2(); end;
sleep(10);
DEBUGGING
or end;
end;
Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER,
“area1”,“message2”); startThread(checkgold);
4
Variables
3. Variables ... Local variables
FUNCTIONS
can transfer the values from one type to another. For example: function day3() -- another function in the same
script file
local m = GetGameVar(“temp.gamevar1”); if GetDate(DAY) == day then -- error, since
variable “day” does not exist in
this function.
... Global variables blabla();
These are the most common ones. Usually you can live with only end;
them, without using any other type of variables. It is not a must end;
to define them prior use. The first time you use a name and give
it a value defines the variable and it can be used at any place in the
VARIABLES
script file. For keeping better track of them and avoid potential ... Game variables
errors where using a variable before giving it a value you may still Game variables are required for transporting variables between
define them at the start of a script file like shown on the image script files. For example you have a separate combat script file
on page . beside the general map scripts and you want to use the main fail
variables in combat script. Then you have to define and use game
Example variables with the following commands:
heronm = “Aberrar”; -- with this line you define SetGameVar(“variablename”, value) and
a text string type variable called GetGameVar(“variablename”)
heronm, with current value Aberrar.
TRIGGERS
SYNTAX
DEBUGGING
5
Triggers
4. Triggers
SCRIPT FILE LAYOUT A
In both cases only the latter would work, since it overwrites the
first. Luckily you can do an intermediate function that triggers as
Another very important part of a script is to set the triggers so many other functions as you wish.
that each function is run at the moment when you wish it. You
can call a function up instantly by using its name or you can Example
define the conditions when a function has to run by the Trigger
command. Trigger(NEW_DAY_TRIGGER, “days”);
function blabla()
MessageBox(“Maps/SingleMissions/test/blah.txt”); function day2();
end; commands;
end;
function day2()
if GetDate(DAY)== 2 then Of course different objects can have the same type triggers with-
blabla(); -- here function blabla is triggered out problems and the same object can have different type of trig-
and the messagebox is shown at day 2. gers without problems.
end;
end; 4.3. Triggering fname(parameter)
VARIABLES
type of functions
4.2. Binding functions What if the function has some parameter that you need to
specify? As explained above, in cases where the parameter refers to
to map events and objects currently selected hero, there is no complication. In other cases,
How do define that a function has to run when a certain event avoid using parameters for parameters (long way) or use different
happens on your map? That is what you have the Trigger com- sets of quotation marks
mand for. It is quite nicely described in the official editor docu-
mentation pdfs, consult it for more information. Such triggers Example of the long way
look like:
TRIGGERS
Trigger(NEW_DAY_TRIGGER, “transform1”);
Trigger(EVENT _TYPE, “object to which the event
is bound”, “function name that has to be function transform1();
triggered”); transform(“town1”);
end;
When the Trigger command is not a part of a function, the func-
tion specified among its parameters is bound to the specified function transform(townname)
event at the start of the map. Being a part of another function transformtown(townname, 2);
means that the link between specified function and event is cre- end;
SYNTAX
Note that only one function can be bound to each object and Example of the short way
event combination. For example you cannot trigger two func-
tions simultaneously by defining: Trigger(NEW_DAY_TRIGGER, “transform(‘town1’)”);
-- NB! Different types of quotation marks are
Trigger(OBJECT_CAPTURE_TRIGGER, “town1”, used. Check that “transform1(‘town1)” is entirely
“function1”); orange colored in your editor!
DEBUGGING
Trigger(OBJECT_CAPTURE_TRIGGER, “town1”,
“function2”); function transform(townname)
TransformTown(townname, 2);
or end;
Trigger(NEW_DAY_TRIGGER, “day1”);
Trigger(NEW_DAY_TRIGGER, “day2”);
6
Triggers
4.4. Removing a trigger
Trigger(NEW_DAY_TRIGGER, “transform”);
function transform()
if GetDate(DAY) == 7 then
TransformTown(“town1”, 2);
Trigger(NEW_DAY_TRIGGER, nil);
end;
FUNCTIONS
end;
VARIABLES
TRIGGERS
SYNTAX
DEBUGGING
7
Syntax
5. Syntax
SCRIPT FILE LAYOUT A
that can be used “ and ‘. Generally it does not matter which you
use as long as start and ending marks are the same. A specific case Example
is given under “Triggering funcname(parameter) type of func-
tions”. function blabla()
if GetDate(DAY)== 2 then
... USE NO QUOTES MessageBox(“Maps/SingleMissions/test/
· When declaring a function: blah.txt”); -- quotes required for the text file
name.
Example end;
end;
TRIGGERS
· Numbers and the hard-coded “all capital letters” parameters · quotes are required when calling up or saving game variables.
(like NEW_DAY_TRIGGER or PLAYER_) are always See official manuals for examples.
without quotes. These capitalized words are actually names of
certain numbers (see official file IDs_for_scripts.pdf). Example script: you have a map with towns named (in
respective town properties window) town and town.
SYNTAX
· The function name acts as a command. Namely, each func- A (unnecessarily long, but illustrative) script that changes
tion that you write can be called up in the same way as the town to academy upon capture:
hard-coded commands.
function transform (townname) -- townname without
Example quotes since it is a variable
TransformTown(townname, TOWN_ACADEMY); -- town-
function blabla()
name is a variable name and TOWN_ACADEMY is,
MessageBox(“Maps/SingleMissions/test/blah.txt”);
well, “all capital letters” parameter.
DEBUGGING
end;
end;
function day2()
if GetDate(DAY)== 2 then
blabla(); -- no quotes around blabla.
end;
end;
8
Syntax
function town1capture() For example
FUNCTIONS
message right away, but the script may crash when run.
5.4. How to refer text message files,
Referring to heroes goes via their in-game ID names. You can
map objects and heroes give them a name by yourself, but scripts do not recognize them.
For beginners it can be very hard to get the references to external Not even the standard game names are not understood.
names correctly.
Here is the list of standard names and ID names (the unbolded
Referring to text files requires full path starting from Maps direc- names):
tory.
VARIABLES
Agrael Agrael Galib Tan Laszlo Laszlo Segref Segref
Alaron Ildar Giar Giar Lethos Dalom Shadya Kelodin
Alastor Efion Gilraen Gillion Lorenzo RedHeavenHero02 Sinitar Inagost
Andreas RedHeavenHero01 Giovanni Giovanni Lucretia Tamika Sorgal Ferigl
Anwen Metlirn Glen Glen Maahir Maahir Svea Vegeyr
Biara Biara Godric Godric Maeve Maeve Talanar Nadaur
*Brand Brand Grawl Calid Marbas Marder Temkhan Timerkhan
Cyrus Cyrus Grok Grok Markal Berein Thralsai Thralsai
Deirdre Nemor Guarg Guarg Naadir Muscip Valeria RedHeavenHero03
TRIGGERS
Deleb Deleb Havez Havez Narxes Razzak Vayshan Ohtarig
Dirael Diraya Helmar Ottar Nathir Nur Vinrael Elleshar
Dougal Orrin Inga Una Nebiros Jazaz Vittorio Christian
Duncan Duncan Ingvar Ingvar Nicolai Nicolai Vladimir Pelt
Ebba Bersy Irina Ving Nur Astral Wulfstan Wulfstan
Ellaine Nathaniel Isabel Isabell Nymus Nymus Wyngaal Linaas
Erasial Erasial Jezebeth Oddrema Ornella Ornella Ylaya Shadwyn
Ergar Ergar Jhora Sufi Orson Straker Ylthin Itil
Erling Egil Karli Skeggy Ossir Ossir Yrbeth Almegir
SYNTAX
9
Syntax
5.5. Meaning of some symbols
SCRIPT FILE LAYOUT A
= means give value to. m = means that henceforth AND between two boolean tests means that both tests have
variable m has value . to be true in order to proceed
== compares whether the left side is equal to the right OR between two boolean tests means that one of the tests
side. (returns true or false) has to be true in order to proceed
<= compares whether the left side is smaller than the right random(number) returns a random number between and
side. (returns true or false) specified number. Both inclusive.
>= compares whether the left side is larger than the right mod the left-over of dividing. mod equals to ;
side. (returns true or false) mod equals .
~= compares whether the left side is NOT equal to the nil – means “false”or nil or “none”. Used for disabling.
right side. (returns true or false)
FUNCTIONS
VARIABLES
TRIGGERS
SYNTAX
DEBUGGING
10
Hints for Debugging
6. Hints for debugging
FUNCTIONS
run under different conditions than you wish.
Console shows you many things about the game, including error
· Check that there are enough “end;” commands. A common
messages for faulty scripts.
problem is that the program does not understand properly
where a function ends and therefore ignores (a part of) the
6.2. Using the print command script file.
With console activated, you can track you scripts by using the · Make sure that the map is SingleMission and not MultiPlayer
print command. It prints specified message or variable into the (open the *.h5m file with zip or rar archiver and see the names
console window. You can put it pretty much anywhere between of subdirectories).
VARIABLES
TRIGGERS
SYNTAX
DEBUGGING
11