· ·:·: Stonescript :·:· ·
v4.0.0 - 2024/10/07
intro | manual | beta ·:· release notes | faq
_ ______________________ _ ,:´ \____ __.---,. `. :.! __________\_______\__`--__ \ :' \ \--------------------------.\ \ ':' · \ ·:. :'· :.:· \\ \ ':' \ \ :·' :·:. \\ \ ':' · \ .: ·:: '.:. ':'··:. \\ \ ':' \ \ · :.. \\ \ ':' · \ :·: ..': :·:. ·:: '. \\ \ ':' \ \__________________________\\ \ ':' ` . \ . ) ':' . . . \ . . . . ' . . . . \ . .; `·.;,;,;,;,;,;,;,;,;,;,;,;,;,;,:'
Used in the Mind Stone to automate equipment choices. Stonescript is a minimalistic, yet powerful language inside of Stone Story RPG. New to Stonescript? Consider starting at the Introduction to the Mind Stone tutorial. Need help? Want to collaborate on scripts? Visit our Discord. This manual is the comprehensive reference of all available Stonescript features. Most of the examples can be copy/pasted directly into the Mind Stone, which is a great way to learn how they work. ·:·:· Index ·:·:· 1. Example 2. Basics 3. Game State 4. Commands 5. Search Filters 6. Comparisons 7. Variables 8. Math Operations 9. Functions 10. Native Functions 11. Importing External Scripts 12. ASCII-art 13. Loops 14. Arrays 15. Custom Input 16. User Interface 17. Tips 18. Default script 19. Roadmap Appendix A - Sound Effects Appendix B - Music Appendix C - Ambient Loops
·:·:· Example ·:·:· // Equips the Shovel for Rocky Plateau. // In Caves of Fear it equips loadout 1, // except against the boss, where the // Grappling Hook and a 7 star War Hammer // are used instead. // For Haunted Halls it uses two Wands, // specifying Poison for left hand and // Vigor for the right hand. However, // if the difficulty is over 5 stars it // uses an enchanted +13 Vigor Staff. // Potion activates if hitpoints fall // below 10 ?loc=rocky equip shovel ?loc=cave loadout 1 ?foe=bolesh equip grap equip hammer *7 D ?loc=halls equipL poison wand equipR vigor wand ?loc.stars > 5 equip vigor staff +13 ?hp < 10 activate potion ^Back to top
·:·:· Basics ·:·:·
? Evaluates a logical condition. If true, executes indented lines (if).
E.g.
?loc = caves
loadout 1
: Alternative logical branch, in case the '?' condition is false (else).
E.g.
?loc = caves
loadout 1
:
loadout 2
:? Alternative logical branch, with additional conditions (else-if).
E.g.
?loc = caves
loadout 1
:?loc = deadwood
loadout 2
:
loadout 3
// A comment. All text to the right of '//' has no logical effect when the script executes.
E.g.
?loc = caves
loadout 1
//The above equips loadout 1 for Caves of Fear
/* */ Block comment. All text between the symbols has no logical effect when the script executes.
E.g.
/*
?loc = caves
loadout 1
*/
This script does nothing, as all of it is inside the block comments.
^ Continue previous line.
E.g.
?loc=caves |
^loc = mine
equip repeating

//The above is equal to:
?loc=caves|loc=mine
equip repeating
^Back to top
·:·:· Game State ·:·:· These questions tell you what's happening and what's right in front of the player.
?loc The current location the player is visiting.
E.g.
?loc = caves
loadout 1
?loc.id The unique identifier of the current location.
E.g.
var id
id = loc.id
>Exploring @id@
?loc.gp The total gear power used during the current run.
E.g.
>`0,1,Run GP = @loc.gp@
?loc.name The localized name of the current location.
E.g.
>Exploring @loc.name@
?loc.stars The current location's difficulty.
E.g.
?loc = caves
?loc.stars=4
loadout 1
?loc.stars=5
loadout 2
?loc.begin Is true only on the first frame of a location, when time = 0, before any game simulation has run. Is not true after an Ouroboros loop. Useful for resetting variables.
E.g.
var i
?loc.begin
i = 0
?loc = caves
i = -100
?loc.loop Is true on the first frame of a run after an Ouroboros loop.
E.g.
var loopCount = 0
?loc.loop
loopCount++
?loc.isQuest True if the current location is a special location from a Legend or custom quest. False otherwise.
E.g.
?loc.isQuest
>`0,1,We're in a special quest location
loc.averageTime The current location's average completion time. A location's average time is calculated in a weighted manner, where the latest completion time is worth more and older times are worth progressively less the older they are.
E.g.
>`0,2,Average time =
^ @loc.averageTime@ frames
loc.bestTime The current location's best completion time (your record, high-score).
E.g.
>`0,1,Best time =
^ @loc.bestTime@ frames
?encounter.isElite Tells you if the current encounter is an elite encounter or not.
E.g.
>`0,1,Elite = @encounter.isElite@
?encounter.eliteMod Tells you the special modifier, if any, for the current encounter.
E.g.
>`0,2,Modifier = @encounter.eliteMod@
?foe The current foe being targeted by the player.
E.g.
?foe = boo
equip vigor staff
?foe.id The unique ID (or type) of the foe being targeted by the player.
?foe.name The localized name of the foe being targeted by the player.
?foe.damage The damage per attack of the foe being targeted by the player.
E.g.
>`0,1,foe damage = @foe.damage@
?foe.distance The distance between the player and the foe being targeted.
?foe.z The z position of the foe being targeted.
?foe.count The number of foes within 46 units of the player.
?foe.GetCount(int) The number of foes within a specific number of units.
?foe.hp The current hitpoints of the foe being targeted by the player.
?foe.maxhp The maximum hitpoints of the foe being targeted by the player.
?foe.armor The current armor of the foe being targeted by the player.
?foe.maxarmor The maximum armor of the foe being targeted by the player.
?foe.buffs.count The number of buffs (positive effects) on the foe being targeted.
?foe.buffs.string A composite of information about all the buffs on the target foe.
E.g.
?foe.buffs.count > 0
>`0,3,Foe buffs = @foe.buffs.string@
?foe.buffs.GetCount(str) The number of a specific buff on the target foe.
?foe.buffs.GetTime(str) The duration of a specific buff on the target foe.
?buffs.oldest The ID of the oldest buff on the player
E.g.
>`0,1,Oldest buff: @buffs.oldest@
?foe.debuffs.count The number of debuffs (negative effects) on the foe being targeted.
?foe.debuffs.string A composite of information about all the debuffs on the target foe.
E.g.
?foe.debuffs.count > 0
>`0,4,Foe debuffs = @foe.debuffs.string@
?foe.debuffs.GetCount(str) The number of a specific debuff on the target foe.
E.g.
>`0,1,Chill debuff count =
^ @foe.debuffs.GetCount("debuff_chill")@
?foe.debuffs.GetTime(str) The duration of a specific debuff on the target foe.
E.g.
>`0,2,Chill debuff time =
^ @foe.debuffs.GetTime("debuff_chill")@
?debuffs.oldest The ID of the oldest debuff on the player
E.g.
>`0,1,Oldest debuff: @debuffs.oldest@
?foe.state A number representing the target foe's current state.
E.g.
?foe.state = 0
>`0,0,Foe is asleep
?foe.time Elapsed number of frames in target foe's current state.
E.g.
>`0,0,Foe = @foe.name@:@foe.state@,@foe.time@
?foe.level The level number of the target foe.
E.g.
>`0,0,Foe = @foe.name@ is level @foe.level@
?harvest The next harvestable object, such as a tree or boulder.
E.g.
?harvest=Boulder
equip shovel
?harvest.distance The distance between the player and the nearest harvestable object.
E.g.
?loc=Rocky & harvest.distance < 7
equip shovel
?harvest.z The z position of the nearest harvestable object.
E.g.
?loc=Rocky & harvest.z > 5
equip shovel
?input.x The X position, on the ASCII grid, of the input device (mouse/touch).
?input.y The Y position, on the ASCII grid, of the input device (mouse/touch).
E.g.
> (@input.x@, @input.y@)
?item.left The item equipped to the left hand.
E.g.
>`0,1,Left:@item.left@
>`0,2,Right:@item.right@
?item.right The item equipped to the right hand.
E.g.
?item.right = quarterstaff
activate R
?item.left.gp
?item.right.gp
The gear power value of the item equipped to the left or right hand.
E.g.
>`0,1,Left GP:@item.left.gp@
>`0,2,Right GP:@item.right.gp@
?item.left.id
?item.right.id
The ID of the item equipped to the left or right hand.
E.g.
>`0,1,Left ID:@item.left.id@
>`0,2,Right ID:@item.right.id@
?item.left.state
?item.left.time
?item.right.state
?item.right.time
The numeric representation for an equipped weapon's current state and elapsed frames within that state.
E.g.
>`0,1,@item.left.state@:@item.left.time@
>`0,2,@item.right.state@:@item.right.time@
?item.potion The potion currently brewed. Includes "auto" if auto-refill is enabled on the Cauldron.
E.g.
?item.potion ! empty & item.potion = auto
activate potion
?pickup The current pickup being targeted by the player.
E.g.
?pickup
equip star stone
:
loadout 1
?pickup.distance The distance between the player and the pickup being targeted.
E.g.
?pickup.distance < 5
equipL star stone
?pickup.z The z position of the pickup being targeted.
E.g.
?pickup.z > 7
equipL star stone
?armor The player's current armor, rounded down.
E.g. if the armor says [2.4] ?armor evaluates to 2.
?armor.f The player's current armor's fractional amount.
E.g. if the armor says [2.4] ?armor.f evaluates to 4.
?buffs.count The number of buffs (positive effects) on the player.
?buffs.string A composite of information about all buffs on the player.
E.g.
?buffs.count > 0
>`0,1,Player buffs = @buffs.string@
?buffs.GetCount(str) The number of a specific buff on the player.
?buffs.GetTime(str) The duration of a specific buff on the player.
?debuffs.count The number of debuffs (negative effects) on the player.
?debuffs.string A composite of information about all debuffs on the player.
E.g.
?debuffs.count > 0
>`0,2,Player debuffs = @debuffs.string@
?debuffs.GetCount(str) The number of a specific debuff on the player.
?debuffs.GetTime(str) The duration of a specific debuff on the player.
?hp The player's current hitpoints.
?maxhp The player's maximum hitpoints.
?maxarmor The player's maximum armor, rounded down.
?pos.x The player's current X position.
?pos.y The player's current Y position.
?pos.z The player's current Z position.
?ai.enabled True if the AI is on, False if the AI is off (e.g. during a cinematic moment).
?ai.paused True if the AI is temporarily suspended, such as when waiting for a treasure to drop.
?ai.idle True if the player is idle, waiting for something such as an attack to complete.
?ai.walking True if the player is moving.
?bighead True if the player has Big Head enabled (Moondial).
?face The player's current facial expression.
E.g.
?face = "^^"
>Happy
?key The state of custom game input.
The following prints the current input:
>@key@
?res.stone
?res.wood
?res.tar
?res.ki
?res.bronze
?res.crystals
The player's current amount of resources in their inventory.
E.g.
?loc = Deadwood
>Wood = @res.wood@

E.g.2
>`0,1,#magenta, ♦ @res.crystals@
?player.direction Indicates the direction in which the player is facing. Returns a value of 1 for right and -1 for left.
E.g.
?player.direction = 1
>`0,0,Walking right
:
>`0,0,Walking left
player.name The name chosen by the player.
This example prints the player's name above their head:
var name
var x
name = player.name
x = string.Size(name) / -2
>o@x@,-2,@name@
player.GetNextLegendName() The next unlocked Legend quest the player hasn't completed yet.
?rng Returns a random integer between 0 and 9999.
E.g.
?rng < 5000
>Heads!
:
>Tails!

E.g.2: Generates a random integer between 5 and 24:
var min = 5
var max = 24
var n = min + rng % (max - min + 1)
?rngf Returns a random floating-point number between 0 and 1.
E.g.
>random float = @rngf@

E.g.2: Generates a random float between 5.0 and 24.0:
var min = 5.0
var max = 24.0
var n = min + (max - min) * rngf
?screen.i The screen's position in-game, as an index that increses when the player reaches the right-side and it slides over.
E.g.
>`0,0,Screen index = @screen.i@
?screen.x The screen's position in-game.
E.g.
>`0,0,Screen position X = @screen.x@
?screen.w The width of the screen's ASCII grid.
E.g.
var sw = screen.w
>Screen width = @sw@
?screen.h The height of the screen's ASCII grid.
E.g.
var sh = screen.h
>Screen height = @sh@
?summon.count The number of summoned allies currently in game.
E.g.
?summon.count = 0
equipL talisman
activate L
summon.GetId(index = 0) Returns the ID of the summon at a given index. The index parameter is optional and defaults to zero (first summon). Returns null if no summons are at that index.
E.g.
?summon.GetId() ! "cinderwisp"
equipR fire talisman
activate R
summon.GetName(index = 0) Returns the localized name of the summon at a given index. The index parameter is optional and defaults to zero (first summon). Returns null if no summons are at that index.
E.g.
>`0,1,Summon:@summon.GetName()@
summon.GetVar(varName,
index = 0)
Returns the value for a custom variable on a summon. Different types of summons expose different variables, based on their unique abilities. The index parameter is optional and defaults to zero (first summon). Returns null if no summons are at that index. Shows an error if varName does not correspond to a valid variable.
E.g.
?summon.GetId() = cinderwisp &
^summon.GetVar("ignition") > 2
activate cinderwisp
summon.GetState(index = 0) Returns a number representing the current state of a summon. The index parameter is optional and defaults to zero (first summon). Returns -1 if no summons are at that index.
E.g.
>`0,1,Summon state:@summon.GetState()@
summon.GetTime(index = 0) Returns the elapsed number of frames in the current state of a summon. The index parameter is optional and defaults to zero (first summon). Returns -1 if no summons are at that index.
E.g.
>`0,1,Summon time:@summon.GetTime()@
?totalgp The total "Gear Power" of your inventory, calculated from item star levels and enchantment bonuses.
E.g.
>My gear power = @totalgp@
?time The current frame number of the location.
E.g.
?time % 300 = 0
>Every 10 seconds you'll see this message
?totaltime The current frame number of the location, accumulated in case of boss sub-location.
E.g.
>`0,0,Current time = @totaltime@ frames
time.msbn Unix time represents the number of milliseconds that have elapsed since
1970-01-01T00:00:00Z (January 1, 1970, at 12:00 AM UTC). It does not take leap seconds into account. Returns a BigNumber
E.g.
>@time.msbn@
time.year, time.month, time.day, time.hour, time.minute, time.second The local system time on the player's computer.
E.g.
>`0,0,@time.year@/@time.month@/@time.day@
^ @time.hour@:@time.minute@:@time.second@
utc.year, utc.month, utc.day, utc.hour, utc.minute, utc.second The current UTC time.
E.g.
var utcZ = utc.year*356*12*24*30 +
^utc.month*12*24 + utc.day*24+utc.hour
var timeZ = time.year*356*12*24*30 +
^time.month*12*24 + time.day*24+time.hour
var timeZone = timeZ - utcZ
?timeZone < 0
>`0,0,Time Zone: UTC@timeZone@
:
>`0,0,Time Zone: UTC+@timeZone@
^Back to top
·:·:· Commands ·:·:· These tell the game to do something.
activate (ability) Activates an item ability. (ability) can have these values: potion, P, left, L, right, R.
E.g.
activate R
(activates the ability of the item equipped on the right side, such as the Hatchet)
brew (ingredients) Refills the potion bottle to the specified combination of ingredients. Executes only at the beginning of a run, at time 0. Ingredients can be stone, wood, tar or bronze and should be separated by +. Ingredient names can be written in English or in the language selected in the settings.
E.g.
?loc.begin
brew bronze + tar
equip (str) Equips an item. (str) has a limit of 7 criteria. Two-handed items must use this form of the equip command.
E.g.
equip vigor crossbow *8 +5
equipL (str) Equips an item to the left hand that best fits the given criteria.
E.g.
equipL poison d_sword
equipR (str) Equips an item to the right hand that best fits the given criteria.
E.g.
equipR vigor shield
equip @var@ Equips an item based on criteria from a string variable. Equip and other item search commands support subtractive criteria.
E.g.
var weaponName = "poison sword *10 -big"
equipR @weaponName@
loadout (n) Equips a specific loadout number.
E.g.
?loc = caves
loadout 1
?loc = deadwood
loadout 2
> (str) Prints a string to the top of the screen.
E.g.
>Hello World!
> @varName@ Prints a string with the value of a variable inserted. Multiple variables can be inserted into a single print. To insert, surround the variable's name with @.
The following example prints information about the currently targeted foe:
var foeInfo
foeInfo = foe
>FOE = @foeInfo@
>(abcd Shows a custom facial expression on the player. Requires Big Head.
E.g.
>( OwO
>oX,Y,[#rrggbb,](str) Advanced print relative to the player's position. X and Y are the coordinate offsets. #rrggbb is the color of the text in hexadecimal notation. Color can also be set with these constants: #white, #cyan, #yellow, #green, #blue and #red. To print in rainbow use #rainFF where the last 2 characters define the brightness.
The following example writes "Let's go!" in red font, relative to the player's position, 6 to the left and 3 down:
>o-6,3,#red,Let's go!
>hX,Y,[#rrggbb,](str) Similar to ">o", however, draws on the same layer as the Big Head. Ideal for accessories such as hats.
The following draws a yellow hat on the player. Works best if Big Head is enabled:
>h-2,-3,#yellow,ascii
##_
#| |
_|_|_
asciiend
>`X,Y,[#rrggbb,](str) Advanced print relative to the upper-left corner of the screen.
The following prints "Hello World!", but uses variables for the coordinates and the color:
var posX = 10
var posY = 5
var color = rainE1
>`@posX@,@posY@,#@color@,Hello World!
>cX,Y,[#rrggbb,](str) Advanced print relative to the center of the screen. Similar to ">`". Note that in all these the color is optional.
This example demonstrates how the color is optional and defaults to white:
>c0,0,Hello World!
>fX,Y,[#rrggbb,](str) Advanced print relative to the target foe's head position.
The following draws a red crosshairs on the targeted foe:
>f-2,0,#ff0000,ascii
##!
-#·#-
##¡
asciiend
var (variable) Declares a variable that can be used in math, logical and string operations. See the variables section for details about their lifecycle and behavior, that may differ from other languages.
E.g.
var message = Hello World!
>@message@
func (function) Declares a function that can be called later.
E.g.
func Print(message)
>@message@

Print(Hello World!)
for v = a..b Creates a loop that iterates a variable 'v' from value 'a' to value 'b'. Code that appears inside the loop's scope will run multiple times.
E.g.
var a
a = 0
for i = 1..5
a = a + i
>a = @a@
import (script) Loads and executes a singular copy of an external script.
This example imports the fishing mini-game located at
(save-file folder)/Stonescript/Fishing.txt

import Fishing
new (script) Loads and executes an external script similar to 'import'. However, objects loaded with 'new' are each an individual copy and their script body will only execute one time.
This example creates and prints a vector object:
var v = new Components/Vector
v.Init(10, 5)
>Vector = @v@
disable abilities Prevents activation of potion and weapon abilities. Also greys out the HUD buttons.
enable abilities Restores activation of abilities that were disabled by a previous call to "disable abilities".
disable banner Prevents rendering of the horizontal banner that appears with the location name at the beginning and end of a location.
enable banner Restores rendering of the horizontal banner with location name.
disable hud (opts) Hides and disables the gameplay user interface elements. Accepts optional parameters, specifying the set of elements to disable: p = player health and debuffs, f = foe health and debuffs, a = ability buttons, r = resources, b = banner, u = utility belt.
E.g.
disable hud // Disables all hud elements
E.g.2
disable hud ru // Disables only resources (r) and utility belt (u)
enable hud (opts) Brings back the user interface elements hidden by previous "disable hud" commands. Accepts the same optional parameters as the disable command.
disable loadout input Prevents weapon loadouts from being saved or recalled with input keys.
enable loadout input Restores the saving or recalling of weapon loadouts by means of input keys.
disable loadout print Hides the messages that appear when a loadout is recalled.
enable loadout print Brings back the printing of loadout messages.
disable npcDialog Hides and auto-skips NPC dialog bubbles.
enable npcDialog Brings back NPC dialog bubbles.
disable pause Hides the pause button user interface. Pause is still available with the [P] shortcut.
enable pause Brings back the pause button hidden by a previous "disable pause" command.
disable player Hides the player. Has no effect on combat, this is only cosmetic.
enable player Brings back the player rendering if it was hidden by a previous "disable player" command.
play (sound) (pitch) Plays a sound effect with an optional pitch value. The pitch default value is 100 with higher numbers increasing the pitch and smaller numbers lowering it.
E.g.
?key = primary
play buy
?key = up
play buy 200

E.g.2:
var pitch
?time%30 = 0
pitch = rng/100 + 50
>@pitch@
play buy @pitch@
^Back to top
·:·:· Search Filters ·:·:· These are used when evaluating foes, locations and items. E.g.: ?foe = insect | foe = poison loadout 3 poison vigor aether fire air ice arachnid serpent insect machine humanoid elemental boss phase1 phase2 phase3 spawner flying slow ranged explode swarm unpushable undamageable magic_resist magic_vulnerability immune_to_stun immune_to_ranged immune_to_debuff_damage immune_to_physical *[number] star level (location or item) +[number] enchantment bonus (item only) ^Back to top
·:·:· Comparisons ·:·:· Used in conjunction with game state to make decisions
= Compares values equal or string contains.
E.g.
?hp = maxhp
loadout 2
! Compares values not equal or string does not contain.
E.g.
?foe ! poison
equipL sword
& Logical AND operator.
E.g.
?loc=caves & foe=boss
| Logical OR operator. If '&' and '|' are mixed in a single complex expression, all '&' operate first.
E.g.
?foe=slow | foe.count>3
activate potion
> Greater-than compare. Can be used with a location's difficulty, number of foes, health, etc.
E.g.
?foe.count > 10
equip shiny bardiche
< Less-than compare.
E.g.
?hp < 6
activate potion
>= Greater-than or equal compare. The combination of '>' and '=' into a single comparison.
The following two examples are equivalent:

?loc.stars >= 6
equipR vigor shield

?loc.stars > 6 | loc.stars = 6
equipR vigor shield
<= Less-than or equal compare. The combination of '<' and '=' into a single comparison.
E.g.
?hp <= 6
activate potion
^Back to top
·:·:· Variables ·:·:· Variables are a way of storing value to use later. Declare a new variable with the keyword 'var'. E.g.: var myVar = 10 (myVar is the name of the variable, and it's initialized with value 10) myVar = myVar + 5 (myVar now equals 15) var secondVar = 3 myVar = myVar - secondVar (Many variables can be combined in math operations. myVar now equals 12) When a variable is declared it is initialized only once, the first time 'var' executes. E.g.: var i = 0 i++ >i = @i@ In this example, variable 'i' is declared and starts with value 0. During each frame of the run, the value of 'i' increases by 1 and then is printed to the screen. Variables only reset to their initial value if you leave a location and begin a new run manually. They do not reset when the Ouroboros loops or when the Mind Stone is opened then closed again. String variables can optionally be declared with quotes. This allows special symbols and trailing spaces. E.g.: var a = 10 var b = 5 var myVar = a + " x " + b + " = " + (a * b) >@myVar@ (This example also demonstrates how to join strings with the '+' operator) Variables in imported scripts are contained within those scripts and their names won't collide with variables or functions in other scripts. ^Back to top
·:·:· Math Operations ·:·:· Operators modify numbers. Can be used in conjunction with variables or directly in game state expressions.
+ Adds two numbers or variables together.
E.g.:
var a = 2 + 3
(a equals 5)
- Subtracts two numbers or variables from each other.
E.g.:
?hp < maxhp - 5
equip vigor sword dL
* Multiplies two numbers or variables together.
E.g.:
var a = 2
var b = 5
a = a * b
// a equals 10

E.g.2:
var a = 2 * 0.4
// a equals 0.8
/ Divides one number or variable by another. In the case of integers, the result is rounded down.
E.g.:
var a = 8
a = a / 4
// a equals 2

E.g.2:
var a = 5.0
a = a / 2
// a equals 2.5
++ Increments a variable.
E.g.:
var a = 3
a++
// a equals 4
-- Decrements a variable.
E.g.:
var a = 3
a--
// a equals 2
% Modulo. Gives the remainder of dividing one number by another.
E.g.:
var a = 5 % 4
(a equals 1)

E.g.2:
?time % 8 < 4
> \O)
?time % 8 > 3
> (O/
// this draws an animated emoji
( ) Parenthesis can be used to prioritize operations.
E.g.:
var a = 2 * (3 - 1)
// a equals 4
! Negation. Inverts the value when used in front of a boolean expression.
E.g.:
? !ai.enabled
>The AI is not enabled.
^Back to top
·:·:· Functions ·:·:· Custom functions serve an important organizational purpose to scripts as they grow in complexity. They make scripts easier to read and reduce repetition. When a function is declared its contents are not executed immediately. Instead, lines of script inside a function execute when the function is called at a later point. This example creates a counter that increases by 1 each frame. When any custom input key is pressed, ResetCounter() is called and the counter value goes back to zero: var count = 0 count++ >Counter = @count@ func ResetCounter() count = 0 ?key=begin ResetCounter() Another aspect of functions is that they can return a value. In this example we declare a simple function that calculates the duration of the main location (non-boss area): func NonBossDuration() return totalTime - time var duration duration = NonBossDuration() >Time was: @duration@ Functions also accept any number of arguments/parameters, making them even more powerful, with the ability to operate on arbitrary input. Here, we declare a utility function that generates a random number within a range, then we use it to generate random numbers between 5 and 10: func RandomRange(min, max) ?min >= max return min return min + rng % (max - min + 1) var randomValue randomValue = RandomRange(5, 10) >RNG: @randomValue@ The prefix 'this' can be used inside a funtion when referencing variables that belong to the outside script. Use of 'this' is optional, and script variables can be accessed by a function without the prefix. However, in the following example the variable 'a' appears both inside and outside of the function, so 'this.a' is used for differentiation: var a = 1 func TestScope(a) >Script var = @this.a@, function var = @a@ TestScope(3) When functions call other functions, or themselves, this creates an execution stack that can build in size until the application crashes. To safeguard computer resources Stonescript has a stack limit of 215 and will throw an error if the limit is exceeded. ^Back to top
·:·:· Native Functions ·:·:· While scripts can define their own functions, Stonescript comes with a set of pre-defined/native functions that behave similar to commands, but differ in that they are more clearly grouped by subject, can accept parameters and sometimes return a value.
ambient
‾‾‾‾‾‾‾
?ambient
Return string
Returns a comma-separated list of all active ambient audio IDs.
E.g.
>`0,0,Ambient Layers = @ambient@
ambient.Add(str)
No return value
Adds a layer of ambient audio, with the given sound ID. Up to 4 layers. If a 5th layer is added, the oldest layer is removed.
E.g.
?loc.begin
ambient.Add(ambient_crypt)
ambient.Stop()
No return value
Clears all ambient layers.
E.g.
?time = 3
ambient.Stop()
ambient.Add(ambient_mines)

BigNumber
‾‾‾‾‾‾‾‾‾

BigNumbers are a special type of object that provide a way to work with large integers that exceed 32 bits. While they can only hold positive and negative whole number values, their arithmetic and comparison operations work with floats as well as integers and other BigNumbers.
b.Add(num)
b.Add(BigNumber)
Returns itself
Adds a number to a BigNumber (+)
E.g.
var bn = math.BigNumber(12)
bn.Add(5)
>@bn@
// 17
b.Sub(num)
b.Sub(BigNumber)
Returns itself
Subtracts a number from a BigNumber (-)
E.g.
var bn = math.BigNumber(12)
bn.Sub(5)
>@bn@
// 7
b.Mul(num)
b.Mul(BigNumber)
Returns itself
Multiplies a BigNumber by a number (*)
E.g.
var myBigNum1 = math.BigNumber(12)
var myBigNum2 = math.BigNumber(12)
myBigNum1.Mul(5)
myBigNum2.Mul(1.5)
>@myBigNum1@ @myBigNum2@
// 60 18
b.Div(num)
b.Div(BigNumber)
Returns itself
Divides a BigNumber by a number (/)
E.g.
var myBigNum1 = math.BigNumber(12)
var myBigNum2 = math.BigNumber(12)
myBigNum1.Div(5)
myBigNum2.Div(1.5)
>@myBigNum1@ @myBigNum2@
// 2 8
b.Eq(num)
b.Eq(BigNumber)
Returns bool
Determines if a BigNumber is equal to a number (=)
E.g.
var bn = math.BigNumber(5)
>@bn.Eq(5)@ @bn.Eq(3)@
// true false
b.Gt(num)
b.Gt(BigNumber)
Returns bool
Determines if a BigNumber is greater than a number (>)
E.g.
var bn = math.BigNumber(5)
>@bn.Gt(3)@ @bn.Gt(10)@
// true false
b.Ge(num)
b.Ge(BigNumber)
Returns bool
Determines if a BigNumber is greater than or equal to a number (>=)
E.g.
var bn = math.BigNumber(5)
>@bn.Ge(3)@ @bn.Ge(5)@
// true true
b.Lt(num)
b.Lt(BigNumber)
Returns bool
Determines if a BigNumber is less than a number (<)
E.g.
var bn = math.BigNumber(5)
>@bn.Lt(3)@ @bn.Lt(10)@
// false true
b.Le(num)
b.Le(BigNumber)
Returns bool
Determines if a BigNumber is less than or equal to a number (<=)
E.g.
var bn = math.BigNumber(5)
>@bn.Le(10)@ @bn.Le(5)@
// true true
b.ToString()
Returns string
Returns a string representation of the BigNumber. Can be used to serialize it for storage.
E.g.
var myBigNum = math.BigNumber("123456789123456789")
storage.Set("myBN", myBigNum.ToString())
---
var bnStr = storage.Get("myBN")
var myBigNum = math.BigNumber(bnStr)
b.ToUI()
Returns string
Returns a shortened string representation of the number for use in user interfaces.
E.g.
var myBigNum = math.BigNumber("123456789123456789")
>@myBigNum.ToUI()@
// 123.5Qa

color
‾‾‾‾‾

Colors in Stonescript are represented with a string in hexadecimal notation, such as #ff0000 or with simplified presets such as #red.
color.FromRGB(r,g,b)
Returns string
Converts a color from three integer numbers (0 to 255) into a string.
E.g.
var c = color.FromRGB(255, 0, 128)
>`0,0,@c@, @c@
color.ToRGB(string)
Returns int[3]
Converts a color from string to three integer numbers (0 to 255).
E.g.
var c = color.Random()
var rgb = color.ToRGB(c)
var r = rgb[0]
var g = rgb[1]
var b = rgb[2]
>`0,0,@c@, @c@ \n @r@ \n @g@ \n @b@
color.Lerp(c1,c2,t)
Returns string
Interpolates linearly from color c1 to color c2 at time (percentage) t.
E.g.
var c1 = "#ff4400"
var c2 = "#8888ff"
var t = 0.5
var c
t = math.sin(time*0.1) / 2 + 0.5
c = color.Lerp(c1, c2, t)
>`0,1,@c@,@c@\n ██████
color.Random()
Returns string
Returns a random color.
E.g.
var c
c = color.Random()
>`0,0,@c@,@c@\n ██████
draw
‾‾‾‾
draw.Bg(x, y, color)
No return value
Sets the background color at a specific screen position.
E.g.
draw.Bg(5, 4, #red)
draw.Bg(x, y, color, w, h)
No return value
Sets the background color of a rectangular region on screen.
E.g.
draw.Bg(5, 4, #cyan, 10, 6)
draw.Box(x, y, w, h, color, style)
No return value
Draws a rectangular shape at the specified position and size. The rectangle's border is defined by color and a style number. Negative style numbers cause the center of the rectangle to be transparent. CAVEAT - At this time, advanced prints always draw on top of boxes.
Use this example to explore the different styles by pressing Left/Right
var style = 1
?key = leftBegin
style--
?key = rightBegin
style++
draw.Box(10, 5, 30, 15, #333333, style)
>`12,6,#ffffff,Style = @style@
>`12,8,#888888,Press Left/Right\nto change style
draw.Clear()
No return value
Clears the entire screen.
draw.GetSymbol(x, y)
Returns string
Returns the glyph at screen position (x, y).
This example selects a screen coordinate and draws the symbol found there in the top left. The selection [ ] can be moved by the player:
var s
var x = 20
var y = 10
var drawX
?key=leftBegin
x--
?key=rightBegin
x++
?key=upBegin
y--
?key=downBegin
y++
s = draw.GetSymbol(x, y)
>`0,1,Symbol = @s@
drawX = x - 1
>`@drawX@,@y@,[#]
draw.Player()
draw.Player(x,y)
No return value
Draws the player character, with all equipment and addons, at a specific point in the script. Optional offset values x, y. For drawing to an absolute screen position, see the screen namespace and derive offsets that convert from the player's local position to screen position.

int
‾‾‾
int.Parse(str)
Returns integer
Converts a string of a number into an integer value. If the given string is not a number an error is thrown.
E.g.
var s = "999"
var i = int.Parse(s)
i++
event
‾‾‾‾‾
event.GetObjectiveId(int)
Returns string

event.GetObjectiveProgress
(int)
event.GetObjectiveGoal(int)
Returns int
Returns information about active objectives in a community or seasonal event. Pass the index of the desired objective. Events are usually limited to a maximum of 3 active objectives, therefore the first parameter would be 0, 1 or 2.
E.g.
var id
var p
var g
id = event.GetObjectiveId(0)
p = event.GetObjectiveProgress(0)
g = event.GetObjectiveGoal(0)
>`0,1,@id@:@p@/@g@
item
‾‾‾‾
item.CanActivate()
Returns boolean
Returns true if it's possible to activate item abilities. False otherwise. In some gameplay situations all ability activations are disabled, even if they are not on cooldown, such as moments before a boss fight or during a cinematic.
E.g.
?item.CanActivate()
equip Bardiche
activate R
item.CanActivate(str)
Returns boolean
Returns true if it's possible to activate a specific item. Will only ever be true if the item is equipped. Some items can have mechanics that don't allow them to be activated unless specific criteria are met. This is a sub-set of item.GetCooldown(), as an item's cooldown may be zero and it cannot be activated, but it will never be possible to activate an item that is on cooldown.
E.g.
equip bardiche
?item.GetCooldown("skeleton_arm") <= 0
equip skeleton arm
?item.CanActivate("skeleton_arm")
activate R
item.GetCooldown(str)
Returns integer
Returns the remaining cooldown time (in frames) for a given ability.
E.g.
?foe = boss & item.GetCooldown("bardiche") <= 0
equip bardiche
activate R
See the following table for all available ability strings. NOTE: Invalid ability strings will return -1. Some abilities from weapons that have not been used yet will return -1.
Item
----
Cooldown ID
-----------

Æther Talisman "aether_talisman"
Bardiche "bardiche"
Bashing Shield "bash"
Blade of the Fallen God "blade"
Cinderwisp Devour "cinderwisp"
Cultist Mask "mask"
Dashing Shield "dash"
Fire Talisman "fire_talisman"
Hatchet "hatchet"
Heavy Hammer "heavy_hammer"
Mind Stone "mind"
Quarterstaff "quarterstaff"
Skeleton Arm "skeleton_arm"
Voidweaver Devour "voidweaver"
item.GetCount(str)
Returns integer
Returns the number of copies of an item in the inventory. Returns 0 if no item is found.
E.g.
var searchCriteria = "sword *0 -big -socket"
var swordCount = item.GetCount(searchCriteria)
>I have @swordCount@ basic swords
item.GetLoadoutL(int)
item.GetLoadoutR(int)
Returns string
Returns the items in a specific loadout. The integer parameter is the loadout number to query. Returns a blank string if that loadout has no item in that slot.
E.g.
>`0,1,Left: @item.GetLoadoutL(1)@
>`0,2,Right: @item.GetLoadoutR(1)@
item.GetTreasureCount()
Returns integer
Returns the current number of treasure chests in your inventory.
item.GetTreasureLimit()
Returns integer
Returns the total space for treasure chests in your inventory. In other words, the maximum capacity.
E.g.
var trs
var max
trs = item.GetTreasureCount()
max = item.GetTreasureLimit()
>`0,2,Treasures: @trs@/@max@
key
‾‾‾

The key namespace allows for the customization of standard game inputs and shortcuts. This system is based on actions (abbreviated "act") and keys, where each action corresponds to a type of input/shortcut and each key corresponds to a physical key press. The list of all possible keys that can be assigned to actions can be found here. Changes to action bindings persist between runs (they currently do not save to storage). For optimization purposes, it is recommended to not change bindings every frame.
Action
------
Default Key
-----------
Default Key 2
-------------

Pause P Space
Leave L
Inventory I
Mindstone M
Potion Q
ItemLeft E
ItemRight R
Up W UpArrow
Down S DownArrow
Left A LeftArrow
Right D RightArrow
Primary Return KeypadEnter
Back X
Ability1 LeftShift RightShift
Ability2 LeftControl RightControl
BumpL Z
BumpR C
Dynamic1 F
Dynamic2 T
Dynamic3 G
Dynamic4 V
Dynamic5 B
key.Bind(act, key1)
key.Bind(act, key1, key2)
No return value
Assigns a new set of keys to a specific action. If another action already has one of those keys, then the key already in use is abandoned for the original action. Up to two keys may be assigned to an action.
E.g.
?loc.begin
key.Bind("Potion", "P")
// In this example, the "P" key that originally is assigned to Pause, no longer pauses the game and activates the potion instead. Also, the Potion's original "Q" key no longer works. "Q" is bound to no action.
key.GetKeyAct(key)
Returns string
Returns the action bound to a given key. Returns "None" if the given key is not bound to any actions.
key.GetActKey(act)
Returns string
Returns the first key bound to a given action. Returns "None" if the given action has no keys bound to it.
key.GetActKey2(act)
Returns string
Returns the second key bound to a given action. Returns "None" if the given action does not have a secondary key bound to it.
key.GetActLabel(act)
Returns string
Returns a user-facing label that represents the first key bound to a given action. The current implementation returns the first letter of the bound key, which can be confusing in cases such as "LeftShift".
key.ResetBinds()
no return value
Resets all actions to their default key bindings.

loc
‾‾‾
loc.Leave()
No return value
Causes the run to be abandoned as if the player had pressed to leave manually.
loc.Pause()
No return value
Causes the run to be paused as if the player had pressed the pause button manually.

math
‾‾‾‾

The math API works with both integers and floating-point (float) numbers. When a number is delcared with a decimal period, it's implied to be a float (e.g. var a = 0.5). If there is no decimal number, then it's treated as an integer (e.g. var a = 2).
math.Abs(num)
Returns number
Returns the absolute value of a given number.
E.g.
var number = -2
number = math.Abs(number)
// number now equals 2
math.Acos(num)
Returns number
Returns the arc-cosine of a number, in radians. The input bounds are -1 to 1. If the input value is out of bounds then "NaN" is returned.
E.g.
var number = math.Acos(-1)
// number equals π
math.Asin(num)
Returns number
Returns the arc-sine of a number, in radians. The input bounds are -1 to 1. If the input value is out of bounds then "NaN" is returned.
E.g.
var number = math.Asin(1)
// number equals π/2
math.Atan(num)
Returns number
Returns the arc-tangent of a number, in radians.
E.g.
var number = math.Atan(2)
// number equals 1.107149
math.Atan2(y, x)
Returns number
Returns the angle, in radians, between the x-axis and the line from the origin to the point (x,y)
E.g.
var number = math.Atan2(3, 2)
// number equals 0.9827937
math.BigNumber()
math.BigNumber(number)
math.BigNumber(str)
Returns BigNumber
Creates a new BigNumber object from a float or int, or parses a string into a BigNumber object.
E.g.
var myBigNum = math.BigNumber("500")
myBigNum.Add(500).Mul(1000).Mul(1000).Mul(1000)
>@myBigNum@
// 1000000000000
math.Ceil(num)
Returns number
Rounds a number up, to the first whole number greater than it.
E.g.
var number = math.Ceil(4.2)
// number equals 5.0
math.CeilToInt(num)
Returns integer
Rounds a number up, to the first integer greater than it.
E.g.
var number = math.CeilToInt(4.2)
// number equals 5
math.Clamp(num, min, max)
Returns number
Constrains a number to within the range 'min' and 'max'. If the number is already within the range then it will be returned without change.
E.g.
var number = 50
number = math.Clamp(number, 0, 10)
// number has been clamped down and will equal 10
math.Cos(num)
Returns number
Returns the cosine of a given radian angle.
E.g.
var number = math.Cos(0)
// number equals 1
math.e
float
The constant e, also known as Euler's number, approximately 2.71828
E.g.
>E = @math.e@
// prints the value of e to the screen
math.Exp(num)
Returns number
Returns e raised to a given power.
E.g.
var number = math.Exp(3)
// number equals 20.08554
math.Floor(num)
Returns number
Rounds a number down, to the first whole number smaller than it.
E.g.
var number = math.Floor(2.7)
// number equals 2.0
math.FloorToInt(num)
Returns integer
Rounds a number down, to the first integer smaller than it.
E.g.
var number = math.FloorToInt(2.7)
// number equals 2
math.Lerp(a, b, t)
Returns number
Performs a linear interpolation, from value a to b at time (percentage) t.
E.g.
var number = math.Lerp(0.0, 20.0, 0.75)
// number equals 15.0

E.g.2:
var n = 0.0
?key = Begin
n = 0.0
n = math.Lerp(n, 100, 0.02)
>n = @n@
// Variable n eases towards 100, at 2% per frame. When a key is pressed it resets
math.Log(num, base)
Returns number
Returns the logarithm of a number at a given base.
E.g.
var number = math.Log(5, 2)
// number equals 2.321928
math.Max(num1, num2)
Returns number
Returns the largest of the two numbers.
E.g.
var number = math.Max(3, 10)
// number equals 10
math.Min(num1, num2)
Returns number
Returns the smallest of the two numbers.
E.g.
var number = math.Min(3, 10)
// number equals 3
math.pi
float
The constant π, approximately 3.1415926
E.g.
>PI = @math.pi@
// prints the value of π to the screen
math.Pow(num, p)
Returns number
Returns the number raised to a power.
E.g.
var number = math.Pow(3, 2)
// number equals 9
math.Round(num)
Returns number
Rounds a number to the nearest whole number.
E.g.
var number = math.Round(2.7)
// number equals 3.0
math.RoundToInt(num)
Returns integer
Rounds a number to the nearest whole integer.
E.g.
var number = math.RoundToInt(2.7)
// number equals 3
math.Sign(num)
Returns number
Returns -1 if the given number is negative. Otherwise, returns 1.
E.g.
var sign = math.Sign(-21)
var n = 10 * sign
// n equals -10
math.Sin(num)
Returns number
Returns the sine of a given radian angle.
E.g.
var number = math.Sin(math.pi / 2)
// number equals 1
math.Sqrt(num)
Returns number
Returns the square root of a number.
E.g.
var number = math.Sqrt(9)
// number equals 3
math.Tan(num)
Returns number
Returns the tangent of a given radian angle.
E.g.
var number = math.Tan(2)
// number equals -2.18504
math.ToDeg(num)
Returns number
Converts a radian number to degrees.
E.g.
var number = math.ToDeg(2 * math.pi)
// number equals 360
math.ToRad(num)
Returns number
Converts a degrees number to radians.
E.g.
var number = math.ToRad(360)
// number equals 2π
music
‾‾‾‾‾
?music
Return string
Returns the ID of the currently playing music.
E.g.
>`0,0,Current Music = @music@
music.Play(str)
No return value
Plays a music, with the given sound ID. There can only be one music playing at a time.
E.g.
?loc.begin | loc.loop
music.Play(temple_0)
music.Stop()
No return value
Stops all music.
E.g.
?!string.Equals(music, "")
music.Stop()
player
‾‾‾‾‾‾
player.ShowScaredFace(num)
No return value
If the player has big-head enabled, their facial expression will change to scared for a given amount of time.
E.g.
?key = primaryBegin
player.ShowScaredFace(1)
screen
‾‾‾‾‾‾
screen.FromWorldX(int)
Returns integer
Converts a value on the X-axis from world-space to screen-space.
screen.FromWorldZ(int)
Returns integer
Converts a value from the world-space Z-axis to screen-space Y-axis.
E.g.
var x
var y
x = screen.FromWorldX(pos.x)
y = screen.FromWorldZ(pos.z - pos.y)
>`0,1,Player position on screen: @x@,@y@
screen.ToWorldX(int)
Returns integer
Converts a value on the X-axis from screen-space to world-space.
screen.ToWorldZ(int)
Returns integer
Converts a value from the screen-space Y-axis to world-space Z-axis.
E.g.
var x
var y
var z
x = input.x
y = input.y
>`0,1,Screen position of cursor: @x@,@y@

x = screen.ToWorldX(input.x)
z = screen.ToWorldZ(input.y)
>`0,2,World position of cursor: @x@,@z@
screen.Next()
No return value
For locations that are multi-screen, moves the camera one screen forward in relation to the player.
E.g.
?key = rightBegin
screen.Next()
screen.Previous()
No return value
For locations that are multi-screen, moves the camera one screen back in relation to the player.
E.g.
?key = leftBegin
screen.Previous()
screen.ResetOffset()
No return value
Resets the camera to follow the player, undoing changes made by screen.Next() and screen.Previous()
E.g.
var lastScreenI = -1
?lastScreenI ! screen.i
screen.ResetOffset()
lastScreenI = screen.i
storage
‾‾‾‾‾‾‾
Values saved into permanent storage persist when you leave a location, as well as when the game is shut down. They are not part of your primary_save, existing instead in a series of separate files within the Stonescript folder. Imported scripts access storage in isolation from each other, allowing different modules to use the same keys without modifying each other's data.
storage.Delete(string)
No return value
Deletes any value that may exist at the specified key.
E.g.
storage.Delete("highscore")
storage.Get(string)
Returns value
Retrieves a permanent value stored at the specified key.
E.g.
var value = storage.Get("highscore")
?value
>High Score = @value@
:
>No High Score found.
storage.Get(string, value)
Returns value
Retrieves a permanent value stored at the specified key. If it's not found, returns the second parameter as a default value.
E.g.
var value = storage.Get("highscore", 0)
>High Score = @value@
storage.Has(string)
Returns boolean
Returns true if the specified key exists in permanent storage; false otherwise.
E.g.
?storage.Has("highscore")
var value = storage.Get("highscore")
>High Score = @value@
:
>No High Score found.
storage.Incr(string)
Returns integer
Increases by 1 the value stored at the specified key, then returns the new value.
E.g.
?gameOver
storage.Incr("stat_TimesPlayed")
storage.Keys()
Returns array
Retrieves an array of strings containing all the storage keys available in the current context.
E.g.
var a
?time % 30 = 0
a = storage.Keys()
for i = 0 .. a.Count()-1
>Key @i@ = @a[i]@
storage.Incr(string, integer)
Returns integer
Increases the value stored at the specified key by a given amount, then returns the new value.
E.g.
var amount
?foundCoins
amount = rng%5 + 5
storage.Incr("coins", amount)
storage.Set(string, value)
No return value
Saves a value to permanent storage at a specified key.
E.g.
var score = 1000
storage.Set("highscore", score)
string
‾‾‾‾‾‾
string.Break(string, integer)
Returns array
Breaks a string into multiple strings, given a max width.
E.g.
var s = "The brown fox jumps over the lazy dog"
var a = string.Break(s, 14)
for i = 0 .. a.Count()-1
>`0,@i@,@a[i]@
string.Capitalize(str)
Returns string
Changes the first letter of a string to be upper-case.
E.g.
var a = "foo"
a = string.Capitalize(a)
>@a@
(Prints "Foo")
string.Equals(str1, str2)
Returns boolean
Takes two string parameters and returns true if they are exactly the same. Returns false otherwise. Case sensitive.
E.g.
var a = "foo"
?string.Equals(a, "foo")
>The strings are equal
:
>They are NOT equal
// The strings are equal in this case. string.Equals() evaluates to true
string.Format(str1, ...)
Returns string
Modifies a string by replacing format-templates with the values of the other parameters, then returns the final composed string. This is a powerful function that supports lots of formatting options.
E.g.
var str = "My name is {0} and I have {1} power!"
var result = string.Format(
^ str,
^ player.name,
^ totalgp
^)
>@result@
string.IndexOf(str, criteria)
Returns integer
Takes a string variable and a string criteria as parameters and finds the position of the criteria inside the string. Returns -1 if not found.
E.g.
var a = Hello World!
var index = string.IndexOf(a, llo)
// index equals 2
string.IndexOf(str, criteria, startAt)
Returns integer
Takes a string variable, a string criteria and a starting index as parameters. Finds the position of the criteria inside the string, but begins the search at 'startAt'. Returns -1 if not found.
E.g.
var a = Hello World!
var index = string.IndexOf(a, llo, 4)
// index equals -1 because the search began at position 4
// therefore 'llo' was not found
string.Join(s, [])
string.Join(s, [], int)
string.Join(s, [], int,int)
Returns string
Takes an array of strings [] and combines it into a single string with the separator s. Optional integer parameters can be passed that specify the starting index and number of elements to combine. If no index parameters are provided, the entire array is combined.
E.g.
var a = ["Hello", "World", "!"]
var b = string.Join(";", a)
>`0,0,@b@
// Prints "Hello;World;!"

E.g.2
var a = ["Hello", "World", "!"]
var b = string.Join(";", a, 1)
>`0,0,@b@
// Prints "World;!"

E.g.3
var a = ["Hello", "World", "!"]
var b = string.Join(";", a, 0, 2)
>`0,0,@b@
// Prints "Hello;World"
string.Size(str)
Returns integer
Takes a string variable as parameter and calculates how long it is, in number of glyphs.
E.g.
var a = Hello World!
var size = string.Size(a)
>size = @size@
string.Split(str)
string.Split(str, s…)
string.Split(str, s…, bool)
string.Split(str, bool)
Returns array
Takes a string and breaks it down into an array of strings, given a set of string separators s…. If no separators are provided, then the string is broken wherever there is a space. An optional boolean parameter specifies if empty entries should be discarded.
E.g.
var a = string.Split("Hello World !")
for i = 0 .. a.Count()-1
>`0,@i@,[@i@] = @a[i]@
// Breaks up the string into: "Hello", "World", "!"

E.g.2
var a = string.Split("Hello World !", " ", "l")
for i = 0 .. a.Count()-1
>`0,@i@,[@i@] = @a[i]@
// Breaks up the string into: "He", " ", "o", "Wor", "d", "!"

E.g.3
var a
a = string.Split("Hello World !","l","r",true)
for i = 0 .. a.Count()-1
>`0,@i@,[@i@] = @a[i]@
// Breaks up the string into: "He", "o Wo", "d !"
string.Sub(str, startAt)
Returns string
Takes a string variable and a starting index as parameters and splits the string from that point forward.
E.g.
var a = Hello World!
var subString = string.Sub(a, 6)
>substring = @subString@
// subString equals "World!"
string.Sub(str, startAt, length)
Returns string
Takes a string variable, a starting index and a length as parameters and splits the string from that starting point, stopping at the given length.
E.g.
var a = Hello World!
var subString = string.Sub(a, 6, 3)
>substring = @subString@
// subString equals "Wor"
string.ToLower(str)
Returns string
Changes all letters in a string to lower-case.
E.g.
var a = "Foo"
a = string.ToLower(a)
>@a@
// Prints "foo" to the screen
string.ToUpper(str)
Returns string
Changes all letters in a string to upper-case.
E.g.
var a = "Foo"
a = string.ToUpper(a)
>@a@
// Prints "FOO" to the screen
sys
‾‾‾
(The sys namespace is not functioning as intended at the moment)
sys.cacheRemoteFiles
boolean
Indicates if files imported remotely should be cached between runs. Default is true. If set to false, then remote scripts will re-download when you begin play from the Locations screen. It can be useful to change this during development and iteration of new scripts that are deployed remotely. This global property persists between runs.
E.g.
// We use the "up" key as an input to toggle
// remote caching on/off during rapid iteration
?key = upBegin
sys.cacheRemoteFiles = !sys.cacheRemoteFiles
?sys.cacheRemoteFiles
>Remote caching ENABLED
:
>Remote caching DISABLED
sys.fileUrl
string (get only)
Getter for the current file path to be used when importing scripts. The default value depends on your device. On PC the default value is local. On mobile the default is https://StonestoryRPG.com/stonescript/
E.g.
>`0,1,fileUrl = @sys.fileUrl@
sys.SetFileUrl(str)
No return value
Changes the origin of imported scripts when using the commands import or new. Can only be called on the Mind Stone and will error if written on an imported script. Accepts any URL as a remote location, but also accepts the values "local" and "remote" as shortcuts to easily point at your local drive or to the official Stone Story RPG repository, respectively. If null is passed as parameter, then the file URL resets to the default value for your device. This global property persists between runs.
E.g.
sys.SetFileUrl(
^"https://MyCoolDomain.com/scripts/")
import MyCombatScript
sys.os
Returns string
The user's operating system, such as "Android", "iOS", "Linux", "OSX" or "Windows".
sys.isMobile
Returns bool
Returns true if the users is on Android or iOS.
sys.isPC
Returns bool
Returns true if the users is on Win/Mac/Linux.
Text Localization
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
Stonescript supports 12 languages as of this writing. A few operations allow custom scripts to adapt to the player's chosen language.
te.language
string
The code for the language selected by the player in settings. Possible values: EN, PT-BR, ZH-CN, ZH-TW, FR, DE, RU, ES-LA, ES-EU, JP, KR and TK.
E.g.
var lang = te.language
>Language = @lang@
te.xt(str)
Returns string
Translates a given English text into the player's selected language. If a translated version is not found, then the input text is returned instead. Alternatively, a text identifier (TID) can be used as input--albeit the exhausting list of TIDs is beyond the scope of this manual.
E.g.
var button = ui.AddButton()
button.text = te.xt(Play)
// Change your language in settings to see this example at work
te.GetTID(str)
Returns string
Returns the text identifier (TID) for a given text. The input text is expected in the language selected by the player.
E.g.
var tid = te.GetTID("Play")
>`0,1,@tid@
// Prints tid_button_play to the screen
te.ToEnglish(str)
Returns string
Translates a given text from the player's selected language into the original English text. If a translated version is not found, then the input text is returned instead.
E.g.
>`0,1,@te.ToEnglish("Jogar")@
// If Portuguese is chosen in settings it will print "Play"
// otherwise it will print "Jogar"
time
‾‾‾‾
time.FormatCasual(int)
time.FormatCasual(int,bool)
Returns string
Converts an amount of frames into a human-readable string representation of time, such as "1m 23s". The second parameter (bool) is optional; If 'true', then precision is maximized in the result.
E.g.
>`0,0,Current time =
^ @time.FormatCasual(totaltime, true)@
time.FormatDigital(int)
time.FormatDigital(int,bool)
Returns string
Converts an amount of frames into a human-readable string representation of time, such as "1:23". The second parameter (bool) is optional; If 'true', then precision is maximized in the result.
E.g.
>`0,0,Current time =
^ @time.FormatDigital(totaltime, true)@
UI
‾‾

See the User Interface section for details about Stonescript's advanced UI system. Miscellaneous functions of the ui namespace:
ui.OpenInv()
No return value
Opens the inventory screen.
ui.OpenMind()
No return value
Opens the Mind Stone screen.
ui.ShowBanner(str)
ui.ShowBanner(str,str)
No return value
Displays the animated banner with up to two messages. The banner animation restarts each time ui.ShowBanner() is called.
E.g.
?time = 120
ui.ShowBanner("Hello World!")
Other
‾‾‾‾‾
Type(var)
Returns string
Evaluates the type of a variable and returns a string representation. Possible types include 'string', 'int', 'bool', 'function', 'object' and 'null'.
E.g.
var a = 0
?Type(a) = int
>Variable 'a' is an integer.
^Back to top
·:·:· Importing External Scripts ·:·:· Your script doesn't have to be all in the Mind Stone. Stonescript supports the loading of external files through the 'import' and 'new' keywords. For external scripts to work they must be located in your save-file folder, inside a /Stonescript folder and end in '.txt'. In the most basic example an external script is imported and runs as if it were directly in your Mind Stone, making this a convenient way to organize farming scripts: import Rocky import Deadwood import Caves import Forest When a script is imported it's copied into its own container and returns as a reference. Variables declared in the external script are isolated and don't interact with variables in other scripts. In this example, a printing utility script offers simplified services: // PrintUtil.txt func LowerLeft(x, y, color, message) y = y + screen.h >`@x@,@y@,@color@,@message@ func LowerRight(x, y, color, message) x = x + screen.w y = y + screen.h >`@x@,@y@,@color@,@message@ // Main script in Mind Stone var print = import PrintUtil disable hud print.LowerLeft(0,-1,#ffffff,"Health: " + hp) Advanced solutions can import the same script multiple times using the 'new' command, for example, to implement componentization or an Object Oriented paradigm: // Vector.txt var x = 0 var y = 0 func init(_x, _y) x = _x y = _y func subtract(otherVect) x = x - otherVect.x y = y - otherVect.y // Main script in Mind Stone var vectFrom = new Components/Vector var vectTo = new Components/Vector vectFrom.init(5, 4) vectTo.init(8, 2) vectTo.subtract(vectFrom) >x = @vectTo.x@, y = @vectTo.y@ External scripts can implement a 'ToString()' function, allowing their direct use in advanced print commands: // Vector.txt var x = 0 var y = 0 func init(_x, _y) x = _x y = _y func ToString() return "(" + x + ", " + y + ")" // Main script in Mind Stone var v = import Components/Vector v.init(3,5) >Vector = @v@ External scripts can be imported from subfolders: import Games/Blackjack import Cosmetics/PetFrog import Cosmetics/Hats While similar, there are two important differences between 'import' and 'new'. With 'import' the same object is returned each time. If you import the same script from multiple places they will all be using the same object. Scripts imported with 'new' are unique copies, but their script body will only run 1 time as opposed to every frame. ^Back to top
·:·:· ASCII-art ·:·:· In Stonescript, custom ASCII-art can be embedded within the scripts and drawn on screen with the advanced print commands. There are a few methods to do this and some glyphs have special behavior: # - Blank space. Transparency. Does not draw. \n - Line break. Causes the draw to continue on the next line. WARNING: This is an expensive operator and should not be used for breaking lines in large drawings. Use the ascii/asciiend block instead. Method 1 - Advanced print This example draws a green circle to the top-left of the screen. >`1,0,#green,ascii #.-. ( ) #`-´ asciiend Method 2 - Variables This example saves the art for a spooky fish into a variable, then draws it to the top-left of the screen in red color. var fishSprite fishSprite = ascii ###(°_## #_/_ o\# #´ `'"# asciiend >`0,3,#red,@fishSprite@ ^Back to top
·:·:· Loops ·:·:· Loops allow a section of code to run multiple times. To create a loop use the 'for' keyword in the form: for v = a..b The variable 'v' begins the loop with value 'a' and increases in value until it reaches 'b', then the loop ends: for i = 1..5 >`0,@i@,i = @i@ The iteration variable 'v' should not be declared prior to the 'for' and is contained to the scope of the loop. However, the begin and end values 'a' and 'b' can be declared prior to the loop: var min = 1 var max = 4 var sum sum = 0 for j = min..max sum = sum + j >sum = @sum@ Loops can also go in the opposite direction, as well as use negative numbers: var g g = "" for k = 5..-2 g = g + k >g = @g@ Loops can be nested inside each other, as well as inlined with math expressions to form complex algorithms: for x = 1..9 for y = x/2 .. x/2 + 6 >`@x@,@y@,* To break out of the loop early, modify the iteration variable so that it's out of range: var n n = "" for i = 1..5 ?i = 3 i = -1 n = n + i >n = @n@ Similarly, break out of the loop with the break command: for i = 1..5 ?i = 3 break Loops also support the continue command. When called, instructions below the continue are skipped and the loop continues looping: var n n = "" for i = 1..5 ?i = 3 continue n = n + i >n = @n@ It's possible to loop through elements of an array using this form: var a = [1, 2, 3] var n n = "" for value : a n = n + value >n = @n@ ^Back to top
·:·:· Arrays ·:·:· Arrays are a special type of variable. They provide a way to sequentially organize values and objects into a collection that is assigned to a single variable.
Operation
---------
Description
-----------
a = [] Initializes a new array. See below for more information.
a[integer] Reads the value at a given position.
E.g.:
var myArray = [10, 3]
?myArray[1] = 3
>Yes, the value at [1] equals 3
a.Add(value) Adds a new value/object to the end of the array.
E.g.:
var myArray = []
myArray.Add(10)
a.Clear() Removes all elements from the array, making it empty. This is more efficient than re-declaring the array with [].
E.g.:
var myArray = [10, 3]
myArray.Clear()
a.Contains(value) Determines if a given value is inside the array. Returns true if found; false otherwise.
E.g.:
var myArray = [10, 3]
?myArray.Contains(3)
>Yes
a.Count() Returns the number of elements in the array.
E.g.:
var myArray = ["apple","banana"]
var size = myArray.Count()
>Array size = @size@
a.Emplace(integer, value) Replaces the value at a given position with a new value.
E.g.:
var myArray = [10, 3]
myArray.Emplace(0, 4)
var value = myArray[0]
>Value at [0] is now @value@
a.IndexOf(value) Searches for a given value inside the array. Returns an integer indicating the position of the first occurrance of the value. If the value is not found returns -1.
E.g.:
var myArray = [10, 3]
var index = myArray.IndexOf(3)
>Found at position @index@
a.Insert(integer, value) Adds a new value/object to a specific position of the array. Elements to the right are shifted to the next position.
E.g.:
var myArray = [10, 3]
myArray.Insert(1, "apple")
// The array is now [10, "apple", 3]
a.RemoveAt(integer) Removes an element in the array from a specific position. Returns the value removed.
Zero-based: myArray.RemoveAt(0) removes the first element.
Elements to the right are shifted to the previous position.
E.g.:
var myArray = [1, 2, 3]
myArray.RemoveAt(1)
// The array is now [1, 3]
a.Sort() Organizes the array's elements into ascending order. If the array contains objects of different types it will still be sorted, but no expected results are defined and elements are not guaranteed to be grouped by type.
E.g.:
var myArray = ["Cherry", 2, "Apple", 1, true, false, "Banana", 3]
var value

myArray.Sort()

for i = 0 .. myArray.Count() - 1
value = myArray[i]
>`0,@i@,@value@
Here are some of the different ways to initialize and use arrays: var emptyCollection = [] var magicNumbers = [10, 3, 0, 15, -7] var someStrings = ["apple", "banana", "cherry"] var sameButMultiLine = [ "apple", "banana", "cherry", ] var redeclaredEachFrame redeclaredEachFrame = [] // Not good for the PC var clearedEachFrame = [] clearedEachFrame.Clear() // Better for CPU & memory var clearedEachLoop = [] ?loc.begin | loc.loop clearedEachLoop.Clear() var multiDimensional = [[], [], []] var objectCollection = [ new Components/Float, new Components/Float, new Components/Vector, ] var animationFrames = [ascii ───┼ O/ /| / \ asciiend ^,ascii ---. O \ /|\┼─── / \ asciiend ^] Looping through arrays: var myArray = ["Apple", "Banana", "Cherry"] var count var value count = myArray.Count() ?count > 0 for i = 0 .. count - 1 value = myArray[i] >`0,@i@,@value@ // This example prints fruit names to the left of the screen Multi-dimensional access: var a = [[1,2], [3,4]] var value value = a[1][0] >Found value @value@ at (1, 0)
^Back to top
·:·:· Custom Input ·:·:· Stonescript can read player inputs by use of the ?key game state. This can be used to drive advanced behaviors, such as different modes for the AI, but custom inputs allow the creation of entirely new experiences layered on top of Stone Story. In this example, the @ symbol can be moved across the screen like the main character in a classic Rogue-like game. The key codes (leftBegin, etc) refer to the initial downpress of the button. var x = 0 var y = 0 ?key = leftBegin x-- ?x < 0 x = 0 ?key = rightBegin x++ ?key = upBegin y-- ?y < 0 y = 0 ?key = downBegin y++ >`@x@,@y@,#ffffff,@ Table with all the available key codes:
Held
----
Pressed
-------
Released
--------
Default PC
----------
left leftBegin leftEnd A or ←
right rightBegin rightEnd D or →
up upBegin upEnd W or ↑
down downBegin downEnd S or ↓
primary primaryBegin primaryEnd LMB, Return
back backBegin backEnd X
ability1 ability1Begin ability1End Shift
ability2 ability2Begin ability2End Control
bumpL bumpLBegin bumpLEnd Z
bumpR bumpRBegin bumpREnd C
^Back to top
·:·:· User Interface ·:·:· Buttons, text, animations... Stonescript provides a system for building complex layouts and high performance User Interfaces. An invisible "root" Panel exists by default, at the base of the system. Various other UI elements can be added to the root Panel, including additional Panels, forming a tree structure. All elements are drawn together, in a single step, in the order in which they are added. root │ ├─ Panel │ ├─ Text │ ├─ ASCII-art │ └─ Button │ ├─ Panel │ ├─ Panel | | └─ Text ...
UI
‾‾
Call functions in the ui namespace to build the interface.
ui.root
Panel
The base UI object on top of which the entire tree is built.
E.g.
disable hud
ui.root.visible = true
ui.AddAnim(string)
Returns Anim
Adds an Anim object to the root Panel. Accepts an animation sprite sheet as parameter.
E.g.
?loc.begin
ui.AddAnim(ascii
\o)
%%
(o/
asciiend)
ui.AddButton()
Returns Button
Adds a Button object to the root Panel.
E.g.
func OnPressed()
> Hello World!

?loc.begin
var button = ui.AddButton()
button.y = 1
button.text = Press me
button.SetPressed(OnPressed)
ui.AddPanel()
Returns Panel
Adds a Panel object to the root Panel. Panels are an important object type, serving as containers for other elements.
E.g.
?loc.begin
var p = ui.AddPanel()
p.color = #red
ui.AddStyle()
Returns int
Adds a new style that can be used for drawing rectangular Components such as Panels and Buttons. Returns an ID number of the new style. Is protected against the same style being added multiple times, in which case nothing changes and the same ID is returned. Because different scripts may all call ui.AddStyle(), it's recommended to save the ID as a variable instead of hard-coding style numbers into the script.
E.g.
var customStyle = ui.AddStyle("
^123
^456
^789")
?loc.begin
var p = ui.AddPanel()
p.style = customStyle
ui.AddText()
ui.AddText(string)
Returns Text
Adds a Text object to the root Panel.
E.g.
?loc.begin
var t = ui.AddText()
t.text = "Hello World!"
ui.Clear()
No return value
Removes all UI elements from the main container.
E.g.
?key = backBegin
ui.Clear()

Component
‾‾‾‾‾‾‾‾‾

Component is a base type for all other UI types. This means that other elements (Panels, Text, Buttons and Anim) all have the following properties:
component.x
integer
The X position of the component relative to its docked position.
component.y
integer
The Y position of the component relative to its docked position.
component.w
integer
The component's width. Default value varies by object type.
E.g.
button.w = string.Size(button.text) + 4
// Sizes a button to fit its current text, +2 on each side
component.h
integer
The component's height. Default value is 5.
E.g.
panel.h = panel.parent.h
// Sets the height of a panel to match the height of its parent panel
component.absoluteX
component.absoluteY
integer
read-only
The component's position relative to the screen.
E.g.
var t
?loc.begin
var p = ui.AddPanel()
p.anchor = bottom_right
p.dock = bottom_right
t = ui.AddText("Foo")
p.Add(t)
`0,1,Relative pos = @t.x@,@t.y@
>`0,2,Absolute pos = @t.absoluteX@,@t.absoluteY@
component.anchor
string
Auto-layout property representing the internal pivot of the component. This guides the UI system on how to position the component relative to itself. Default value is "center_center". Possible values: top_left, top_center, top_right, center_left, center_center, center_right, bottom_left, bottom_center and bottom_right.
component.dock
string
Auto-layout property similar to anchor. However, dock represents the external pivot, or position inside the parent where to position the component. If in doubt, use the same value for both anchor and dock, which is the most common situation.
E.g.
?loc.begin
var p = ui.AddPanel()
p.anchor = top_right
p.dock = top_right
p.w = 20
p.h = 9
var t = ui.AddText("HelloWorld!")
t.anchor = left_bottom
t.dock = bottom_left
t.x = 2
t.h = t.lines.Count() + 1
p.Add(t)
component.ax
string
The X part of the anchor. Possible values: left, center and right.
component.ay
string
The Y part of the anchor. Possible values: top, center and bottom.
component.dx
string
The X part of the dock. Possible values: left, center and right.
component.dy
string
The Y part of the dock. Possible values: top, center and bottom.
E.g.
var p
?loc.begin
p = ui.AddPanel()
p.ax = right
p.ay = top
p.dx = right
p.dy = top
component.parent
Panel
read-only
Reference to the component's parent Panel. May refer to the root Panel if the component was created but never added to another Panel. When panel.Add(component) is called the component's parent changes.
component.visible
multi type
bool/string
Visibility of the component. Default value is "inherit". Possible values: true, false and inherit. If set to 'true', the component will always be visible, ignoring the status of its parent. If set to 'false', the component will be invisible, regardless of its parent. However, if set to 'inherit', the component will follow the visibility of its parent.
component.Recycle()
No return value
Removes the component from its parent Panel. It will be repurposed in future ui.Add_() calls. Any variable references to the recycled element should be nulled or reassigned to avoid bugs.

Panel > Component
‾‾‾‾‾

Panels are rectangular Components that serve as containers for other Components. A chain of Panels added to each other form a tree structure.
panel.children
Component[]
Array with all the child components that have been added to the Panel with panel.Add().
panel.clip
bool
Indicates if the bounds of Panel should be used to contrain the drawing of child components. If true, parts of child components that fall outside of the Panel's bounds will not draw.
E.g.
var p
?loc.begin
p = ui.AddPanel()
p.w = 4
p.h = 3
var t = ui.AddText("The quick brown fox jumps
^ over the lazy dog.")
p.Add(t)

?time%30 < 15
p.clip = true
:
p.clip = false
panel.color
string
The panels color, in RGB hexadecimal format.
panel.style
int
ID number of the Panel's current style. Default value is 1. Possible values from -8 to 8. Additional styles can be added with ui.AddStyle()
panel.Add(Component)
panel.Add(Component, int)
No return value
Adds a Component to a Panel. The Component becomes a child of the Panel and the Panel becomes the parent of the Component. The order in which elements are added to a Panel affects the draw order. Components may be inserted to a specific sorting position by use of the optional integer parameter. No integer parameter means the Component is added as the last child of the Panel. This function can also be used for changing the draw order of Components that are already children of the Panel.
panel.Clear()
No return value
Removes all UI elements from the Panel. Components removed this way are recycled into the UI system and will be repurposed in future ui.Add_() calls. Any variable references to those elements should be nulled or reassigned to avoid bugs.
panel.Remove(Component)
panel.Remove(int)
No return value
Removes a specific Component from a Panel or removes the Component at a specified index number. Components removed this way are recycled into the UI system and will be repurposed in future ui.Add_() calls. Any variable references to those elements should be nulled or reassigned to avoid bugs.

Text > Component
‾‾‾‾

Multi-line text box. Supports color metadata.
text.align
string
The alignment/justification of the text inside the box. Default value is "left". Possible values: left, center and right.
text.color
string
The color of the text, in RGB hexadecimal format.
text.lines
string[]
Array of strings that are the broken-down lines of text after the Text box has formatted its contents. Excludes color metadata.
text.text
string
The full contents of the Text box. A subsection of the text may be colored with the metadata [color=#rrggbb][/color].
E.g.
?loc.begin
var t = ui.AddText()
t.text = "Hello [color=#red]World[/color]!"

Button > Component
‾‾‾‾‾‾
button.text
string
The text that appears inside the button.
E.g.
button.text = player.name
// Put your name on the button!
button.tcolor
string
The color of the text inside the button, in RGB hexadecimal format.
E.g.
button.tcolor = #ff0000
// Sets the button text color to red
button.bcolor
string
The color of the button's border, in RGB hexadecimal format.
E.g.
>@button.bcolor@
button.bcolor = #880000
// Prints the border's current color, then sets it to a dark red
button.hcolor
string
The color of the button's highlight when it's pressed, in RGB hexadecimal format.
E.g.
?loc.begin
var b = ui.AddButton()
b.hcolor = #yellow
button.sound
string
The sound effect that plays when the button is pressed. Default is "confirm".
E.g.
button.sound = buy
// Changes the button so it plays the buying sound when pressed
button.style
int
ID number of the Buttons's current style. Default value is 1. Possible values from -8 to 8. Additional styles can be added with ui.AddStyle()
button.SetPressed(f)
function callaback
Assigns a function to be called when the button is pressed. The function can have any number of parameters (even no parameters). When the function is called, the first parameter will be a reference to the button itself.
E.g.
var button1
var button2
func OnPressed(btn)
?btn = button1
>Button1 was pressed
:
>Button2 was pressed

?loc.begin
button1 = ui.AddButton()
button1.y = 1
button1.SetPressed(OnPressed)

button2 = ui.AddButton()
button2.y = 6
button2.SetPressed(OnPressed)
button.SetDown(f)
function callaback
Similar to .SetPressed(), .SetDown() assigns a function to be called when the button press begins (first user contact).
button.SetUp(f)
function callaback
Similar to .SetPressed(), .SetUp() assigns a function to be called when a depress ends on top of the button (last user contact).
E.g.
func OnDown()
> Down!

func OnUp()
> Up!

?loc.begin
var button = ui.AddButton()
button.y = 1
button.text = Press me
button.SetDown(OnDown)
button.SetUp(OnUp)

Anim > Component
‾‾‾‾

ASCII sprite-sheet animations that can be added to UI.
anim.color
string
The animation's color, in RGB hexadecimal format.
anim.duration
int
Time length of the animation, in frames.
anim.flipX
bool
If true, flips the art horizontally, over its pivot.
anim.flipY
bool
If true, flips the art vertically, over its pivot.
anim.frame
int
Current animation frame being drawn. Can be changed to set an animation to a specific frame.
anim.gamePause
bool
If true, the animation automatically pauses playback if the player pauses the game and resumes playback if the player exits the pause screen.
anim.loop
bool
If true, the animation will restart from the begining as soon as it reaches the end of its duration.
anim.playing
bool
read-only
True if the animation is currently playing.
anim.paused
bool
read-only
True if the animatino is playing, but has been paused with a call to anim.Pause().
anim.pivotX
anim.pivotY
int
Additional pivot offset that can be used for fine-tuning where the ASCII-art draws in relationship to its position.
anim.playOnStart
bool
If true, the animation will begin playing as soon as possible.
anim.AddLayer(string)
Returns Anim
Adds a new ASCII sprite on top of this one. As the animation plays (or its frame is changed with anim.frame) all layers stay in sync. Each layer has their own set of properties for color, pivot, etc. Advantages of using animation layers for complex ASCII-art include improved performance and better code quality. If the animation is recycled all layers clean up simultaneously.
E.g.
var a = ui.AddAnim(asciiArtA)
var layer2 = a.AddLayer(asciiArtB)
layer2.color = #bbbbbb
anim.Load(string)
No return value
Assigns a new ASCII sprite sheet.
anim.Pause()
No return value
Suspends playback of the animation at its current frame. A subsequent call to anim.Play() resumes playback.
anim.Play()
No return value
Begins playing the animation, or resumes playback in case it had been paused.
E.g.
var dance
?loc.begin
dance = ui.AddAnim(ascii
(O/
%%
\O)
asciiend)
dance.duration = 20
dance.loop = true
dance.Play()
anim.Stop()
No return value
Suspends playback and sets the animation back to its first frame.

Canvas > Component
‾‾‾‾‾‾

Container optimized for drawing arbitrary glyphs and colors.
canvas.blend
string
The blend mode of the canvas, when composed with elements behind it. Possible values: Opaque, Multiply, Divide, Add, Subtract. Default value is "opaque".
E.g.
var filter1 = ui.AddCanvas()
var filter2 = ui.AddCanvas()
filter1.w = screen.w
filter1.h = screen.h
filter2.w = screen.w
filter2.h = screen.h

filter1.blend = multiply
filter1.SetFG(#aa5555)
filter1.SetBG(#dddddd)

filter2.blend = add
filter2.SetFG(#aa6600)
filter2.SetBG(#662200)
canvas.Get(int,int)
Returns string
Returns the glyph at a specific position x,y on the canvas.
canvas.Set(str)
No return value
Fills the entire canvas with a given glyph.
E.g.
?loc.begin
var canvas = ui.AddCanvas()
canvas.Set("X")
canvas.Set(int,int,str)
No return value
Changes a specific position x,y on the canvas to a given glyph.
E.g.
?loc.begin
var canvas = ui.AddCanvas()
canvas.Set(0, 0, "A")
canvas.Set(int,int, fg,str)
canvas.Set(int,int, fg,bg,str)
No return value
Overloads for changing a canvas at a specific position, while simultaneously setting the foreground and background colors.
E.g.
?loc.begin
var canvas = ui.AddCanvas()
for x = 0..canvas.w
for y = 0..canvas.h
var fg = color.Random()
var bg = color.Random()
canvas.Set(x, y, fg, bg, ▄)
canvas.SetFG(color)
No return value
Sets a foreground color to the entire canvas.
E.g.
?loc.begin
var canvas = ui.AddCanvas()
canvas.Set("R")
canvas.SetFG(#red)
canvas.SetFG(int,int, color)
No return value
Changes the foreground color at a specific position x,y.
E.g.
?loc.begin
var canvas = ui.AddCanvas()
canvas.Set("X")
canvas.SetFG(2, 1, #ff00ff)
canvas.SetBG(color)
No return value
Sets a background color to the entire canvas.
E.g.
?loc.begin
var canvas = ui.AddCanvas()
canvas.Set("g")
canvas.SetBG(#00aa00)
canvas.SetBG(int,int, color)
No return value
Changes the background color at a specific position x,y.
E.g.
?loc.begin
var canvas = ui.AddCanvas()
canvas.Set("X")
canvas.SetBG(2, 1, #yellow)
^Back to top
·:·:· Tips ·:·:· Space (indentation) matters when defining what happens as a result of '?' comparisons (scope). The script can be changed in the middle of a run by pressing 'M' on your keyboard. The Power button in the top-right of the Mind Stone turns the script ON/OFF. If multiple equip Commands are called, whichever comes last will occur. The script executes 30 times per second (once per frame). To experiment with different scripts it's recommended to copy them into an external text editor, such as Notepad. Common shortcuts such as Ctrl+A, Ctrl+C and Ctrl+V are useful. Holding the Tab key in-game gives you a lot of information about game state and shows a list of recent Stonescript errors. A print command can be broken into multiple lines by using '\n' in the text. ^Back to top
·:·:· Default script ·:·:· import Fishing ?hp < 7 activate potion ?loc = caves equipL sword equipR shield ?foe = boss equip crossbow ^Back to top
·:·:· Roadmap ·:·:· Things that are planned, but not yet in the game: Line drawing. Find() to get ahold of enemy or decoration references. Native modding of enemies, decorations and weapons. Expanded API for use in user-generated side quests. Particle emissions. equipF (str) - equips an item to the Faerie. foes - The list of foes within 46 units. ^Back to top
·:·:· Appendix - Sound Effects ·:·:· Stonescript can play sound effects from the game, based on custom logic. In this example, the 'unequip' sound is played whenever the player loses health: var lasthp = hp ?hp < lasthp play unequip lasthp = hp Most sounds have variations that either play randomly or sequentially. If the same sound is played more than once in a single frame it will be ignored. If more than 5 sounds are played per second they will be throttled. Here is the full list of sounds available in Stone Story RPG: acronian_cultist_power_up air_hiss ant_attack ant_death ant_hill ant_walk auggie_voice bang_go_forward bardiche_cast bat_attack bat_attack_small bat_death bat_death_small bat_wing bat_wing_small bearer3_talk bearer4_talk bearer4_talk_evolving bearer5_talk bearer_attack bearer_attack_hit bearer_death bearer_evolving bearer_scream bearer_stealing bearer_super_attack bell_ringer_attack bell_ringer_attack_hit blade_drag blade_glow blade_pallas_attack blade_raise bomb_cart_explosion bomb_cart_fuse bomb_cart_move boo_voice booklet_close booklet_open booklet_turn_page bronze_gate_close bronze_gate_locked bronze_gate_open bronze_guardian_attack1 bronze_guardian_attack2 bronze_guardian_attack3 bronze_guardian_attack4 bronze_guardian_death bronze_guardian_ears_ring bronze_guardian_fuse bronze_guardian_helmet bronze_guardian_power_up bronze_guardian_pulling_hammer bronze_guardian_removing_hammer bronze_guardian_steps bronze_guardian_turbine buy click confirm controller_death controller_whip_attack controller_whip_hit cross_deadwood_bump cross_deadwood_row cross_deadwood_splash crossbow_cast crossbow_hit cult_guard_attack cult_guard_attack_hit cult_marksman_attack cult_marksman_attack_hit cult_sorcerer_attack cult_sorcerer_attack_hit cultist_death devolved_talk dog_bark dominotaur_awake dominotaur_death dominotaur_whip_attack dominotaur_whip_hit dysangelos_guidance dysangelos_guidance_1 dysangelos_guidance_2 dysangelos_guidance_3 dysangelos_intro_talk elementalist_aether_attack elementalist_aether_attack_hit elementalist_aether_blink elementalist_death elementalist_evolving elementalist_fire_attack elementalist_fire_attack_hit elementalist_fire_blink elementalist_ice_attack elementalist_ice_attack_hit elementalist_ice_blink elementalist_poison_attack elementalist_poison_attack_hit elementalist_poison_blink elementalist_vigor_attack elementalist_vigor_attack_hit elementalist_vigor_blink epilogue_devolving epilogue_talk epliogue_player_evolves equip error falling_stonefolk fire_beast_1 fire_beast_2 fire_elemental_attack fire_elemental_attack_hit fire_elemental_awake fire_elemental_death fire_geyser fire_orbs first_controller fissure_break_apart fissure_unmake flying_serpent_loop frog ghost_attack ghost_attack_small ghost_death ghost_death_small ghost_loop ghost_loop_small ghost_tomb_death giant_ice_elemental_attack grappling_cast grappling_hit grappling_idle hammer_cast hammer_hit hans_scream hans_talk_intro hans_talk_reward hatchet_cast hatchet_hit haunted_gate_key_bounce_1 haunted_gate_key_bounce_2 haunted_gate_key_bounce_3 haunted_gate_key_into_gate haunted_gate_npc_voice haunted_gate_opening haunted_gate_point_lost haunted_gate_shuffle haunted_gate_shuffle_fast haunted_gate_torch_off haunted_gate_torch_on haunted_gate_try_to_open ice_elemental_attack ice_elemental_attack_hit ice_elemental_awake ice_elemental_death ice_pillar insta_kill key_drop ki_eater_attack ki_eater_attack_hit ki_eater_awake ki_eater_death ki_gobbler_attack ki_gobbler_attack_hit ki_gobbler_awake ki_gobbler_death ki_slerper_attack ki_slerper_attack_hit ki_slerper_awake ki_slerper_death ki_slerper_walk level_up life_gain logo_full logo_short lost_item_boost mask_summon_1 mask_summon_2 metal_drop mindstone_found mindstone_off mindstone_on mine_walker_attack_a mine_walker_attack_b mine_walker_attack_hit mine_walker_awake mine_walker_death mine_walker_helmet_break mine_walker_step morel_punch mosquito_attack mosquito_death mosquito_loop mushroom_boss_awake mushroom_boss_death mushroom_boss_fat_slam mushroom_boss_punch mushroom_boss_shoot mushroom_boss_split nagaraja_attack_eat nagaraja_attack_lick nagaraja_attack_swallow nagaraja_awake_roar nagaraja_awake_swallow nagaraja_awake_tongue_1 nagaraja_awake_tongue_2 nagaraja_choir nagaraja_dead nagaraja_poison_attack nagaraja_poison_attack_hit nagaraja_tongue_damaged nagaraja_tongue_lift nagaraja_tongue_smell nagaraja_tongue_wrap nagaraja_wail nagaraja_wail_brick open_note paint_splat pallas_voice perfected_attack perfected_attack_hit perfected_death perfected_defense perfected_energy_ball perfected_energy_ball_hit perfected_fly_end perfected_fly_loop perfected_fly_start perfected_summon perfected_talk pickup_bronze pickup_stone pickup_success pickup_tar pickup_wood player_death player_hit player_kick player_punch poison_adept_attack poison_adept_attack_hit poison_powerup potion_berserk potion_cleansing potion_defensive potion_experience potion_healing potion_invisibility potion_lightning potion_lucky potion_strength potion_vampiric progress_1 progress_2 progress_3 progress_4 progress_5 progress_6 progress_7 progress_8 progress_9 prompt_choice quarterstaff_cast quest_stone_jump quest_stone_unlock ranting_tree_halt ranting_tree_talk_again ranting_tree_talk_avenge ranting_tree_talk_extra ranting_tree_talk_get_out ranting_tree_talk_halt ranting_tree_talk_how_dare ranting_tree_talk_impressive ranting_tree_talk_very_well scarab_awake scarab_bite scarab_death scarab_horn scarab_wings scorpion_death scotty_a_pleasure scotty_a_worthy_opponent scotty_deuced scotty_failte_back scotty_getting_good scotty_grr scotty_guess_which scotty_hell_be_back scotty_intro scotty_lets_harden scotty_make_ye_guess scotty_noo_jist scotty_out_of_treasure scotty_perhaps_the_rules scotty_pick_some_treasure scotty_shall_we_up scotty_there_he_is scotty_we_have_wee_use scotty_well_met scotty_well_then scotty_wizard scotty_wrong_choice scout_arrives scout_dialog scout_focus scout_leaves scout_wing serpent_attack serpent_death serpent_handler_release serpent_hiss serpent_slither shield_dash shop_door_enter shop_door_open shovel_cast sightstone_cast skeletimmy_attack skeletimmy_death skeleton_boss_arm1 skeleton_boss_arm2 skeleton_boss_arm_reconnect skeleton_boss_arm_woosh skeleton_boss_attack skeleton_boss_awake skeleton_boss_bone_bounce skeleton_boss_death skeleton_boss_hand_slam skeleton_boss_idle skeleton_boss_legs_die skeleton_boss_summon_minions skeletony_attack skeletony_awake_a skeletony_awake_b skeletony_death skeletony_walk slave_npc slave_outro_chatter slave_outro_transition slave_outro_voice smithy_hammer smithy_hammer_fail snail_attack snail_attack_small snail_death snail_death_small snail_walk soul_stone soul_stone_drop spider_attack spider_boss_attack spider_boss_awake spider_boss_death spider_death spider_death_small spider_eggs_spawn spider_walk stone_throw_cast stone_throw_hit sword_cast sword_hit talisman_reveal temple_npc_chant temple_npc_clear_throat temple_npc_talk torch_cast torch_hit torch_idle treasure_close treasure_drop treasure_drop_common treasure_drop_epic treasure_drop_giant treasure_drop_humble treasure_drop_rare treasure_item_blue treasure_item_cyan treasure_item_green treasure_item_lost treasure_item_pop treasure_item_rainbow treasure_item_red treasure_item_show treasure_item_yellow treasure_open tree_boss_attack tree_boss_awake tree_boss_death tree_boss_idle tree_boss_spike triskelion_fuse ui_starfirst ui_starnew ui_starold1 ui_starold2 ui_starold3 ui_starold4 unequip uulaa_voice wand_aether_cast wand_aether_hit wand_air_cast wand_air_hit wand_cast wand_drop wand_fire_cast wand_fire_hit wand_hit wand_ice_cast wand_ice_hit wand_poison_cast wand_poison_hit wand_vigor_cast wand_vigor_hit waterfall_hook_hit waterfall_land waterfall_rope_grab waterfall_rope_swing waterfall_splash worm_rider_hop xp_tick yeti_attack yeti_attack_flick yeti_attack_hit yeti_awake_blow yeti_awake_explosion yeti_awake_inhale yeti_awake_lick yeti_blow yeti_blow_ice_wall yeti_death yeti_inhale yeti_inhale_lick ^Back to top
·:·:· Appendix - Music ·:·:· Stonescript can play music tracks from the game, based on custom logic. Available tracks depend on the platform. ?loc.begin | loc.loop music.Play(temple_0) Here is the full list of music available in Stone Story RPG: Boiling Mine bronze_guardian_3 bronze_guardian_4 bronze_guardian_5 bronze_guardian_cyan bronze_mine_0 bronze_mine_1 bronze_mine_2 bronze_mine_3 bronze_mine_4 bronze_mine_5 bronze_mine_cyan slave_outro_climb slave_outro_loop Caves of Fear caustic_caves spider_boss Deadwood cross_deadwood_river cross_deadwood_wind deadwood_0 deadwood_1 deadwood_2 deadwood_3 deadwood_4 deadwood_5 deadwood_cyan tree_boss waterfall_descent poena Haunted Halls skeleton_boss undead_crypt_0 undead_crypt_1 undead_crypt_2 undead_crypt_3 undead_crypt_4 undead_crypt_5 undead_crypt_cyan undead_crypt_intro Icy Ridge bridge_broken bridge_crossing icy_ridge_0 icy_ridge_1 icy_ridge_2 icy_ridge_3 icy_ridge_4 icy_ridge_5 icy_ridge_cyan yeti Mushroom Forest fire_loop fungus_forest_0 fungus_forest_1 fungus_forest_2 fungus_forest_3 fungus_forest_4 fungus_forest_5 fungus_forest_cyan mushroom_boss mushroom_boss_cyan shop Rocky Plateau rocky_plateau_0 rocky_plateau_1 rocky_plateau_2 rocky_plateau_3 rocky_plateau_4 rocky_plateau_5 rocky_plateau_epilogue rocky_plateau_fight rocky_plateau_talk Temple nagaraja temple_0 temple_1 temple_2 temple_3 temple_4 temple_5 temple_cyan Events event_fall event_hamartia event_spring event_stonejam event_summer event_winter Other credits main_menu bone_factory osteophone uulaa ^Back to top
·:·:· Appendix - Ambient Loops ·:·:· Stonescript can play multiple layers of background ambient audio, based on custom logic. ?loc.begin ambient.Stop() ambient.Add(ambient_crypt) Here is the full list of ambient audio available in Stone Story RPG: ambient_mines ambient_caves ambient_bronze_gate ambient_deadwood ambient_mushroom ambient_bridge ambient_icy ambient_cave ambient_rocky ambient_temple ambient_crypt ambient_haunted_gate ambient_pallas waterfall_a waterfall_b waterfall_c ^Back to top
Copyright Martian Rex, Inc. 2020