Globulation 2 includes a map editor which allows you to create custom maps and games for everyone to enjoy. The map editor is quite straightforward. There are, however, some obscure behaviours. They include:
- On the last menu, teams can be either AI or human. For custom games this does not matter, but for campaign games atleast one team must be human.
- When deleting a team, all related buildings and units are destroyed.
- If terrain is set to water under a unit who can't swim, the unit is deleted.
- Don't modify the default objective text unless its a campaign map.
When making a map you need to keep a few things in mind:
- Make the map balanced. Achieving this through symmetry is the easiest strategy though this makes the maps look artificial.
- All teams should have access to wheat, wood, algae and stone. Additionally the water near wheat and wood is essential. So this should be balanced, too.
- The amount of water can challenge the teams as it makes them overgrown within short time. Also keep in mind that passages might grow closed which can make maps unbalanced later in a match.
- If you want to have schools built early in the game, place at least 10 bits of algae near any base so it can be grabbed without having the ability to swim.
- The swarm should be placed no more than 10 tiles away from the pile of wheat that you have created for the team.
- Each Team should start with 4 workers and an explorer.
- Don't touch fruits if you don't have any special concept about it.
A good start is to use the random map generator. These maps are not symmetric so pay attention on all mentioned aspects of balancing these maps.
Scripting Syntax
Globulation 2 includes a powerful scripting language called "SGSL" that lets map creators add features to their maps, to improve the gaming experience. SGSL is simple and has a very easy syntax. An SGSL script is nothing else than a list of lines which are executed sequentially. The power of SGSL is its ability to execute several scripts at the same time. So there can be, for instance, two different ways to win the game, and both will be valid. This is known as multi-threaded-scripting (MTS).
SGSL is functional, that is, every keyword is a function. In order for the script to continue, each of the functions has to evaluate to true. The syntax is simple, math-like with "functionName(list arguments)" possible arguments can also be functions.
SGSL can be edited from the map editor. You can get to it by clicking on the script editing button in the right sidebar (directly below the "Quit" button). In the SGSL editor, the script can be saved to or loaded from external text files, allowing you to edit it in any word application such as WordPad.
Keywords
The possible keywords (functions) are:
- show("text", lang)
- Shows "text" until hide is reached. If lang is given, "text" is only displayed if lang is equal to the current language.
- hide
- Hides the text displayed by show.
- wait(condition)
- Waits until condition is true. As a special case, specifying an integer waits that number of seconds (e.g. wait (300) makes the script execution wait for 300 seconds at this line), and specifying a numerical comparison waits until that comparison is true (e.g. wait(Inn(0,0) = 1) makes the script wait until there is exactly one level 1 inn being built.
- space
- Waits until the spacebar is pressed before executing any other part in the script.
- not(function)
- Negates the result of the function given as parameter.
- isdead(player)
- Returns true if the player "player" (designed by an integer) is dead (this is mostly useful in wait())
- area("areaName", who)
- Returns true if globules or structures of the players designed by the function who are in the area "areaName" (mostly useful with wait()). Valid values of who include:
- enemy(player) enemies of player
- ally(player) allies of player
- an integer p player p
- timer(time)
- Starts a global timer. When it reaches 0, the game is won. The remaining time is shown on the screen.
- alliance(player1, player2, level)
- Changes alliance level between players player1 and player2 to level.
- level 0 enemies
- level 1 shared market vision
- level 2 shared inn vision
- level 3 allies and fully shared vision
- label("labelName")
- Puts the marker "labelName" in the code to go back with jump.
- Jump("labelName")
- Jumps to the code labelled "labelName" by label.
- setArea("name", x, y, r)
- Defines an area with the name "name" at x, y and radius r on the map. Note: This is now deprecated, the "Script Areas" that can be placed in the map editor can be used interchangably with these areas by setting the name in the editor.
- summonUnits("areaName", amount, type, level, player)
- Creates an amount of globules of type type, controlled by the player at the position set by the area "areaName". The radius of the area is not important, but if there is no place to summon the globules, less or no globules will be summoned.
- summonFlag("flagName", x, y, r, unitcount, team)
- Creates a `WarFlag for the team with the given position x, y and radius r. The `WarFlag is set to require unitcount units.
- destroyFlag("flagName")
- Destroys a flag created by summonFlag
- win(player)
- loose(player)
- Makes player win/lose the game (note the misspelling of the word lose).
- story
- Indicates the beginning of a new script to execute in parallel.
- guiEnable(guiElement)
- guiDisable(guiElement)
- Enables/disables a GUI element. Be aware that only the GUI elements are disabled - AIs are still able to use the related functions. In campaigns with several missions, GUI elements are not re-enabled between missions, so you will should explicitly enable and disable GUI elements at the start of your scripts. Valid GUI elements are:
- AllianceScreen
- BuildingTab
- FlagTab
- TextStatTab
- GfxStatTab
- ExporationFlag
- WarFlag
- ClearingFlag
- ForbiddenFlag
- CancelFlag
- any variable (see below)
- objectiveHidden(objectiveNumber)
- Sets the given objective as hidden
- objectiveVisible(objectiveNumber)
- Sets the given objective as visible
- objectiveComplete(objectiveNumber)
- Sets the given objective as complete
- objectiveFailed(objectiveNumber)
- Sets the given objective as failed
- hintHidden(hintNumber)
- Sets the given hint as hidden
- hintVisible(hintNumber)
- Sets the given hint as visible
- hilightItem("itemName")
- unhilightItem("itemName")
- Shows or removes an arrow pointed at the provided item. Possibilities are:
- "main menu icon"
- "right side panel"
- "under minimap icons"
- "units assigned bar"
- "units ratio bar"
- "workers working free stat"
- hilightUnits(unit type)
- unhilightUnits(unit type)
- Shows or removes arrows pointed at all of the units of that type
- hilightBuildings(building type)
- unhilightBuildings(building type)
- Shows or removes arrows pointed at all of the buildings of that type
- hilightBuildingOnPanel(building type)
- unhilightBuildingOnPanel(building type)
- Shows or removes arrows pointed at the building selection on the right panel of the screen
- resetAI(player, ai type)
- Resets the given player as an AI. Can be used to change AI's of teams mid-match. AI Type is a number, as follows:
- 0) None
- 1) Numbi
- 2) Castor
- 3) Warrush
- 4) Reach To Infinity
- 5) Nicowar
Conditions
The possible parameters for the function wait are:
- any integer
- The amount of seconds to wait (example: wait (300), makes the script execution wait for 300 seconds at this line).
The other conditions are functions returning true or false (true meaning that waiting is over / false meaning it will continue to wait):
- not(function)
- Negates the result of the function given as parameter.
- isdead(player)
- eturns true if the player "player" (designed by an integer) is dead.
- area("areaName", who)
- Returns true if globules or structures of the players designed by the function who are in the area "areaName". Who may be:
- enemy(player) enemies of player
- ally(player) allies of player
- an integer p player p
- variable(...) comparison value
- True when the comparison comparison is true between value and the result of the function variable. comparison can be: greater-than, less-than and equal to
Variables
- [only] variable(player, level);
- Returns the number of buildings (or globules, depending of the chosen "variable" function) belonging to the player player and which are of level level or higher (levels are disregarded for globules). For buildings, if optional "only" is given, only specified level and not higher ones is taken into account (in mercurial source tree from 2007-12-25, before, the "only" behaviour was the only possible one). The "variable" functions are the following:
- Worker: Number of working globules.
- Explorer: Number of exploring globules.
- Warrior: Number of warrior globules.
- Swarm: Number of swarms.
- Inn: Number of inns.
- Hospital: Number of hospitals.
- Racetrack: Number of race tracks.
- Pool: Number of swimming pools.
- Camp: Number of training camps.
- School: Number of schools.
- Tower: Number of towers.
- Market: Number of markets.
- Wall: Number of walls.
Building levels are treated like this:
Building level |
Building in construction |
Level used for comparison
|
0 |
yes |
0
|
0 |
no |
1
|
1 |
yes |
2
|
1 |
no |
3
|
2 |
yes |
4
|
2 |
no |
5
|
Example
Here is the script used in the map The Sand Square:
setArea("dest1",60,0,1)
setArea("dest0",31,0,1)
show("Get to the sand square in your opponents base.")
wait(10)
hide
story
wait(area("dest0",1))
loose(0)
story
wait(area("dest1",0))
loose(1)
USL
The next release of Globulation 2 will feature a new scripting language, called USL. This language is more flexible and allows you to write complex scenario.
Example
This little script displays "Hello" on the screen, waits 5 seconds and then displays "Hallo" instead of "Hello":
show "Hello"
sleep 5
show "Hallo"
Language and built-in features
single-line or multiline
\# this is a single-line comment
\*
this is a multi-
line comment
\*
Data types
- strings
- "Hello"
- boolean values
- true, false
- integers
- 1, 2, 3
- arrays
- between [], they are used to group values together
array := [1, 2, 3]
print (array at 0) \# prints 1
- tuples
- between (), they work like arrays, except when empty or with a single value
nil := () \# this is not an empty array, it is the special value nil
zero := (0) \# this is the same as 0
array := (0, 1) \# this is the same as [0, 1]
- declarations
- as seen in the examples above, you can declare variables using :=
a := 1
b := a + 2
Control structures
These are implemented in the script itself. You can make your own structures if these do not suit your needs.
- conditions
if (x = 3) {
show "x = 3"
} else {
show "x != 3"
}
- loops
while (getUnits("targetArea").empty) { \# this is equivalent to wait(!getUnits("targetArea").empty)
sleep 1
}
- blocks
- between {}, they are executed and evaluate to the last result of the block
x := { \# x takes the value (5 * 8) - 2
a := 5 * 8
a - 2
}
Functions
Functions can be named or anonymous.
def f(x) := x + 1
def y := fun x -> x + 1
z := fun x -> x + 1
Other
- members
- declarations inside arrays or tuples act as local declarations
a := [
b := 2
def c(x) := x + b
]
d := a.c(3)
\# this can also be written as
d := a c 3
Globulation 2 API
Constants
Constants are physically integers, but semantically enum types.
In this section, we list them along with their semantic types, that we will use thereafter in functions descriptions.
Unit
Ability
- AbilityWalk
- AbilitySwim
- AbilityFly
- AbilityBuild
- AbilityHarvest
- AbilityAttackSpeed
- AbilityAttackStrength
- AbilityMagicAttackAir
- AbilityMagicAttackGround
Building
- Swarm
- Inn
- Hospital
- Racetrack
- Pool
- Camp
- School
- Tower
- Wall
- Market
BuildingLevel
- Level0Construction
- Level0Completed
- Level1Construction
- Level1Completed
- Level2Construction
- Level2Completed
General getters
General getters return informations about the whole game, not about any particular area.
teamsCount() -> int
- Get whether a team is alive
isAlive(team:int) -> int
- Get the number of unit in a team:
unitsCount(team:int, type:Unit) -> int
- Get the number of unit with a given upgrade in a team:
unitsUpgradesCount(team:int, type:Unit, upgrade:Ability, level:int) -> int
- Get the number of building in a team:
buildingsCount(team:int, type:Building, level:BuildingLevel) -> int
GUI functions
GUI functions allow USL to interact with the user.
- Show a message, regardless of the language. Replace any message previously shown in this step.
show(message:string)
- Show a message, only if the current language matches the one in function. Replace any message previously shown in this step.
showTr(message:string, lang:string)
- Hide the shown message, if any
hide()