-
Notifications
You must be signed in to change notification settings - Fork 70
Expanded "types of script" page #484
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
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
0718480
Initial work on types of script
ferafiks 054c31c
Mostly finished type specific pages (except one section for async)
ferafiks 53b86f6
Finished async script
ferafiks de1400a
Updated types of script index
ferafiks 3a2cedf
Fixed minor spelling
ferafiks 477e60f
Fixed wrong script types in examples and added api references
ferafiks 5b41b76
Fixed mistakes
ferafiks 2502c02
Small mistake
ferafiks 4522e80
Added a warning for Task.Run
ferafiks 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 was deleted.
Oops, something went wrong.
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,119 @@ | ||
| # Async script | ||
|
|
||
| <span class="badge text-bg-primary">Advanced</span> | ||
| <span class="badge text-bg-success">Programmer</span> | ||
|
|
||
| Asynchronous scripts get executed only once asynchronously. They can be used for initializing the scene and it's contents or performing game logic for every frame. | ||
|
|
||
| ```csharp | ||
| public class Example : AsyncScript | ||
| { | ||
| public override Task Execute() | ||
| { | ||
| // Execute the asynchronous code | ||
| } | ||
|
|
||
| public override void Cancel() | ||
| { | ||
| // Do stuff for when the script is unloaded | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## When to use | ||
|
|
||
| Asynchronous scripts are meant to be used for doing game logic that needs to await something. | ||
|
|
||
| If you **don't need to await any tasks**, consider **using a [startup script](./startup-script.md) or a [synchronous script](./sync-script.md)** instead. | ||
|
|
||
| ## What is asynchronous code? | ||
|
|
||
| Asynchronous programming in C# means writing code that can **run in parallel**. | ||
|
|
||
| For example: let's say we have a method for saving the game's state that **takes 10 seconds** to execute. Instead of pausing everything until it finishes running, **we can run it asynchronously**, meaning that **the game can continue while we are saving the player's progress**. | ||
|
|
||
| An asynchronous method is a normal method that returns a `Task`, which can then be awaited. While it's running, other non asynchronous and asynchronous code will be allowed to run. | ||
|
|
||
| ```csharp | ||
| protected override async Task Execute() | ||
| { | ||
| // Waits for 1 second without freezing the game | ||
| await Task.Delay(1000); | ||
| } | ||
| ``` | ||
|
|
||
| ## Performing code every frame | ||
|
|
||
| In order to keep performing logic for every frame (like a synchronous script), you can use `Script.NextFrame()` in a loop. | ||
|
|
||
| ```csharp | ||
| public class Example : AsyncScript | ||
| { | ||
| public override async Task Execute() | ||
| { | ||
| // Initialization code goes here | ||
|
|
||
| // A loop that will keep running as long as the script is active | ||
| while (Game.IsRunning) | ||
| { | ||
| // Code that gets executed every frame goes here | ||
|
|
||
| await Script.NextFrame(); | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Executing tasks in parallel | ||
|
|
||
| Sometimes it's useful to execute two async tasks in the same script. This can be achieved using [`Script.AddTask()`](xref:Stride.Engine.Processors.ScriptSystem.AddTask). | ||
|
|
||
| ```csharp | ||
| public class Example : AsyncScript | ||
| { | ||
| public override async Task Execute() | ||
| { | ||
| Script.AddTask(ParallelTask); | ||
|
|
||
| // Execute code at the same time as ParallelTask | ||
| } | ||
|
|
||
| private async Task ParallelTask() | ||
| { | ||
| // Execute code at the same time as Execute | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| > [!WARNING] | ||
| > **Avoid using [`Task.Run`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.run)** for parallel tasks, as it will execute your code **on the thread pool instead of the main thread**. This will make interacting with the engine **unsafe** and could result in **unexpected behaviours**. | ||
|
|
||
| ## Overridable methods | ||
|
|
||
| Asynchronous scripts feature 2 methods which can be overridden in order to perform game logic. | ||
|
|
||
| > [!NOTE] | ||
| > These methods **only get called during runtime** - they will never be called in Game Studio. | ||
|
|
||
| ### `Execute()` | ||
|
|
||
| The [Execute](xref:Stride.Engine.AsyncScript.Execute) method gets called when the script is added to the game. For example: | ||
| * When a scene the script is in gets loaded | ||
| * When a new entity containing the script is added to a scene | ||
| * When the script is added to an already existing entity | ||
|
|
||
| The method may be executed more than once if an entity the script is attached to gets removed and then re-added to the scene. | ||
|
|
||
| ### `Cancel()` | ||
|
|
||
| The [Cancel](xref:Stride.Engine.ScriptComponent.Cancel) method gets called when the script is removed from the game. This includes: | ||
| * When a scene the script is in gets unloaded | ||
| * When an entity the script is attached to gets removed from it's scene | ||
| * When the script gets removed from a scene entity | ||
| * When the game gets closed | ||
|
|
||
| The method may be executed more than once if an entity the script is attached to gets re-added and then removed from the scene. | ||
|
|
||
| ## Tutorial | ||
|
|
||
| Check out the [Async scripts tutorial](../../../tutorials/csharpintermediate/async-scripts.md) for more examples. | ||
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,77 @@ | ||
| # Types of script | ||
|
|
||
| <span class="badge text-bg-primary">Beginner</span> | ||
| <span class="badge text-bg-success">Programmer</span> | ||
|
|
||
| There are three main types of script in Stride: **startup scripts**, **synchronous scripts**, and **asynchronous scripts**. | ||
|
|
||
| When you write your script, inherit from the type of script with the behavior that best fits your needs. | ||
|
|
||
| ## Startup scripts | ||
|
|
||
| Startup scripts only run when they are added or removed at runtime. They're mostly used to initialize game elements (eg spawning characters) and destroy them when the scene is unloaded. They have a [Start](./startup-script.md#start) method for initialization and a [Cancel](./startup-script.md#cancel) method. You can override either method if you need to. | ||
|
|
||
| ```cs | ||
| public class Example : StartupScript | ||
| { | ||
| public override void Start() | ||
| { | ||
| // Do some stuff during initialization | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| For more information check out the [startup script page](./startup-script.md). | ||
|
|
||
| ## Synchronous scripts | ||
|
|
||
| Synchronous scripts are initialized, then updated every frame, and finally canceled (when the script is removed). | ||
|
|
||
| * The initialization code, if any, goes in the [Start](./sync-script.md#start) method. | ||
| * The code performing the update goes in the [Update](./sync-script.md#update) method. | ||
| * The code performing the cancellation goes in the [Cancel](./sync-script.md#cancel) method. | ||
|
|
||
| The following script performs updates every frame, no matter what: | ||
|
|
||
| ```cs | ||
| public class Example : SyncScript | ||
| { | ||
| public override void Update() | ||
| { | ||
| // Do stuff that needs to be executed every frame | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| For more information check out the [sync script page](./sync-script.md). | ||
|
|
||
| ## Asynchronous scripts | ||
|
|
||
| Asynchronous scripts are initialized only once, then canceled when removed from the scene. | ||
|
|
||
| * Asynchronous code goes in the [Execute](./async-script.md#execute) function. | ||
| * Code performing the cancellation goes in the [Cancel](./async-script#cancel) method. | ||
|
|
||
| The following script performs actions that depend on events and triggers: | ||
|
|
||
| ```cs | ||
| public class Example : AsyncScript | ||
| { | ||
| public override async Task Execute() | ||
| { | ||
| // Execute asynchronous code | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| For more information check out the [async script page](./async-script.md). | ||
|
|
||
| ## See also | ||
|
|
||
| * [Create a script](create-a-script.md) | ||
| * [Use a script](use-a-script.md) | ||
| * [Public properties and fields](public-properties-and-fields.md) | ||
| * [Scheduling and priorities](scheduling-and-priorities.md) | ||
| * [Events](events.md) | ||
| * [Debugging](debugging.md) | ||
| * [Preprocessor variables](preprocessor-variables.md) |
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,53 @@ | ||
| # Startup script | ||
|
|
||
| <span class="badge text-bg-primary">Beginner</span> | ||
| <span class="badge text-bg-success">Programmer</span> | ||
|
|
||
| Startup scripts run when they are added or removed from a scene. | ||
|
|
||
| ```csharp | ||
| public class Example : StartupScript | ||
| { | ||
| public override void Start() | ||
| { | ||
| // Do stuff for when the script is loaded | ||
| } | ||
|
|
||
| public override void Cancel() | ||
| { | ||
| // Do stuff for when the script is unloaded | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## When to use | ||
|
|
||
| Startup scripts are meant to be used for **executing code once when the scene is loaded or when an entity the script is attached to is added to a scene**. They serve as a way to initialize other scripts and entities, but not control them every frame. | ||
|
|
||
| However, if your code **needs to await asynchronous methods**, then it's advised to **use an [asynchronous script](./async-script.md)** instead. | ||
|
|
||
| ## Overridable methods | ||
|
|
||
| Startup scripts feature 2 methods which can be overridden in order to perform game logic. | ||
|
|
||
| > [!NOTE] | ||
| > These methods **only get called during runtime** - they will never be called in Game Studio. | ||
|
|
||
| ### `Start()` | ||
|
|
||
| The [Start](xref:Stride.Engine.StartupScript.Start) method gets called when the script is added to the game. For example: | ||
| * When a scene the script is in gets loaded | ||
| * When a new entity containing the script is added to a scene | ||
| * When the script gets added to an already existing entity | ||
|
|
||
| The method may be executed more than once if an entity the script is attached to gets removed and then re-added to the scene. | ||
|
|
||
| ### `Cancel()` | ||
|
|
||
| The [Cancel](xref:Stride.Engine.ScriptComponent.Cancel) method gets called when the script is removed from the game. This includes: | ||
| * When a scene the script is in gets unloaded | ||
| * When an entity the script is attached to gets removed from it's scene | ||
| * When the script gets removed from a scene entity | ||
| * When the game gets closed | ||
|
ferafiks marked this conversation as resolved.
|
||
|
|
||
| The method may be executed more than once if an entity the script is attached to gets re-added and then removed from the scene. | ||
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.
Uh oh!
There was an error while loading. Please reload this page.