๐Ÿ—บ
Language Tour
A very brief overview of ByteSkript's language features, with links to their respective documentation pages.
Welcome to the short tour of the language. For clarity, this has been divided into a list of sections you can find on the right margin of the page.
script.bsk
1
on script load:
2
trigger:
3
print "Welcome to ByteSkript!"
Copied!
If you want to follow along with the tour, you can copy any of the examples into a script file and run them locally. Information about installing and running scripts can be found here.
For those interested in technical information, each section has a how it works box where you can learn about how that language feature was created.

Scripts

Every program is made up of one of more scripts. These go inside scriptname.bsk files inside the skript/ directory.
Script names must be written in alphaneumeric characters (a-z0-9) and allow underscores _. They must start with a letter (a-z).
Valid names: myscript.bsk, cool_thing.bsk, MyScript.bsk, My_Cool_Script123.bsk.
Your program can have as many scripts in as you like.
How it Works

Syntax Features

An introduction to the core syntax and some of its basic uses.

Events

Events are triggered externally when something happens. They are used as 'entry points' to a program (to start it running.)
Most scripts will use the on [script] load event to start off. Multiple handlers can be added for the same event, which will start separate processes.
script.bsk
1
on script load:
2
trigger:
3
print "Welcome to ByteSkript!"
4
โ€‹
5
on script load:
6
trigger:
7
print "This is a second entry-point!"
Copied!
Click here to read more about events.
How it Works

Variables

Variables are used to hold data values in your code. They are named inside {curly} brackets.
Variable names must be written in alphaneumeric characters (a-z0-9) and allow underscores _. They must start with a letter (a-z).
Valid names: {myvar}, {my_var}, {number}, {CoolThing}, {var_123}.
Regular variables are local to the current trigger. They won't be set in a different trigger.
script.bsk
1
on script load:
2
trigger:
3
set {var} to "Hello"
4
set {number} to 3
5
set {number} to {number} + 2
6
print {var} + ", the number is " + {number}
7
// Hello, the number is 5
Copied!
Variables do not have fixed types: you can store any value in the same variable.
If a variable is used before it is set, it will be empty and have a 'null' value.
script.bsk
1
on script load:
2
trigger:
3
print {var} // null
4
set {var} to "Hello"
5
set {var} to 3
6
print {var} // 3
Copied!
Click here to read more about variables.
How it Works

Functions

Functions are a great way to organise your scripts, rather than putting all the code into one big trigger.
You can give values to a function as arguments.
You can have multiple functions with the same name, as long as they have different numbers of parameters.
script.bsk
1
on script load:
2
trigger:
3
run my_func()
4
run my_func("Bob", 66)
5
6
function my_func: // no parameters
7
trigger:
8
print "This is my function!"
9
โ€‹
10
function my_func(name, age): // 'name' -> {name}, 'age' -> {age}
11
trigger:
12
print "My name is " + {name}
13
print "My age is " + {age}
Copied!
Functions may also give back values to the trigger that called them using the return effect.
You can specify the return type to help users to know what to expect, but this is optional.
script.bsk
1
on script load:
2
trigger:
3
set {var} to add(1, 2)
4
print {var} // 3
5
set {var} to add_six({var})
6
print {var} // 9
7
8
function add(x, y):
9
trigger:
10
return {x} + {y}
11
12
function add_six(number):
13
return: Number // optional!
14
trigger:
15
return {number} + 6
Copied!
Click here to learn more about functions.
The values you give to a function are called arguments.
run func({arg1}, {arg2})
The values the function takes are called parameters.
function func(param1, param2)
How it Works

Effects

Every line of runnable code inside a script is an effect. Most of these lines will take inputs, which come from expressions.
Effects do not give back any value, and cannot be used as inputs for other syntax.
Effects will usually be verbs or action words like "print", "make" or "run".
You can think of them as instructions for the program.
The simplest 'control' effects are the set..., add..., delete..., and run... effects.
script.bsk
1
on script load:
2
trigger:
3
print "Welcome to ByteSkript!"
4
set {var} to 1
5
delete {var}
6
set {list} to a new list
7
add "hello" to {list}
Copied!
Click here to read more about effects.
How it Works

Expressions

Expressions are any syntax that gives back a value. Some expressions may also accept inputs.
Expressions cannot go on their own line, they need to go inside an effect or another expression.
script.bsk
1
on script load:
2
trigger:
3
print the java version // [the] java version is an expression
4
print {var} // {var} is an expression
5
print "Welcome to ByteSkript!" // "..." is a Literal expression
6
print my_func() // the my_func() call is an expression.
Copied!
Click here to read more about expressions.
How it Works

Conditions

Conditions are sections that run if (and only if) a certain check passes.
They are split into an if, else/if, else tree structure.
script.bsk
1
on script load:
2
trigger:
3
set {var} to true
4
if {var} is true:
5
print "That worked!"
6
else if {var} is true:
7
print "That worked!"
8
else:
9
print "Something went wrong..."
Copied!
You can also access and re-assign variables in these sections.
script.bsk
1
function my_func(number):
2
trigger:
3
if {number} is greater than 6:
4
set {var} to "yes"
5
else if {number} is 3:
6
set {var} to "no"
7
print {var} // "yes", "no" or 'null'
Copied!
Click here to read more about conditions.
How it Works

Loops

Loops can be used to run code multiple times, according to certain behaviour.
A while loop will run until the condition fails.
script.bsk
1
on script load:
2
trigger:
3
set {var} to 0
4
while {var} is less than 10:
5
set {var} to {var} + 2
6
print "Counting " + {var}
7
print "I counted to " + {var}
Copied!
A loop %Number% times will loop the specified number of times. (Crazy, right?)
script.bsk
1
on script load:
2
trigger:
3
set {var} to 6
4
loop {var} times:
5
print "hello"
6
print "Done!"
Copied!
A loop %Variable% in %Objects% will loop through the collection of objects, storing each one in the variable and running the loop for it.
script.bsk
1
on script load:
2
trigger:
3
set {things} to ("hello", 6, "bean", 4.3)
4
loop {thing} in {things}:
5
print "The thing is " + {thing}
6
if {thing} is a Number:
7
print "That's a number!"
8
print "Done!"
Copied!
Click here to read more about loops.
How it Works

Lambdas

Lambdas can be used to define runnable code inside a trigger.
These can be stored inside variables and run multiple times. They can also be returned from or given to functions.
1
on script load:
2
trigger:
3
set {var} to a new runnable:
4
print "hello!"
5
run {var} // prints hello
6
set {bye} to get_runner()
7
run {bye} // prints goodbye
8
9
function get_runner:
10
trigger:
11
return a new runnable:
12
print "goodbye!"
13
Copied!
Click here to read more about lambdas.
How it Works

Types

Scripts can define types that are used to create objects.
This is an advanced feature.
These are most useful for interacting with Java libraries (like Java's JDK) but they can also help advanced users to follow (semi) object-oriented design and prevent repeating code.
1
type Square:
2
function get_sides:
3
trigger:
4
return 4
5
โ€‹
6
on script load:
7
trigger:
8
set {square} to a new Square
9
print get_sides() from {square}
10
Copied!
Click here to read more about types.

Language Features

Features of the language itself, rather than specific syntaxes.

Simple Processes

ByteSkript aims to make it simple to manage timings and threads, without needing to deal with errors or clunky procedures for starting background tasks and getting results.
1
print "hello"
2
run a new runnable in the background:
3
print "goodbye"
4
run my_func() in the background
Copied!
You can communicate easily between processes, allowing you to run actions in the background and notify the main task when it's time to continue.
1
print "Going to sleep"
2
set {@var} to 0
3
set {thread} to the current process
4
run a new runnable in the background:
5
print "I'll wake you in 10 seconds"
6
wait 10 seconds
7
set {@var} to 100
8
wake {thread} // wakes the main process up
9
sleep // waits until something else wakes us up
10
print "Somebody woke me up!"
11
print "The number is " + {@var} // 100
Copied!
Since ByteSkript runs between multiple processes, variable types that are accessible between processes have to be atomic (respect changes from other threads.)
This prevents concurrent modification (where two separate processes try to access the same thing at the same time) and makes race conditions less serious.
1
set {@omic} to "hello"
2
set {runner} to a new runnable:
3
wait 1 second
4
print {@omic}
5
run {runner} in the background
6
set {@omic} to "goodbye"
7
// goodbye!
Copied!
How it Works

Easy Modification

ByteSkript is designed to be modified.
  • Third-party libraries written in Java can add new syntax or entire language features.
  • Scripts can compile new syntax that links to functions.
  • ByteSkript can be forked and applied as a DSL for an existing program.
This makes it possible to apply ByteSkript to a lot of different situations, and customise it to be more suitable for particular tasks. Very few other languages offer language-level modification from within the language itself.
As the Skript language is designed to be English-readable and accessible for beginners, this gives it an advantage over more complicated (and difficult) programming languages.

Fluid Typing

ByteSkript achieves a mixture of static and dynamic typing using its double-compiler structure.
Scripts are usually written with dynamic typing - you don't need to specify types for variables, function parameters, etc.
1
set {var} to "hello" // var is a string
2
set {var} to 3 // var is now a number
Copied!
But they are still able to interact with the JVM, which uses static typing.
1
set {var} to 3
2
set {var} to "hello"
3
run broadcast({var}) from org/example/MyClass // a Java method!
Copied!
How it Works
This also applies to functions that belong to an object (like non-static methods in Java.)
This allows you to run matching functions from entirely different objects.
1
if {something} is true:
2
set {var} to a new list
3
else:
4
set {var} to a new map
5
set {size} to size() from {var} // size() is a Java method!
6
print {size} // 0
Copied!
In Java, this structure would be impossible since the size method from Map and List are different - they don't share an interface.
How it Works