From 226c9258e986f4145b6e10d01fe05d2e71707df9 Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 3 Jan 2026 22:46:10 +0100 Subject: [PATCH 01/23] change: Move Game category to weight 1 --- docs/angelscript/game/meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/angelscript/game/meta.json b/docs/angelscript/game/meta.json index 45754fe1..ad750754 100644 --- a/docs/angelscript/game/meta.json +++ b/docs/angelscript/game/meta.json @@ -1,5 +1,5 @@ { "title": "Game", "type": "angelscript", - "weight": 0 + "weight": 1 } From 039690e9a7e515aaf8bb9aa005164f966c03c226 Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 3 Jan 2026 22:46:19 +0100 Subject: [PATCH 02/23] add: Chapter 1 mostly done --- docs/angelscript/guide/chapter1.md | 72 ++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/angelscript/guide/chapter1.md diff --git a/docs/angelscript/guide/chapter1.md b/docs/angelscript/guide/chapter1.md new file mode 100644 index 00000000..5f732968 --- /dev/null +++ b/docs/angelscript/guide/chapter1.md @@ -0,0 +1,72 @@ +--- +title: Chapter 1 - Introduction +weight: 0 +--- + +# Chapter 1 - Introduction + +## What will you learn in this chapter +You will learn about: +- AngelScript as a programming language, +- Purpose of AngelScript in Strata Source, +- Client - Server model of the engine, +- How to load code in the game, +- Writing your own Hello World program. + +> [!CAUTION] +> This guide assumes you have basic skills of programming in languages like Python, C/C++, Squirrel (VScript), etc. +> It is recommended you already have experience in programming, although this guide aims to be as begineer's friendly as possible. +> Basic concepts will **not** be taught. + +--- + +## AngelScript +The [AngelScript's home page](https://www.angelcode.com/angelscript/) describes AngelScript as: +> The AngelCode Scripting Library, or AngelScript as it is also known, is an extremely flexible cross-platform scripting library designed to allow applications to extend their functionality through external scripts. + +Besides that, you can treat AngelScript as some sort of hybrid between C++ and Python. In some areas it behaves like C++, for example it is staticly typed, meaning that when you are declaring a variable you also have to declare it's types, and it also implements it's own version of pointers (called handles); it also aims to help out users in writing code, whether by dissallowing certain operations or by assuming. More on that will be explained in later parts of the guide. + +Its use cases vary, it is much closer to pure engine code than VScript, meaning that you can for example program in custom entities, or custom commands. + +Its official documentation can be found here: [AS Official Docs](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html). + + +## What can you do with AngelScript +This question is not properly asked, because AngelScript will allow you to do mostly anything you want, however it's main task in Strata Source is to allow users to create custom entities, create custom commands, bind to in-game events, and more. + +While VScript (mainly) sits between entities and handles the interactions between them, AngelScripts sits in a level above, where AS can be treated as entities *themselves*. + +--- + +## AngelScript in Strata Source + +### Client - Server model +Before we get into writing your first script, there is one more thing you need to know. Most engines including Source in general, operate on the client-server model. Meaning that client code is separate from the server code, even on singleplayer. When you start a map in singleplayer you essentially create a one-player server that runs beside the client. This is very important because AS code can be loaded on both. Some functionality will only be available on the server (like entities) and some functionality will only be available on the client (like Panorama/UI). + + +### Loading code +Your first question might be: Where do I place the files containing my code? +The answer is pretty simple, each file that contains your code should be ended with the **.as** extension and be placed in the **code/** folder of a respective `Game` searchpath. Example locations would be `p2ce/custom/my-addon/code/` or just `p2ce/code/` (the latter not being recommended). + +You can name your files however you'd like. You can create custom directories, you can loosely place files, it all depends on what you're trying to achieve; in the long run it doesn't matter. What does matter are the "starting points" of sorts. The engine will not attempt to load any files besides 3 files placed **directly** in the **code/** folder: + +1. `init.as` - Will get loaded by server and client. +2. `sv_init.as` - Will only get loaded by the server. +3. `cl_init.as` - Will only get loaded by the client. + +### Your first script +Now, you should be ready to write your very first and own program that will print a Hello World message to the console. You might not know everything in the code below but don't get dissappointed! You should place this code into `cl_init.as` as it is a client command. + +```cpp +[ClientCommand("HelloWorld", "")] +void MyCommand(const CommandArgs@ args) { + Msg("Hello world from AngelScript!\n"); // You can place your own text here! +} +``` + +Now, the only thing left is to launch up the game, open the console and execute the *HelloWorld* command. + +## Tips + +> [!TIP] +> Reading console output can be tiresome as much more is happening in the console than just the script system. However, there is an easy way to just listen to the script system output. You can run `con_filter_text scriptsys; con_filter_enable 1` filter out anything that is not the script system. From be996f99661ea973e2087175d9502a1c52a078ed Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 3 Jan 2026 22:46:47 +0100 Subject: [PATCH 03/23] add: meta.json for guide category --- docs/angelscript/guide/meta.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docs/angelscript/guide/meta.json diff --git a/docs/angelscript/guide/meta.json b/docs/angelscript/guide/meta.json new file mode 100644 index 00000000..76da0b32 --- /dev/null +++ b/docs/angelscript/guide/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Begineer's Guide", + "weight": 0 +} From 10e56e5c9d779eb0cfa04c7c00d765d3eafaad9a Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 3 Jan 2026 22:47:05 +0100 Subject: [PATCH 04/23] add: Chapter 2 mostly done --- docs/angelscript/guide/chapter2.md | 110 +++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 docs/angelscript/guide/chapter2.md diff --git a/docs/angelscript/guide/chapter2.md b/docs/angelscript/guide/chapter2.md new file mode 100644 index 00000000..25900a0a --- /dev/null +++ b/docs/angelscript/guide/chapter2.md @@ -0,0 +1,110 @@ +--- +title: Chapter 2 - Value Types +weight: 1 +--- + +# Chapter 2 - Value Types + +## What will you learn in this chapter +In this chapter you will learn: +- What are Value Types, how to declare and initialize them, +- About the auto keyword, +- What are constants. + + +Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle value types in your script. + +> [!NOTE] +> This guide won't cover every detail about any of data types, it is recommended you visit the [Data Types Section](../game/type) of the wiki for more information. +> Alternatively, you can find references on the [AS Official Documentation](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes.html), however please note that Strata's wiki will be the most representative, some functionality might have been changed! + +--- + +## Value Types +Value types are the more "primitive" types, and are only implemented in the backend by the Strata Team inside the engine itself. These types include: `int`, `string`, `bool`, `float`, `double`, etc. + +> [!WARNING] +> It is assumed you already know about these data types from other languages (mainly C++). This subsection will only provide information relevant to AngelScript itself. + +### Declaration and assignment +Value types can easily get assigned and can be passed by value to functions (more on that later). +To create a value type you usually perform a declaration and an assignment, or both at once: +```cpp +int myInt; // Declaration +myInt = 20; // Assignment + +string myString = "Hey!"; // Initialization +``` + +You can declare multiple variables of the same type at once: +```cpp +int myInt1, myInt2, myInt3; +``` + +Once declared, variables cannot change their type without redeclaration. This is not allowed: +```cpp +int myInt; +myInt = 3.2 // myInt is of type int, not float/double! +``` + +### Auto keyword +Although not recommended, the `auto` keyword will make the compiler automatically determine the data type of the variable: +```cpp +auto i = 1; // Will set type of i to integer +auto s = "My string"; // Will set type s to string +auto var = functionThatWillReturnAnObjectWithAVeryLongName(); + +// Handles (described in later chapters) can also be declared with auto +auto@ handle = @obj; +``` + +The `auto` keyword is not recommended for several cases. The main one of them is that you cannot immediately see the data type of a returned object especially from functions, like the one above. We don't know what that function will return. Another reason is that sometimes the compiler might guess wrong, especially in cases like integers, where you have multiple ways that `1` could have been described (e.g. int8/int16, both can describe `1`, even `bool` can). + +--- + +### Constants +Constant variables are variables that cannot change over the lifetime of the [variable scope](chapter3) they are created in. +You can define a constant variable using the `const` keyword: +```cpp +const int size = 31; +const auto st = "string"; // const also works with the auto keyword +``` + +Constants can be useful as a sort of configuration of the script itself. If you reuse a staticly defined value you can instead define a global constant and then changing one value will change everything at once: +```cpp +const int MAX_SIZE = 16; + +void main() { + string mystring = "lorem ipsum"; + my_func1(mystring, MAX_SIZE); // A function that does something with mystring, but also needs to have additional information + my_func2(mystring, MAX_SIZE) // Another function that does something else with mystring, but it also needs the same additional information +} +``` + +Constants are also a way to optimize your code. If you know that a variable won't change (or shouldn't change), always make it a constant. +```cpp +bool function(string s, float i) { + const float value = s.length() - i; + return i > value; +} + +``` +--- + +### Integer size reference table +The table below shows the minimum and maximum values for each integer subtype (don't worry as pretty much no programmers remember this table, just remember that it exists): +|Type|Short description|Minimum Value|Maximum Value| +|---|---|---|---| +|int8| Signed, 8 bits |-128 | 127 | +|int16| Signed, 16 bits |-32,768 | 32,767 | +|int| Signed, 32 bits |-2,147,483,648 | 2,147,483,647 | +|int64| Signed, 64 bits |-9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 | +|uint8| Unsigned, 8 bits, also represents characters (char) | 0 | 255 | +|uint16| Unsigned, 16 bits | 0 | 65,535 | +|uint| Unsigned, 32 bits | 0 | 4,294,967,295 | +|uint64| Unsigned, 64 bits | 0 | 18,446,744,073,709,551,615 | + +> [!TIP] +> The official AngelScript documentation mentions that the scripting engine has been mostly optimized for 32 bit datatypes (int/uint). Using these is recommended for the most part (unless you are dealing with numbers that don't fit into int/uint). + + From 0aff3b918a2ca9415fdac82368340f33ca6d82cd Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 3 Jan 2026 22:47:17 +0100 Subject: [PATCH 05/23] add: Initial chapter 3 and chapter X --- docs/angelscript/guide/chapter3.md | 49 ++++++++++++++++ docs/angelscript/guide/chapterX.md | 90 ++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 docs/angelscript/guide/chapter3.md create mode 100644 docs/angelscript/guide/chapterX.md diff --git a/docs/angelscript/guide/chapter3.md b/docs/angelscript/guide/chapter3.md new file mode 100644 index 00000000..7c09a4a5 --- /dev/null +++ b/docs/angelscript/guide/chapter3.md @@ -0,0 +1,49 @@ +--- +title: Chapter 3 - Statements, Functions & Variable Scope +weight: 2 +--- +# Chapter 3 - Statements, Functions & Variable Scope + +## What will you learn in this chapter +In this chapter you will learn: +- What are Value Types, +- What is the Variable Scope. + +## Functions + +As you already know or not, functions are a way of implementing routines that operate on an input and produce a result. In Layman's terms, you give it some data, it processes the data and (may, but doesn't need to) give you an output. + +A function declaration consists of 3 main parts: *return value*, *function name*, and the *parameters*. +These follow pretty much the same syntax as C++. + + +-- + +## Variable Scope + +Variable Scope determines which data can be accessed from where. In AngelScript the Variable Scope behaves exactly as the one in C++. + +In general the Variable Scope makes programs use less memory by not holding useless information inside memory, as an example: +```cpp + +int number = 10; + +void my_func1() { + int my_number = 21; +} + +void my_func2() { + number = 20; // Success, number has been reassigned to 20 + my_number = 80; // Error, my_number has not been declared +} +``` +In this case my_number doesn't exist inside *my_func2*, it only exists inside *my_func1* and only for the duration of that function's execution. + +Statements such as `if`, `else`, `for`, `while`, `try`, etc. create local variable scopes each time, meaning that variables declared inside them cannot be accessed outside of them, contrary to how for example Python handles it (where scopes are only created inside functions). + +In AS, global variables are allowed, however: + +> [!NOTE] +> From the official documentation: *Variables of primitive types are initialized before variables of non-primitive types. This allows class constructors to access other global variables already with their correct initial value. The exception is if the other global variable also is of a non-primitive type, in which case there is no guarantee which variable is initialized first, which may lead to null-pointer exceptions being thrown during initialization.* + +A good practice is to avoid global variables altogether, and use different means of sharing information between functions such as returning values or &out references (more on that in later chapters). \ No newline at end of file diff --git a/docs/angelscript/guide/chapterX.md b/docs/angelscript/guide/chapterX.md new file mode 100644 index 00000000..53cc9447 --- /dev/null +++ b/docs/angelscript/guide/chapterX.md @@ -0,0 +1,90 @@ +--- +title: Chapter X - Object Handles & Reference Types +weight: 5 +--- + +# Chapter X - Object Handles & Reference Types + +## What will you learn in this chapter +In this chapter you will learn: +- What are Value Types, +- What are References and how to use them, +- What are Reference Types. + + +Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle data in your script. Described below are various "types" of data types, and their differences. + +--- + +## Object handles + +Object handles are like smart pointers from C++, they don't actually hold data themselves, rather they hold an address in memory (reference) that can be used to locate the object they point to. + +### Declaration +An object handle is declared by appending the **@** sign after the data type name, e.g.: +```cpp +object@ handle; +``` +This code will create a handle of type `object` and point it to null (meaning that it doesn't actually point anywhere). + +> [!CAUTION] +> It is not guaranteed that handles will actually point to valid data. Handles initialized like the one above point nowhere, and trying to perform any operation on them (such as calling methods) will cause an exception. + +> [!NOTE] +> None of the Value Types (primitives) have object handles. + +You can access the handle of any reference type by prepending the **@** symbol to the variable: +```cpp +object my_object; +@my_object; // This is a handle to my_object +``` + +### Expressions +In expressions, object handles are treated exactly the same as object variables themselves. For reference types they are essentially the same. Meaning that: +```cpp +object my_object; +object@ my_handle = @my_object; +my_handle is my_object // Is true + +//Calling methods can be done like so (both ways are correct) +my_handle.Method(); +my_object.Method(); +``` +In most of times the compiler will automatically know what you are trying to do, in order to explicitly call a handle operation you have to **prepend the variable name with the handle symbol (@)**. + +```cpp +object obj1; +object@ objhandle; + +objhandle = @obj1; // This will not work, and will make the script not compile. +@objhandle = @obj1; // This is a proper handle assignment, @objhandle gets set to point to obj1. +@objhandle = obj1; // This will also work because of object variables being handles internally, but is confusing to read, and so - not recommended. +``` + +--- + +The below section of the Object Handles subchapter contains more detailed information about the implementation of handles in AngelScript. If you don't feel like delving deeper into this subject you can skip the rest of this section for now, remember that you may always return here after you feel accustomed to object handles. + +As an example, let's assume the `object` class implements opAssign, trying to do: +```cpp +my_object = 10; +``` + +Will result in an error, because you are not allowed to do value assignment on a reference type. However, you will be able to do: + +```cpp +@my_object = 10; +``` + +Because that calls the internal opAssign method (which should return a reference to the `object` (us)), and so we are actually doing a handle assignment (that assigns the handle to the same object, but in which opAssign has modified the internal properties). + +You can also initialize objects this way: +```cpp +object@ my_object = 10; +``` +This is a completely valid way of declaring and initializing a variable. This code will call the default constructor, then opAssign(10). + +--- + +## Reference types + From 0fdc1d7697f694353e32cda2ad50ca82145537fa Mon Sep 17 00:00:00 2001 From: Enderek Date: Sun, 4 Jan 2026 17:41:20 +0100 Subject: [PATCH 06/23] change: Mass upate all articles (many, many changes) --- docs/angelscript/guide/chapter1.md | 56 +++++++-- docs/angelscript/guide/chapter2.md | 44 ++++--- docs/angelscript/guide/chapter3.md | 140 +++++++++++++++++++--- docs/angelscript/guide/chapter4.md | 169 +++++++++++++++++++++++++++ docs/angelscript/guide/chapter5.md | 13 +++ docs/angelscript/guide/chapterX-1.md | 27 +++++ docs/angelscript/guide/chapterX.md | 4 +- 7 files changed, 409 insertions(+), 44 deletions(-) create mode 100644 docs/angelscript/guide/chapter4.md create mode 100644 docs/angelscript/guide/chapter5.md create mode 100644 docs/angelscript/guide/chapterX-1.md diff --git a/docs/angelscript/guide/chapter1.md b/docs/angelscript/guide/chapter1.md index 5f732968..8d4d1480 100644 --- a/docs/angelscript/guide/chapter1.md +++ b/docs/angelscript/guide/chapter1.md @@ -6,25 +6,33 @@ weight: 0 # Chapter 1 - Introduction ## What will you learn in this chapter -You will learn about: -- AngelScript as a programming language, -- Purpose of AngelScript in Strata Source, -- Client - Server model of the engine, -- How to load code in the game, -- Writing your own Hello World program. +In this chapter you will learn about: +- [AngelScript as a programming language](#angelscript), +- [Purpose of AngelScript in Strata Source](#what-can-you-do-with-angelscript), +- [Client - Server model of the engine](#client---server-model), +- [How to load code in the game](#loading-code), +- [Writing your own Hello World program](#your-first-script), +- [Testing out your own code](#how-to-test-out-your-code-in-a-basic-way) +- [Additional tips that might help you](#additional-tips). + +> [!TIP] +> In each chapter, you can easily navigate the page by clicking links in the "What will you learn in this chapter" section. > [!CAUTION] > This guide assumes you have basic skills of programming in languages like Python, C/C++, Squirrel (VScript), etc. -> It is recommended you already have experience in programming, although this guide aims to be as begineer's friendly as possible. +> It is recommended you already have *some* experience in programming, although this guide aims to be as begineer's friendly as possible. > Basic concepts will **not** be taught. +> [!NOTE] +> It is recommended that while reading this guide, you will try out the things you have learned. This guide will include example tasks for you to do as a practice. + --- ## AngelScript The [AngelScript's home page](https://www.angelcode.com/angelscript/) describes AngelScript as: > The AngelCode Scripting Library, or AngelScript as it is also known, is an extremely flexible cross-platform scripting library designed to allow applications to extend their functionality through external scripts. -Besides that, you can treat AngelScript as some sort of hybrid between C++ and Python. In some areas it behaves like C++, for example it is staticly typed, meaning that when you are declaring a variable you also have to declare it's types, and it also implements it's own version of pointers (called handles); it also aims to help out users in writing code, whether by dissallowing certain operations or by assuming. More on that will be explained in later parts of the guide. +Besides that, you can treat AngelScript as some sort of hybrid between C++ and Python. In some areas it behaves like C++, for example it is statically typed, meaning that when you are declaring a variable you also have to declare it's types, and it also implements it's own version of pointers (called handles); it also aims to help out users in writing code, whether by dissallowing certain operations or by assuming. More on that will be explained in later parts of the guide. Its use cases vary, it is much closer to pure engine code than VScript, meaning that you can for example program in custom entities, or custom commands. @@ -54,6 +62,10 @@ You can name your files however you'd like. You can create custom directories, y 2. `sv_init.as` - Will only get loaded by the server. 3. `cl_init.as` - Will only get loaded by the client. +### IDE and testing environment +It is suggested to use Visual Studio Code with the [AngelScript Language Server (sashi0034.angel-lsp)](https://marketplace.visualstudio.com/items?itemName=sashi0034.angel-lsp) extension. From there you can open the `code/` folder of your choice as a project and develop there. +The engine compiles scripts on every map load (you can use the `reload` command to recompile the scripts). + ### Your first script Now, you should be ready to write your very first and own program that will print a Hello World message to the console. You might not know everything in the code below but don't get dissappointed! You should place this code into `cl_init.as` as it is a client command. @@ -66,7 +78,33 @@ void MyCommand(const CommandArgs@ args) { Now, the only thing left is to launch up the game, open the console and execute the *HelloWorld* command. -## Tips +> ### TASK 1: +> Run the HelloWorld program mentioned above. + +## How to test out your code in a basic way +For now you need to know how to run your code so that you will be able to solve tasks given to you with this guide. +In `sv_init.as` include: +```cpp +[ServerCommand("CodeTest", "")] +void CodeTest(const Command@ args) { + // Here you can put your code +} +``` + +The code in this function will run whenever you run the `CodeTest` command in game. Remember to `reload` to see the changes! +The `Msg(string)` function will serve you as a way to view your variables (like print or cout), just do `Msg(a)` where a is your variable and a will get printed to the console! +Remember to add `"\n"` to the input of Msg (or just call `Msg("\n");` after your message), otherwise everything will print in one line! + +> [!BUG] +> Some types such as `int` cannot be directly converted to string, and so you won't be able to put them directly into Msg(). +> > [!TIP] +> > In order to avoid that problem you can append to an empty string, just do `"" + a` and in most cases this will work: `Msg("" + a);` + +### Compilation errors +Most of times scripts will report errors before they are ran, on map load. This is why if you don't see your functionality (like when a command is not there in the console), scroll up and check the error. Additionally you can use the first tip in the [tip section](#additional-tips) and then use `reload`. + + +## Additional Tips > [!TIP] > Reading console output can be tiresome as much more is happening in the console than just the script system. However, there is an easy way to just listen to the script system output. You can run `con_filter_text scriptsys; con_filter_enable 1` filter out anything that is not the script system. diff --git a/docs/angelscript/guide/chapter2.md b/docs/angelscript/guide/chapter2.md index 25900a0a..feafadcd 100644 --- a/docs/angelscript/guide/chapter2.md +++ b/docs/angelscript/guide/chapter2.md @@ -1,21 +1,22 @@ --- -title: Chapter 2 - Value Types +title: Chapter 2 - Value Types, Declaration & Assignment weight: 1 --- -# Chapter 2 - Value Types +# Chapter 2 - Value Types, Declaration & Assignment ## What will you learn in this chapter -In this chapter you will learn: -- What are Value Types, how to declare and initialize them, -- About the auto keyword, -- What are constants. +In this chapter you will learn about: +- [Value Types](#value-types), +- [Declaration and assignment of value types](#value-types), +- [Auto keyword](#auto-keyword), +- [Constants and the const keyword](#constants), +- [Integer size reference table](#integer-size-reference-table). - -Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle value types in your script. +> Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle value types in your script. > [!NOTE] -> This guide won't cover every detail about any of data types, it is recommended you visit the [Data Types Section](../game/type) of the wiki for more information. +> This chapter won't cover every detail about any of data types, it is recommended you visit the [Data Types Section](../game/type) of the wiki for more information. > Alternatively, you can find references on the [AS Official Documentation](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes.html), however please note that Strata's wiki will be the most representative, some functionality might have been changed! --- @@ -44,9 +45,13 @@ int myInt1, myInt2, myInt3; Once declared, variables cannot change their type without redeclaration. This is not allowed: ```cpp int myInt; -myInt = 3.2 // myInt is of type int, not float/double! +myInt = 3.2; // myInt is of type int, not float/double! ``` +> ### TASK 1: +> 1. Create a program that will declare and assign variables of types `string`, `int`, `bool`, `double`, and then print them out to the console. +> 2. Do the same but use variable initialization. + ### Auto keyword Although not recommended, the `auto` keyword will make the compiler automatically determine the data type of the variable: ```cpp @@ -70,29 +75,30 @@ const int size = 31; const auto st = "string"; // const also works with the auto keyword ``` -Constants can be useful as a sort of configuration of the script itself. If you reuse a staticly defined value you can instead define a global constant and then changing one value will change everything at once: +Constants can be useful as a sort of configuration of the script itself. If you reuse a statically defined value you can instead define a global constant and then changing one value will change everything at once: ```cpp const int MAX_SIZE = 16; -void main() { - string mystring = "lorem ipsum"; - my_func1(mystring, MAX_SIZE); // A function that does something with mystring, but also needs to have additional information - my_func2(mystring, MAX_SIZE) // Another function that does something else with mystring, but it also needs the same additional information -} +string mystring = "lorem ipsum"; +my_func1(mystring, MAX_SIZE); // A function that does something with mystring, but also needs to have additional information +my_func2(mystring, MAX_SIZE) // Another function that does something else with mystring, but it also needs the same additional information ``` -Constants are also a way to optimize your code. If you know that a variable won't change (or shouldn't change), always make it a constant. +Constants are also a way to optimize your code. If you know that a variable won't change (or shouldn't change) after it's initialization, always make it a constant. ```cpp bool function(string s, float i) { const float value = s.length() - i; return i > value; } - ``` + +> ### TASK 2: +> Write a program that initializes a constant variable with the `auto` keyword, and then tries to change it after. Observe the compilation error in the console. + --- ### Integer size reference table -The table below shows the minimum and maximum values for each integer subtype (don't worry as pretty much no programmers remember this table, just remember that it exists): +The table below shows the minimum and maximum values for each integer subtype (don't worry about remembering this, just remember that it exists here): |Type|Short description|Minimum Value|Maximum Value| |---|---|---|---| |int8| Signed, 8 bits |-128 | 127 | diff --git a/docs/angelscript/guide/chapter3.md b/docs/angelscript/guide/chapter3.md index 7c09a4a5..50d0d681 100644 --- a/docs/angelscript/guide/chapter3.md +++ b/docs/angelscript/guide/chapter3.md @@ -1,31 +1,142 @@ --- -title: Chapter 3 - Statements, Functions & Variable Scope +title: Chapter 3 - Statements, Expressions, Conditions & Variable Scope weight: 2 --- -# Chapter 3 - Statements, Functions & Variable Scope +# Chapter 3 - Statements, Expressions, Conditions & Variable Scope + ## What will you learn in this chapter -In this chapter you will learn: -- What are Value Types, -- What is the Variable Scope. +In this chapter you will learn about: +- [Expression statements](#expression-statements), +- [Comparison operators](#comparison-operators), +- [Logic operators](#logic-operators), +- [If/else block](#ifelse-block), +- [Switch statement](#switch-statement), +- [Variable Scope](#variable-scope). + +> Statements, expressons, conditions and the variable scope are the foundation of every program or script. +--- -## Functions +## Basic statements -As you already know or not, functions are a way of implementing routines that operate on an input and produce a result. In Layman's terms, you give it some data, it processes the data and (may, but doesn't need to) give you an output. +Your code is like a recipe, and statements are the individual steps. -A function declaration consists of 3 main parts: *return value*, *function name*, and the *parameters*. -These follow pretty much the same syntax as C++. +Statements are a way to tell the script engine what it needs to do, we already used them in previous chapters, such as the assignment or declaration. +### Expression statements +Any expression can be placed on a line as a statement. Examples of expressions include: +- Function call **()** operator - calls a function (more on functions later), +- Equals **=** operator - performs assignment, +- Add **+** operator - adds two values together, +- Substraction **-** operator - substracts two values from each other, +- Many more, such as **+=**, **-=**, **++**, etc. are available. More about them can be found in the [expression reference table](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html). --- +Such statements need to end with the semicolon (`;`): +```cpp +b = a + b; +func(); +a += b; +``` -## Variable Scope +AngelScript follows a specific instruction of operation order. Function calls are evaluated first bottom to top, then AS sticks to order of operations as specified in the [Operator Precedence](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_operator_precedence.html) reference. -Variable Scope determines which data can be accessed from where. In AngelScript the Variable Scope behaves exactly as the one in C++. +You can force an order of operations by using parenthesis: +```cpp +float a = 1 + 1.0 / 2; // This will return 1,5 +float b = (1 + 1.0) / 2; // This will return 1 +``` + +> [!TIP] +> Order of how operators are evaluated for standard math operators such as **+**, **-**, **\***, **/**, etc. follow the standard Order of Operations. + +> ### TASK 1: +> Given `float a = 4; float b = 5;` Write a program that calculates the number c given by the equation: `c = (a - 2)^2 + (b + 1) / 2`. + + +### Comparison operators +Comparison operators are operators of which expressions evaluate to the `true` or `false` boolean values. An example of a comparsion operator is the equals (**==**) operator, which checks if the two values on boths sides of such operator are equal. Another type of a condition operator is the greater than operator (**>**), which checks if the value on the left side is greater than the value on the right side. For comparison operator reference please check the [expression reference table](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html). +```cpp +int a = 1; +int b = 2; +a == b; // Will return false, but it won't save the value anywhere, treat this as a whole: (a == b) + +b = 1; +bool result = a == b; // Result now stores the information if a and b were equal when it was defined. +``` + +### Logic operators +Logic operators are a way to combine comparison expressions in order to achieve one result: +- NOT - denoted as `!` or the keyword `not`, evaluates to ftrue, if value is false and vice versa, +- AND - denoted as `&&` or the keyword `and`, evaluates to true, if both values are true, +- OR - denoted as `||` or the keyword `or`, evaluates to true, if even one of the values is true, else false if both are false, +- XOR - denoted as `^^` or the keyword `xor`, evaluates to true, if and only if **one** of the values is true. + +```cpp +a && b; // AND +a and b; // AND +a and b || c; // A combination of AND and OR, a and b is going to get evaluated first +a and (b || c); // You can use parenthesis to specify which operator should get evaluated first, here OR will get evaluated first +``` -In general the Variable Scope makes programs use less memory by not holding useless information inside memory, as an example: +--- + +## Conditions +Conditions are a way to tell the engine to execute specific code only if a specific condition is met. For example, only add numbers if they are positive. +They should contain an expression that evalues to true or false, and they can be any sort of valid combination of comparison operators and logic operators, etc. + +### If/else block +The `if`/`if else`/`else` block is used to run specific code only on certain conditions. The `if else` and `else` are not required, but the block must start with an `if` statement. ```cpp +if ( a > 10 ) { // Condition 1 + // Run the code in here +} else if ( a < 10 ) { // Condition 2 + // If we haven't met condition 1, but have met condition 2, execute the code in here +} else if ( condition3 ) { + // We haven't met neither condition 1, nor condition 2, but we have met condition 3 +} else { + // If none of the conditions were met, execute this code +} +``` +> ### TASK 2: +> Given two numerical values *a* and *b* (defined statically in your script) prints out an absolute value of their difference. + + +### Switch statement +The switch statement is a very useful tool for situations where you need to compare to a lot of different cases. It performs the *is equal* operation comparing a value to every value specified in case blocks. It is also much faster than a block of the `if`/`else if`/`else` statements. +```cpp +switch ( value ) { + case 0: + // Do if value == 0 + break; // Required keyword to go out of the switch block + + case 2: + case 3: + // Execute if value == 2 or value == 3 + break; + + default: + // Execute if neither cases were met +} +``` +> [!CAUTION] +> Each case requires a `break` statement after finishing code execution. This is because switch behaves more like the `goto` (C++) functionality, meaning that it doesn't stop executing code after finishing a specific case. The `break` statement will tell the code to go out of the `switch` block. This is also why in the upper example `case 2:` and `case 3:` can be used to both execute the same lines of code. + +> ### TASK 3: +> Given a string as a value (statically defined), write a program that would simulate a command-like behaviour using the switch statement. If the string is equal to: +> - "hello" - print "HelloWorld" to the console +> - "engine" - print "Strata Source" to the console +> - "name" - print "My name is Chell" to the console +> - on any other string - print "Command not recognized!" to the console + + +--- + +## Variable Scope + +Variable Scope determines which data can be accessed from where. In AngelScript the Variable Scope behaves exactly as the one in C++. +In general the Variable Scope makes programs use less memory by not holding expired (not useful anymore) information inside the memory, as an example: +```cpp int number = 10; void my_func1() { @@ -46,4 +157,5 @@ In AS, global variables are allowed, however: > [!NOTE] > From the official documentation: *Variables of primitive types are initialized before variables of non-primitive types. This allows class constructors to access other global variables already with their correct initial value. The exception is if the other global variable also is of a non-primitive type, in which case there is no guarantee which variable is initialized first, which may lead to null-pointer exceptions being thrown during initialization.* -A good practice is to avoid global variables altogether, and use different means of sharing information between functions such as returning values or &out references (more on that in later chapters). \ No newline at end of file +> [!TIP] +> A good practice is to avoid global variables altogether, and use different means of sharing information between functions such as returning values or &out references (more on that in later chapters). \ No newline at end of file diff --git a/docs/angelscript/guide/chapter4.md b/docs/angelscript/guide/chapter4.md new file mode 100644 index 00000000..6392af14 --- /dev/null +++ b/docs/angelscript/guide/chapter4.md @@ -0,0 +1,169 @@ +--- +title: Chapter 4 - Loops +weight: 3 +--- + +# Chapter 4 - Loops + + +## What will you learn in this chapter +In this chapter you will learn about: +- [While, do while loops](#while-do-while), +- [For loop](#for), +- [Foreach](#foreach), +- [Continue/Break keywords](#special-keywords). + +> Loops are a way to make the code repeat itself a certain amount of times, of which the amount of repetitions may vary depending on what is going on in the code. + +--- + +### Arrays - short introduction +> [!NOTE] +> This subsection is supposed to teach you the very basics of arrays, because next you will learn about loops, and loops are mostly useful for array manipulation. +> You won't learn in details what the array is and how to do operations on it, but you will learn how to create one and access its elements. + +An array is an ordered group of elements, of which there is a starting element and an element at the end. + +Code-wise it's a template object, as you need to specify of which data type its values will be. To create an array you can use the **{element, element2, ...}** assignment: +```cpp +array a = {0, 1, 2, 3, 4}; +array b = {true, false, false, true, false}; +array c = {.1, .3, .5}; +``` + +To access elements in an array you use the index operator **[]**, where `[i]` will access the i'th element of the array (counting from 0): +```cpp +a[3] // = 3 +b[1] // = false +b[0] // = .1 +``` + +More on the arrays will be talked about in later parts of this guide. + +## While, do while +The `while (expression)` loop will execute code until the expression evaluates to false: +```cpp +int a = 10; +while (a > 0) { + a--; // Decrement (substract one from a) each time the code executes + // Code in here will stop executing when a will be equal to 0 +} + +other_code(); // This will execute after the loop +``` +The `while` loop will not execute the code (even once) if the condition evaluates to false from the very start. + +A `do while` loop however, will first execute the code inside the loop and only *then* check if the condition is true to execute it once more: +```cpp +int a = 10; +do { + a--; +} while (a > 0); // Note the semicolon +``` + +> [!WARNING] +> It is possible to create a never ending loop, the easiest way is to do `while (true)`. Such loops are most of times an error in programming. However, these loops can be an intentional decision when **you are sure the loop will at some time stop executing**, either with the `break` statement (more on that in a bit) or other ways. + +> ### TASK 1: +> Write a program that will print out "Hello again!" to the console 10 times. + +## For +A `for` loop is an advanced version of the `while` loop. It takes 3 arguments in its statement - `for (statement1; statement2; statement3) {...}`: +- Statement 1 - gets executed before the loop runs (but in the loop's variable scope (variable scopes will be talked about in a bit)), often used to intialiaze a local indexing variable, such as `int i = 0;`. +- Statement 2 - is a condition for the execution of the loop, checked before the loop executes the code inside. +- Statement 3 - is executed after a successful code execution inside the loop (every time). + +An example of a `for` loop can be a loop that cycles through every character in a string: +```cpp +array numbers = {1, 1, 2, 3, 5, 8, 13}; +for (int i = 0; i < numbers.length(); i++) { // For every i until i is greater or equal to the array length (this will ensure i won't go out of bounds) + numbers[i] // Represents the i'th number in the array + // After executing code do i++ (add one to i), so we can access the next element +} +``` + +> [!TIP] +> Statements 1 and 3 in for loops can be skipped, as an example `for (;condition;)` is a valid form of a `for` loop, and so is `for (int a = 0;condition;)` etc. + +> ### TASK 2: +> Given an array of integers, write a program that will add all of these integers and print out the result. +> > [!NOTE] +> > Because of the [Variable Scope](#variable-scope), you will need to define a variable to store the sum outside of the loop. + + + + +## Foreach + +A `foreach` loop can be used to perform code for each item in a container objects. Container objects are objects that store values of other data types, such as the `array` object or the `dictionary` object. Its structure `foreach (vars : container_object)` consists of two parts: where vars contains declarations of the variable names, such as `int val`, and the container object is the, well, container object. Some objects unpack more than one variable, such as the `dictionary` objects that unpacks the key and the appropriate value. + +```cpp +array integers = {1, 2, 3, 4}; +foreach (int i : integers) { + // Code here, where i will cycle through every value in integers +} + +dictionary mydict = { + {"key1", value1}, + {"key2", value2}, + {"key3", value3} +}; +foreach (auto value, auto key : mydict) {// NOTE: the order is flipped here, as compared to e.g. foreach in Squirrel (VScript), value goes first + // Loop through mydict +} + +foreach (auto value : mydict) {...} // It is also possible to just loop over one of the elements to unpack +``` + +> ### TASK 3: +> Write a program that will print out every element of a given array. + + +## Special keywords + +These are the special keywords that can be used inside loops. + +### Break statement +The `break` statement is a way to exit a loop execution early. Calling it will cause the program to abort loop execution and continue executing code after the loop. + +```cpp +int a = 10; +while (a > 0) { + if (a == 5) { + break; + } +} +// This loop will stop executing when a will be equal to 5 +``` + +### Continue statement +The `continue` statement will cause the loop to stop and go to the next element. + +```cpp +int sum = 0; +for(int i = 0; i < 10; i++) { + + if (i == 4) { // If i is equal to 4, we are skipping it + continue; + } + + // This code will not execute for i = 4 + sum += i; +} +``` + +### Nested loops and special keywords +Keywords like `break` and `continue` work on the bottom-most loop in nested code, meaning that if you have code like this: +```cpp +while (condition) { + for (int a = 5; a < 10; a++) { + + if (a > 5) { + break; // This will break of the for loop, not the while loop! + } + } +} +``` + +> ### TASK 4: +> Create a **while (true)** loop that adds all integers until 20. diff --git a/docs/angelscript/guide/chapter5.md b/docs/angelscript/guide/chapter5.md new file mode 100644 index 00000000..cc504c09 --- /dev/null +++ b/docs/angelscript/guide/chapter5.md @@ -0,0 +1,13 @@ +--- +title: Chapter 5 - Functions +weight: 4 +--- + + + +## Functions + +As you already know or not, functions are a way of implementing routines that operate on an input and produce a result. In Layman's terms, you give it some data, it processes the data and (may, but doesn't need to) give you an output. + +A function declaration consists of 3 main parts: *return value*, *function name*, and the *parameters*. +These follow pretty much the same syntax as C++. diff --git a/docs/angelscript/guide/chapterX-1.md b/docs/angelscript/guide/chapterX-1.md new file mode 100644 index 00000000..dbb1cd7c --- /dev/null +++ b/docs/angelscript/guide/chapterX-1.md @@ -0,0 +1,27 @@ +--- +title: Chapter X - Reference Types +weight: 4 +--- + + +# Chapter X - Reference types + +### Declaring template objects +Sometimes objects are described with a template, such as the `array` object. Because the `array` class is supposed to be versatile, it can support different types of data for it's values; you can have an array of integers, an array of floats, an array of strings, etc. There is no need to re-create the array class for each and every available data type, as this is where the template functionality is used for. + +When declaring an array you need to specify the data type of its values, like so: +```cpp +array string_array = {"string1", "string2", "string3"}; // Create an array of strings +array myArray = {1, 2, 3, 4}; // Create an array of integers +``` + +Functions can be templates too, an example of such function can be the cast function, which converts one data type to another (if possible) (more on the cast function later): +```cpp +obj1 myobj1; +obj2 myobj2; +@myobj1 = cast(@myobj2); // Cast function will convert obj2 into obj1 +``` + +> [!NOTE] +> It is currently not possible to create your own custom template objects, although this functionality is planned for future releases of AngelScript. + diff --git a/docs/angelscript/guide/chapterX.md b/docs/angelscript/guide/chapterX.md index 53cc9447..97041445 100644 --- a/docs/angelscript/guide/chapterX.md +++ b/docs/angelscript/guide/chapterX.md @@ -1,9 +1,9 @@ --- -title: Chapter X - Object Handles & Reference Types +title: Chapter X - Object Handles weight: 5 --- -# Chapter X - Object Handles & Reference Types +# Chapter X - Object Handles ## What will you learn in this chapter In this chapter you will learn: From 99f4fc9f58fb7e60f1f8ada5c09af3a3f68abd96 Mon Sep 17 00:00:00 2001 From: Enderek Date: Sun, 4 Jan 2026 18:46:57 +0100 Subject: [PATCH 07/23] change: chapter 4 update --- docs/angelscript/guide/chapter4.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/angelscript/guide/chapter4.md b/docs/angelscript/guide/chapter4.md index 6392af14..424f016e 100644 --- a/docs/angelscript/guide/chapter4.md +++ b/docs/angelscript/guide/chapter4.md @@ -69,7 +69,7 @@ do { ## For A `for` loop is an advanced version of the `while` loop. It takes 3 arguments in its statement - `for (statement1; statement2; statement3) {...}`: -- Statement 1 - gets executed before the loop runs (but in the loop's variable scope (variable scopes will be talked about in a bit)), often used to intialiaze a local indexing variable, such as `int i = 0;`. +- Statement 1 - gets executed before the loop runs (but in the loop's variable scope), often used to intialiaze a local indexing variable, such as `int i = 0;`. - Statement 2 - is a condition for the execution of the loop, checked before the loop executes the code inside. - Statement 3 - is executed after a successful code execution inside the loop (every time). @@ -88,7 +88,7 @@ for (int i = 0; i < numbers.length(); i++) { // For every i until i is greater o > ### TASK 2: > Given an array of integers, write a program that will add all of these integers and print out the result. > > [!NOTE] -> > Because of the [Variable Scope](#variable-scope), you will need to define a variable to store the sum outside of the loop. +> > Because of the [Variable Scope](chapter3/#variable-scope), you will need to define a variable to store the sum outside of the loop. From 1c5a3df749607485420701f4d6d82b7b8d544f61 Mon Sep 17 00:00:00 2001 From: Enderek Date: Mon, 5 Jan 2026 15:13:41 +0100 Subject: [PATCH 08/23] change: Update docs about using C-style like notation for logic operators --- docs/angelscript/guide/chapter3.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/angelscript/guide/chapter3.md b/docs/angelscript/guide/chapter3.md index 50d0d681..173e4cb1 100644 --- a/docs/angelscript/guide/chapter3.md +++ b/docs/angelscript/guide/chapter3.md @@ -66,17 +66,19 @@ bool result = a == b; // Result now stores the information if a and b were equal ### Logic operators Logic operators are a way to combine comparison expressions in order to achieve one result: -- NOT - denoted as `!` or the keyword `not`, evaluates to ftrue, if value is false and vice versa, -- AND - denoted as `&&` or the keyword `and`, evaluates to true, if both values are true, -- OR - denoted as `||` or the keyword `or`, evaluates to true, if even one of the values is true, else false if both are false, -- XOR - denoted as `^^` or the keyword `xor`, evaluates to true, if and only if **one** of the values is true. +- NOT - denoted as `!`, evaluates to true, if value is false and vice versa, +- AND - denoted as `&&`, evaluates to true, if both values are true, +- OR - denoted as `||`, evaluates to true, if even one of the values is true, else false if both are false, +- XOR - denoted as `^^`, evaluates to true, if and only if **one** of the values is true. ```cpp a && b; // AND -a and b; // AND -a and b || c; // A combination of AND and OR, a and b is going to get evaluated first -a and (b || c); // You can use parenthesis to specify which operator should get evaluated first, here OR will get evaluated first +a && b || c; // A combination of AND and OR, a AND b is going to get evaluated first +a && (b || c); // You can use parenthesis to specify which operator should get evaluated first, here OR will get evaluated first ``` +> [!NOTE] +> Although AngelScript supports Python-like logic operator notation (and, or, ...) it is recommended to stick to the C-like notation. This is mainly because AS is much more similar to C in it's syntax, and also not every extension adding AS support for your IDE has support for the Python-like notation. + --- From b054ab4e2fa4800ed7be07ca884d5f8ceabe7fc1 Mon Sep 17 00:00:00 2001 From: Enderek Date: Mon, 5 Jan 2026 15:14:38 +0100 Subject: [PATCH 09/23] change: Change "if else" to "else if" --- docs/angelscript/guide/chapter3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/angelscript/guide/chapter3.md b/docs/angelscript/guide/chapter3.md index 173e4cb1..9d8e12d0 100644 --- a/docs/angelscript/guide/chapter3.md +++ b/docs/angelscript/guide/chapter3.md @@ -87,7 +87,7 @@ Conditions are a way to tell the engine to execute specific code only if a speci They should contain an expression that evalues to true or false, and they can be any sort of valid combination of comparison operators and logic operators, etc. ### If/else block -The `if`/`if else`/`else` block is used to run specific code only on certain conditions. The `if else` and `else` are not required, but the block must start with an `if` statement. +The `if`/`else if`/`else` block is used to run specific code only on certain conditions. The `else if` and `else` are not required, but the block must start with an `if` statement. ```cpp if ( a > 10 ) { // Condition 1 // Run the code in here From 07c0c11bec3f34bc183acbf7ee1f69bc54c187e2 Mon Sep 17 00:00:00 2001 From: Enderek Date: Tue, 6 Jan 2026 16:46:39 +0100 Subject: [PATCH 10/23] change: Initialize arrays as object handles --- docs/angelscript/guide/chapter4.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/angelscript/guide/chapter4.md b/docs/angelscript/guide/chapter4.md index 424f016e..cdcaa5cd 100644 --- a/docs/angelscript/guide/chapter4.md +++ b/docs/angelscript/guide/chapter4.md @@ -26,11 +26,14 @@ An array is an ordered group of elements, of which there is a starting element a Code-wise it's a template object, as you need to specify of which data type its values will be. To create an array you can use the **{element, element2, ...}** assignment: ```cpp -array a = {0, 1, 2, 3, 4}; -array b = {true, false, false, true, false}; -array c = {.1, .3, .5}; +array@ a = {0, 1, 2, 3, 4}; +array@ b = {true, false, false, true, false}; +array@ c = {.1, .3, .5}; ``` +> [!NOTE] +> Since `array` and `dictionary` are reference types, you initialize them as an object handles (the @ symbol). For now, just remember that you add that symbol after the type name, it will get explained later on. + To access elements in an array you use the index operator **[]**, where `[i]` will access the i'th element of the array (counting from 0): ```cpp a[3] // = 3 @@ -75,7 +78,7 @@ A `for` loop is an advanced version of the `while` loop. It takes 3 arguments in An example of a `for` loop can be a loop that cycles through every character in a string: ```cpp -array numbers = {1, 1, 2, 3, 5, 8, 13}; +array@ numbers = {1, 1, 2, 3, 5, 8, 13}; for (int i = 0; i < numbers.length(); i++) { // For every i until i is greater or equal to the array length (this will ensure i won't go out of bounds) numbers[i] // Represents the i'th number in the array // After executing code do i++ (add one to i), so we can access the next element @@ -98,12 +101,12 @@ for (int i = 0; i < numbers.length(); i++) { // For every i until i is greater o A `foreach` loop can be used to perform code for each item in a container objects. Container objects are objects that store values of other data types, such as the `array` object or the `dictionary` object. Its structure `foreach (vars : container_object)` consists of two parts: where vars contains declarations of the variable names, such as `int val`, and the container object is the, well, container object. Some objects unpack more than one variable, such as the `dictionary` objects that unpacks the key and the appropriate value. ```cpp -array integers = {1, 2, 3, 4}; +array@ integers = {1, 2, 3, 4}; foreach (int i : integers) { // Code here, where i will cycle through every value in integers } -dictionary mydict = { +dictionary@ mydict = { {"key1", value1}, {"key2", value2}, {"key3", value3} From 48ec859081369a0c4f3cce46c1963f6b03368825 Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 10 Jan 2026 14:27:07 +0100 Subject: [PATCH 11/23] change: misc change to chapter4 - add a line break after the array introduction --- docs/angelscript/guide/chapter4.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/angelscript/guide/chapter4.md b/docs/angelscript/guide/chapter4.md index cdcaa5cd..0e889f06 100644 --- a/docs/angelscript/guide/chapter4.md +++ b/docs/angelscript/guide/chapter4.md @@ -43,6 +43,8 @@ b[0] // = .1 More on the arrays will be talked about in later parts of this guide. +--- + ## While, do while The `while (expression)` loop will execute code until the expression evaluates to false: ```cpp From 08f5e1903b747e64bfe31e11ed1a5a8203287d2c Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 10 Jan 2026 14:27:19 +0100 Subject: [PATCH 12/23] add: Chapter 5 - functions complete --- docs/angelscript/guide/chapter5.md | 343 ++++++++++++++++++++++++++++- 1 file changed, 341 insertions(+), 2 deletions(-) diff --git a/docs/angelscript/guide/chapter5.md b/docs/angelscript/guide/chapter5.md index cc504c09..57d6d327 100644 --- a/docs/angelscript/guide/chapter5.md +++ b/docs/angelscript/guide/chapter5.md @@ -3,11 +3,350 @@ title: Chapter 5 - Functions weight: 4 --- +# Chapter 5 - Functions +## What will you learn in this chapter +In this chapter you will learn about: +- [Declaring functions and calling functions](#syntax), +- [Calling methods on built-in objects](#calling-methods-on-objects), +- [Default parameters](#default-parameters), +- [References and passing variables by reference to functions (`&in`/`&out`)](#references---short-intro), +- [Returning references and when it can be done](#returning-references), +- [Function overloads](#function-overloads). -## Functions +> Functions are a way to split up the code into re-usable parts. + +--- + +## Functions - Basics + +### Syntax As you already know or not, functions are a way of implementing routines that operate on an input and produce a result. In Layman's terms, you give it some data, it processes the data and (may, but doesn't need to) give you an output. A function declaration consists of 3 main parts: *return value*, *function name*, and the *parameters*. -These follow pretty much the same syntax as C++. +These follow pretty much the same syntax as C++: + +```cpp +// return_value func_name(parameters), +// examples: + +int myCoolFunction() { // This function returns an integer + ... + return integer_variable; +} + +void myFunction() { + ... + // No return statement + + // or return statement without a value (useful if you want to return early) + return; +} + +bool myFunction(int a, int b) { + ... + return bool_variable; +} +``` + +Each function **must** have a return statement in each of its "paths". What that basically means, is that whatever you do in your function, it will always end with a return statement. The only exception is the `void` return type (which means return nothing), in which you can skip the `return` keyword entirely, or use the `return;` statement when you want to exit the function early. + + +### Calling functions + +Calling functions in code is very simple, you use the **function call `()`** operator, `func(arguments)`. In it, you include every needed argument: + +> [!NOTE] +> ""Variables"" in a function declaration are called **parameters**, while ""variables"" in a function call are called **arguments**. + +```cpp +int sum(int a, int b) { // a, b are parameters + return a + b; +} + +int just5() { + return 5; +} + +int a = sum(1, 2); // 1, 2 are arguments + +a = sum(a, just5()); // just5 will get evaluated first, then its result will get passed to sum +// a = 5 +``` + +Calling a function is a statement, which means it can be freely used in expressions in every combination. You can treat `func(p)` as a value that you do operations with. + +### Calling methods on objects +Some objects such as `string` or `array` implement methods. For now, you can think of methods as functions that sit inside the object (variable), and operate on that object. You can invoke them by using the `.` operator and then the function call. +```cpp +string mystr = "ABC"; + +mystr.length(); // Returns the length of this string (3) +``` + +For a list of available methods per each type please refer to the [types section](../game/type) of this wiki. +> [!NOTE] +> Primitive types (`int`, `float`, `bool`, etc.) don't implement any methods. + +### Recursiveness + +Like in any other language, a function can call itself. This is function is then called a *recursive* function. + +--- + +## Parameters + +Function parameters in AngelScript can be a bit confusing, since AS has custom keywords and custom behaviors for different types of parameters. + +### Default parameters +Sometimes you want to add additional functionality to your function, but for most cases you already know what it should do, although you still want to include a customizable option for fine-tuning. You can do that by default parameters. + +Each parameter can have a default value assigned to it, like so: +```cpp +void myFunc(int a = 5, int b = 1) {...} +``` + +This function can be called with *0*, *1*, and *2* arguments, and each call will be valid. +Calling it with 0 arguments will mean that `a` will be set to `5`, and `b` to `1`. Calling it with one argument will set a to that arguments value and so on. +```cpp +myFunc(); // a = 5, b = 1 +myFunc(2); // a = 2, b = 1 +myFunc(2, 5); // a = 2, b = 5 +``` + +> [!NOTE] +> It is currently not possible to explicitly set each parameter to a specific argument. In Python for example, doing `myFunc(b=2)` is allowed and will set `b` equal to `2`, however this is not the case in AngelScript. +> > [!TIP] +> > You can use [function overloads](#function-overloads) to overcome this issue. + +### Constant parameters + +Constant parameters work just like constant variables. If declare a certain parameter constant, you won't be able to change it in any way. +```cpp +void myFunc(const int a, const bool y = true) // Default parameters can also be constants +``` + +One important note is that declaring a const parameter will make the compiler not copy the object (if it ensures the object's lifetime). More on that will be in the next chapters. + +> ### TASK 1: +> Create a function that computes the nth number of the fibonnaci sequence. It should take uint as the parameter (n) and return an uint (the number). You can tackle this problem recursively (using recursion) or iteratively (using a loop). It is recommend to try out both. + +### References - short intro +Before we delve into the next subchapter, you need to know what *references* are. In each computer, variables are stored in memory. You can visualize computers memory as a some sort of a box with labels. Each label has some space that it describes, and there can be an item in each label. Such items are our variables, and these labels are memory addresses. In such way, the computer knows where to look for these variables when it needs to find them. + +References are just the labels we have been comparing to, they *are* the address of the variable they correspond to. + +They are denoted with the **&** symbol. Conceptually: +```cpp +string mystring = "lorem ipsum"; +&mystring // Memory address of mystring +``` + +In angelscript you cannot directly manipulate references, but you can do many useful things when you combine functions and references. The AngelScript compiler will automatically manage referencing (getting a variables adress) and dereferencing (looking up a variable from an adress). + +### Reference parameters +Functions can be set to use references as parameters. + +In the examples shown above every argument was **copied**. Here's a better example: +```cpp +void func(int c) {...} + +int a = 1; +func(a); +``` +In this example, before `c` gets assigned a value from `a`, the value of `a` gets copied first, and only after the assignment occurs. This happens, so that doing any operations on `c` in `func` will not cause `a` outside the function to change in any way. + +However, passing by reference changes that mechanism. Since now, the thing that gets copied is the memory address, not the actual variable value. Meaning that if we were to pass by reference in `func` above, doing any operation such as `c = 5;` would cause `a` to change accordingly (a = 5). + +Telling the compiler that you want to pass by reference gets done in the function parameters declaration, like so: +```cpp +void func(int c&) // This is a pass by reference +``` + +No special syntax for calling is needed: +```cpp +int a = 1; +func(a); // a gets passed by reference +``` + +AngelScript implements more functionality to passing by reference, and that includes 2 options: + +#### &in +This marks the parameter as an input to the function. This option provides little to no benefit as to just passing by value (copying), as the compiler still has to ensure the object won't get modified outside the function, and the only way to do that is to make a copy. + +> [!TIP] +> Combining `&in` with `const` can however, yield a way more optimized code. `&in` should almost always be used whenever you are using a `const` parameter. + + + +#### &out +This option specifies that this parameter is an output of a function. This is especially useful whenever you have functions that need to have multiple output values. At the start of a function's execution, this reference will point to an uninitialized variable. After the function returns, the value assigned to this variable will be copied over to the appropriate argument. + +Example usage of passing by reference of all 3 options: +```cpp + +int myFunc(string& a) {...} // Is the same as +int myFunc(string&inout a) {...} + +// Example of &in usage +void PrintMessage(const string&in msg) { // This will make the compiler try to not copy the argument when calling the function, as we are not modifying it in any way. + Msg(msg + "\n"); // Convenience function that prints the message with \n appended +} + +// Example usage of &out +bool WholeDivision(int a, int b, int&out result, int&out rest) { + // Calculates the whole part of a/b and the rest + // Returns true if the operation can be done. + if (b == 0) { + return false; // We cannot divide by zero + } + + result = a / b; + rest = a % b; + + return true; +} + + +int myresult, myrest; +WholeDivision(10, 3, myresult, myrest); //This will set myresult and myrest to the appropriate (3 and 1 respecitvely). +``` + +> [!NOTE] +> AngelScript also supports a 3rd mode, `&inout` or `&`, but this is only allowed for reference types (more on that later), and additionally, Strata Source is configured to only pass reference types by reference (pass by value is disabled), which means that there is no need to specify pass by reference for these types anyway. + + +--- + +## Returning references + +Functions can also *return* references. Meaning that they return an address to an object, rather than the object itself. In previous examples we have discussed functions that return by value, meaning that the value of the variable that gets returned, gets copied to a temporary location and then gets "transfered" over to the variable outside the function: +```cpp +int func(int a) { + return a * 2; +} + +int b; +b = func(2); // Result of func(2) gets stored in a temporary location and then copied over to b. + +func(2) = 1; // This will not work. +``` + +Returning references works in a different way, we return an address, that means the actual value of the variable never gets copied which saves on performance. Additionally, it allows you to do operations on the return value of a function. To declare a function that returns a reference, you append the `&` symbol at the end of the type name in the return type. + +Before we overview examples, there is one more thing to discuss about returning references. Not every variable can get it's reference returned. In general, variables that don't exist outside the function will not be able to get returned by reference, because they will get erased once the code gets out of the function. + +#### 1. References to global variables are allowed. +Returning references to global variables is allowed, because the variable won't get destroyed outside the function. Example: +```cpp +int a = 1; + +int& addToA(int b) { + a + b; + return a; // Like in reference parameters, no additional syntax is needed. +} + +//This will allow us to do something like: +addToA(1) = 3; // We add 1 to a, but then we change a to be equal to 3. +``` + +#### 2. References to class members and `this` are allowed. +> [!NOTE] +> This information will be useful once we get to custom classes and reference types, so if you don't know what these are you can skip this for now. + +References to class members (properties) and to ourselves (`this`) are allowed to be returned by methods. + +```cpp +class myclass { + int myvar; + + int& GetMyVarRef() { + return this.myvar; + } + + myclass& GetMe() { // Note: this will automatically translate to myclass@& (reference to the handle of myclass) + return this; + } +} +``` + +#### 3. Returning a reference to a local variable is not allowed. +Returning a reference to a local variable is not allowed, this is because the variable will not exist after the function returns. +```cpp +int& myFunc() { + int a = 1; + return a; // a will not exist outside of myFunc, this is not allowed +} +``` + +#### 4. Returning a reference to a deferred parameter is not allowed. +Values passed by reference into a function cannot be returned by reference. This is because AS does additional cleanup after the function returns, hence why there is no guarantee that an object passed by `&in`/`&out` will exist after the function returns. + +```cpp +int& func(int a&in ) { + return a; // This is not allowed +} +``` + +> ### TASK 2: +> Create a function that splits a string into two same-length parts. It should take a string and return a boolean if the string can be split (if the strings length is not divisible by two you cannot create two equal-length parts), and it should also return these two parts (use `&out`). + +--- + +## Function overloads +Function overloading is a very powerful concept, as it allows you to declare a function multiple times, each time with a different set of parameters. The compiler will then attempt to choose the best "fit" for which exact function to call (the criteria of how it does so are available on the [official documentation](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script_func_overload.html)). + +This is mainly used for functions that can accept multiple combinations and types of parameters, but produce a similar result. +```cpp +void myFunc(int a) {...} +void myFunc(string a) {...} + +myFunc(10); // Will call the first option +myFunc("a"); // Will call the second option +myFunc(10.5); // Will call the first option (but float will get converted to int) +myFunc(false); // Will cause an error since none of the options specify bool as a parameter +``` + +Default parameters are also allowed to be used in overloading, but you have to be careful whilst doing so. If you define your function wrong, the compiler will not be able to decide whether it should use an overload or use a default parameter. + +```cpp +void myFunc(int a, int b = 2) {...} +void myFunc(int a) {...} + +myFunc(1, 3); // Will work, since there is only one option. +myFunc(1); // Will not work, since the compiler doesn't know which option to choose (should it use the first and set the default parameter or should it use the second?) + +void myFunc(string a) {...} +void myFunc(int a, string c = "C") {...} // Same goes for different types of default parameters + +myFunc("A"); // Will work, there is only one option +myFunc(1); // Now there are 3 options to choose from and none are more important +myFunc(1, "A"); // Will work +``` + +> [!WARNING] +> Different return types are allowed for overloads, e.g. one function can return an int, whilst other can return a string (the auto keyword is useful here); however the compiler will not take the return type as a criteria for deciding which overload to use. + +> ### TASK 3: +> In the default parameters section there was a problem mentioned about how you cannot explicitly set custom parameters. Given a function: +> ```cpp +> int printXTimes(string msg, string end = "\n", int x = 1) { +> for (int i = 0; i < x; i++) { +> Msg(msg + end); +> } +> } +> ``` +> Find a way to use it to print 10 times the message "CONSOLE SPAM!" **without specifying a value for the `end` parameter!** +> > [!TIP] +> > You can call an overload to a different function in an overloaded function: +> > ```cpp +> > void myFunc(int a) {...} +> > +> > void myFunc(int a, int b) { +> > myFunc(a); +> > } +> > ``` + +> [!NOTE] +> If you completed the task above, congratulations! This was one of the harder tasks. However, please note that this way of solving that problem is only viable when your default parameters have different types, because if they don't, the overload will not work. \ No newline at end of file From 3e96421d5f70a8ceb590f3cd316e699072fbb0c3 Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 10 Jan 2026 16:35:04 +0100 Subject: [PATCH 13/23] fix: typos in chapter 5 --- docs/angelscript/guide/chapter5.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/angelscript/guide/chapter5.md b/docs/angelscript/guide/chapter5.md index 57d6d327..7db1bdf2 100644 --- a/docs/angelscript/guide/chapter5.md +++ b/docs/angelscript/guide/chapter5.md @@ -155,13 +155,13 @@ void func(int c) {...} int a = 1; func(a); ``` -In this example, before `c` gets assigned a value from `a`, the value of `a` gets copied first, and only after the assignment occurs. This happens, so that doing any operations on `c` in `func` will not cause `a` outside the function to change in any way. +In this example, before `c` gets assigned a value from `a`, the value of `a` gets copied first, and only after that the assignment occurs. This happens, so that doing any operations on `c` in `func` will not cause `a` outside the function to change in any way. However, passing by reference changes that mechanism. Since now, the thing that gets copied is the memory address, not the actual variable value. Meaning that if we were to pass by reference in `func` above, doing any operation such as `c = 5;` would cause `a` to change accordingly (a = 5). Telling the compiler that you want to pass by reference gets done in the function parameters declaration, like so: ```cpp -void func(int c&) // This is a pass by reference +void func(int& c) // This is a pass by reference ``` No special syntax for calling is needed: From 39edea4f803df295c8a1e6e4a3b956a614a8bdef Mon Sep 17 00:00:00 2001 From: Enderek Date: Sat, 10 Jan 2026 16:36:13 +0100 Subject: [PATCH 14/23] change: Remove usage example of &inout from chapter 5 --- docs/angelscript/guide/chapter5.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/angelscript/guide/chapter5.md b/docs/angelscript/guide/chapter5.md index 7db1bdf2..1f334df4 100644 --- a/docs/angelscript/guide/chapter5.md +++ b/docs/angelscript/guide/chapter5.md @@ -185,10 +185,6 @@ This option specifies that this parameter is an output of a function. This is es Example usage of passing by reference of all 3 options: ```cpp - -int myFunc(string& a) {...} // Is the same as -int myFunc(string&inout a) {...} - // Example of &in usage void PrintMessage(const string&in msg) { // This will make the compiler try to not copy the argument when calling the function, as we are not modifying it in any way. Msg(msg + "\n"); // Convenience function that prints the message with \n appended From e743d9a0d76bf9654a3229b6987f846a82655779 Mon Sep 17 00:00:00 2001 From: Ashleyanna Rivers <73501856+d0ctorzer0@users.noreply.github.com> Date: Thu, 2 Apr 2026 02:33:25 -0600 Subject: [PATCH 15/23] Rephrasing and grammar changes (#157) * Rephrasing and grammar changes Changed a few misspellings and edited the grammar to make the flow more natural. * Broken link fixed Fixed the broken link. Also edited one more sentence to align with the rest of the doc. * Most requested changes added --- docs/angelscript/guide/chapter1.md | 77 +++++++++++++++--------------- docs/angelscript/guide/meta.json | 2 +- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/docs/angelscript/guide/chapter1.md b/docs/angelscript/guide/chapter1.md index 8d4d1480..0831bdc1 100644 --- a/docs/angelscript/guide/chapter1.md +++ b/docs/angelscript/guide/chapter1.md @@ -5,69 +5,70 @@ weight: 0 # Chapter 1 - Introduction -## What will you learn in this chapter +## What You Will Learn In this chapter you will learn about: -- [AngelScript as a programming language](#angelscript), -- [Purpose of AngelScript in Strata Source](#what-can-you-do-with-angelscript), -- [Client - Server model of the engine](#client---server-model), -- [How to load code in the game](#loading-code), -- [Writing your own Hello World program](#your-first-script), +- [AngelScript as a programming language](#angelscript) +- [Purpose of AngelScript in Strata Source](#what-can-you-do-with-angelscript) +- [Client-Server model of the engine](#client---server-model) +- [How to load code in the game](#loading-code) +- [Writing your own Hello World program](#your-first-script) - [Testing out your own code](#how-to-test-out-your-code-in-a-basic-way) -- [Additional tips that might help you](#additional-tips). +- [Additional tips that might help you](#additional-tips) > [!TIP] -> In each chapter, you can easily navigate the page by clicking links in the "What will you learn in this chapter" section. +> In each chapter, you can easily navigate the page by clicking the links in the "What You Will Learn" section. > [!CAUTION] -> This guide assumes you have basic skills of programming in languages like Python, C/C++, Squirrel (VScript), etc. -> It is recommended you already have *some* experience in programming, although this guide aims to be as begineer's friendly as possible. +> This guide assumes you have basic programming skills in languages such as Python, C, C++, Squirrel (VScript), etc. +> It is recommended you already have *some* experience in programming, although this guide aims to be as beginner-friendly as possible. > Basic concepts will **not** be taught. > [!NOTE] -> It is recommended that while reading this guide, you will try out the things you have learned. This guide will include example tasks for you to do as a practice. +> It is recommended to try out what you learn in this guide as you go through it. This guide will include example tasks for you to attempt as practice. --- ## AngelScript -The [AngelScript's home page](https://www.angelcode.com/angelscript/) describes AngelScript as: +[AngelScript's home page](https://www.angelcode.com/angelscript/) describes AngelScript as: > The AngelCode Scripting Library, or AngelScript as it is also known, is an extremely flexible cross-platform scripting library designed to allow applications to extend their functionality through external scripts. -Besides that, you can treat AngelScript as some sort of hybrid between C++ and Python. In some areas it behaves like C++, for example it is statically typed, meaning that when you are declaring a variable you also have to declare it's types, and it also implements it's own version of pointers (called handles); it also aims to help out users in writing code, whether by dissallowing certain operations or by assuming. More on that will be explained in later parts of the guide. +Besides that, AngelScript commonly behaves like C++ - for example, when it is statically typed. Just as in C++, when you declare a variable in AngelScript, you also must declare its types. In addition, AngelScript also implements its own version of pointers (called handles). It also aims to help users in writing its code, whether by disallowing certain operations or by assuming. More on that will be explained in later parts of the guide. -Its use cases vary, it is much closer to pure engine code than VScript, meaning that you can for example program in custom entities, or custom commands. +Use cases for AngelScript vary heavily. It is much closer to pure engine code than VScript, meaning that you can achieve outputs not possible in VScript, such as programming in custom entities and custom commands. -Its official documentation can be found here: [AS Official Docs](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html). +AngelScript's official documentation can be found here: [AS Official Docs](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html). -## What can you do with AngelScript -This question is not properly asked, because AngelScript will allow you to do mostly anything you want, however it's main task in Strata Source is to allow users to create custom entities, create custom commands, bind to in-game events, and more. +## What Can You Do With AngelScript +ngelScript allows for a closer connection to the internal engine code by having the engine provide various APIs to its internal classes. This allows you to do various things, such as creating custom entities, creating your own ConCommands and ConVars, making custom weapons - all things that aren't normally easy to do with VScript. -While VScript (mainly) sits between entities and handles the interactions between them, AngelScripts sits in a level above, where AS can be treated as entities *themselves*. +While VScript (mainly) sits between entities and handles the interactions between them, AngelScripts sits in a level above, being able to *create* entities and define their behavior. --- ## AngelScript in Strata Source -### Client - Server model -Before we get into writing your first script, there is one more thing you need to know. Most engines including Source in general, operate on the client-server model. Meaning that client code is separate from the server code, even on singleplayer. When you start a map in singleplayer you essentially create a one-player server that runs beside the client. This is very important because AS code can be loaded on both. Some functionality will only be available on the server (like entities) and some functionality will only be available on the client (like Panorama/UI). +### Client - Server Model +Before you write your first script, there is one more thing you need to know. Most engines, including the Source engine, operate on the client-server model. This means that client code is separate from the server code, even in singleplayer. When starting a map in singleplayer, you essentially create a one-player server that runs beside the client. This is very important to remember as AS code can be loaded on both. Some functionality will only be available on the server (such as entities) and some functionality will only be available on the client (such as Panorama/UI). -### Loading code -Your first question might be: Where do I place the files containing my code? -The answer is pretty simple, each file that contains your code should be ended with the **.as** extension and be placed in the **code/** folder of a respective `Game` searchpath. Example locations would be `p2ce/custom/my-addon/code/` or just `p2ce/code/` (the latter not being recommended). +### Loading Code +Where should you place the files containing your code? +Each file that contains your code should end with the **.as** extension and be placed in the **code/** folder of your respective `Game` searchpath. Example locations would be `p2ce/custom/my-addon/code/` or just `p2ce/code/` (the latter is not recommended). +Code can also be placed inside the `code` folder of an addon created with the SDK Launcher. -You can name your files however you'd like. You can create custom directories, you can loosely place files, it all depends on what you're trying to achieve; in the long run it doesn't matter. What does matter are the "starting points" of sorts. The engine will not attempt to load any files besides 3 files placed **directly** in the **code/** folder: +You may name your files however you'd like. You can create custom directories or you can place your files loosely - it all depends on what you're trying to achieve. In the long run, it's not important. What *is* important is where you place the "starting points". The engine will not attempt to load any files except for these 3 files placed **directly** in the **code/** folder: 1. `init.as` - Will get loaded by server and client. 2. `sv_init.as` - Will only get loaded by the server. 3. `cl_init.as` - Will only get loaded by the client. -### IDE and testing environment -It is suggested to use Visual Studio Code with the [AngelScript Language Server (sashi0034.angel-lsp)](https://marketplace.visualstudio.com/items?itemName=sashi0034.angel-lsp) extension. From there you can open the `code/` folder of your choice as a project and develop there. +### IDE and Testing Environment +It is suggested to use Visual Studio Code with the [AngelScript Language Server (sashi0034.angel-lsp)](https://marketplace.visualstudio.com/items?itemName=sashi0034.angel-lsp) extension. From there, you can open the `code/` folder of your choice as a project and begin development. The engine compiles scripts on every map load (you can use the `reload` command to recompile the scripts). -### Your first script -Now, you should be ready to write your very first and own program that will print a Hello World message to the console. You might not know everything in the code below but don't get dissappointed! You should place this code into `cl_init.as` as it is a client command. +### Your First Script +You should now be ready to begin writing your very first program. For now, let's just print a Hello World message to the console. Though the code below may look foreign for now, don't be dissuaded! Place this code into `cl_init.as` as it is a client command. ```cpp [ClientCommand("HelloWorld", "")] @@ -76,13 +77,13 @@ void MyCommand(const CommandArgs@ args) { } ``` -Now, the only thing left is to launch up the game, open the console and execute the *HelloWorld* command. +Now, the only thing left to do now is launch the game, open the console, and execute the *HelloWorld* command. > ### TASK 1: > Run the HelloWorld program mentioned above. -## How to test out your code in a basic way -For now you need to know how to run your code so that you will be able to solve tasks given to you with this guide. +## How To Test Out Your Code in a Basic Way +For now, you will need to know how to run your code so that you can complete the tasks given to you within this guide. In `sv_init.as` include: ```cpp [ServerCommand("CodeTest", "")] @@ -92,19 +93,19 @@ void CodeTest(const Command@ args) { ``` The code in this function will run whenever you run the `CodeTest` command in game. Remember to `reload` to see the changes! -The `Msg(string)` function will serve you as a way to view your variables (like print or cout), just do `Msg(a)` where a is your variable and a will get printed to the console! -Remember to add `"\n"` to the input of Msg (or just call `Msg("\n");` after your message), otherwise everything will print in one line! +The `Msg(string)` function will serve as a way to view your variables (like print or cout). Just type `Msg(a)` where *a* is your variable, and *a* will be printed to the console. +Remember to add `"\n"` to the input of Msg (or just call `Msg("\n");` after your message), otherwise everything will print in one line. To avoid having to do this, you can use the `Msgl(string)` which will automatically append an `"\n"` to the end of each message. > [!BUG] -> Some types such as `int` cannot be directly converted to string, and so you won't be able to put them directly into Msg(). +> Some types such as `int` cannot be directly converted to string, and as such, you won't be able to put them directly into Msg(). > > [!TIP] -> > In order to avoid that problem you can append to an empty string, just do `"" + a` and in most cases this will work: `Msg("" + a);` +> > In order to avoid this issue, you can append to an empty string. Just do `"" + a` and in most cases this will work: `Msg("" + a);` -### Compilation errors -Most of times scripts will report errors before they are ran, on map load. This is why if you don't see your functionality (like when a command is not there in the console), scroll up and check the error. Additionally you can use the first tip in the [tip section](#additional-tips) and then use `reload`. +### Compilation Errors +Scripts will often report errors before they are ran, usually on map load. If you don't see your functionality (such as a command not being the console), scroll up and check the error. Additionally, you can use the first tip in the [tip section](#additional-tips) and then use `reload`. ## Additional Tips > [!TIP] -> Reading console output can be tiresome as much more is happening in the console than just the script system. However, there is an easy way to just listen to the script system output. You can run `con_filter_text scriptsys; con_filter_enable 1` filter out anything that is not the script system. +> Reading console output can be tiresome, as much more is happening in the console than just the script system. To overcome this problem, you can run `con_filter_text scriptsys; con_filter_enable 1` to filter out anything that is not the script system. diff --git a/docs/angelscript/guide/meta.json b/docs/angelscript/guide/meta.json index 76da0b32..fa31d875 100644 --- a/docs/angelscript/guide/meta.json +++ b/docs/angelscript/guide/meta.json @@ -1,4 +1,4 @@ { - "title": "Begineer's Guide", + "title": "Beginner's Guide", "weight": 0 } From 6a9a90b7c3a8fe6cf3639a23c4654b42818a740a Mon Sep 17 00:00:00 2001 From: Enderek Date: Sun, 12 Apr 2026 14:11:44 +0200 Subject: [PATCH 16/23] add/change: AS guide --- docs/angelscript/guide/chapter2.md | 36 +++---- docs/angelscript/guide/chapter4.md | 2 +- docs/angelscript/guide/chapter5.md | 23 ++++- docs/angelscript/guide/chapter6.md | 80 ++++++++++++++++ docs/angelscript/guide/chapter7.md | 135 +++++++++++++++++++++++++++ docs/angelscript/guide/chapterX-1.md | 27 ------ docs/angelscript/guide/chapterX.md | 90 ------------------ 7 files changed, 254 insertions(+), 139 deletions(-) create mode 100644 docs/angelscript/guide/chapter6.md create mode 100644 docs/angelscript/guide/chapter7.md delete mode 100644 docs/angelscript/guide/chapterX-1.md delete mode 100644 docs/angelscript/guide/chapterX.md diff --git a/docs/angelscript/guide/chapter2.md b/docs/angelscript/guide/chapter2.md index feafadcd..ddbb00ca 100644 --- a/docs/angelscript/guide/chapter2.md +++ b/docs/angelscript/guide/chapter2.md @@ -1,19 +1,19 @@ --- -title: Chapter 2 - Value Types, Declaration & Assignment +title: Chapter 2 - Primitive Types, Declaration & Assignment weight: 1 --- -# Chapter 2 - Value Types, Declaration & Assignment +# Chapter 2 - Primitive Types, Declaration & Assignment ## What will you learn in this chapter In this chapter you will learn about: -- [Value Types](#value-types), -- [Declaration and assignment of value types](#value-types), +- [Primitive Types](#primitive-types), +- [Declaration and assignment of primitive types](#primitive-types), - [Auto keyword](#auto-keyword), - [Constants and the const keyword](#constants), - [Integer size reference table](#integer-size-reference-table). -> Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle value types in your script. +> Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle primitive types in your script. > [!NOTE] > This chapter won't cover every detail about any of data types, it is recommended you visit the [Data Types Section](../game/type) of the wiki for more information. @@ -21,20 +21,20 @@ In this chapter you will learn about: --- -## Value Types -Value types are the more "primitive" types, and are only implemented in the backend by the Strata Team inside the engine itself. These types include: `int`, `string`, `bool`, `float`, `double`, etc. +## Primitive Types +Primitive types are the more "simpler" types, and are only implemented in the backend by the Strata Team inside the engine itself. These types include: `int`, `bool`, `float`, `double`, etc. > [!WARNING] > It is assumed you already know about these data types from other languages (mainly C++). This subsection will only provide information relevant to AngelScript itself. ### Declaration and assignment -Value types can easily get assigned and can be passed by value to functions (more on that later). -To create a value type you usually perform a declaration and an assignment, or both at once: +Primitive types can easily get assigned and can be passed by primitive to functions (more on that later). +To create a primitive type you usually perform a declaration and an assignment, or both at once: ```cpp int myInt; // Declaration myInt = 20; // Assignment -string myString = "Hey!"; // Initialization +int myInt2 = 2; // Initialization ``` You can declare multiple variables of the same type at once: @@ -49,14 +49,14 @@ myInt = 3.2; // myInt is of type int, not float/double! ``` > ### TASK 1: -> 1. Create a program that will declare and assign variables of types `string`, `int`, `bool`, `double`, and then print them out to the console. +> 1. Create a program that will declare and assign variables of types `int`, `bool`, `double`, and then print them out to the console. > 2. Do the same but use variable initialization. ### Auto keyword Although not recommended, the `auto` keyword will make the compiler automatically determine the data type of the variable: ```cpp auto i = 1; // Will set type of i to integer -auto s = "My string"; // Will set type s to string +auto s = 3.14; // Will set type s to float auto var = functionThatWillReturnAnObjectWithAVeryLongName(); // Handles (described in later chapters) can also be declared with auto @@ -72,22 +72,22 @@ Constant variables are variables that cannot change over the lifetime of the [va You can define a constant variable using the `const` keyword: ```cpp const int size = 31; -const auto st = "string"; // const also works with the auto keyword +const auto w = true; // const also works with the auto keyword ``` Constants can be useful as a sort of configuration of the script itself. If you reuse a statically defined value you can instead define a global constant and then changing one value will change everything at once: ```cpp const int MAX_SIZE = 16; -string mystring = "lorem ipsum"; -my_func1(mystring, MAX_SIZE); // A function that does something with mystring, but also needs to have additional information -my_func2(mystring, MAX_SIZE) // Another function that does something else with mystring, but it also needs the same additional information +int myint = 27; +my_func1(myint, MAX_SIZE); // A function that does something with myint, but also needs to have additional information +my_func2(myint, MAX_SIZE) // Another function that does something else with myint, but it also needs the same additional information ``` Constants are also a way to optimize your code. If you know that a variable won't change (or shouldn't change) after it's initialization, always make it a constant. ```cpp -bool function(string s, float i) { - const float value = s.length() - i; +bool function(int s, float i) { + const float value = s - i; return i > value; } ``` diff --git a/docs/angelscript/guide/chapter4.md b/docs/angelscript/guide/chapter4.md index 0e889f06..e1a33bf7 100644 --- a/docs/angelscript/guide/chapter4.md +++ b/docs/angelscript/guide/chapter4.md @@ -32,7 +32,7 @@ array@ c = {.1, .3, .5}; ``` > [!NOTE] -> Since `array` and `dictionary` are reference types, you initialize them as an object handles (the @ symbol). For now, just remember that you add that symbol after the type name, it will get explained later on. +> Since `array` and `dictionary` are value types, you initialize them as an object handles (the @ symbol). For now, just remember that you add that symbol after the type name, it will get explained later on. To access elements in an array you use the index operator **[]**, where `[i]` will access the i'th element of the array (counting from 0): ```cpp diff --git a/docs/angelscript/guide/chapter5.md b/docs/angelscript/guide/chapter5.md index 1f334df4..71d92f78 100644 --- a/docs/angelscript/guide/chapter5.md +++ b/docs/angelscript/guide/chapter5.md @@ -93,6 +93,19 @@ For a list of available methods per each type please refer to the [types section Like in any other language, a function can call itself. This is function is then called a *recursive* function. +### Calling template functions + +Templates are a way of generalizing code for multiple types. To use a template function, you specify the type(s) in the angle brackets, like so: +```cpp +function_name(argument1, argument2, ...); +``` + +These functions are not very common, but here's an example of one (`util::CreateEntityByNameT`): +```cpp +CBaseEntity@ script_ent = util::CreateEntityByNameT("logic_script"); +CBaseAnimating@ model_ent = util::CreateEntityByNameT("prop_dynamic"); +``` + --- ## Parameters @@ -178,7 +191,8 @@ This marks the parameter as an input to the function. This option provides littl > [!TIP] > Combining `&in` with `const` can however, yield a way more optimized code. `&in` should almost always be used whenever you are using a `const` parameter. - +> [!WARNING] +> Primitve types should not be passed with `&in`, as the memory address still has to be copied over, resulting in the same hit of performance (or worse!) as just copying the value itself. #### &out This option specifies that this parameter is an output of a function. This is especially useful whenever you have functions that need to have multiple output values. At the start of a function's execution, this reference will point to an uninitialized variable. After the function returns, the value assigned to this variable will be copied over to the appropriate argument. @@ -209,8 +223,11 @@ int myresult, myrest; WholeDivision(10, 3, myresult, myrest); //This will set myresult and myrest to the appropriate (3 and 1 respecitvely). ``` +#### &inout / & +This option specifies that this parameter will be passed by reference in both directions. Meaning, the argument will not be copied, and also any changes made to this variable will result in a modified state of the argument outside the function. + > [!NOTE] -> AngelScript also supports a 3rd mode, `&inout` or `&`, but this is only allowed for reference types (more on that later), and additionally, Strata Source is configured to only pass reference types by reference (pass by value is disabled), which means that there is no need to specify pass by reference for these types anyway. +> `&inout` or `&` are **not** supported for primitive types. --- @@ -345,4 +362,4 @@ myFunc(1, "A"); // Will work > > ``` > [!NOTE] -> If you completed the task above, congratulations! This was one of the harder tasks. However, please note that this way of solving that problem is only viable when your default parameters have different types, because if they don't, the overload will not work. \ No newline at end of file +> If you completed the task above, congratulations! However, please note that this way of solving that problem is only viable when your default parameters have different types, because if they don't, the overload will not work. \ No newline at end of file diff --git a/docs/angelscript/guide/chapter6.md b/docs/angelscript/guide/chapter6.md new file mode 100644 index 00000000..c6e5e121 --- /dev/null +++ b/docs/angelscript/guide/chapter6.md @@ -0,0 +1,80 @@ +--- +title: Chapter 6 - Value Types +weight: 5 +--- + + +# Chapter 6 - Value Types + +## What will you learn in this chapter +In this chapter you will learn about: +- [Value types](#value-types---short-introduction) +- [Constructors](#constructors), +- [Value type initialization](#initializing-a-value-type), +- [Template value types initialization](#initializing-template-value-types) + +> Value types are a step above primitive types, basically. + +--- + +## Value types - short introduction +Value types are types that behave a bit differently in AngelScript compared to primitives. They are in some ways similar to primitive types mentioned before, however the main differences are: +- Although it might not always be the case, value types take up (much) more memory, +- They support object handles, and should be passed via them, +- They have methods, meaning functions that are bound to their type, +- They support the `&in` and `&inout` passing by reference in functions. + +One example of a value type is the `Vector` type. + +You can easily distinguish value types from primitive types based on a simple rule. Value types are described as literals, such as `1`, `true`, `3.14`, etc. +Whenever you see a literal, you are **sure** that this literal represents a **specific** value. However, when you see a value type used in code, you can be unsure of the value it represents, for example, `1` represents the number one, but there is no guarantee what `Vector()` represents. It can represent a 0 vector, but it can also be anything. There are also no literals that would represent any value type (one might suggest an example of: `const Vector ZERO_VEC(0, 0, 0);`, but that would be a constant global variable, not a literal). + +> [!NOTE] +> Value types can only be defined inside the application itself, you cannot create your own value types in AngelScript. User created types are called *reference types*, more on that in further chapters. + +## Using value types + +### Constructors +Constructors are functions that are ran on value type initialization, when an object gets created. They are often overloaded, meaning that you can create an object using different arguments, different types etc. Each type can have their own constuctors defined, thus you should refer to the each type's documentation on the constructors available. + +As an example, the `Vector` type has 3 different constructors: +```cpp +Vector(); // Calls the default constructor, meaning no arguments are passed +Vector(float x, float y, float z); // Constructs vector from 3 floats, respectively x, y, z +Vector(const Vector&in vec); // So-called copy constructor, constructs copying data from another vector +``` + +### Initializing a value type + +Initializing a value type is done by using parenthesis, after the variable name, like so: + +```cpp +Vector v1(1, 2, 3); // Creates a vector v1 +Vector v2(v1); //Creates a vector v2, copying data from v1 +``` + +> [!CAUTION] +> #### Common mistake - initializing with the assign operator. +> It is a common mistake to initialize an object using the assign operator, like so: +> ```cpp +> Vector v1 = Vector(1, 2, 3); +> ``` +> This is, indeed, a valid (in the language sense) method to initialize, although this should be avoided if possible. This is because, underneath, what the server is doing is: +> 1. Creating the object `Vector(1, 2, 3);` +> 2. Creating the `v1` Vector using the default constructor. +> 3. Calling the assign operator on v1, using data from the right side of the operator +> 4. Deleting the right object (`Vector(1, 2, 3)`) +> +> **This is much more inefficient than just calling the appropriate constructor (which would perform only one of the operations listed above!).** + + +#### Initializing template value types +Sometimes objects are described with a template, such as the `array` object. Because the `array` class is supposed to be versatile, it can support different types of data for it's values; you can have an array of integers, an array of floats, an array of strings, etc. There is no need to re-create the array class for each and every available data type, as this is where the template functionality is used for. + +When declaring an array you need to specify the data type of its values, like so: +```cpp +array@ string_array = {"string1", "string2", "string3"}; // Create an array of strings +array@ myArray = {1, 2, 3, 4}; // Create an array of integers +// Or, by using a constructor +array@ myArray2(10, 5); // Array: {10, 10, 10, 10, 10} +``` diff --git a/docs/angelscript/guide/chapter7.md b/docs/angelscript/guide/chapter7.md new file mode 100644 index 00000000..3a3dd8ee --- /dev/null +++ b/docs/angelscript/guide/chapter7.md @@ -0,0 +1,135 @@ +--- +title: Chapter 7 - Object Handles +weight: 6 +--- + +# Chapter 7 - Object Handles + +## What will you learn in this chapter +In this chapter you will learn about: +- [Value types](#value-types---short-introduction) +- [Constructors](#constructors), +- [Value type initialization](#initializing-a-value-type), +- [Template value types initialization](#initializing-template-value-types) + +> Object handles are like smart pointers from C++, they don't actually hold an object themselves, rather they hold an address in memory (reference) that can be used to locate the object they point to. + +--- + +## Declaration +An object handle is declared by appending the **@** sign after the data type name, e.g.: +```cpp +type@ handle; +// Or more explicitly: +type@ handle = null; +``` +This code will create a handle of type `type` and point it to null (meaning that it doesn't actually point anywhere). + +> [!CAUTION] +> It is not guaranteed that handles will actually point to valid data. Handles initialized like the one above point nowhere, and trying to perform any operation on them (such as calling methods) will cause an exception. + +> [!NOTE] +> Primitive types don't support object handles. + +You can access the handle of any reference type by prepending the **@** symbol to the variable: +```cpp +type my_object; +@my_object; // This is a handle to my_object + +type@ objhandle = @my_object; // Store the object handle in a handle variable +``` + +## Expressions +In expressions, object handles are treated *almost always* exactly the same as object variables themselves, which is something very specific to the AngelScript language. This means that: +```cpp +type my_object; +type@ my_handle = @my_object; + +// Calling methods can be done like so (both ways are correct) +my_handle.Method(); // In C++, you would need to use the -> operator here, but this is not the case with AngelScript. +my_object.Method(); +``` +In most of times the compiler will automatically know what you are trying to do, however, in order to explicitly call a handle operation you have to **prepend the variable name with the handle symbol (@)**. + +```cpp +type obj1; +type@ objhandle; + +objhandle = @obj1; // This will not work, and will make the script not compile. +@objhandle = @obj1; // This is a proper handle assignment, @objhandle gets set to point to obj1. +@objhandle = obj1; // This will also work because of object variables being handles internally, but is confusing to read, and so - not recommended. +``` + +--- + +## The Initialization Problem + +As explained in chapter 6, initializing value types with the assign operator is well performant. +As an example, let's assume the `object` class implements opAssign (assignement operator method), doing: +```cpp +type my_object = 10; +``` + +Will result in the previously explained behaviour, which is **not recommended**, however, doing: + +```cpp +type@ my_object = 10; +// more specific example: +Vector@ vec_handle = @Vector(1, 2, 3); +// or +array@ array_handle = {1, 2, 3}; +``` +**Is fine to do**, because here an object gets created once, and assignment is done on the object handle, not the object itself! +This doesn't result in so many calls being made, because that calls the internal opAssign method (which should return a reference to the `type` type (us)), and so, we are actually doing a handle assignment (that assigns the handle to the same object, but in which opAssign has modified the internal properties). This is a completely valid way of declaring and initializing a value type. This code will call the default constructor, then opAssign(10). It depends on the implementation, but the performance hit here should be marginal (mainly because we're doing way less memory writes/reads). + +--- + +## Reference counting + +Object handles are reference counted, meaning that if somewhere in the memory, exists a handle to an object, it is safe to assume that object will **always** be accessible, and **will not** be removed after exiting from the variable scope it was created in. Objects are only removed from memory when all handles to them have been removed first. + +```cpp +// Returns a vector with coordinates [1, 2, 3] +Vector@ MagicVector() { + // Create the vector + Vector v1(1, 2, 3); + + //Return the handle + return @v1; +} + +... { + + Vector@ magic_vector = MagicVector(); + + // v1 object created in MagicVector has not been removed! It is safe to use magic_vector + float magic_vector_length = magic_vector.length(); // = 3.74... + + magic_vector = null; + // Since this was the only handle pointing to the v1 object, it got deleted. + +} +``` + +This gets especially useful when initializing reference types (the most advanced of data type), because you can initialize them directly to a handle: +```cpp +my_type@ my_handle = @my_type(...); +``` +There is no need to separately intialize my_type to a variable (`my_type my_obj(...);`). + + +## Handles and functions. + +In this regard, handles behave very similarly to primitives. You can pass them as arguments, specify them as parameters, return them, etc... + +```cpp +void scale(Vector@ v1_handle, const int factor) { + v1 *= factor; +} +``` +> [!NOTE] +> In the example above, the object passed with the handle **will** get modified outside the function. Here what gets copied is the handle, **not** the object underneath! + +> [!NOTE] +> Handles also support passing by reference, meaning that specifying e.g. `Vector@&out` will be valid. +> #### TODO: Do the same restrictions as for primitives (no &in) apply? \ No newline at end of file diff --git a/docs/angelscript/guide/chapterX-1.md b/docs/angelscript/guide/chapterX-1.md deleted file mode 100644 index dbb1cd7c..00000000 --- a/docs/angelscript/guide/chapterX-1.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Chapter X - Reference Types -weight: 4 ---- - - -# Chapter X - Reference types - -### Declaring template objects -Sometimes objects are described with a template, such as the `array` object. Because the `array` class is supposed to be versatile, it can support different types of data for it's values; you can have an array of integers, an array of floats, an array of strings, etc. There is no need to re-create the array class for each and every available data type, as this is where the template functionality is used for. - -When declaring an array you need to specify the data type of its values, like so: -```cpp -array string_array = {"string1", "string2", "string3"}; // Create an array of strings -array myArray = {1, 2, 3, 4}; // Create an array of integers -``` - -Functions can be templates too, an example of such function can be the cast function, which converts one data type to another (if possible) (more on the cast function later): -```cpp -obj1 myobj1; -obj2 myobj2; -@myobj1 = cast(@myobj2); // Cast function will convert obj2 into obj1 -``` - -> [!NOTE] -> It is currently not possible to create your own custom template objects, although this functionality is planned for future releases of AngelScript. - diff --git a/docs/angelscript/guide/chapterX.md b/docs/angelscript/guide/chapterX.md deleted file mode 100644 index 97041445..00000000 --- a/docs/angelscript/guide/chapterX.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Chapter X - Object Handles -weight: 5 ---- - -# Chapter X - Object Handles - -## What will you learn in this chapter -In this chapter you will learn: -- What are Value Types, -- What are References and how to use them, -- What are Reference Types. - - -Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle data in your script. Described below are various "types" of data types, and their differences. - ---- - -## Object handles - -Object handles are like smart pointers from C++, they don't actually hold data themselves, rather they hold an address in memory (reference) that can be used to locate the object they point to. - -### Declaration -An object handle is declared by appending the **@** sign after the data type name, e.g.: -```cpp -object@ handle; -``` -This code will create a handle of type `object` and point it to null (meaning that it doesn't actually point anywhere). - -> [!CAUTION] -> It is not guaranteed that handles will actually point to valid data. Handles initialized like the one above point nowhere, and trying to perform any operation on them (such as calling methods) will cause an exception. - -> [!NOTE] -> None of the Value Types (primitives) have object handles. - -You can access the handle of any reference type by prepending the **@** symbol to the variable: -```cpp -object my_object; -@my_object; // This is a handle to my_object -``` - -### Expressions -In expressions, object handles are treated exactly the same as object variables themselves. For reference types they are essentially the same. Meaning that: -```cpp -object my_object; -object@ my_handle = @my_object; -my_handle is my_object // Is true - -//Calling methods can be done like so (both ways are correct) -my_handle.Method(); -my_object.Method(); -``` -In most of times the compiler will automatically know what you are trying to do, in order to explicitly call a handle operation you have to **prepend the variable name with the handle symbol (@)**. - -```cpp -object obj1; -object@ objhandle; - -objhandle = @obj1; // This will not work, and will make the script not compile. -@objhandle = @obj1; // This is a proper handle assignment, @objhandle gets set to point to obj1. -@objhandle = obj1; // This will also work because of object variables being handles internally, but is confusing to read, and so - not recommended. -``` - ---- - -The below section of the Object Handles subchapter contains more detailed information about the implementation of handles in AngelScript. If you don't feel like delving deeper into this subject you can skip the rest of this section for now, remember that you may always return here after you feel accustomed to object handles. - -As an example, let's assume the `object` class implements opAssign, trying to do: -```cpp -my_object = 10; -``` - -Will result in an error, because you are not allowed to do value assignment on a reference type. However, you will be able to do: - -```cpp -@my_object = 10; -``` - -Because that calls the internal opAssign method (which should return a reference to the `object` (us)), and so we are actually doing a handle assignment (that assigns the handle to the same object, but in which opAssign has modified the internal properties). - -You can also initialize objects this way: -```cpp -object@ my_object = 10; -``` -This is a completely valid way of declaring and initializing a variable. This code will call the default constructor, then opAssign(10). - ---- - -## Reference types - From d545f222bdd15de100769310098be3c1dd2be945 Mon Sep 17 00:00:00 2001 From: Enderek Date: Sun, 12 Apr 2026 14:21:27 +0200 Subject: [PATCH 17/23] change: minor tweaks to chapter 7 --- docs/angelscript/guide/chapter7.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/angelscript/guide/chapter7.md b/docs/angelscript/guide/chapter7.md index 3a3dd8ee..6fba37ef 100644 --- a/docs/angelscript/guide/chapter7.md +++ b/docs/angelscript/guide/chapter7.md @@ -7,15 +7,21 @@ weight: 6 ## What will you learn in this chapter In this chapter you will learn about: -- [Value types](#value-types---short-introduction) -- [Constructors](#constructors), -- [Value type initialization](#initializing-a-value-type), -- [Template value types initialization](#initializing-template-value-types) +- [Object handles](#object-handles) +- [Object handle declaration](#declaration), +- [Object handle expressions](#expressions), +- [The Initialization Problem](#the-initialization-problem), +- [Handle reference counting](#reference-counting), +- [Object handle usage in functions](#handles-and-functions) > Object handles are like smart pointers from C++, they don't actually hold an object themselves, rather they hold an address in memory (reference) that can be used to locate the object they point to. --- +## Object handles +These are objects that hold the address of an object, rather than the object itself. Meaning that by using object handles, you are manipulating the information about addresses of objects that are somewhere else, not ""in"" the variable itself. + + ## Declaration An object handle is declared by appending the **@** sign after the data type name, e.g.: ```cpp From c719d8dc3a7f8561b8a29fd108f0135d77091eca Mon Sep 17 00:00:00 2001 From: Orsell <34631691+OrsellGit@users.noreply.github.com> Date: Tue, 28 Apr 2026 03:45:55 -0700 Subject: [PATCH 18/23] fix: Some file structure and grammar fixes for the AS guide --- docs/angelscript/guide/chapter1.md | 26 ++++-- docs/angelscript/guide/chapter2.md | 60 ++++++++----- docs/angelscript/guide/chapter3.md | 59 ++++++++----- docs/angelscript/guide/chapter4.md | 57 +++++++----- docs/angelscript/guide/chapter5.md | 100 +++++++++++++++------- docs/angelscript/guide/chapter6.md | 27 ++++-- docs/angelscript/guide/chapter7.md | 46 ++++++---- docs/angelscript/guide/language/meta.json | 4 + docs/angelscript/guide/meta.json | 2 +- 9 files changed, 247 insertions(+), 134 deletions(-) create mode 100644 docs/angelscript/guide/language/meta.json diff --git a/docs/angelscript/guide/chapter1.md b/docs/angelscript/guide/chapter1.md index 0831bdc1..cb9ad126 100644 --- a/docs/angelscript/guide/chapter1.md +++ b/docs/angelscript/guide/chapter1.md @@ -5,10 +5,12 @@ weight: 0 # Chapter 1 - Introduction -## What You Will Learn +## What You Will Learn in This Chapter + In this chapter you will learn about: -- [AngelScript as a programming language](#angelscript) -- [Purpose of AngelScript in Strata Source](#what-can-you-do-with-angelscript) + +- [AngelScript](#angelscript) +- [What You Can Do With AngelScript](#what-you-can-do-with-angelscript) - [Client-Server model of the engine](#client---server-model) - [How to load code in the game](#loading-code) - [Writing your own Hello World program](#your-first-script) @@ -29,6 +31,7 @@ In this chapter you will learn about: --- ## AngelScript + [AngelScript's home page](https://www.angelcode.com/angelscript/) describes AngelScript as: > The AngelCode Scripting Library, or AngelScript as it is also known, is an extremely flexible cross-platform scripting library designed to allow applications to extend their functionality through external scripts. @@ -38,9 +41,9 @@ Use cases for AngelScript vary heavily. It is much closer to pure engine code th AngelScript's official documentation can be found here: [AS Official Docs](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html). +## What You Can Do With AngelScript -## What Can You Do With AngelScript -ngelScript allows for a closer connection to the internal engine code by having the engine provide various APIs to its internal classes. This allows you to do various things, such as creating custom entities, creating your own ConCommands and ConVars, making custom weapons - all things that aren't normally easy to do with VScript. +AngelScript allows for a closer connection to the internal engine code by having the engine provide various APIs to its internal classes. This allows you to do various things, such as creating custom entities, creating your own ConCommands and ConVars, making custom weapons - all things that aren't normally easy to do with VScript. While VScript (mainly) sits between entities and handles the interactions between them, AngelScripts sits in a level above, being able to *create* entities and define their behavior. @@ -49,12 +52,13 @@ While VScript (mainly) sits between entities and handles the interactions betwee ## AngelScript in Strata Source ### Client - Server Model -Before you write your first script, there is one more thing you need to know. Most engines, including the Source engine, operate on the client-server model. This means that client code is separate from the server code, even in singleplayer. When starting a map in singleplayer, you essentially create a one-player server that runs beside the client. This is very important to remember as AS code can be loaded on both. Some functionality will only be available on the server (such as entities) and some functionality will only be available on the client (such as Panorama/UI). +Before you write your first script, there is one more thing you need to know. Most engines, including the Source engine, operate on the client-server model. This means that client code is separate from the server code, even in single player. When starting a map in single player, you essentially create a one-player server that runs beside the client. This is very important to remember as AS code can be loaded on both. Some functionality will only be available on the server (such as entities) and some functionality will only be available on the client (such as Panorama/UI). ### Loading Code + Where should you place the files containing your code? -Each file that contains your code should end with the **.as** extension and be placed in the **code/** folder of your respective `Game` searchpath. Example locations would be `p2ce/custom/my-addon/code/` or just `p2ce/code/` (the latter is not recommended). +Each file that contains your code should end with the **.as** extension and be placed in the **code/** folder of your respective `Game` search path. Example locations would be `p2ce/custom/my-addon/code/` or just `p2ce/code/` (the latter is not recommended). Code can also be placed inside the `code` folder of an addon created with the SDK Launcher. You may name your files however you'd like. You can create custom directories or you can place your files loosely - it all depends on what you're trying to achieve. In the long run, it's not important. What *is* important is where you place the "starting points". The engine will not attempt to load any files except for these 3 files placed **directly** in the **code/** folder: @@ -64,10 +68,12 @@ You may name your files however you'd like. You can create custom directories or 3. `cl_init.as` - Will only get loaded by the client. ### IDE and Testing Environment + It is suggested to use Visual Studio Code with the [AngelScript Language Server (sashi0034.angel-lsp)](https://marketplace.visualstudio.com/items?itemName=sashi0034.angel-lsp) extension. From there, you can open the `code/` folder of your choice as a project and begin development. The engine compiles scripts on every map load (you can use the `reload` command to recompile the scripts). ### Your First Script + You should now be ready to begin writing your very first program. For now, let's just print a Hello World message to the console. Though the code below may look foreign for now, don't be dissuaded! Place this code into `cl_init.as` as it is a client command. ```cpp @@ -79,12 +85,14 @@ void MyCommand(const CommandArgs@ args) { Now, the only thing left to do now is launch the game, open the console, and execute the *HelloWorld* command. -> ### TASK 1: +> ### TASK 1: +> > Run the HelloWorld program mentioned above. ## How To Test Out Your Code in a Basic Way For now, you will need to know how to run your code so that you can complete the tasks given to you within this guide. In `sv_init.as` include: + ```cpp [ServerCommand("CodeTest", "")] void CodeTest(const Command@ args) { @@ -102,8 +110,8 @@ Remember to add `"\n"` to the input of Msg (or just call `Msg("\n");` after your > > In order to avoid this issue, you can append to an empty string. Just do `"" + a` and in most cases this will work: `Msg("" + a);` ### Compilation Errors -Scripts will often report errors before they are ran, usually on map load. If you don't see your functionality (such as a command not being the console), scroll up and check the error. Additionally, you can use the first tip in the [tip section](#additional-tips) and then use `reload`. +Scripts will often report errors before they are ran, usually on map load. If you don't see your functionality (such as a command not being the console), scroll up and check the error. Additionally, you can use the first tip in the [tip section](#additional-tips) and then use `reload`. ## Additional Tips diff --git a/docs/angelscript/guide/chapter2.md b/docs/angelscript/guide/chapter2.md index ddbb00ca..092c3779 100644 --- a/docs/angelscript/guide/chapter2.md +++ b/docs/angelscript/guide/chapter2.md @@ -5,13 +5,15 @@ weight: 1 # Chapter 2 - Primitive Types, Declaration & Assignment -## What will you learn in this chapter +## What You Will Learn in This Chapter + In this chapter you will learn about: -- [Primitive Types](#primitive-types), -- [Declaration and assignment of primitive types](#primitive-types), -- [Auto keyword](#auto-keyword), -- [Constants and the const keyword](#constants), -- [Integer size reference table](#integer-size-reference-table). + +- [Primitive Types](#primitive-types) +- [Declaration and assignment of primitive types](#primitive-types) +- [Auto keyword](#auto-keyword) +- [Constants and the const keyword](#constants) +- [Integer size reference table](#integer-size-reference-table) > Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle primitive types in your script. @@ -27,9 +29,11 @@ Primitive types are the more "simpler" types, and are only implemented in the ba > [!WARNING] > It is assumed you already know about these data types from other languages (mainly C++). This subsection will only provide information relevant to AngelScript itself. -### Declaration and assignment +### Declaration and Assignment + Primitive types can easily get assigned and can be passed by primitive to functions (more on that later). To create a primitive type you usually perform a declaration and an assignment, or both at once: + ```cpp int myInt; // Declaration myInt = 20; // Assignment @@ -38,22 +42,27 @@ int myInt2 = 2; // Initialization ``` You can declare multiple variables of the same type at once: + ```cpp int myInt1, myInt2, myInt3; ``` Once declared, variables cannot change their type without redeclaration. This is not allowed: + ```cpp int myInt; myInt = 3.2; // myInt is of type int, not float/double! ``` > ### TASK 1: +> > 1. Create a program that will declare and assign variables of types `int`, `bool`, `double`, and then print them out to the console. > 2. Do the same but use variable initialization. -### Auto keyword +### Auto Keyword + Although not recommended, the `auto` keyword will make the compiler automatically determine the data type of the variable: + ```cpp auto i = 1; // Will set type of i to integer auto s = 3.14; // Will set type s to float @@ -65,17 +74,20 @@ auto@ handle = @obj; The `auto` keyword is not recommended for several cases. The main one of them is that you cannot immediately see the data type of a returned object especially from functions, like the one above. We don't know what that function will return. Another reason is that sometimes the compiler might guess wrong, especially in cases like integers, where you have multiple ways that `1` could have been described (e.g. int8/int16, both can describe `1`, even `bool` can). ---- +--- ### Constants + Constant variables are variables that cannot change over the lifetime of the [variable scope](chapter3) they are created in. You can define a constant variable using the `const` keyword: + ```cpp const int size = 31; const auto w = true; // const also works with the auto keyword ``` Constants can be useful as a sort of configuration of the script itself. If you reuse a statically defined value you can instead define a global constant and then changing one value will change everything at once: + ```cpp const int MAX_SIZE = 16; @@ -85,6 +97,7 @@ my_func2(myint, MAX_SIZE) // Another function that does something else with myin ``` Constants are also a way to optimize your code. If you know that a variable won't change (or shouldn't change) after it's initialization, always make it a constant. + ```cpp bool function(int s, float i) { const float value = s - i; @@ -93,24 +106,25 @@ bool function(int s, float i) { ``` > ### TASK 2: +> > Write a program that initializes a constant variable with the `auto` keyword, and then tries to change it after. Observe the compilation error in the console. --- -### Integer size reference table -The table below shows the minimum and maximum values for each integer subtype (don't worry about remembering this, just remember that it exists here): -|Type|Short description|Minimum Value|Maximum Value| -|---|---|---|---| -|int8| Signed, 8 bits |-128 | 127 | -|int16| Signed, 16 bits |-32,768 | 32,767 | -|int| Signed, 32 bits |-2,147,483,648 | 2,147,483,647 | -|int64| Signed, 64 bits |-9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 | -|uint8| Unsigned, 8 bits, also represents characters (char) | 0 | 255 | -|uint16| Unsigned, 16 bits | 0 | 65,535 | -|uint| Unsigned, 32 bits | 0 | 4,294,967,295 | -|uint64| Unsigned, 64 bits | 0 | 18,446,744,073,709,551,615 | +### Integer Size Reference Table -> [!TIP] -> The official AngelScript documentation mentions that the scripting engine has been mostly optimized for 32 bit datatypes (int/uint). Using these is recommended for the most part (unless you are dealing with numbers that don't fit into int/uint). +The table below shows the minimum and maximum values for each integer subtype (don't worry about remembering this, just remember that it exists here): +| Type | Short description | Minimum Value | Maximum Value | +| ------ | --------------------------------------------------- | -------------------------- | --------------------------- | +| int8 | Signed, 8 bits | -128 | 127 | +| int16 | Signed, 16 bits | -32,768 | 32,767 | +| int | Signed, 32 bits | -2,147,483,648 | 2,147,483,647 | +| int64 | Signed, 64 bits | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 | +| uint8 | Unsigned, 8 bits, also represents characters (char) | 0 | 255 | +| uint16 | Unsigned, 16 bits | 0 | 65,535 | +| uint | Unsigned, 32 bits | 0 | 4,294,967,295 | +| uint64 | Unsigned, 64 bits | 0 | 18,446,744,073,709,551,615 | +> [!TIP] +> The official AngelScript documentation mentions that the scripting engine has been mostly optimized for 32 bit data types (int/uint). Using these is recommended for the most part (unless you are dealing with numbers that don't fit into int/uint). diff --git a/docs/angelscript/guide/chapter3.md b/docs/angelscript/guide/chapter3.md index 9d8e12d0..d6a62f1e 100644 --- a/docs/angelscript/guide/chapter3.md +++ b/docs/angelscript/guide/chapter3.md @@ -2,19 +2,21 @@ title: Chapter 3 - Statements, Expressions, Conditions & Variable Scope weight: 2 --- + # Chapter 3 - Statements, Expressions, Conditions & Variable Scope +## What You Will Learn in This Chapter -## What will you learn in this chapter In this chapter you will learn about: -- [Expression statements](#expression-statements), -- [Comparison operators](#comparison-operators), -- [Logic operators](#logic-operators), -- [If/else block](#ifelse-block), -- [Switch statement](#switch-statement), -- [Variable Scope](#variable-scope). - -> Statements, expressons, conditions and the variable scope are the foundation of every program or script. + +- [Expression statements](#expression-statements) +- [Comparison operators](#comparison-operators) +- [Logic operators](#logic-operators) +- [If/else block](#ifelse-block) +- [Switch statement](#switch-statement) +- [Variable Scope](#variable-scope) + +> Statements, expressions, conditions and the variable scope are the foundation of every program or script. --- ## Basic statements @@ -23,15 +25,18 @@ Your code is like a recipe, and statements are the individual steps. Statements are a way to tell the script engine what it needs to do, we already used them in previous chapters, such as the assignment or declaration. -### Expression statements +### Expression Statements + Any expression can be placed on a line as a statement. Examples of expressions include: + - Function call **()** operator - calls a function (more on functions later), - Equals **=** operator - performs assignment, - Add **+** operator - adds two values together, -- Substraction **-** operator - substracts two values from each other, +- Subtraction **-** operator - subtracts two values from each other, - Many more, such as **+=**, **-=**, **++**, etc. are available. More about them can be found in the [expression reference table](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html). Such statements need to end with the semicolon (`;`): + ```cpp b = a + b; func(); @@ -41,6 +46,7 @@ a += b; AngelScript follows a specific instruction of operation order. Function calls are evaluated first bottom to top, then AS sticks to order of operations as specified in the [Operator Precedence](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_operator_precedence.html) reference. You can force an order of operations by using parenthesis: + ```cpp float a = 1 + 1.0 / 2; // This will return 1,5 float b = (1 + 1.0) / 2; // This will return 1 @@ -52,9 +58,10 @@ float b = (1 + 1.0) / 2; // This will return 1 > ### TASK 1: > Given `float a = 4; float b = 5;` Write a program that calculates the number c given by the equation: `c = (a - 2)^2 + (b + 1) / 2`. +### Comparison Operators + +Comparison operators are operators of which expressions evaluate to the `true` or `false` boolean values. An example of a comparison operator is the equals (**==**) operator, which checks if the two values on both sides of such operator are equal. Another type of a condition operator is the greater than operator (**>**), which checks if the value on the left side is greater than the value on the right side. For comparison operator reference please check the [expression reference table](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html). -### Comparison operators -Comparison operators are operators of which expressions evaluate to the `true` or `false` boolean values. An example of a comparsion operator is the equals (**==**) operator, which checks if the two values on boths sides of such operator are equal. Another type of a condition operator is the greater than operator (**>**), which checks if the value on the left side is greater than the value on the right side. For comparison operator reference please check the [expression reference table](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html). ```cpp int a = 1; int b = 2; @@ -64,8 +71,10 @@ b = 1; bool result = a == b; // Result now stores the information if a and b were equal when it was defined. ``` -### Logic operators +### Logic Operators + Logic operators are a way to combine comparison expressions in order to achieve one result: + - NOT - denoted as `!`, evaluates to true, if value is false and vice versa, - AND - denoted as `&&`, evaluates to true, if both values are true, - OR - denoted as `||`, evaluates to true, if even one of the values is true, else false if both are false, @@ -76,18 +85,21 @@ a && b; // AND a && b || c; // A combination of AND and OR, a AND b is going to get evaluated first a && (b || c); // You can use parenthesis to specify which operator should get evaluated first, here OR will get evaluated first ``` + > [!NOTE] > Although AngelScript supports Python-like logic operator notation (and, or, ...) it is recommended to stick to the C-like notation. This is mainly because AS is much more similar to C in it's syntax, and also not every extension adding AS support for your IDE has support for the Python-like notation. - --- ## Conditions + Conditions are a way to tell the engine to execute specific code only if a specific condition is met. For example, only add numbers if they are positive. -They should contain an expression that evalues to true or false, and they can be any sort of valid combination of comparison operators and logic operators, etc. +They should contain an expression that evaluates to true or false, and they can be any sort of valid combination of comparison operators and logic operators, etc. + +### If/else Block -### If/else block The `if`/`else if`/`else` block is used to run specific code only on certain conditions. The `else if` and `else` are not required, but the block must start with an `if` statement. + ```cpp if ( a > 10 ) { // Condition 1 // Run the code in here @@ -103,15 +115,16 @@ if ( a > 10 ) { // Condition 1 > ### TASK 2: > Given two numerical values *a* and *b* (defined statically in your script) prints out an absolute value of their difference. +### Switch Statement -### Switch statement The switch statement is a very useful tool for situations where you need to compare to a lot of different cases. It performs the *is equal* operation comparing a value to every value specified in case blocks. It is also much faster than a block of the `if`/`else if`/`else` statements. + ```cpp switch ( value ) { case 0: // Do if value == 0 break; // Required keyword to go out of the switch block - + case 2: case 3: // Execute if value == 2 or value == 3 @@ -121,23 +134,26 @@ switch ( value ) { // Execute if neither cases were met } ``` + > [!CAUTION] > Each case requires a `break` statement after finishing code execution. This is because switch behaves more like the `goto` (C++) functionality, meaning that it doesn't stop executing code after finishing a specific case. The `break` statement will tell the code to go out of the `switch` block. This is also why in the upper example `case 2:` and `case 3:` can be used to both execute the same lines of code. > ### TASK 3: -> Given a string as a value (statically defined), write a program that would simulate a command-like behaviour using the switch statement. If the string is equal to: +> +> Given a string as a value (statically defined), write a program that would simulate a command-like behavior using the switch statement. If the string is equal to: +> > - "hello" - print "HelloWorld" to the console > - "engine" - print "Strata Source" to the console > - "name" - print "My name is Chell" to the console > - on any other string - print "Command not recognized!" to the console - --- ## Variable Scope Variable Scope determines which data can be accessed from where. In AngelScript the Variable Scope behaves exactly as the one in C++. In general the Variable Scope makes programs use less memory by not holding expired (not useful anymore) information inside the memory, as an example: + ```cpp int number = 10; @@ -150,6 +166,7 @@ void my_func2() { my_number = 80; // Error, my_number has not been declared } ``` + In this case my_number doesn't exist inside *my_func2*, it only exists inside *my_func1* and only for the duration of that function's execution. Statements such as `if`, `else`, `for`, `while`, `try`, etc. create local variable scopes each time, meaning that variables declared inside them cannot be accessed outside of them, contrary to how for example Python handles it (where scopes are only created inside functions). diff --git a/docs/angelscript/guide/chapter4.md b/docs/angelscript/guide/chapter4.md index e1a33bf7..d7e94312 100644 --- a/docs/angelscript/guide/chapter4.md +++ b/docs/angelscript/guide/chapter4.md @@ -5,26 +5,29 @@ weight: 3 # Chapter 4 - Loops +## What You Will Learn in This Chapter -## What will you learn in this chapter In this chapter you will learn about: -- [While, do while loops](#while-do-while), -- [For loop](#for), -- [Foreach](#foreach), -- [Continue/Break keywords](#special-keywords). + +- [While, do while loops](#while-do-while) +- [For loop](#for) +- [Foreach](#foreach) +- [Continue/Break keywords](#special-keywords) > Loops are a way to make the code repeat itself a certain amount of times, of which the amount of repetitions may vary depending on what is going on in the code. --- -### Arrays - short introduction +### Arrays - Short Introduction + > [!NOTE] -> This subsection is supposed to teach you the very basics of arrays, because next you will learn about loops, and loops are mostly useful for array manipulation. +> This subsection is supposed to teach you the very basics of arrays, because next you will learn about loops, and loops are mostly useful for array manipulation. > You won't learn in details what the array is and how to do operations on it, but you will learn how to create one and access its elements. An array is an ordered group of elements, of which there is a starting element and an element at the end. Code-wise it's a template object, as you need to specify of which data type its values will be. To create an array you can use the **{element, element2, ...}** assignment: + ```cpp array@ a = {0, 1, 2, 3, 4}; array@ b = {true, false, false, true, false}; @@ -35,6 +38,7 @@ array@ c = {.1, .3, .5}; > Since `array` and `dictionary` are value types, you initialize them as an object handles (the @ symbol). For now, just remember that you add that symbol after the type name, it will get explained later on. To access elements in an array you use the index operator **[]**, where `[i]` will access the i'th element of the array (counting from 0): + ```cpp a[3] // = 3 b[1] // = false @@ -43,22 +47,26 @@ b[0] // = .1 More on the arrays will be talked about in later parts of this guide. ---- +--- + +## While, Do While -## While, do while The `while (expression)` loop will execute code until the expression evaluates to false: + ```cpp int a = 10; while (a > 0) { - a--; // Decrement (substract one from a) each time the code executes + a--; // Decrement (subtract one from a) each time the code executes // Code in here will stop executing when a will be equal to 0 } other_code(); // This will execute after the loop ``` -The `while` loop will not execute the code (even once) if the condition evaluates to false from the very start. + +The `while` loop will not execute the code (even once) if the condition evaluates to false from the very start. A `do while` loop however, will first execute the code inside the loop and only *then* check if the condition is true to execute it once more: + ```cpp int a = 10; do { @@ -73,16 +81,19 @@ do { > Write a program that will print out "Hello again!" to the console 10 times. ## For + A `for` loop is an advanced version of the `while` loop. It takes 3 arguments in its statement - `for (statement1; statement2; statement3) {...}`: -- Statement 1 - gets executed before the loop runs (but in the loop's variable scope), often used to intialiaze a local indexing variable, such as `int i = 0;`. + +- Statement 1 - gets executed before the loop runs (but in the loop's variable scope), often used to initialize a local indexing variable, such as `int i = 0;`. - Statement 2 - is a condition for the execution of the loop, checked before the loop executes the code inside. - Statement 3 - is executed after a successful code execution inside the loop (every time). An example of a `for` loop can be a loop that cycles through every character in a string: + ```cpp array@ numbers = {1, 1, 2, 3, 5, 8, 13}; for (int i = 0; i < numbers.length(); i++) { // For every i until i is greater or equal to the array length (this will ensure i won't go out of bounds) - numbers[i] // Represents the i'th number in the array + numbers[i] // Represents the i'th number in the array // After executing code do i++ (add one to i), so we can access the next element } ``` @@ -91,13 +102,11 @@ for (int i = 0; i < numbers.length(); i++) { // For every i until i is greater o > Statements 1 and 3 in for loops can be skipped, as an example `for (;condition;)` is a valid form of a `for` loop, and so is `for (int a = 0;condition;)` etc. > ### TASK 2: +> > Given an array of integers, write a program that will add all of these integers and print out the result. > > [!NOTE] > > Because of the [Variable Scope](chapter3/#variable-scope), you will need to define a variable to store the sum outside of the loop. - - - ## Foreach A `foreach` loop can be used to perform code for each item in a container objects. Container objects are objects that store values of other data types, such as the `array` object or the `dictionary` object. Its structure `foreach (vars : container_object)` consists of two parts: where vars contains declarations of the variable names, such as `int val`, and the container object is the, well, container object. Some objects unpack more than one variable, such as the `dictionary` objects that unpacks the key and the appropriate value. @@ -123,12 +132,12 @@ foreach (auto value : mydict) {...} // It is also possible to just loop over one > ### TASK 3: > Write a program that will print out every element of a given array. - -## Special keywords +## Special Keywords These are the special keywords that can be used inside loops. -### Break statement +### Break Statement + The `break` statement is a way to exit a loop execution early. Calling it will cause the program to abort loop execution and continue executing code after the loop. ```cpp @@ -141,7 +150,8 @@ while (a > 0) { // This loop will stop executing when a will be equal to 5 ``` -### Continue statement +### Continue Statement + The `continue` statement will cause the loop to stop and go to the next element. ```cpp @@ -151,14 +161,16 @@ for(int i = 0; i < 10; i++) { if (i == 4) { // If i is equal to 4, we are skipping it continue; } - + // This code will not execute for i = 4 sum += i; } ``` -### Nested loops and special keywords +### Nested Loops and Special Keywords + Keywords like `break` and `continue` work on the bottom-most loop in nested code, meaning that if you have code like this: + ```cpp while (condition) { for (int a = 5; a < 10; a++) { @@ -171,4 +183,5 @@ while (condition) { ``` > ### TASK 4: +> > Create a **while (true)** loop that adds all integers until 20. diff --git a/docs/angelscript/guide/chapter5.md b/docs/angelscript/guide/chapter5.md index 71d92f78..9d7fe91b 100644 --- a/docs/angelscript/guide/chapter5.md +++ b/docs/angelscript/guide/chapter5.md @@ -5,14 +5,16 @@ weight: 4 # Chapter 5 - Functions -## What will you learn in this chapter +## What You Will Learn in This Chapter + In this chapter you will learn about: -- [Declaring functions and calling functions](#syntax), -- [Calling methods on built-in objects](#calling-methods-on-objects), -- [Default parameters](#default-parameters), -- [References and passing variables by reference to functions (`&in`/`&out`)](#references---short-intro), -- [Returning references and when it can be done](#returning-references), -- [Function overloads](#function-overloads). + +- [Declaring functions and calling functions](#syntax) +- [Calling methods on built-in objects](#calling-methods-on-objects) +- [Default parameters](#default-parameters) +- [References and passing variables by reference to functions (`&in`/`&out`)](#references---short-intro) +- [Returning references and when it can be done](#returning-references) +- [Function overloads](#function-overloads) > Functions are a way to split up the code into re-usable parts. @@ -39,7 +41,7 @@ int myCoolFunction() { // This function returns an integer void myFunction() { ... // No return statement - + // or return statement without a value (useful if you want to return early) return; } @@ -52,8 +54,7 @@ bool myFunction(int a, int b) { Each function **must** have a return statement in each of its "paths". What that basically means, is that whatever you do in your function, it will always end with a return statement. The only exception is the `void` return type (which means return nothing), in which you can skip the `return` keyword entirely, or use the `return;` statement when you want to exit the function early. - -### Calling functions +### Calling Functions Calling functions in code is very simple, you use the **function call `()`** operator, `func(arguments)`. In it, you include every needed argument: @@ -77,8 +78,10 @@ a = sum(a, just5()); // just5 will get evaluated first, then its result will get Calling a function is a statement, which means it can be freely used in expressions in every combination. You can treat `func(p)` as a value that you do operations with. -### Calling methods on objects +### Calling Methods on Objects + Some objects such as `string` or `array` implement methods. For now, you can think of methods as functions that sit inside the object (variable), and operate on that object. You can invoke them by using the `.` operator and then the function call. + ```cpp string mystr = "ABC"; @@ -89,18 +92,20 @@ For a list of available methods per each type please refer to the [types section > [!NOTE] > Primitive types (`int`, `float`, `bool`, etc.) don't implement any methods. -### Recursiveness +### Recursion -Like in any other language, a function can call itself. This is function is then called a *recursive* function. +Like in any other language, a function can call itself. This is function is then called a *recursive* function. ### Calling template functions Templates are a way of generalizing code for multiple types. To use a template function, you specify the type(s) in the angle brackets, like so: + ```cpp function_name(argument1, argument2, ...); ``` These functions are not very common, but here's an example of one (`util::CreateEntityByNameT`): + ```cpp CBaseEntity@ script_ent = util::CreateEntityByNameT("logic_script"); CBaseAnimating@ model_ent = util::CreateEntityByNameT("prop_dynamic"); @@ -112,16 +117,19 @@ CBaseAnimating@ model_ent = util::CreateEntityByNameT("prop_dyn Function parameters in AngelScript can be a bit confusing, since AS has custom keywords and custom behaviors for different types of parameters. -### Default parameters +### Default Parameters + Sometimes you want to add additional functionality to your function, but for most cases you already know what it should do, although you still want to include a customizable option for fine-tuning. You can do that by default parameters. Each parameter can have a default value assigned to it, like so: + ```cpp void myFunc(int a = 5, int b = 1) {...} ``` This function can be called with *0*, *1*, and *2* arguments, and each call will be valid. Calling it with 0 arguments will mean that `a` will be set to `5`, and `b` to `1`. Calling it with one argument will set a to that arguments value and so on. + ```cpp myFunc(); // a = 5, b = 1 myFunc(2); // a = 2, b = 1 @@ -136,6 +144,7 @@ myFunc(2, 5); // a = 2, b = 5 ### Constant parameters Constant parameters work just like constant variables. If declare a certain parameter constant, you won't be able to change it in any way. + ```cpp void myFunc(const int a, const bool y = true) // Default parameters can also be constants ``` @@ -143,41 +152,49 @@ void myFunc(const int a, const bool y = true) // Default parameters can also be One important note is that declaring a const parameter will make the compiler not copy the object (if it ensures the object's lifetime). More on that will be in the next chapters. > ### TASK 1: -> Create a function that computes the nth number of the fibonnaci sequence. It should take uint as the parameter (n) and return an uint (the number). You can tackle this problem recursively (using recursion) or iteratively (using a loop). It is recommend to try out both. +> +> Create a function that computes the nth number of the Fibonacci sequence. It should take uint as the parameter (n) and return an uint (the number). You can tackle this problem recursively (using recursion) or iteratively (using a loop). It is recommend to try out both. + +### References - Short Intro -### References - short intro Before we delve into the next subchapter, you need to know what *references* are. In each computer, variables are stored in memory. You can visualize computers memory as a some sort of a box with labels. Each label has some space that it describes, and there can be an item in each label. Such items are our variables, and these labels are memory addresses. In such way, the computer knows where to look for these variables when it needs to find them. References are just the labels we have been comparing to, they *are* the address of the variable they correspond to. They are denoted with the **&** symbol. Conceptually: + ```cpp string mystring = "lorem ipsum"; &mystring // Memory address of mystring ``` -In angelscript you cannot directly manipulate references, but you can do many useful things when you combine functions and references. The AngelScript compiler will automatically manage referencing (getting a variables adress) and dereferencing (looking up a variable from an adress). +In AngelScript you cannot directly manipulate references, but you can do many useful things when you combine functions and references. The AngelScript compiler will automatically manage referencing (getting a variables address) and dereferencing (looking up a variable from an address). -### Reference parameters -Functions can be set to use references as parameters. +### Reference Parameters + +Functions can be set to use references as parameters. In the examples shown above every argument was **copied**. Here's a better example: + ```cpp void func(int c) {...} -int a = 1; +int a = 1; func(a); ``` + In this example, before `c` gets assigned a value from `a`, the value of `a` gets copied first, and only after that the assignment occurs. This happens, so that doing any operations on `c` in `func` will not cause `a` outside the function to change in any way. However, passing by reference changes that mechanism. Since now, the thing that gets copied is the memory address, not the actual variable value. Meaning that if we were to pass by reference in `func` above, doing any operation such as `c = 5;` would cause `a` to change accordingly (a = 5). Telling the compiler that you want to pass by reference gets done in the function parameters declaration, like so: + ```cpp void func(int& c) // This is a pass by reference ``` No special syntax for calling is needed: + ```cpp int a = 1; func(a); // a gets passed by reference @@ -186,18 +203,21 @@ func(a); // a gets passed by reference AngelScript implements more functionality to passing by reference, and that includes 2 options: #### &in + This marks the parameter as an input to the function. This option provides little to no benefit as to just passing by value (copying), as the compiler still has to ensure the object won't get modified outside the function, and the only way to do that is to make a copy. > [!TIP] > Combining `&in` with `const` can however, yield a way more optimized code. `&in` should almost always be used whenever you are using a `const` parameter. > [!WARNING] -> Primitve types should not be passed with `&in`, as the memory address still has to be copied over, resulting in the same hit of performance (or worse!) as just copying the value itself. +> Primitive types should not be passed with `&in`, as the memory address still has to be copied over, resulting in the same hit of performance (or worse!) as just copying the value itself. #### &out + This option specifies that this parameter is an output of a function. This is especially useful whenever you have functions that need to have multiple output values. At the start of a function's execution, this reference will point to an uninitialized variable. After the function returns, the value assigned to this variable will be copied over to the appropriate argument. Example usage of passing by reference of all 3 options: + ```cpp // Example of &in usage void PrintMessage(const string&in msg) { // This will make the compiler try to not copy the argument when calling the function, as we are not modifying it in any way. @@ -220,21 +240,22 @@ bool WholeDivision(int a, int b, int&out result, int&out rest) { int myresult, myrest; -WholeDivision(10, 3, myresult, myrest); //This will set myresult and myrest to the appropriate (3 and 1 respecitvely). +WholeDivision(10, 3, myresult, myrest); //This will set myresult and myrest to the appropriate (3 and 1 respectively). ``` #### &inout / & + This option specifies that this parameter will be passed by reference in both directions. Meaning, the argument will not be copied, and also any changes made to this variable will result in a modified state of the argument outside the function. > [!NOTE] > `&inout` or `&` are **not** supported for primitive types. - --- ## Returning references -Functions can also *return* references. Meaning that they return an address to an object, rather than the object itself. In previous examples we have discussed functions that return by value, meaning that the value of the variable that gets returned, gets copied to a temporary location and then gets "transfered" over to the variable outside the function: +Functions can also *return* references. Meaning that they return an address to an object, rather than the object itself. In previous examples we have discussed functions that return by value, meaning that the value of the variable that gets returned, gets copied to a temporary location and then gets "transferred" over to the variable outside the function: + ```cpp int func(int a) { return a * 2; @@ -250,8 +271,10 @@ Returning references works in a different way, we return an address, that means Before we overview examples, there is one more thing to discuss about returning references. Not every variable can get it's reference returned. In general, variables that don't exist outside the function will not be able to get returned by reference, because they will get erased once the code gets out of the function. -#### 1. References to global variables are allowed. +### 1. References to global variables are allowed. + Returning references to global variables is allowed, because the variable won't get destroyed outside the function. Example: + ```cpp int a = 1; @@ -264,7 +287,8 @@ int& addToA(int b) { addToA(1) = 3; // We add 1 to a, but then we change a to be equal to 3. ``` -#### 2. References to class members and `this` are allowed. +### 2. References to class members and `this` are allowed. + > [!NOTE] > This information will be useful once we get to custom classes and reference types, so if you don't know what these are you can skip this for now. @@ -284,8 +308,10 @@ class myclass { } ``` -#### 3. Returning a reference to a local variable is not allowed. +### 3. Returning a reference to a local variable is not allowed. + Returning a reference to a local variable is not allowed, this is because the variable will not exist after the function returns. + ```cpp int& myFunc() { int a = 1; @@ -293,7 +319,8 @@ int& myFunc() { } ``` -#### 4. Returning a reference to a deferred parameter is not allowed. +### 4. Returning a reference to a deferred parameter is not allowed. + Values passed by reference into a function cannot be returned by reference. This is because AS does additional cleanup after the function returns, hence why there is no guarantee that an object passed by `&in`/`&out` will exist after the function returns. ```cpp @@ -303,14 +330,17 @@ int& func(int a&in ) { ``` > ### TASK 2: +> > Create a function that splits a string into two same-length parts. It should take a string and return a boolean if the string can be split (if the strings length is not divisible by two you cannot create two equal-length parts), and it should also return these two parts (use `&out`). --- -## Function overloads +## Function Overloads + Function overloading is a very powerful concept, as it allows you to declare a function multiple times, each time with a different set of parameters. The compiler will then attempt to choose the best "fit" for which exact function to call (the criteria of how it does so are available on the [official documentation](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script_func_overload.html)). This is mainly used for functions that can accept multiple combinations and types of parameters, but produce a similar result. + ```cpp void myFunc(int a) {...} void myFunc(string a) {...} @@ -342,18 +372,22 @@ myFunc(1, "A"); // Will work > Different return types are allowed for overloads, e.g. one function can return an int, whilst other can return a string (the auto keyword is useful here); however the compiler will not take the return type as a criteria for deciding which overload to use. > ### TASK 3: +> > In the default parameters section there was a problem mentioned about how you cannot explicitly set custom parameters. Given a function: -> ```cpp +> +>```cpp > int printXTimes(string msg, string end = "\n", int x = 1) { > for (int i = 0; i < x; i++) { > Msg(msg + end); -> } +> } > } > ``` +> > Find a way to use it to print 10 times the message "CONSOLE SPAM!" **without specifying a value for the `end` parameter!** > > [!TIP] > > You can call an overload to a different function in an overloaded function: -> > ```cpp +> > +> >```cpp > > void myFunc(int a) {...} > > > > void myFunc(int a, int b) { @@ -362,4 +396,4 @@ myFunc(1, "A"); // Will work > > ``` > [!NOTE] -> If you completed the task above, congratulations! However, please note that this way of solving that problem is only viable when your default parameters have different types, because if they don't, the overload will not work. \ No newline at end of file +> If you completed the task above, congratulations! However, please note that this way of solving that problem is only viable when your default parameters have different types, because if they don't, the overload will not work. diff --git a/docs/angelscript/guide/chapter6.md b/docs/angelscript/guide/chapter6.md index c6e5e121..ace5e21b 100644 --- a/docs/angelscript/guide/chapter6.md +++ b/docs/angelscript/guide/chapter6.md @@ -3,22 +3,25 @@ title: Chapter 6 - Value Types weight: 5 --- - # Chapter 6 - Value Types -## What will you learn in this chapter +## What You Will Learn in This Chapter + In this chapter you will learn about: + - [Value types](#value-types---short-introduction) -- [Constructors](#constructors), -- [Value type initialization](#initializing-a-value-type), +- [Constructors](#constructors) +- [Value type initialization](#initializing-a-value-type) - [Template value types initialization](#initializing-template-value-types) > Value types are a step above primitive types, basically. --- -## Value types - short introduction +## Value Types - Short Introduction + Value types are types that behave a bit differently in AngelScript compared to primitives. They are in some ways similar to primitive types mentioned before, however the main differences are: + - Although it might not always be the case, value types take up (much) more memory, - They support object handles, and should be passed via them, - They have methods, meaning functions that are bound to their type, @@ -32,12 +35,14 @@ Whenever you see a literal, you are **sure** that this literal represents a **sp > [!NOTE] > Value types can only be defined inside the application itself, you cannot create your own value types in AngelScript. User created types are called *reference types*, more on that in further chapters. -## Using value types +## Using Value Types ### Constructors + Constructors are functions that are ran on value type initialization, when an object gets created. They are often overloaded, meaning that you can create an object using different arguments, different types etc. Each type can have their own constuctors defined, thus you should refer to the each type's documentation on the constructors available. As an example, the `Vector` type has 3 different constructors: + ```cpp Vector(); // Calls the default constructor, meaning no arguments are passed Vector(float x, float y, float z); // Constructs vector from 3 floats, respectively x, y, z @@ -54,24 +59,30 @@ Vector v2(v1); //Creates a vector v2, copying data from v1 ``` > [!CAUTION] +> > #### Common mistake - initializing with the assign operator. +> > It is a common mistake to initialize an object using the assign operator, like so: +> > ```cpp > Vector v1 = Vector(1, 2, 3); > ``` +> > This is, indeed, a valid (in the language sense) method to initialize, although this should be avoided if possible. This is because, underneath, what the server is doing is: +> > 1. Creating the object `Vector(1, 2, 3);` > 2. Creating the `v1` Vector using the default constructor. > 3. Calling the assign operator on v1, using data from the right side of the operator > 4. Deleting the right object (`Vector(1, 2, 3)`) -> +> > **This is much more inefficient than just calling the appropriate constructor (which would perform only one of the operations listed above!).** +#### Initializing Template Value Types -#### Initializing template value types Sometimes objects are described with a template, such as the `array` object. Because the `array` class is supposed to be versatile, it can support different types of data for it's values; you can have an array of integers, an array of floats, an array of strings, etc. There is no need to re-create the array class for each and every available data type, as this is where the template functionality is used for. When declaring an array you need to specify the data type of its values, like so: + ```cpp array@ string_array = {"string1", "string2", "string3"}; // Create an array of strings array@ myArray = {1, 2, 3, 4}; // Create an array of integers diff --git a/docs/angelscript/guide/chapter7.md b/docs/angelscript/guide/chapter7.md index 6fba37ef..86579c45 100644 --- a/docs/angelscript/guide/chapter7.md +++ b/docs/angelscript/guide/chapter7.md @@ -5,30 +5,35 @@ weight: 6 # Chapter 7 - Object Handles -## What will you learn in this chapter +## What You Will Learn in This Chapter + In this chapter you will learn about: + - [Object handles](#object-handles) -- [Object handle declaration](#declaration), -- [Object handle expressions](#expressions), -- [The Initialization Problem](#the-initialization-problem), -- [Handle reference counting](#reference-counting), +- [Object handle declaration](#declaration) +- [Object handle expressions](#expressions) +- [The Initialization Problem](#the-initialization-problem) +- [Handle reference counting](#reference-counting) - [Object handle usage in functions](#handles-and-functions) > Object handles are like smart pointers from C++, they don't actually hold an object themselves, rather they hold an address in memory (reference) that can be used to locate the object they point to. --- -## Object handles -These are objects that hold the address of an object, rather than the object itself. Meaning that by using object handles, you are manipulating the information about addresses of objects that are somewhere else, not ""in"" the variable itself. +## Object Handles +These are objects that hold the address of an object, rather than the object itself. Meaning that by using object handles, you are manipulating the information about addresses of objects that are somewhere else, not ""in"" the variable itself. ## Declaration + An object handle is declared by appending the **@** sign after the data type name, e.g.: + ```cpp type@ handle; // Or more explicitly: type@ handle = null; ``` + This code will create a handle of type `type` and point it to null (meaning that it doesn't actually point anywhere). > [!CAUTION] @@ -38,6 +43,7 @@ This code will create a handle of type `type` and point it to null (meaning that > Primitive types don't support object handles. You can access the handle of any reference type by prepending the **@** symbol to the variable: + ```cpp type my_object; @my_object; // This is a handle to my_object @@ -46,7 +52,9 @@ type@ objhandle = @my_object; // Store the object handle in a handle variable ``` ## Expressions + In expressions, object handles are treated *almost always* exactly the same as object variables themselves, which is something very specific to the AngelScript language. This means that: + ```cpp type my_object; type@ my_handle = @my_object; @@ -55,6 +63,7 @@ type@ my_handle = @my_object; my_handle.Method(); // In C++, you would need to use the -> operator here, but this is not the case with AngelScript. my_object.Method(); ``` + In most of times the compiler will automatically know what you are trying to do, however, in order to explicitly call a handle operation you have to **prepend the variable name with the handle symbol (@)**. ```cpp @@ -71,12 +80,13 @@ objhandle = @obj1; // This will not work, and will make the script not compile. ## The Initialization Problem As explained in chapter 6, initializing value types with the assign operator is well performant. -As an example, let's assume the `object` class implements opAssign (assignement operator method), doing: +As an example, let's assume the `object` class implements opAssign (assignment operator method), doing: + ```cpp type my_object = 10; ``` -Will result in the previously explained behaviour, which is **not recommended**, however, doing: +Will result in the previously explained behavior, which is **not recommended**, however, doing: ```cpp type@ my_object = 10; @@ -85,6 +95,7 @@ Vector@ vec_handle = @Vector(1, 2, 3); // or array@ array_handle = {1, 2, 3}; ``` + **Is fine to do**, because here an object gets created once, and assignment is done on the object handle, not the object itself! This doesn't result in so many calls being made, because that calls the internal opAssign method (which should return a reference to the `type` type (us)), and so, we are actually doing a handle assignment (that assigns the handle to the same object, but in which opAssign has modified the internal properties). This is a completely valid way of declaring and initializing a value type. This code will call the default constructor, then opAssign(10). It depends on the implementation, but the performance hit here should be marginal (mainly because we're doing way less memory writes/reads). @@ -104,7 +115,8 @@ Vector@ MagicVector() { return @v1; } -... { +... +{ Vector@ magic_vector = MagicVector(); @@ -113,29 +125,29 @@ Vector@ MagicVector() { magic_vector = null; // Since this was the only handle pointing to the v1 object, it got deleted. - } ``` This gets especially useful when initializing reference types (the most advanced of data type), because you can initialize them directly to a handle: + ```cpp my_type@ my_handle = @my_type(...); ``` -There is no need to separately intialize my_type to a variable (`my_type my_obj(...);`). +There is no need to separately initialize my_type to a variable (`my_type my_obj(...);`). -## Handles and functions. +## Handles and Functions -In this regard, handles behave very similarly to primitives. You can pass them as arguments, specify them as parameters, return them, etc... +Handles can be passed as arguments for function and they can be returned. ```cpp void scale(Vector@ v1_handle, const int factor) { - v1 *= factor; + @v1_handle *= factor; } ``` + > [!NOTE] > In the example above, the object passed with the handle **will** get modified outside the function. Here what gets copied is the handle, **not** the object underneath! > [!NOTE] -> Handles also support passing by reference, meaning that specifying e.g. `Vector@&out` will be valid. -> #### TODO: Do the same restrictions as for primitives (no &in) apply? \ No newline at end of file +> Handles also support passing by reference, meaning that specifying e.g. `Vector@&out`, `Vector@&in` and `Vector@&` will be valid. diff --git a/docs/angelscript/guide/language/meta.json b/docs/angelscript/guide/language/meta.json new file mode 100644 index 00000000..851cd864 --- /dev/null +++ b/docs/angelscript/guide/language/meta.json @@ -0,0 +1,4 @@ +{ + "title": "The AngelScript Language", + "weight": 0 +} diff --git a/docs/angelscript/guide/meta.json b/docs/angelscript/guide/meta.json index fa31d875..726152cc 100644 --- a/docs/angelscript/guide/meta.json +++ b/docs/angelscript/guide/meta.json @@ -1,4 +1,4 @@ { - "title": "Beginner's Guide", + "title": "AngelScript Guides", "weight": 0 } From 083e7ff5527412de3ce227cb21a3e7575a2697fb Mon Sep 17 00:00:00 2001 From: Enderek Date: Wed, 29 Apr 2026 21:29:58 +0200 Subject: [PATCH 19/23] change: Move stuff around to have a place for an implementation guide --- docs/angelscript/guide/Game Engine/meta.json | 4 ++++ .../guide/Hammer World Editor/meta.json | 4 ++++ .../{chapter2.md => Language Basics/chapter1.md} | 6 +++--- .../{chapter3.md => Language Basics/chapter2.md} | 4 ++-- .../{chapter4.md => Language Basics/chapter3.md} | 4 ++-- .../{chapter5.md => Language Basics/chapter4.md} | 6 +++--- .../{chapter6.md => Language Basics/chapter5.md} | 4 ++-- .../{chapter7.md => Language Basics/chapter6.md} | 4 ++-- docs/angelscript/guide/Language Basics/meta.json | 4 ++++ .../guide/{chapter1.md => introduction.md} | 16 ++++++++++++++-- docs/angelscript/guide/language/meta.json | 4 ---- 11 files changed, 40 insertions(+), 20 deletions(-) create mode 100644 docs/angelscript/guide/Game Engine/meta.json create mode 100644 docs/angelscript/guide/Hammer World Editor/meta.json rename docs/angelscript/guide/{chapter2.md => Language Basics/chapter1.md} (96%) rename docs/angelscript/guide/{chapter3.md => Language Basics/chapter2.md} (98%) rename docs/angelscript/guide/{chapter4.md => Language Basics/chapter3.md} (99%) rename docs/angelscript/guide/{chapter5.md => Language Basics/chapter4.md} (99%) rename docs/angelscript/guide/{chapter6.md => Language Basics/chapter5.md} (98%) rename docs/angelscript/guide/{chapter7.md => Language Basics/chapter6.md} (98%) create mode 100644 docs/angelscript/guide/Language Basics/meta.json rename docs/angelscript/guide/{chapter1.md => introduction.md} (92%) delete mode 100644 docs/angelscript/guide/language/meta.json diff --git a/docs/angelscript/guide/Game Engine/meta.json b/docs/angelscript/guide/Game Engine/meta.json new file mode 100644 index 00000000..1a8eb566 --- /dev/null +++ b/docs/angelscript/guide/Game Engine/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Game Engine", + "weight": 2 +} diff --git a/docs/angelscript/guide/Hammer World Editor/meta.json b/docs/angelscript/guide/Hammer World Editor/meta.json new file mode 100644 index 00000000..e3394732 --- /dev/null +++ b/docs/angelscript/guide/Hammer World Editor/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Hammer World Editor", + "weight": 3 +} diff --git a/docs/angelscript/guide/chapter2.md b/docs/angelscript/guide/Language Basics/chapter1.md similarity index 96% rename from docs/angelscript/guide/chapter2.md rename to docs/angelscript/guide/Language Basics/chapter1.md index 092c3779..9f5ff3a4 100644 --- a/docs/angelscript/guide/chapter2.md +++ b/docs/angelscript/guide/Language Basics/chapter1.md @@ -1,9 +1,9 @@ --- -title: Chapter 2 - Primitive Types, Declaration & Assignment +title: Chapter 1 - Primitive Types, Declaration & Assignment weight: 1 --- -# Chapter 2 - Primitive Types, Declaration & Assignment +# Chapter 1 - Primitive Types, Declaration & Assignment ## What You Will Learn in This Chapter @@ -18,7 +18,7 @@ In this chapter you will learn about: > Unfortunately, in this chapter you won't learn anything really interesting, but this knowledge is crucial to continue further. Data types in general are a very extensive subject, but you don't need to know everything. This chapter is supposed to teach you how to handle primitive types in your script. > [!NOTE] -> This chapter won't cover every detail about any of data types, it is recommended you visit the [Data Types Section](../game/type) of the wiki for more information. +> This chapter won't cover every detail about any of data types, it is recommended you visit the [Data Types Section](../../game/type) of the wiki for more information. > Alternatively, you can find references on the [AS Official Documentation](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes.html), however please note that Strata's wiki will be the most representative, some functionality might have been changed! --- diff --git a/docs/angelscript/guide/chapter3.md b/docs/angelscript/guide/Language Basics/chapter2.md similarity index 98% rename from docs/angelscript/guide/chapter3.md rename to docs/angelscript/guide/Language Basics/chapter2.md index d6a62f1e..682869d7 100644 --- a/docs/angelscript/guide/chapter3.md +++ b/docs/angelscript/guide/Language Basics/chapter2.md @@ -1,9 +1,9 @@ --- -title: Chapter 3 - Statements, Expressions, Conditions & Variable Scope +title: Chapter 2 - Statements, Expressions, Conditions & Variable Scope weight: 2 --- -# Chapter 3 - Statements, Expressions, Conditions & Variable Scope +# Chapter 2 - Statements, Expressions, Conditions & Variable Scope ## What You Will Learn in This Chapter diff --git a/docs/angelscript/guide/chapter4.md b/docs/angelscript/guide/Language Basics/chapter3.md similarity index 99% rename from docs/angelscript/guide/chapter4.md rename to docs/angelscript/guide/Language Basics/chapter3.md index d7e94312..b3f30c4e 100644 --- a/docs/angelscript/guide/chapter4.md +++ b/docs/angelscript/guide/Language Basics/chapter3.md @@ -1,9 +1,9 @@ --- -title: Chapter 4 - Loops +title: Chapter 3 - Loops weight: 3 --- -# Chapter 4 - Loops +# Chapter 3 - Loops ## What You Will Learn in This Chapter diff --git a/docs/angelscript/guide/chapter5.md b/docs/angelscript/guide/Language Basics/chapter4.md similarity index 99% rename from docs/angelscript/guide/chapter5.md rename to docs/angelscript/guide/Language Basics/chapter4.md index 9d7fe91b..cd44be14 100644 --- a/docs/angelscript/guide/chapter5.md +++ b/docs/angelscript/guide/Language Basics/chapter4.md @@ -1,9 +1,9 @@ --- -title: Chapter 5 - Functions +title: Chapter 4 - Functions weight: 4 --- -# Chapter 5 - Functions +# Chapter 4 - Functions ## What You Will Learn in This Chapter @@ -88,7 +88,7 @@ string mystr = "ABC"; mystr.length(); // Returns the length of this string (3) ``` -For a list of available methods per each type please refer to the [types section](../game/type) of this wiki. +For a list of available methods per each type please refer to the [types section](../../game/type) of this wiki. > [!NOTE] > Primitive types (`int`, `float`, `bool`, etc.) don't implement any methods. diff --git a/docs/angelscript/guide/chapter6.md b/docs/angelscript/guide/Language Basics/chapter5.md similarity index 98% rename from docs/angelscript/guide/chapter6.md rename to docs/angelscript/guide/Language Basics/chapter5.md index ace5e21b..041aabc4 100644 --- a/docs/angelscript/guide/chapter6.md +++ b/docs/angelscript/guide/Language Basics/chapter5.md @@ -1,9 +1,9 @@ --- -title: Chapter 6 - Value Types +title: Chapter 5 - Value Types weight: 5 --- -# Chapter 6 - Value Types +# Chapter 5 - Value Types ## What You Will Learn in This Chapter diff --git a/docs/angelscript/guide/chapter7.md b/docs/angelscript/guide/Language Basics/chapter6.md similarity index 98% rename from docs/angelscript/guide/chapter7.md rename to docs/angelscript/guide/Language Basics/chapter6.md index 86579c45..4c06477f 100644 --- a/docs/angelscript/guide/chapter7.md +++ b/docs/angelscript/guide/Language Basics/chapter6.md @@ -1,9 +1,9 @@ --- -title: Chapter 7 - Object Handles +title: Chapter 6 - Object Handles weight: 6 --- -# Chapter 7 - Object Handles +# Chapter 6 - Object Handles ## What You Will Learn in This Chapter diff --git a/docs/angelscript/guide/Language Basics/meta.json b/docs/angelscript/guide/Language Basics/meta.json new file mode 100644 index 00000000..b261aa76 --- /dev/null +++ b/docs/angelscript/guide/Language Basics/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Language Basics", + "weight": 1 +} diff --git a/docs/angelscript/guide/chapter1.md b/docs/angelscript/guide/introduction.md similarity index 92% rename from docs/angelscript/guide/chapter1.md rename to docs/angelscript/guide/introduction.md index cb9ad126..aa267913 100644 --- a/docs/angelscript/guide/chapter1.md +++ b/docs/angelscript/guide/introduction.md @@ -1,9 +1,9 @@ --- -title: Chapter 1 - Introduction +title: Introduction weight: 0 --- -# Chapter 1 - Introduction +# Introduction ## What You Will Learn in This Chapter @@ -47,6 +47,18 @@ AngelScript allows for a closer connection to the internal engine code by having While VScript (mainly) sits between entities and handles the interactions between them, AngelScripts sits in a level above, being able to *create* entities and define their behavior. +--- + +## This guide + +This guide is split into two parts: +1. Language Basics - is supposed to teach you how to program in AngelScript, but it doesn't contain any information about on any Strata-specific feature, such as entity creation, command registering and so on. + +2. Game Engine - contains tutorials on using AngelScript inside the game itself. This includes entity creation, custom command making, etc. + +3. Hammer World Editor - contains tutorials on various topics regarding the AngelScript implementation in the Hammer World Editor program. + + --- ## AngelScript in Strata Source diff --git a/docs/angelscript/guide/language/meta.json b/docs/angelscript/guide/language/meta.json deleted file mode 100644 index 851cd864..00000000 --- a/docs/angelscript/guide/language/meta.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "title": "The AngelScript Language", - "weight": 0 -} From 05aeef17867bb0ec235300827648e29e58b58937 Mon Sep 17 00:00:00 2001 From: Enderek Date: Fri, 1 May 2026 23:23:49 +0200 Subject: [PATCH 20/23] add: chapter 7, constant handles chapter in chapter 6 --- .../guide/Language Basics/chapter6.md | 28 ++ .../guide/Language Basics/chapter7.md | 368 ++++++++++++++++++ 2 files changed, 396 insertions(+) create mode 100644 docs/angelscript/guide/Language Basics/chapter7.md diff --git a/docs/angelscript/guide/Language Basics/chapter6.md b/docs/angelscript/guide/Language Basics/chapter6.md index 4c06477f..239a1939 100644 --- a/docs/angelscript/guide/Language Basics/chapter6.md +++ b/docs/angelscript/guide/Language Basics/chapter6.md @@ -151,3 +151,31 @@ void scale(Vector@ v1_handle, const int factor) { > [!NOTE] > Handles also support passing by reference, meaning that specifying e.g. `Vector@&out`, `Vector@&in` and `Vector@&` will be valid. + +--- + +## Constant handles + +Handles can be declared as constant, declared read-only, or both. A constant handle is a handle that points to a constant object, but is not constant by itself, which is a bit counter-intuitive. A read-only handle however, is a handle that once initialized, cannot point to a different object. + +```cpp +my_type a(...); + +my_type@ h1 = @a; // Read/write handle to a modifiable object + +const my_type@ h2 = @a; // Read/write handle to a constant object! +// The syntax here is also a bit counter-intuitive + +// Alternatively, creating a handle whilst creating an object: +const my_type@ h2_b = @my_type(...); + + +my_type@ const h3 = @a; // Read only handle to a modifable object + +const my_type@ const h4 = @a; // Constant, read only handle + +``` + +Quoting AngelScript documentation: + +> A handle to a non-modifiable object can refer to both modifiable objects and non-modifiable objects, but the script will not allow the object to be modified through that handle, nor allow the handle to be passed to another handle that would allow modifications. diff --git a/docs/angelscript/guide/Language Basics/chapter7.md b/docs/angelscript/guide/Language Basics/chapter7.md new file mode 100644 index 00000000..3346207f --- /dev/null +++ b/docs/angelscript/guide/Language Basics/chapter7.md @@ -0,0 +1,368 @@ +--- +title: Chapter 7 - Object Oriented Programming +weight: 7 +--- + +# Chapter 7 - Object Oriented Programming + +## What You Will Learn in This Chapter + +In this chapter you will learn about: + +- [Object handles](#object-handles) +- [Object handle declaration](#declaration) +- [Object handle expressions](#expressions) +- [The Initialization Problem](#the-initialization-problem) +- [Handle reference counting](#reference-counting) +- [Object handle usage in functions](#handles-and-functions) + +> Object oriented programming is the second branch of programming you could say. Here you learn how to manipulate data in a more efficient way, by defining custom data types. + +--- + +## Classes + +Classes are definitions of your custom data types, that get initialized into objects. You can compare them to other data types by imagining that an entity in the Source Engine (e.g. logic_relay, prop_static, etc.) is your standard data type, like the integer or bool types. In this comparsion, a class would be an instance file. Something that you can reuse across multiple scripts (maps). + +Classes hold properties and methods. Properties are the "variables" that the class holds. They can be any data type (including handles!). + +Methods are functions that belong to a specific class. They live in one space, globally accessible to objects of this class. + +Although not technically needed in a language sense, each class (that you later intend to initialize) needs **at least one constructor**. Otherwise, trying to intialize such class will result in an error. + +Let's start by defining a simple class: + +```cpp +class MyClass { + + // Properties + int a; + float b; + bool c; + + // Default constructor (takes no parameters) + MyClass() { + a = 0; + b = 0; + c = false; + } +} + +// Then, this class can be used like so: + +MyClass my_object(); +my_object.a = 2; +my_object.b = 1; +my_object.c = my_object.a == 1; +``` + +--- + +## Methods and `this` keyword. + +As mentioned previously, methods are a way to bind specific functions to a class type. Additionally, you can use the `this` keyword inside declared methods, to reference the object the method was called on. + +Methods are declared the same way functions are. + +```cpp +class MyClass() { + + int a; + int b; + + MyClass(int a, int b) { + this.a = a; // Constructors also have access to `this` + this.b = b; // Here we don't get a name conflict, because this.a explicitly points to "a" that resides in the object namespace. + } + + void Mult(int c) { + this.a *= c; + this.b *= c; + } + + int GetAB() { + return this.a * this.b; + } +} + +// Example usage: +MyClass obj(1, 5); + +obj.Mult(3); +int k = obj.GetAB(); // k = 45 + +``` +> [!NOTE] +> `this` keyword is technically not needed in most cases. However, for code readability, it's most often recommended, so that the reader knows that you are referencing something that's been declared inside this object. + +--- + +## Constant Methods + +Methods can also be declared constant. This has very big implications for both usage and performance. Constant methods declare the method as something that under no circumstances can modify anything inside the object. It can only read the data, and trying to write will result in a compiler error. + +```cpp +class MyClass() { + int a; + int b; + + MyClass() {...} + + const int GetAB() { + return this.a * this.b; // A very good usage of a constant method, no value is modified here. + } + + /* Bad example that won't compile: + const void Mult(int c) { + this.a *= c; // ERROR: this is a write operation, in a constant method + this.b *= c; + } + */ + + void Mult(int c) { + this.a *= c; + this.b *= c; + } +} + +//... + +MyClass obj(1, 5); + +obj.Mult(3); +int k = obj.GetAB(); // k = 45 + +``` + +The code from above will behave the exact same way as before. However, there is a difference when an object is passed around in code as constant. For example, in constant handles, or as `&in` in functions. In these cases, **only the constant methods can be called!** Calling any other method that isn't declared as constant will result in an error: + +```cpp +// Given code above... + +const MyClass@ obj_handl = @obj; + +int l = obj_handl.GetAB(); // l = 45 + +/* + obj_handl.Mult(10); //ERROR +*/ + +void CoolFunction(MyClass&in val) { + int z = val.GetAB(); // z = 45 + + /* + val.Mult(15); // ERROR + */ +} +``` +--- + +## Constructors + +Constructors have been mentioned previously, but they are a much broader topic than that. They can be divided into four types: + +1. [Default Constructor](#default-constructor) - one constructor that doesn't have any parameters. +2. [Copy Constructor](#copy-constructor) - a constructor that takes an object of the same type. This is most often used to copy data from the argument object to us, hence the name. +3. [Type Conversion Constructors](#type-conversion-constructors) - constructors that can be used to implicitly convert other data types to our type. Always with one parameter. +4. [Other Constructors](#other-constructors) - other constructors accepting various parameters. + +> [!NOTE] +> You cannot call other constructors from constructors. If you wish to share functionality between constructors, bundle it into a method, these can then be called from constructors. + +### Default constructor + +A default constructor is one that doesn't accept any parameters. It is the simplest of all, and is used to create a blank object. + +```cpp +class MyClass { + int a; + int b; + + MyClass() { + int.a = 0; + int.b = 0; + } +} + +MyClass obj; // This will use the default constructor +MyClass obj2(); // This will too +``` + +### Copy constructor + +The copy constructor is used to explicitly state the copying process. Without it, the compiler will use the default constructor, and then try to copy everything using the assign operator. A copy constructor is much more effective and performant though, besides that you can run additional code to ensure that things get properly initialized. + +Copy constructors are most often defined with the `const &in` options. Most likely you don't want to modify the object **or accidentally copy by passing it as an argument**. + +```cpp +class MyClass { + int a; + int b; + + MyClass() {...} //Default constructor + + MyClass(const MyClass&in them) { // Copy constructor + this.a = them.a; + this.b = them.b; + //Additional code... + } + +} + +// Example usage: + +MyClass obj1; +...; + +MyClass obj2(obj1); // Explicit call of the copy constructor + +MyClass obj2 = obj1; // Implicit call of the copy constructor in the form of an assignment operator. +``` + +### Type Conversion Constructors + +Type conversion constructors are used to perform, well, type conversions to the given type. They will be used by the compiler whenever it needs to perform such conversions, given an appropriate constructor is specified. + +It is also possible to flag such a constructor with the `explicit` keyword, which will dissallow the compiler from using that constructor implicitly to perform type conversion. Then the constructor will only be called when initializing an object directly. + +```cpp +class MyClass { + int a; + + MyClass() { + this.a = 0; + } + + MyClass(int a) { + this.a = a; + } + + MyClass(float a) { + this.a = a / 10; + // Let's say that in case of converting from float, we divide by 10 and convert to int. + } + + MyClass(string a) explicit { // Explicit constructor, compiler will not use this to convert string to MyClass. + ... + } +} + +// Example usage: + +void MyFunc(MyClass w) { + ... +} + +MyFunc(10); // Will initialize MyClass using the 'int' constructor. +MyFunc(5.5); // Will initialize MyClass using the 'float' constructor. +``` + +### Other Constructors +Besides the types specified above, constructors can accept any amount of parameters of any type. You can easily combine and overload constructors to your desire. + +--- + +## Object Destructor + +Similarly to constructors, an (**one**) object destructor can be specified, in order to explicitly perform operations when an objects gets erased from memory. However, it is important to note, that because AngelScript uses garbage collection for memory management, it is unknown *when* exactly a destructor will be called. + +A destructor is declared the exact same way as a constructor, however with the tilde (`~`) symbol before the name: + +```cpp +class MyClass() { + //Properties + ... + + // Constructors + MyClass() {...} + + //Destructor + ~MyClass() { + this.property.CallDestroyed(); + // This example calls the CallDestroyed() method on the object stored in "property" to let it know that we've been removed. + } +} +``` + +## Operator Overloads + +In classes, you can overwrite the given operators and change their behaviour. For example the `+` operator, or the `/` operator, and many more! Operator overloads are defined as methods in the object with an appropriate name. They can also be overloaded by themselves, meaning that you can have different behaviours for different data types that are on the right side of the operator. + +The list of function names and their corresponding operators can be found in the [AngelScript documentation](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script_class_ops.html), where `op` is the operator, and `opfunc` is the method name used. + +Here's an example of a class using operator overloads: +```cpp +class MyClass { + + int a; + int b; + + // Constructors + MyClass() {...} + + // Operator overloads + MyClass opAdd(const MyClass&in other) { + // Operation that adds two objects and returns a new one with the result + MyClass newobj(this); // Use the copy constructor + newobj.a += other.a; + newobj.b += other.b; + return newobj; + } + + MyClass& opAddAssign(const MyClass&in other) { + this.a += other.a; + this.b += other.b; + return this; + + // Notice how here we don't copy the object. It's because we're also doing assignment. + } + + bool opEquals(const MyClass&in other) { + return this.a == other.a && this.b == other.b; + } + +} +``` + + +Although operator overloads behave mostly the same, there are a couple of differences between different types of operators. + +### Unary operators + +### Comparison operators + +### Assignment operators + +### Binary operators + +### Index operator + +### Functor operator + +### Type conversion operators + +### Foreach loop operators + + + + +The list of function names and their corresponding operators can be found in the [AngelScript documentation](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script_class_ops.html), where `op` is the operator, and `opfunc` is the method name used. + +Here's an example of overloading operators: +```cpp +class MyClass { + + int a; + int b; + + // Constructors + MyClass() {...} + + // Operator overloads + MyClass& opAdd() + + +} + + +``` \ No newline at end of file From 2a2969618448feb1365430c5407e02444a3634ed Mon Sep 17 00:00:00 2001 From: Enderek Date: Wed, 6 May 2026 22:04:13 +0200 Subject: [PATCH 21/23] change: Chapter 7 done --- .../guide/Language Basics/chapter7.md | 98 +++++++++++++++++-- 1 file changed, 89 insertions(+), 9 deletions(-) diff --git a/docs/angelscript/guide/Language Basics/chapter7.md b/docs/angelscript/guide/Language Basics/chapter7.md index 3346207f..fea48fb8 100644 --- a/docs/angelscript/guide/Language Basics/chapter7.md +++ b/docs/angelscript/guide/Language Basics/chapter7.md @@ -9,12 +9,11 @@ weight: 7 In this chapter you will learn about: -- [Object handles](#object-handles) -- [Object handle declaration](#declaration) -- [Object handle expressions](#expressions) -- [The Initialization Problem](#the-initialization-problem) -- [Handle reference counting](#reference-counting) -- [Object handle usage in functions](#handles-and-functions) +- [Classes](#classes) +- [Methods and *this* keyword](#methods-and-this-keyword) +- [Constant methods](#constant-methods) +- [Constructors](#constructors) +- [Operator overloads](#operator-overloads) > Object oriented programming is the second branch of programming you could say. Here you learn how to manipulate data in a more efficient way, by defining custom data types. @@ -58,7 +57,7 @@ my_object.c = my_object.a == 1; --- -## Methods and `this` keyword. +## Methods and *this* keyword As mentioned previously, methods are a way to bind specific functions to a class type. Additionally, you can use the `this` keyword inside declared methods, to reference the object the method was called on. @@ -326,25 +325,105 @@ class MyClass { Although operator overloads behave mostly the same, there are a couple of differences between different types of operators. +Below is a short compilation of the most important things to know: + +> [!NOTE] +> Whenever there is a mention of "us", it means the object the method is being called on. ### Unary operators +1. Prefixed unary operators should return a modified object (by reference) +2. Postfixed unary operators should return a copy of the object (make a copy, do modifications, return the copy). Alternatively, to avoid the overhead of copying a value when returning from a function, you can overload these operators based on handles (accept a handle as a parameter and return a handle). + + ### Comparison operators +1. opEquals operators should return a boolean. +2. In case of `opEquals` (`==` operator), the expression (`a == b`) is re-written as `a.opEquals(b)` or `b.opEquals(a)` depending on the available methods (best fit is used). +3. Comparison operators (`>`, `<`, ...) - \[opCmp method] should return an integer. If the argument is larger than us, the return value should be negative, else positive. If objects are equal the return value should be 0. (`a < b => a - b < 0`...) + ### Assignment operators +1. Assignment operators should return by reference, and in almost all cases, should return a reference to us, that is to allow operator chaining (e.g. `a = b = c`). +2. It depends on the specific use case, however `opAssign (=)` should in most cases, copy the properties of argument object to us. +3. The compiler will automatically generate an `opAssign` method if no is specified, that copies all properties. If this is not desired, you can explicitly disable this behaviour with `MyClass& opAssign(const MyClass &inout) delete;`. +4. All other assignment operators should only modify the object, not make copies! + ### Binary operators +1. All binary operators have two methods that they can be overloaded on: `opX` and `opX_r`. This is because the compiler will try to rewrite the expression `a x b` as `a.opX(b)` or `o.opX_r(b)`, depending on the best fit. This can mean, that even if the class of `a` doesn't implement that operator, you can still perform `a x b` by using the `_r` method. This is especially useful for operations that are not alternating. + +2. These operators should return a copy of objects, thus returning by value. Whether you copy `a` or `b`, doesn't matter much, however make sure to apply appropriate changes onto that copy. + +3. In order to save on performance on returning a value, consider specifying the operators as handle based (meaning that they take a handle and return a handle). This way an object is not copied (besides the copy inside the method, that is done to not make changes on `a` or `b`). Additionally, you can specify two overloads, one for a handle input that returns a handle, and one that returns by value, example: + 1. `MyClass@ opAdd(MyClass@ other) {...}` + 2. `MyClass opAdd(const MyClass&in other) {...}` + ### Index operator +1. Expression `a[i]` gets rewritten to `a.opIndex(i)`. +2. Multiple arguments are allowed, e.g. `a[i, j, k]` => `a.opIndex(i, j, k)` +3. The index operator can also be written as a pair of property accessors, `get_opIndex(...)` and `set_opIndex(...)`. These are called on getting a value and setting a property respectively. `get_opIndex` should generally have a return type of the value you're retrieving, and `set_opIndex` should return void. + ### Functor operator +The expression `a(i, j, k, ...)` will get rewritten to `a.opCall(i, j, k, ...)`. + ### Type conversion operators -### Foreach loop operators +#### Value conversions +1. Explicit conversions, e.g.: `type(a)` will make the compiler try: + 1. Constructing object of type `type` using a constructor that can accept the type of `a`. + 2. Try to call `opConv` on `a` that returns `type`. + 3. Try to call `opImplConv` on `a` that returns `type`. + +2. Implicit conversions will try to also call the constructor first, then **skip** `opConv` and go to `opImplConv` +3. `opConv` and `opImplConv` methods get differentiated based on the return type. +4. The methods above are supposed to be used for value conversions, meaning that they should return a copy of the data with the appropriate type. +#### Reference casts +1. Reference casts are done on handles! +2. Casts can be overloaded with the `opCast` or `opImplCast` methods, for explicit and implicit casting. +3. On explicit casts the compiler will try to use `opCast` first, then `opImplCast`. +4. Implicit casts only use `opImplCast`. +### Foreach loop operators +You can override the behaviour of the `foreach` loop by overloading `opForBegin`, `opForEnd`, etc. It's best to look at the official documentation about this: + +> | op | opfunc | +> |--------------------------|------------| +> | begin *foreach* | opForBegin | +> | end *foreach* | opForEnd | +> | next *foreach iteration* | opForNext | +> | *foreach value* | opForValue, opForValue0, opForValue1, opForValue2...| +> +> When the compiler tries to compile a foreach loop it will need a use a set of methods on the container type. +> ```cpp +> foreach( auto val, auto key : expr ) +> { +> ... +> } +> ``` +> +> The above will be compiled as if it was written as +> ```cpp +> for( auto @container = expr, auto @it = container.opForBegin(); !container.opForEnd(it); @it = container.opForNext(it) ) +> { +> auto val = container.opForValue0(it); +> auto key = container.opForValue1(it); +> ... +> } +> ``` +> +> Where the types support handles the compiler will use handle assignments, otherwise it will use value assignments. +> +> The iterator type returned by opForBegin, can be a simple integer for indexing, or an iterator class if more complex operations are needed for keeping track of the iterations. +> +> If the container only supports a single value, then the operator opForValue can be used, otherwise multiple numbered opForValue# operators must be used. + + +### Operator overloads - misc The list of function names and their corresponding operators can be found in the [AngelScript documentation](https://www.angelcode.com/angelscript/sdk/docs/manual/doc_script_class_ops.html), where `op` is the operator, and `opfunc` is the method name used. @@ -359,7 +438,8 @@ class MyClass { MyClass() {...} // Operator overloads - MyClass& opAdd() + MyClass@ opAdd(MyClass@ other) {...} // Handle + MyClass opAdd(const MyClass&in other) {...} // Value } From 30c8d59b7c5d75bf2f2d3590d1575c8f83a4a9fb Mon Sep 17 00:00:00 2001 From: Enderek Date: Wed, 6 May 2026 22:04:25 +0200 Subject: [PATCH 22/23] add: Reserve space for chapter 8 and 9 --- docs/angelscript/guide/Language Basics/chapter8.md | 4 ++++ docs/angelscript/guide/Language Basics/chapter9.md | 9 +++++++++ 2 files changed, 13 insertions(+) create mode 100644 docs/angelscript/guide/Language Basics/chapter8.md create mode 100644 docs/angelscript/guide/Language Basics/chapter9.md diff --git a/docs/angelscript/guide/Language Basics/chapter8.md b/docs/angelscript/guide/Language Basics/chapter8.md new file mode 100644 index 00000000..168dc5a5 --- /dev/null +++ b/docs/angelscript/guide/Language Basics/chapter8.md @@ -0,0 +1,4 @@ +--- +title: Chapter 8 - Inheritance and Polymorphism +weight: 8 +--- \ No newline at end of file diff --git a/docs/angelscript/guide/Language Basics/chapter9.md b/docs/angelscript/guide/Language Basics/chapter9.md new file mode 100644 index 00000000..2b4d95ce --- /dev/null +++ b/docs/angelscript/guide/Language Basics/chapter9.md @@ -0,0 +1,9 @@ +--- +title: Chapter 9 - Other features +weight: 9 +--- + +# Enums + +# Namespaces + From e2ef166fcce0c6c167931f456d38d4d2f16aef2f Mon Sep 17 00:00:00 2001 From: Enderek Date: Thu, 7 May 2026 10:30:35 +0200 Subject: [PATCH 23/23] fix: Remove the info, as `const` would make the compiler not copy when invoking a function. --- docs/angelscript/guide/Language Basics/chapter4.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/angelscript/guide/Language Basics/chapter4.md b/docs/angelscript/guide/Language Basics/chapter4.md index cd44be14..e9b40c12 100644 --- a/docs/angelscript/guide/Language Basics/chapter4.md +++ b/docs/angelscript/guide/Language Basics/chapter4.md @@ -149,8 +149,6 @@ Constant parameters work just like constant variables. If declare a certain para void myFunc(const int a, const bool y = true) // Default parameters can also be constants ``` -One important note is that declaring a const parameter will make the compiler not copy the object (if it ensures the object's lifetime). More on that will be in the next chapters. - > ### TASK 1: > > Create a function that computes the nth number of the Fibonacci sequence. It should take uint as the parameter (n) and return an uint (the number). You can tackle this problem recursively (using recursion) or iteratively (using a loop). It is recommend to try out both. @@ -207,7 +205,7 @@ AngelScript implements more functionality to passing by reference, and that incl This marks the parameter as an input to the function. This option provides little to no benefit as to just passing by value (copying), as the compiler still has to ensure the object won't get modified outside the function, and the only way to do that is to make a copy. > [!TIP] -> Combining `&in` with `const` can however, yield a way more optimized code. `&in` should almost always be used whenever you are using a `const` parameter. +> **Combining `&in` with `const` can however, yield a way more optimized code. `&in` should almost always be used whenever you are using a `const` parameter. This actually disables the copying mechanism!** > [!WARNING] > Primitive types should not be passed with `&in`, as the memory address still has to be copied over, resulting in the same hit of performance (or worse!) as just copying the value itself.