🗺️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.
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.
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.
Click here to read more about events.
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.
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.
Click here to read more about variables.
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.
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.
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)
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.
Click here to read more about effects.
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.
Click here to read more about expressions.
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.
You can also access and re-assign variables in these sections.
Click here to read more about conditions.
Loops
Loops can be used to run code multiple times, according to certain behaviour.
A while
loop will run until the condition fails.
A loop %Number% times
will loop the specified number of times. (Crazy, right?)
A loop %Variable% in %Objects%
will loop through the collection of objects, storing each one in the variable and running the loop for it.
Click here to read more about loops.
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.
Click here to read more about lambdas.
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.
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.
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.
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.
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.
But they are still able to interact with the JVM, which uses static typing.
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.
In Java, this structure would be impossible since the size
method from Map
and List
are different - they don't share an interface.
Last updated