Forráskód Böngészése

Merge branch 'master' into Eideren-patch-1

Eideren 10 hónapja
szülő
commit
3d7c2a0652

+ 7 - 0
en/ReleaseNotes/ReleaseNotes.md

@@ -8,6 +8,13 @@ Read the full blog post here: [Announcing Stride 4.2](https://www.stride3d.net/b
 
 A massive thank you to the open-source Stride community for your dedicated contributions. This release saw over 75 contributions from more than 22 amazing contributors, each playing a crucial role in making Stride 4.2 a reality.
 
+## Minor releases since the last major release
+
+- [4.2.0.2293](https://github.com/stride3d/stride/releases/tag/releases%2F4.2.0.2293): January 2025
+- [4.2.0.2282](https://github.com/stride3d/stride/releases/tag/releases%2F4.2.0.2282): December 2024
+- [4.2.0.2232](https://github.com/stride3d/stride/releases/tag/releases%2F4.2.0.2232): September 2024
+- [4.2.0.2188](https://github.com/stride3d/stride/releases/tag/releases%2F4.2.0.2188): June 2024
+
 ## What's new in Stride 4.2
 Stride 4.2 includes numerous enhancements and improvements. Here’s what to expect:
 

+ 8 - 2
en/contributors/donate.md

@@ -1,10 +1,16 @@
-# Donating to Stride
+# Donating to Stride
+
 In order to support our contributors or if we want to finance a specific feature, we collect donations from individuals as well as organisations. 
 
 ## Open Collective
+
 We gather funding through a website called [OpenCollective](https://opencollective.com/stride3d). This website displays where all the money is coming from and where it is going to: 100% transparency guaranteed.
 
 ## Projects
-Stride's Open Collective hosts different '[Projects](https://opencollective.com/stride3d/projects)' — think of them as funding goals for specific features or contributions. Each project typically has a related GitHub ticket for more details on what's required for its development. If you're interested in working on or contributing to a particular feature, you can let us know by either replying:
+
+Stride's Open Collective hosts different [Projects](https://opencollective.com/stride3d/projects), think of them as funding goals for specific features or contributions. Each project typically has a related GitHub ticket for more details on what's required for its development.
+
+If you're interested in working on or contributing to a particular feature, you can let us know by either replying:
+
  - In each projects related GitHub thread and mention @stride3d/stride-contributors 
  - In the Stride [Contributors channel on Discord](https://discord.gg/bDhMhGVHvD)

+ 22 - 35
en/contributors/roadmap.md

@@ -1,38 +1,25 @@
 # Roadmap
-The Stride game engine (MIT) is a collaborative endeavor managed by a small group of core volunteer developers, each with expertise in different areas of development. There are no full-time developers dedicated solely to Stride's advancement; instead, the engine progresses through the voluntary contributions of both the [core team](core-team.md) and the broader community. These individuals dedicate their spare time to enhance and expand the engine, motivated by personal interest, passion for the project, or their areas of expertise.
+
+The Stride game engine (MIT) is a collaborative endeavor managed by a small group of core volunteer developers, each with expertise in different areas of development. There are no full-time developers solely focused on Stride's advancement; instead, the engine progresses through the voluntary contributions of both the [core team](core-team.md) and the wider community. These individuals dedicate their spare time to enhance and expand the engine, driven by personal interest, passion for the project, or their areas of expertise.
 
 ## Contributors
-Contributions to Stride come in various forms. Some contributors focus on resolving existing issues, fostering the engine's stability and usability. Others venture into new territories, introducing improvements and features they deem beneficial, are personally intrigued by, or hold expertise in.
-
-## Community Roadmap and Open Collective
-The community has highlighted a range of feature requests, some of which are quite extensive of an Epic nature, requiring a long-term commitment from developers to complete. These larger goals form a "Community Roadmap" of sorts, reflecting the volunteer-driven nature of Stride's development process.
-
-Given the voluntary nature of contributions, the pace of progress hinges largely on the personal commitments and availability of our contributors. However, to catalyze action around certain desired features, Stride has established bounties through the [Open Collective](https://opencollective.com/stride3d). These bounties serve as a rallying call, incentivizing efforts towards tackling specific requests.
-
-- Bepu Physics integration <span class="badge text-bg-warning">In Progress</span>
-  - GitHub: https://github.com/stride3d/stride/pull/2131
-- Migrate Game Studio to Avalonia <span class="badge text-bg-warning">In Progress</span>
-  - GitHub: https://github.com/stride3d/stride/issues/1629
-  - Open collective project: https://opencollective.com/stride3d/projects/editor-rewrite-avalonia
-- Linux/MacOS https://github.com/stride3d/stride/issues/70
-- Improving asset pipeline <span class="badge text-bg-success">Done</span>
-  - Open collective project: https://opencollective.com/stride3d/projects/fbx-import-cpp-to-c-sharp
-  - Open collective project: https://opencollective.com/stride3d/projects/multiple-animations-per-model
-- Morph targets <span class="badge text-bg-info">On Hold</span>
-  - GitHub: https://github.com/stride3d/stride/issues/339
-  - Open collective project: https://opencollective.com/stride3d/projects/morph-targets
-- Decals https://opencollective.com/stride3d/projects/decals
-- Open XR support <span class="badge text-bg-info">On Hold</span>
-  - GitHub: https://github.com/stride3d/stride/discussions/1848
-  - Open collective project: https://opencollective.com/stride3d/projects/openxr-support
-- Embed into UI frameworks
-  - GitHub: https://github.com/stride3d/stride/pull/1315
-  - Open collective project: https://opencollective.com/stride3d/projects/embed-stride-ui-frameworks
-- Silk.NET integration
-  - GitHub: https://github.com/stride3d/stride/pull/
-  - Open collective project: https://opencollective.com/stride3d/projects/stride3d-silknet
-
-Other areas where contributors have been active 
-- Plugins: https://github.com/stride3d/stride/issues/1120
-- Improving Docs
-- Improving Website
+
+Contributions to Stride come in various forms. Some contributors focus on addressing [existing issues](https://github.com/stride3d/stride/issues) to improve stability and usability. Others explore new features or improvements they find valuable, intriguing, or hold expertise in.
+
+## Community Roadmap
+
+The community has highlighted a range of feature requests, some of which are quite extensive and of an epic nature, requiring a long-term commitment from developers to complete. These larger goals form a "Community Roadmap" of sorts, reflecting the volunteer-driven nature of Stride's development process.
+
+You can view the current list of feature requests, to-dos, and in-progress tasks on the [Community Roadmap](https://github.com/orgs/stride3d/projects/13).
+
+## Open Collective
+
+Because all contributions to Stride are voluntary, the pace of development largely depends on each contributor’s personal bandwidth and interests. To help prioritize or incentivize certain features, Stride maintains bounties through the [Open Collective](https://opencollective.com/stride3d/projects). These bounties encourage and reward contributors for tackling specific community requests.
+
+## Other Areas
+
+Contributors have also been active in the following areas:
+
+- [Plugins](https://github.com/stride3d/stride/issues/1120)
+- Improving Documentation
+- Enhancing the Website

+ 5 - 6
en/manual/engine/entity-component-system/managing-entities.md

@@ -21,11 +21,10 @@ This approach also solves many update order dependencies issues (just need to or
 
 Here is some examples of entity processors:
 
-- @'Stride.Engine.TransformationProcessor': Compute transformation matrices from hierarchy and local transformation stored in @'Stride.Engine.TransformationComponent'.
-  
-  As a result, @'Stride.Engine.EntityManager' can be used as a hierarchical scenegraph instead of a simple entity list.
-- @'Stride.Engine.MeshProcessor': Add @'Stride.Engine.ModelComponent.Model' to rendering.
-- @'Stride.Engine.LightProcessor': Collects and update lights, and transfer it to rendering system. It can hides implementation details (deferred or forward rendering, etc...)
+- @'Stride.Engine.Processors.TransformProcessor': Compute transformation matrices from hierarchy and local transformation stored in @'Stride.Engine.TransformComponent'.
+  - As a result, @'Stride.Engine.EntityManager' can be used as a hierarchical scenegraph instead of a simple entity list.
+- @'Stride.Engine.Processors.ModelTransformProcessor': Add @'Stride.Engine.ModelComponent.Model' to rendering.
+- @'Stride.Rendering.Lights.LightProcessor': Collects and update lights, and transfer it to rendering system. It can hides implementation details (deferred or forward rendering, etc...)
 
 ## Entity System
 
@@ -45,5 +44,5 @@ foreach (var entity in engine.EntityManager.Entities)
 
 @'Stride.Engine.EntityManager' can be used to enumerate its `Entities (ref:{Stride.Engine.Entity})`. Note that children of a given entities will also be in this list.
 
-To manipulate entities as a scenegraph, refer to @'Stride.Engine.TransformationComponent' class.
+To manipulate entities as a scenegraph, refer to @'Stride.Engine.TransformComponent' class.
 

+ 5 - 0
en/manual/get-started/install-stride.md

@@ -81,6 +81,9 @@ The **Stride Launcher** will download and install the latest version of Stride.
 
     While the installation is in progress, the release notes are displayed.
 
+    > [!Warning]
+    > If the .NET SDK has never been installed on your machine, the .NET SDK installation window might appear below the Stride installation window. Please check step 12 for details and be prepared to manually continue the .NET SDK installation.
+
 12. During the installation, you might be asked to install the .NET SDK if it's not already on your machine.
 
     ![Installation of .NET SDK](media/install-dotnet-SDK.webp)
@@ -99,6 +102,8 @@ The **Stride Launcher** will download and install the latest version of Stride.
 
 > [!Note]
 >  **Stride Launcher:** If you click **Start** and see an error message such as `Could not find a compatible version of MSBuild.` or `Path to dotnet executable is not set.`, close the Stride Launcher and restart it. This issue is caused by the Stride Launcher not detecting the .NET SDK installation. Restarting the Stride Launcher should resolve the issue. Alternatively, restart your computer.
+>
+> Example error: ![First launch error](media/stride-launcher-first-time-after-installation-error.webp)
  
 > [!Note]
 > If you don't install the prerequisites, Stride won't run. In this case, you can download and install the prerequisites separately. For instructions, see [Troubleshooting — Stride doesn't run](../troubleshooting/stride-doesnt-run.md).

+ 3 - 0
en/manual/get-started/media/stride-launcher-first-time-after-installation-error.webp

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d69fb886f884f40a2121a242d0bd94e4a7c31469074980e8f07fcea1ce9ff6d3
+size 82044

+ 15 - 11
en/manual/index.md

@@ -11,10 +11,20 @@ These pages contain information about how to use Stride, an open-source C# game
 
 ### Recent updates
 
+#### Manual
+
+- <span class="badge text-bg-success">New</span> [Physics](physics/index.md) - Bepu Physics docs added
+- <span class="badge text-bg-info">Updated</span> [Bullet Physics](physics-bullet/index.md) - Bullet Physics docs moved
+
+#### Tutorials
+
+- <span class="badge text-bg-info">Updated</span> [Tutorials](../tutorials/index.md) - Added lesson counts and total length
+
 #### Contributors
 
-- <span class="badge text-bg-success">New</span> [Contributing - Core Team](../contributors/core-team.md) - The Stride core team
-- <span class="badge text-bg-info">Updated</span> [Contributing - Roadmap](../contributors/roadmap.md) - Status added 
+- <span class="badge text-bg-info">Updated</span> [Contributing - Roadmap](../contributors/roadmap.md) - GitHup Project - Roadmap link added
+
+### Previous updates
 
 #### Manual
 - <span class="badge text-bg-info">Updated</span> [Scripts - Types of script](scripts/types-of-script.md) - Asynchronous script example improved
@@ -27,16 +37,10 @@ These pages contain information about how to use Stride, an open-source C# game
 - <span class="badge text-bg-info">Updated</span> [Engine - Entity Component model](engine/entity-component-system/index.md) - Content improvements
 - <span class="badge text-bg-info">Updated</span> [Stride for Unity® developers](stride-for-unity-developers/index.md) - Content improvements
 
-### Previous updates
+#### Contributors
 
-- <span class="badge text-bg-success">New</span> [NuGet](nuget/index.md)
-- <span class="badge text-bg-success">New</span> [Video](video/index.md)
-- <span class="badge text-bg-success">New</span> [Cached files](files-and-folders/cached-files.md)
-- <span class="badge text-bg-success">New</span> [iOS](platforms/ios.md)
-- <span class="badge text-bg-success">New</span> [Compile shaders](graphics/effects-and-shaders/compile-shaders.md)
-- <span class="badge text-bg-info">Updated</span> [Skyboxes and backgrounds](graphics/textures/skyboxes-and-backgrounds.md)
-- <span class="badge text-bg-info">Updated</span> [Animate a camera with a model file](graphics/cameras/animate-a-camera-with-a-model-file.md)
-- <span class="badge text-bg-info">Updated</span> [Material slots](graphics/materials/material-slots.md)
+- <span class="badge text-bg-success">New</span> [Contributing - Core Team](../contributors/core-team.md) - The Stride core team
+- <span class="badge text-bg-info">Updated</span> [Contributing - Roadmap](../contributors/roadmap.md) - Status added 
 
 ## Improve this documentation
 

+ 2 - 2
en/manual/nuget/create-packages.md

@@ -10,8 +10,8 @@ First of all, after saving all your changes, open your project with Visual Studi
 ![Open project in Visual Studio](../game-studio/media/open-project-in-visual-studio.png)
 
 A few things to look out for:
-* Delete unecessary assets (i.e. GameSettings, etc...)
-* Delete unecessary `PackageReference`
+* Delete unnecessary assets (i.e. GameSettings, etc...)
+* Delete unnecessary `PackageReference`
 
 ## Optional: Setup Package properties
 

+ 5 - 5
en/manual/physics/colliders.md

@@ -3,11 +3,11 @@
 <span class="badge text-bg-primary">Beginner</span>
 <span class="badge text-bg-success">Designer</span>
 
-Collidables are the base entity components for physics objects. There are three types:
+Collidables are the base entity components for physics objects. There are three main types:
 
-* [Statics](static-colliders.md): Objects that don't move (terrain, ...)
-* [Bodies](rigid-bodies.md): Moving objects, affected by gravity and collisions or Kinematics
-* [Characters](characters.md): Colliders for basic characters (such as players, animals, npcs, ...)
+* [Statics](static-colliders.md): Objects that don't move (terrain, walls, floors, large rocks)
+* [Bodies](rigid-bodies.md): Moving objects, affected by gravity and collisions (cans, balls, boxes) or [Kinematics](kinematic-rigid-bodies.md) (moving platforms, doors)
+* [Characters](characters.md): Colliders for basic characters (player character, animals, NPCs)
 
 ![Static and rigidbody colliders](media/rigid-bodies-static-and-rigid-body-colliders.png)
 
@@ -41,7 +41,7 @@ This relationship is controlled through the [Simulation's Collision Matrix](simu
 
 This property is used to filter collisions inside a group of object, when two or more objects must share the same `Collision Layer`, but should not collide between each other.
 
-It allows objects sharing the same `CollisionGroup.Id` to pass through each other when the absolute difference between their `IndexA`,`IndexB`, and `IndexC` is less than two.
+It allows objects sharing the same `CollisionGroup.Id` to pass through each other when the absolute difference between their `IndexA`, `IndexB`, and `IndexC` is less than two.
 
 Its utility is best shown through concrete examples.
 

+ 1 - 1
en/manual/physics/configuration.md

@@ -21,7 +21,7 @@ You can now add Bepu's own physics component, but before playing around with tha
 
 ## Configuring Physics
 
-To manage Bepu's simulation configuration, in the `Asset View` pane, select your `GameSettings` asset which is at the root of your asset folder, look at the property grid, press on the `+` sign next to `Add configuration` and select `Bepu Configuration`
+To manage Bepu's simulation configuration, in the `Asset View` pane, select your `GameSettings` asset which is at the root of your asset folder, look at the property grid, press on the `+` sign next to `Add configuration` and select `Bepu Configuration`.
 
 ![Create settings](media/bepu-import-settings.png)
 

+ 5 - 5
en/manual/physics/index.md

@@ -12,11 +12,11 @@ This section explains how physics components work, how to add them to your proje
 
 * [Configuration](configuration.md): Setting up Bepu
 * [Simulation](simulation.md): Managing the simulations parameters
-* [Collidables](colliders.md): The physics objects in your game world
-    * [Statics](static-colliders.md): Strong immovable objects like walls, floors, large rocks, and so on
-    * [Bodies](rigid-bodies.md): Objects that can be knocked around, cans, balls, boxes ...
-    * [Kinematic Bodies](kinematic-rigid-bodies.md): Entities which are moved programmatically, moving platforms, doors, ...
-    * [Characters](characters.md): Creatures which are moved programmatically, the player character, animals ...
+* [Collidables](colliders.md): Physics objects in your game world
+    * [Statics](static-colliders.md): Strong immovable objects such as terrain, walls, floors, or large rocks
+    * [Bodies](rigid-bodies.md): Movable objects that can be knocked around, like cans, balls, or boxes
+    * [Kinematic Bodies](kinematic-rigid-bodies.md): Entities moved programmatically, such as moving platforms or doors
+    * [Characters](characters.md): Creatures moved programmatically, such as the player character, animals, or NPCs (non-player characters)
 * [Collider Shapes](collider-shapes.md): Define the geometric shape of yours collidable components
 * [Triggers](triggers.md): Use triggers to detect passing objects
 * [Constraints](constraints.md): Join physics objects together, constrain them around points

+ 2 - 2
en/manual/physics/simulation.md

@@ -27,10 +27,10 @@ There are multiple ways to retrieve a reference to this `BepuSimulation` from in
 
 ## Performance Considerations
 
-The following are relevant excerpts from [Bepu's documentation](https://github.com/bepu/bepuphysics2/blob/master/Documentation/PerformanceTips.md)
+The following are relevant excerpts from [Bepu's documentation](https://github.com/bepu/bepuphysics2/blob/master/Documentation/PerformanceTips.md).
 
 If physics causes your game to hang for a while when simulating for the first time, it may be related to just-in-time compilation. If it becomes a problem, consider running a small simulation that hits all the relevant codepaths (a bunch of objects colliding with constraints applied) behind a loading screen. Using an ahead-of-time compilation toolchain would also work.
 
 ## See also
-* [Colliders](colliders.md)
+* [Collidables](colliders.md)
 * [Collider shapes](collider-shapes.md)

+ 249 - 0
en/manual/scripts/best-practice.md

@@ -0,0 +1,249 @@
+# Best Practices
+
+Tips to build a robust and maintainable CodeBase for your Stride project
+
+## Think Twice, Implement Once
+
+Before starting on major systems, make sure it would integrate with the rest of the existing systems; how would it behave when saving and reloading, with the multiplayer architecture, when the game is paused, would it leak into other scenes or game modes ...
+
+Having this in mind ensures you won't write yourself into a corner, creating a system that would need to be patched up when you could have figured it out earlier with a bit of planning, best to avoid introducing any technical debt if you can help it.
+
+A trap you may fall into is to then over design your systems, supporting features that your game will never need, convincing yourself that you could re-use that system for another game, that you could share or sell it.
+The vast majority of systems in games are purpose built for that game, your next game will require other features you could not support, let alone predict. You will also acquire a significant amount of experience working on this one, seeing issues it had and wanting to rewrite a better one.
+
+### Figuring Out Your System's Lifetime
+
+What is the scope of the system you're writing;
+- Should the same instance be used throughout the entire lifetime of the application ?
+- Only while playing a game session ?
+- Only for the duration of the currently loaded game session ? 
+- Within a single map ?
+- For a specific game mode ?
+- ...
+
+This will set some expectation as to where the system you're building should reside, how it interacts with other systems, and when it should be started and disposed ...
+
+Some entry and exit points to manage your systems' lifetime:
+- On demand by getting and setting it in the Services
+- System as a [singleton script](#Statics-singletons-and-other-global-like-writes) with the `Start()` and `Cancel()` 
+- Through your game's `BeginRun()` and `EndRun()`
+- As a component processor when associated component types are added to the scene
+
+## Statics, Singletons and Other Globals
+We strongly advise you to make sure that the entirety of your game's state is implemented as instance properties on components inside the root scene's hierarchy. Avoid static properties and static objects.
+
+This is essential to reduce bugs that come in when implementing systems that manage the game's state, like the saving system, or the multiplayer layer.
+Those systems can then be implemented with the expectation that everything they may care about is within the root scene, they can replace this root scene and expect the game state to be completely reset, they can serialize or monitor those entities for changes, etc. without the risk of your game's state leaking between play sessions and creating issues that are really hard to reproduce.
+
+Some systems may not make sense as part of the scene when:
+- The functionality and variables saved by such systems persist for the duration of the program, or across all sessions
+    - Saving, loading systems, meta-progression trackers or achievements
+- The system is read-only
+    - Multiplayer server browser or matchmaking back-end. Once connected to a session it's a different story though, now you must hold a bunch of states that are only valid to this session, it should not leak to the rest of the program, and so is best left as a component on an entity in the scene.
+
+Those restrictions do not prevent you from using the singleton pattern, you can use the `ServiceRegistry` which can be accessed from any `ScriptComponent`
+
+<p class="d-inline-flex gap-1">
+  <button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
+    Show Example
+  </button>
+</p>
+<div class="collapse" id="collapseExample">
+  <div class="card card-body">
+
+```cs
+// Here's a basic singleton class
+public class MySingleton : IService
+{
+    public static IService NewInstance(IServiceRegistry r) => new MySingleton();
+
+    public void DoStuff(){}
+}
+
+// You can create and get this singleton from any of your components:
+public override void Update()
+{
+    Services.GetOrCreate<MySingleton>().DoStuff();
+}
+
+// Here's a singleton implementation when you need its lifetime to be limited to the scene's:
+public class MySingleton : SyncScript, IService
+{
+    public override void Start()
+    {
+        var instance = Services.GetService<MySingleton>();
+        if (instance != this)
+            Entity.Remove(this); // Makes sure we remove this instance if another exists already
+        else if (instance is null)
+            Services.AddService(this); // Register this as a service if it was added through the scene instead of through Services.GetOrCreate<MySingleton>()
+    }
+
+    public override void Cancel()
+    {
+        base.Cancel();
+        Services.RemoveService(this); // Remove this one from the services when this component is removed from the scene
+    }
+
+    public override void Update() { }
+
+    public static IService NewInstance(IServiceRegistry r)
+    {
+        var instance = new MySingleton();
+        r.GetService<SceneSystem>().SceneInstance.RootScene.Entities.Add(new Entity{ instance });
+        return instance;
+    }
+}
+```
+  </div>
+</div>
+
+## Implement Custom Assets
+
+Some of the systems you will build make far more sense as [assets](custom-assets.md) rather than entities, consider making them an asset when any of the following is true:
+- It survives between multiple scenes
+- It is read only
+- It is not part of the definition of an entity, doesn't exist within your game world
+- It should be editable within the editor, by a designer
+
+Examples of such are:
+- Player Input Configuration, defining actions in the source, assigning buttons in editor, saving and loading to disk when initializing the game
+- Balance settings, tweaking constants and formulas from the editor to improve iteration when testing your game
+- Mission/quest, referencing quests inside of components to unlock spots in game when they are completed, giving the ability for your designer to set those up
+- Loot tables, having a list of `UrlReference<Prefab>` with a probability of drop to easily re-use across multiple mobs
+- As an all-purpose robust 'key' or 'identifier' type, see [this section](#strings-as-keys-or-identifiers)
+
+### Do not Mutate Assets
+To that point, make sure to only mutate assets when it makes sense to do so. Remember that a single asset may be referenced by hundreds of components and systems, those may not expect them to change at runtime. Adhering strictly to this idea also ensures that your game's state does not leak through them when loading a new session, game mode, or whatever else.
+For example, let's say you have an Axe Asset which has a list of modifier, you save the game, progress for a bit then add a modifier, but end up reloading ot the previous save, the modifier will carry over to that previous game state.
+
+### Scene Quirks
+The default scene the game spawns for you is the instance stored in the content manager, when running the game you mutate that very instance, meaning that if you want to retrieve the scene in its initial state, you must force the content manager to unload it, and then reload it.
+This makes it a bit counterintuitive when you just want to re-spawn the current scene to roll back your changes.
+
+## Strings as Keys or Identifiers
+This is a very popular anti-pattern, strings that are used as keys or identifiers shows up all over the place, here's a short example describing such a usage:
+The quest you're implementing requires the player to gather 10 bear arses, your check for that is to loop through the list of items the player has and check that the item's name match `bear arses`.
+
+Here's a couple of reasons why this is a bad idea:
+- Hard to maintain; if your item ends up changing names because bears are banned in Freedonia, your checks will silently fail
+- Fragile; your string isn't checked against anything, typos - `bear ass` wouldn't work, careful with leading or trailing whitespaces ...
+- Obtuse; designers not aware of how your system work may not understand what they should input there
+- Non-explicit uniqueness requirement, if your system expects those to be unique, i.e.: you are looking for a very specific "bear arse"; but you could have multiple different items all named `bear arse`
+- Hard to keep track of; strings are too ubiquitous, hard to quickly retrieve all instances/usages of those to build a database for different purposes, like translations, validations ...
+
+All of this will inevitably lead to bugs, or additional work to avoid them - time you could definitely use to take care of other, more fun parts of your game.
+
+There are a couple ways to avoid this, one of the more robust ones is to rely on assets themselves; see [custom assets](custom-assets.md)
+```cs
+public class Item { }
+
+// Now in your component ...
+public Item ItemToCheck; // You would assign this reference in the editor
+public int AmountRequired = 10;
+
+public bool HasTheItem()
+{
+    if (Inventory.TryGetAmount(ItemToCheck, out var amount) && amount >= AmountRequired)
+        return true;
+    return false;
+}
+```
+- Robust; you can change its name and its path, as long as you do not delete it or change its internal id, all components referencing it will keep that reference.
+- Easy to use and understand; If a component requires a specific asset, you don't have an infinite amount of possibilities, you can either set it to an existing one or create a new one. It's far more foolproof too now that typos are out of the equation.
+- Easy to keep track of; each type has a unique extension which you can search for in your file explorer, they exist on disk, and so can be organized into the same directory.
+    - The editor's reference window lists all assets that use the selection, this greatly helps when you need to swap the identifier for another or remove it altogether, just go through all the assets that refer to it.
+    - you won't need to keep a document going over each identifier you might have in game, one just has to look at the directory were they are stored in the editor.
+- Easy to extend; your identifier can now be more than just that, you can attach properties to it, perhaps a description to keep more information about this key.
+
+## Avoid Patterns with High Levels of Indirection 
+Particularly when mutating the game state, [Event Keys](events.md) and async methods carry a lot of implicit complexity as they may not complete when signaled/called. When the async resumed/the event key is received, the game may not be in a state where the logic you run is still valid. Some entities might have been removed from the scene, the inventory might no longer hold the item, the player character may be incapacitated ...
+
+This quirk also means that their execution are not part of their callers' stack, making debugging issues with them far harder to figure out.
+
+Their lifetime is also far harder to reason about as EventKeys will carry the signal even if the scene was replaced in the meantime, while async will continue running when running outside your AsyncScript's `Execute()`
+
+Alternatives to EventKeys
+- C# events, although this requires the receivers to have a direct reference to the sender
+- Components with an interface bound to a [Flexible processors](../engine/entity-component-system/flexible-processing.md). Add the processor to the service registry, call some method which goes through and call each one of the components implementing the interface of that processor
+
+Alternatives to async
+- Restructure your async into a synchronous one ... obviously !
+- If you can't avoid using async ...
+- Don't touch the game state, just take some input, spit out an output that gets read by a `SyncScript`
+- Ensure you always leave the game state in a valid state before awaiting, and after awaiting check that it is still in a state were continuing the async method makes sense. I.e.: are we suddenly back on the main menu ?!
+
+You may notice that those two last ones could require a ton of additional logic to support properly, this is an indication that your logic should be rethought - you're writing yourself into a corner
+
+## Avoid Writing Shortcut Extension Methods 
+
+This is specifically referring to methods of this kind:
+```
+static Entity GetFirstChild(this Entity Entity) => Entity.Transform.Children[0].Entity;
+// Or
+static void AddAsFirstChild(this Entity Entity, Entity entity) => Entity.Transform.Children.Insert(0, entity);
+```
+
+It's a double-edged sword:
+- You are reducing the skill floor required for users not accustomed to the API, but you're also hindering their growth as they now rely on your shortcut instead of discovering the API for themselves, making them aware of concepts and objects neighboring that one, giving them a clearer view of how all the objects fit together. What if they need to access all children, from this extension method they would not be aware that the transform component stores them, that they could access it directly for that.
+- Make sure that accessing what you are hiding is never error-prone, even more so if the name of the method does not make that obvious. You may be reducing the time wasted from typing, but you could very well increase the time you would take to debug it when it does create issues.
+- It may very well be a slippery slope to introduce even more shortcuts to other properties or methods of the object you are presenting, how about creating an extension for the second child of the entity, the third ...
+- Polluting intellisense; in most cases this is a non-issue, but collection types are a prime example of this. Discoverability for extension methods through intellisense is nigh-on-impossible, there are just far too many extension methods introduced by linq.
+- It might imply to the user that your shortcut is somehow different from the source.
+
+## Entity and Components' Lifetime
+
+One unexpected quirk of Stride is that components and entities are expected to survive across any number of removal and re-insertion into the scene. Those objects are never truly 'destroyed', they are treated like any other c# object, they either exist or are out of scope.
+
+Make sure that your components adhere to this rule by rolling back any effects introduced in `Start()` through `Cancel()`
+This quirk provides a couple of nice benefits, a major one is that you can temporarily remove components, entities and even scenes from your game and re-introduce them whenever you need without any loss of data or complex serialization steps.
+
+This also means that you should avoid writing any custom 'destroy' function to ensure that any part of the engine at any time can simply remove the entity from the scene and rely on your implementation of `Cancel()` to take care of anything that should occur when 'destroyed'.
+
+### Usage of Get<MyComponent>
+
+When using `Get<MyComponent>` ask yourself whether the function would fail to operate if that call were to return null, if that is the case, then your function is dependent on that component existing on that entity. 
+This is a hard dependency, you should do everything you can to notify the rest of your codebase and designers using the editor that it this component is a requirement to avoid wasting time debugging issues related to it.
+
+There are a couple of ways to do so, here we simply add the component directly as a parameter to the function:
+```cs
+// From
+public void MyFunction(Entity entity)
+{
+    entity.Get<MyComponent>().DoSomething();
+}
+// To
+public void MyFunction(MyComponent component)
+{
+    component.DoSomething();
+}
+```
+And here we add this component as a property to set in the editor:
+```cs
+// From
+public void MyFunction()
+{
+    Entity.Get<MyComponent>().DoSomething();
+}
+
+// To
+
+// The 'required' keyword will generate a warning on build when the value is not set in the editor
+public required MyComponent MyRequiredComponent { get; set; }
+
+public void MyFunction()
+{
+    MyRequiredComponent.DoSomething();
+}
+```
+
+A trap you may fall into after reading this is to write defensively, checking if it is null and returning in such cases even if the rest of the logic expects some sort of change.
+This will more often than not force you to write far more boilerplate logic than you would have if you ensured you had a valid one in the first place.
+
+One thing you may also consider is whether to simply merge the dependant object together, if either one of the objects are used only for the other's purpose, it may make far more sense to simply merge them instead of having two different components.
+
+
+## See also
+
+* [Scheduling and priorities](scheduling-and-priorities.md)
+* [Flexible processors](../engine/entity-component-system/flexible-processing.md)
+* [Custom Assets](custom-assets.md)

+ 1 - 0
en/manual/scripts/create-a-script.md

@@ -127,6 +127,7 @@ You can see the script in the **Asset View**.
 
 ## See also
 
+* [Best Practice](best-practice.md)
 * [Types of script](types-of-script.md)
 * [Use a script](use-a-script.md)
 * [Public properties and fields](public-properties-and-fields.md)

+ 5 - 0
en/manual/scripts/custom-assets.md

@@ -185,3 +185,8 @@ RootAssets: []
 And you're finally done, have fun !
 
 ![Result](media/template-result.png)
+
+
+## See also
+
+* [Best Practice](best-practice.md)

+ 4 - 0
en/manual/scripts/events.md

@@ -1,5 +1,8 @@
 # Events
 
+>[!Note]
+>Events are not recommended anymore, see [Best Practice](best-practice.md)
+
 <span class="badge text-bg-primary">Intermediate</span>
 <span class="badge text-bg-success">Programmer</span>
 
@@ -54,6 +57,7 @@ string asyncData = await gameOverListenerWithData.ReceiveAsync();
 
 ## See also
 
+* [Best Practice](best-practice.md)
 * [Types of script](types-of-script.md)
 * [Create a script](create-a-script.md)
 * [Use a script](use-a-script.md)

+ 44 - 0
en/manual/scripts/example-snippets.md

@@ -0,0 +1,44 @@
+# [WIP] Example snippets
+
+## Basics
+
+### Scripts
+
+Read more about [Scripts](index.md).
+
+[Stride Life Cycle Flow Chart](https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg)
+
+```csharp
+public class BasicMethods : SyncScript
+{
+    public override void Start() { }
+    public override void Cancel() { }        
+    public override void Update() { }
+}
+
+public class BasicMethods : AsyncScript
+{
+    public override async Task Execute()
+    {
+        while (Game.IsRunning)
+        {
+            // Do stuff every new frame
+            await Script.NextFrame();
+        }
+    }
+
+    public override void Cancel() { }     
+}
+
+public class BasicMethods : StartupScript
+{
+    public override void Start() { }
+
+    public override void Cancel() { }     
+}
+
+```
+
+### Transform
+
+Read more about [Transform](index.md).

+ 2 - 1
en/manual/scripts/index.md

@@ -41,4 +41,5 @@ You can still use standard C# classes in Stride, but these aren't called scripts
 * [Preprocessor variables](preprocessor-variables.md)
 * [Create a model from code](create-a-model-from-code.md)
 * [Create Gizmos for your components](gizmos.md)
-* [Create Custom Assets](custom-assets.md)
+* [Create Custom Assets](custom-assets.md)
+* [Best Practice](best-practice.md)

+ 6 - 1
en/manual/stride-for-godot-developers/index.md

@@ -507,4 +507,9 @@ System.Diagnostics.Debug.WriteLine("hello");
 ```
 
 >[!Note]
-> To print debug messages, you have to run the game from Visual Studio, not Game Studio. There's no way to print to the Game Studio output window.
+> To print debug messages, you have to run the game from Visual Studio, not Game Studio. There's no way to print to the Game Studio output window.
+
+
+## See also
+
+* [Best Practice](../scripts/best-practice.md)

+ 4 - 0
en/manual/stride-for-unity-developers/index.md

@@ -817,3 +817,7 @@ public float MyProperty { get; init; }
 ---
 
 Unity® is a trademark of Unity Technologies.
+
+## See also
+
+* [Best Practice](../scripts/best-practice.md)

+ 6 - 4
en/manual/toc.yml

@@ -426,14 +426,14 @@ items:
         href: physics/configuration.md
       - name: Simulation
         href: physics/simulation.md
-      - name: Colliders
+      - name: Collidables
         href: physics/colliders.md
         items:
-          - name: Static colliders
+          - name: Statics
             href: physics/static-colliders.md
-          - name: Rigidbodies
+          - name: Bodies
             href: physics/rigid-bodies.md
-          - name: Kinematic rigidbodies
+          - name: Kinematic Bodies
             href: physics/kinematic-rigid-bodies.md
           - name: Characters
             href: physics/characters.md
@@ -540,6 +540,8 @@ items:
         href: scripts/gizmos.md
       - name: Create Custom Assets
         href: scripts/custom-assets.md
+      - name: Best Practice
+        href: scripts/best-practice.md
 
   - name: Sprites
     href: sprites/index.md

+ 1 - 1
en/manual/troubleshooting/logging.md

@@ -91,7 +91,7 @@ This creates a file in the Debug folder of your project (eg *MyGame\MyGame\Bin\W
 
 ## Example script
 
-The following script checks that the texture `MyTexture` is loaded. When the texture loads, the log displays a debug message (`Log.Error`). If it doesn't load, the log records an error message (`Log.Debug`).
+The following script checks that the texture `MyTexture` is loaded. When the texture loads, the log displays a debug message (`Log.Debug`). If it doesn't load, the log records an error message (`Log.Error`).
 
 ```cs
 using System.Linq;

+ 4 - 0
en/tutorials/csharpbeginner/index.md

@@ -1,4 +1,8 @@
 # 🌱 C# Beginner
+
+<span class="badge text-bg-info">15 lessons</span>
+<span class="badge text-bg-warning">2.5 hours</span>
+
 These tutorials cover the beginner principles of using C# when working with the Stride game engine. Start here if you are new to Stride.
 
 Note: These tutorials do not serve as an introduction to C# itself. While having some coding experience is helpful, it is not mandatory to get started with these tutorials.

+ 4 - 0
en/tutorials/csharpintermediate/index.md

@@ -1,4 +1,8 @@
 # 📈 C# Intermediate
+
+<span class="badge text-bg-info">11 lessons</span>
+<span class="badge text-bg-warning">4 hours</span>
+
 These tutorials cover various intermediate principles of using C# when working with the Stride game engine.
 
 It is recommended that you complete all the [C# Beginner tutorials](../csharpbeginner/index.md) before moving on to the intermediate tutorials.

+ 4 - 1
en/tutorials/gamestudio/index.md

@@ -1,4 +1,7 @@
-# 🛠️ Game studio 
+# 🛠️ Game studio
+
+<span class="badge text-bg-info">12 lessons</span>
+<span class="badge text-bg-warning">1 hour</span>
 
 The Stride engine comes with an editor called **Game Studio**. The videos below cover the basics of the UI and how various concepts work inside the editor. 
 

+ 28 - 1
en/tutorials/index.md

@@ -22,6 +22,10 @@ New to Stride? Start with these tutorials to get familiar with the basics of the
             <img src="media/gamestudio.jpg" class="card-img-top" alt="Game studio tutorials">
             <div class="card-body">
                 <h5 class="card-title">🛠️ Game Studio</h5>
+                <p>
+                    <span class="badge text-bg-info">12 lessons</span>
+                    <span class="badge text-bg-warning">1 hour</span>
+                </p>
                 <p class="card-text">The Stride engine comes with an editor called Game Studio, which is the central tool for game 🕹️ and application production in Stride.</p>
                 <p class="card-text">Learn about Stride launcher, main interface, scene management, transforming entities, asset pipelines and more.</p>
             </div>
@@ -33,6 +37,10 @@ New to Stride? Start with these tutorials to get familiar with the basics of the
             <img src="media/csharp-beginner.png" class="card-img-top" alt="C# beginner tutorials">
             <div class="card-body">
                 <h5 class="card-title">🌱 C# Beginner</h5>
+                <p>
+                    <span class="badge text-bg-info">15 lessons</span>
+                    <span class="badge text-bg-warning">2.5 hours</span>
+                </p>
                 <p class="card-text">These tutorials cover the beginner principles of using C# when working with the Stride game engine 🎮.</p>
                 <p class="card-text">Learn about entities, transform positions, editor properties, components, delta time, cloning, keyboard and mouse input and more.</p>
             </div>
@@ -44,11 +52,30 @@ New to Stride? Start with these tutorials to get familiar with the basics of the
             <img src="media/csharp-intermediate.png" class="card-img-top" alt="C# intermediate tutorials">
             <div class="card-body">
                 <h5 class="card-title">📈 C# Intermediate</h5>
+                <p>
+                    <span class="badge text-bg-info">11 lessons</span>
+                    <span class="badge text-bg-warning">4 hours</span>
+                </p>
                 <p class="card-text">These tutorials cover various intermediate principles of using C# when working with the Stride game engine 🎮.</p>
                 <p class="card-text">Learn more about UI basics, collision triggers, ray-casting, async scripts, scenes, animations, audio, camera and navigation.</p>
-                <p><span class="badge text-bg-success">New</span></p>
+                <!--<p><span class="badge text-bg-success">New</span></p>-->
             </div>
             <p class="px-3 mb-4">🚀 Jump to the <a class="stretched-link" href="csharpintermediate/index.md">C# intermediate tutorials</a></p>
         </div>
     </div>
+    <div class="col-xxl-4 col-md-6">
+        <div class="card h-100">
+            <img src="media/quick-tutorials.webp" class="card-img-top" alt="Stride Quick Tutorials">
+            <div class="card-body">
+                <h5 class="card-title">⚡ Quick Tutorials</h5>
+                <p>
+                    <span class="badge text-bg-info">1 lesson</span>
+                    <span class="badge text-bg-warning">4 minutes</span>
+                </p>
+                <p class="card-text">These quick tutorials provide bite-sized lessons to help you get up to speed with the Stride game engine in no time.</p>
+                <p class="card-text">Learn about setting up your first project, basic scripting, simple animations, quick UI tips, and more.</p>
+            </div>
+            <p class="px-3 mb-4">🚀 Jump to the <a class="stretched-link" href="quick-tutorials/index.md">Quick tutorials</a></p>
+        </div>
+    </div>
 </div>

+ 3 - 0
en/tutorials/media/quick-tutorials.webp

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4f50f3e07532445bb68322c77be90aa1453dfb727fd765271b96188ab96313b1
+size 3836

+ 26 - 0
en/tutorials/quick-tutorials/index.md

@@ -0,0 +1,26 @@
+# ⚡ Quick Tutorials
+
+<span class="badge text-bg-info">1 lesson</span>
+<span class="badge text-bg-warning">4 minutes</span>
+
+These tutorials provide bite-sized lessons to help you get up to speed with the Stride game engine in no time.
+
+## Stride Quick tutorials YouTube series
+
+> [!Video https://www.youtube.com/embed/videoseries?si=K_DN2NtJCukdKEiY&list=PLRZx2y7uC8mMUf0W02IzQl5UcaB--vfft]
+
+<!--
+## All tutorials
+<div class="row g-4 mb-4">
+    <div class="col-md-6">
+        <div class="card h-100">
+            <img src="media/introduction.webp" class="card-img-top" alt="Introduction">
+            <div class="card-body">
+                <h2 class="card-title h5">Introduction</h2>
+                <p class="card-text">A brief introduction to the C# intermediate tutorials for the Stride game engine.</p>
+            </div>
+            <p class="px-3 mb-4">📺 Watch the <a class="stretched-link" href="introduction.md">Introduction</a> tutorial</p>
+        </div>
+    </div>
+</div>
+-->

+ 8 - 3
en/tutorials/toc.yml

@@ -3,7 +3,7 @@ pdfFileName: stride-tutorials.pdf
 items:
 - name: 🎓 Tutorials
   href: index.md
-- name: 🛠️ Game studio
+- name: 🛠️ Game studio (1 hour)
   expanded: false
   href: gamestudio/index.md
   items:
@@ -31,7 +31,7 @@ items:
     href: gamestudio/11-physics-intro.md
   - name: Static colliders
     href: gamestudio/12-static-colliders.md
-- name: 🌱 C# Beginner
+- name: 🌱 C# Beginner (2.5 hours)
   expanded: false
   href: csharpbeginner/index.md
   items:
@@ -67,7 +67,7 @@ items:
     href: csharpbeginner/loading-content.md
   - name: Instantiating prefabs
     href: csharpbeginner/instantiating-prefabs.md
-- name: 📈 C# Intermediate ⭐New
+- name: 📈 C# Intermediate (4 hours)
   href: csharpintermediate/index.md
   items:
   - name: Introduction
@@ -94,3 +94,8 @@ items:
     href: csharpintermediate/third-person-camera.md
   - name: Navigation
     href: csharpintermediate/navigation.md
+- name: ⚡ Quick Tutorials
+  href: quick-tutorials/index.md
+  items:
+  - name: Custom dropdown properties
+    href: https://www.youtube.com/watch?v=hjScw6Xp2gY