Skip to content

Commit

Permalink
Migrate flecs script tutorial to v4
Browse files Browse the repository at this point in the history
  • Loading branch information
awest03 committed Aug 8, 2024
1 parent b6181db commit 43bea76
Show file tree
Hide file tree
Showing 13 changed files with 69 additions and 39 deletions.
108 changes: 69 additions & 39 deletions docs/FlecsScriptTutorial.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
This tutorial hasn't been updated for v4 yet! Use the [Script Manual](FlecsScript.md) for now.

# Flecs Script Tutorial
This tutorial shows you how to use Flecs script, which is a declarative language for creating entities without having to write and compile code. Flecs script can be used for different things, such as building scenes, assets, or as a language for configuration files.

Expand All @@ -20,28 +18,28 @@ The page should look similar to this:

The panel on the left is the entity treeview, which shows all of the entities in our scene. The center view is the canvas, which shows us the renderable entities of our scene (more on that later). Finally, the pane on the right is the editor, where we can write flecs scripts.

At any point in time you can disable panels by clicking on the "x" in the top-right corner. Panels can be brought back by pressing on their button in the menu bar on the left.
At any point in time you can disable panels by clicking on the button in the top-right corner. Panels can be brought back by pressing on their button in the menu bar on the left.

One other important thing is the link button in the top-right of the screen. You can use that button to obtain a link to your content, which is a good way to save progress, or to share what you've created with other people.

## The Basics
Currently the explorer is showing the default scene. Let's clear it by removing all code from the editor. You should now see an empty canvas:
![explorer with empty canvas](img/script_tutorial/tut_playground_empty.png)

Lets create an entity by typing its name into the editor:
Lets create an entity by typing its name into the editor followed by an empty scope:

```js
my_entity
my_entity {}
```

Notice that as we are typing the entity shows up in the treeview:
[![explorer with a single entity](img/script_tutorial/tut_playground_entity.png)](https://www.flecs.dev/explorer/?wasm=https://www.flecs.dev/explorer/playground.js&script=%0Amy_entity%0A)
![explorer with a single entity](img/script_tutorial/tut_playground_entity.png)

Entities are automatically created if they did not exist yet. Try entering the same entity twice:

```js
my_entity
my_entity
my_entity {}
my_entity {}
```

Only one entity shows up in the treeview. The second time `my_entity` was parsed it already existed, so nothing needed to be done.
Expand All @@ -50,38 +48,60 @@ Only one entity shows up in the treeview. The second time `my_entity` was parsed
Now that we have an entity, let's add a few components and tags to it. Change the text in the editor to this, to create an entity with a tag called `SpaceShip`:

```js
my_entity :- SpaceShip
my_entity { SpaceShip }
```

Note that we didn't have to explicitly declare `SpaceShip` in advance, and that it also shows up as entity in the treeview. We can add multiple things to an entity this way:
Note that this alone doesn't work as we didn't explicitly declare `SpaceShip` in advance, to fix this we must first declare `SpaceShip` as an empty entity, which is equivalent to a tag:
```js
SpaceShip {}

my_entity { SpaceShip }
```
We can add multiple tags to an entity:
```js
my_entity :- SpaceShip
my_entity :- FasterThanLight
SpaceShip {}
FasterThanLight {}

my_entity { SpaceShip }
my_entity { FasterThanLight }
```

To avoid repeating the entity name many times, we can use the `{}` operators to open a scope for the entity. Inside the scope we can list components for the entity by prefixing them with a dash (`-`):
To avoid repeating the entity name many times, we can use the `{}` operators to open a scope for the entity. Inside the scope we can list components for the entity by placing them on a new line:

```js
SpaceShip {}
FasterThanLight {}

my_entity {
SpaceShip
FasterThanLight
}
```
Or separating them with the `;` operator:
```js
SpaceShip {}
FasterThanLight {}

my_entity {
- SpaceShip
- FasterThanLight
SpaceShip; FasterThanLight
}
```

We can inspect the entity and its contents by opening it in the entity inspector. To do this, click on the entity in the treeview. You should now see this:

[![entity with two tags](img/script_tutorial/tut_playground_inspector.png)](https://www.flecs.dev/explorer/?local=true&wasm=https://www.flecs.dev/explorer/playground.js&script=%0Amy_entity%20%7B%0A%20%20-%20SpaceShip%0A%20%20-%20FasterThanLight%0A%7D%0A&entity=my_entity)
![entity with two tags](img/script_tutorial/tut_playground_inspector.png)

Note how the `SpaceShip` and `FasterThanLight` tags show up in the editor. There is also a `Script: main` tag, which exists for Flecs to keep track of which entities got created by our script.
Note how the `SpaceShip` and `FasterThanLight` tags show up in the editor. There is also a `Script -> main` tag, which exists for Flecs to keep track of which entities got created by our script.

We can return to the script editor by clicking on the drop-down above the entity treeview, selecting `scripts` and then clicking on our script, `scene.flecs` in the list.

Adding a component is similar to adding tag with a value. Let's add the `Position3` component from the `flecs.components.transform` module which comes preloaded with the playground. Note how it also shows up in the inspector when we add this code:

```js
my_entity {
- SpaceShip
- FasterThanLight
- flecs.components.transform.Position3{1, 2, 3}
SpaceShip
FasterThanLight
flecs.components.transform.Position3: {1, 2, 3}
}
```

Expand All @@ -95,35 +115,39 @@ We can now use the component without the module name, which looks much cleaner:

```js
my_entity {
- SpaceShip
- FasterThanLight
- Position3{1, 2, 3}
SpaceShip
FasterThanLight
Position3{1, 2, 3}
}
```

If all went well, the playground should now look like this:

[![entity with two tags and a component](img/script_tutorial/tut_playground_component.png)](https://www.flecs.dev/explorer/?local=true&wasm=https://www.flecs.dev/explorer/playground.js&script=using%20flecs.components.*%0A%0Amy_entity%20%7B%0A%20%20-%20SpaceShip%0A%20%20-%20FasterThanLight%0A%20%20-%20Position3%7B1%2C%202%2C%203%7D%0A%7D%0A&entity=my_entity)
![entity with two tags and a component](img/script_tutorial/tut_playground_component.png)

Note how after we added the `Position3` component, the inspector also shows the `Transform` and `WorldCell` components. This happens because the playground imports modules that implement world partitioning and transforms, which we get for free just by using `flecs.components.transform.Position3` component.
Note how after we added the `Position3` component, the inspector also shows the `Transform` component. This happens because the playground imports modules that implement transforms, which we get for free just by using `flecs.components.transform.Position3` component.

In addition to components and tags we can also add relationship pairs to entities. To add a pair, add this line to the scope of the entity, and note how it shows up in the inspector:

```js
- (OwnedBy, Player)
(OwnedBy, Player)
```

Entities can be created in hierarchies. A child entity is created in the scope of an entity just like the components and tags, but without the preceding `-`. Add this to the scope of the entity:
Note: you will also need to declare entities for `OwnedBy` and `Player`.

Entities can be created in hierarchies. A child entity is created in the scope of an entity just like the components and tags, but followed by a scope. Add this to the scope of the entity:

```js
cockpit {
pilot :- (Faction, Earth)
pilot { (Faction, Earth) }
}
```

Note: you will also need to declare entities for `Faction` and `Earth`.

You can see the hierarchy this created in the treeview by expanding `my_entity`:

[![entity with hierarchy](img/script_tutorial/tut_playground_hierarchy.png)](https://www.flecs.dev/explorer/?local=true&wasm=https://www.flecs.dev/explorer/playground.js&script=using%20flecs.components.*%0A%0Amy_entity%20%7B%0A%20%20-%20SpaceShip%0A%20%20-%20FasterThanLight%0A%20%20-%20Position3%7B1%2C%202%2C%203%7D%0A%20%20%0A%20%20cockpit%20%7B%0A%20%20%20%20pilot%20%3A-%20(Faction%2C%20Earth)%0A%20%20%7D%0A%7D%0A&entity=my_entity)
![entity with hierarchy](img/script_tutorial/tut_playground_hierarchy.png)

Congratulations! You now know how to create entities, hierarchies, and how to add components and tags. None of the entities we created so far are visible in the canvas however, so lets do something about that.

Expand All @@ -146,14 +170,20 @@ Now add these lines into the editor to create our ground `plane`:

```js
plane {
- Position3{}
Position3: {}
Rectangle: {100, 100}
- Rgb{0.9, 0.9, 0.9}
Rgb: {0.9, 0.9, 0.9}
}
```

Something happened! But it doesn't look quite right:

![an extra ground plane](img/script_tutorial/tut_playground_ground_plane_disable.png)

The playground comes with a ground plane already called `ground_plane`, find it in the entity treeview and disable it by clicking the arrow in the top right of the inspector and then the `Disable` button.

With that out of the way, our ground plane still doesn't look quite right:

[![a buggy ground plane](img/script_tutorial/tut_playground_plane_wrong.png)](https://www.flecs.dev/explorer/?local=true&wasm=https://www.flecs.dev/explorer/playground.js&script=using%20flecs.components.*%0A%0Aplane%20%7B%0A%20%20-%20Position3%7B%7D%0A%20%20-%20Rectangle%7B100%2C%20100%7D%0A%20%20-%20Rgb%7B0.9%2C%200.9%2C%200.9%7D%0A%7D%0A)

The rectangle is rotated the wrong way for our plane. To fix this we need to rotate it 90 degrees or `π/2` radians on the x axis. First lets define `π` as a constant value in our script:
Expand All @@ -165,25 +195,25 @@ const PI = 3.1415926
Now add this line to the scope of `plane`:

```js
- Rotation3{$PI / 2}
Rotation3: {$PI / 2}
```

That looks better:

[![a ground plane](img/script_tutorial/tut_playground_plane_rotated.png)](https://www.flecs.dev/explorer/?local=true&wasm=https://www.flecs.dev/explorer/playground.js&script=using%20flecs.components.*%0A%0Aconst%20PI%20%3D%203.1415926%0A%0Aplane%20%7B%0A%20%20-%20Position3%7B%7D%0A%20%20-%20Rotation3%7B%24PI%20%2F%202%7D%0A%20%20-%20Rectangle%7B100%2C%20100%7D%0A%20%20-%20Rgb%7B0.9%2C%200.9%2C%200.9%7D%0A%7D%0A)
![a ground plane](img/script_tutorial/tut_playground_plane_rotated.png)

Let's increase the sides of the plane to `10000` so that the fog effect makes it blends in with the background, which gives the illusion of a horizon:

[![a ground plane](img/script_tutorial/tut_playground_plane.png)](https://www.flecs.dev/explorer/?local=true&wasm=https://www.flecs.dev/explorer/playground.js&script=using%20flecs.components.*%0A%0Aconst%20PI%20%3D%203.1415926%0A%0Aplane%20%7B%0A%20%20-%20Position3%7B%7D%0A%20%20-%20Rotation3%7B%24PI%20%2F%202%7D%0A%20%20-%20Rectangle%7B10000%2C%2010000%7D%0A%20%20-%20Rgb%7B0.9%2C%200.9%2C%200.9%7D%0A%7D%0A)
![a ground plane](img/script_tutorial/tut_playground_plane.png)

Note that the `PI` variable does not show up in the treeview. Variables do not create entities, and only exist within the context of a script.

Let's now add a cube to the scene. The code for this looks similar to the plane:

```js
box {
- Position3{}
Box: {10, 10, 10}
Position3: {}
Box: {3, 3, 3}
Rgb: {1, 0, 0}
}
```
Expand All @@ -196,15 +226,15 @@ To fix this, we can move it up by setting the `y` member of `Position3` to half

```js
box {
- Position3{y: 5}
Box: {10, 10, 10}
Position3: {y: 1.5}
Box: {3, 3, 3}
Rgb: {1, 0, 0}
}
```

Now the entire cube is visible, and should look like this:

[![a cube](img/script_tutorial/tut_playground_box.png)](https://www.flecs.dev/explorer/?local=true&wasm=https://www.flecs.dev/explorer/playground.js&script=using%20flecs.components.*%0A%0Aconst%20PI%20%3D%203.1415926%0A%0Aplane%20%7B%0A%20%20-%20Position3%7B%7D%0A%20%20-%20Rotation3%7B%24PI%20%2F%202%7D%0A%20%20-%20Rectangle%7B10000%2C%2010000%7D%0A%20%20-%20Rgb%7B0.9%2C%200.9%2C%200.9%7D%0A%7D%0A%0Abox%20%7B%0A%20%20-%20Position3%7By%3A%205%7D%0A%20%20-%20Box%7B10%2C%2010%2C%2010%7D%0A%20%20-%20Rgb%7B1%2C%200%2C%200%7D%0A%7D%0A)
![a cube](img/script_tutorial/tut_playground_box.png)

We now have all of the basic knowledge to start drawing a fence! Note that if you want to move the camera around, first click on the canvas to give it focus. You can now move the camera around. To release focus from the canvas, click on it again (the green border should disappear).

Expand Down
Binary file modified docs/img/script_tutorial/tut_playground.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_box.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_component.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_entity.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_half_box.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_hierarchy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_inspector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_plane.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_plane_rotated.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/script_tutorial/tut_playground_plane_wrong.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 43bea76

Please sign in to comment.