-
Notifications
You must be signed in to change notification settings - Fork 26
AngelScript Guide for Begineers #125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
TheEnderek0
wants to merge
23
commits into
main
Choose a base branch
from
as-guide
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
226c925
change: Move Game category to weight 1
TheEnderek0 039690e
add: Chapter 1 mostly done
TheEnderek0 be996f9
add: meta.json for guide category
TheEnderek0 10e56e5
add: Chapter 2 mostly done
TheEnderek0 0aff3b9
add: Initial chapter 3 and chapter X
TheEnderek0 0fdc1d7
change: Mass upate all articles (many, many changes)
TheEnderek0 99f4fc9
change: chapter 4 update
TheEnderek0 1c5a3df
change: Update docs about using C-style like notation for logic opera…
TheEnderek0 b054ab4
change: Change "if else" to "else if"
TheEnderek0 07c0c11
change: Initialize arrays as object handles
TheEnderek0 48ec859
change: misc change to chapter4 - add a line break after the array in…
TheEnderek0 08f5e19
add: Chapter 5 - functions complete
TheEnderek0 3e96421
fix: typos in chapter 5
TheEnderek0 39edea4
change: Remove usage example of &inout from chapter 5
TheEnderek0 e743d9a
Rephrasing and grammar changes (#157)
d0ctorzer0 6a9a90b
add/change: AS guide
TheEnderek0 d545f22
change: minor tweaks to chapter 7
TheEnderek0 c719d8d
fix: Some file structure and grammar fixes for the AS guide
OrsellGit 083e7ff
change: Move stuff around to have a place for an implementation guide
TheEnderek0 05aeef1
add: chapter 7, constant handles chapter in chapter 6
TheEnderek0 2a29696
change: Chapter 7 done
TheEnderek0 30c8d59
add: Reserve space for chapter 8 and 9
TheEnderek0 e2ef166
fix: Remove the info, as `const` would make the compiler not copy whe…
TheEnderek0 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| { | ||
| "title": "Game", | ||
| "type": "angelscript", | ||
| "weight": 0 | ||
| "weight": 1 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "title": "Game Engine", | ||
| "weight": 2 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "title": "Hammer World Editor", | ||
| "weight": 3 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| --- | ||
| title: Chapter 1 - Primitive Types, Declaration & Assignment | ||
| weight: 1 | ||
| --- | ||
|
|
||
| # Chapter 1 - Primitive Types, Declaration & Assignment | ||
|
|
||
| ## 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) | ||
|
|
||
| > 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. | ||
| > 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! | ||
|
|
||
| --- | ||
|
|
||
| ## 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 | ||
|
|
||
| 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 | ||
|
|
||
| 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 | ||
|
|
||
| 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 | ||
| 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 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; | ||
|
|
||
| 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(int s, float i) { | ||
| const float value = s - 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 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). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,180 @@ | ||
| --- | ||
| title: Chapter 2 - Statements, Expressions, Conditions & Variable Scope | ||
| weight: 2 | ||
| --- | ||
|
|
||
| # Chapter 2 - Statements, Expressions, Conditions & Variable Scope | ||
|
|
||
| ## What You Will 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, expressions, conditions and the variable scope are the foundation of every program or script. | ||
| --- | ||
|
|
||
| ## Basic statements | ||
|
|
||
| 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 | ||
|
|
||
| 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, | ||
| - 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(); | ||
| 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 | ||
| ``` | ||
|
|
||
| > [!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 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). | ||
|
|
||
| ```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 `!`, 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 && 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 evaluates 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`/`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 | ||
| } 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 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; | ||
|
|
||
| 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.* | ||
|
|
||
| > [!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). | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line might be unnecessary or confusing?
You can do things like
a().b();ora += b - c;or even probablya(b += c);So it doesn’t always have to end with a semicolon immediately if it’s part of like a sub expression
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically they all are single statements.
a += b - c;is like saying "To a, add the difference between b - c" and this is in fact one statement.So is
a().b();=>On the result of a() call b().Not sure what would
a(b += c);do?