Skip to content
This repository was archived by the owner on Feb 21, 2025. It is now read-only.

Commit 12dca35

Browse files
heysokamanselmDanielBelmes
authored
[developer] Create the beginner Typescript guide (#114)
* typescript breakout * fmt: Change 00_intro to the new index+nolink system * fmt: Remove unnecesary folder at docs/ root * rmv: Remove the Pong guide, which is worked on at #99 as intermediate * fmt: Restructured the tutorial files/folders/titles * fmt: Formatting changes to fit the Markdown guidelines * new: Quickstart sketch * chg: Turn the confusing install instructions into a simple bash script * chg: Move installation intro to the intro page * chg: Move the UbuntuEasyInstall instructions to a partial file * new: Create the gettingStarted/extras section * fix: Typo in developer/typescript/start/extras category file * fix: Remove id from developer/typescript/start/extras category file * fmt: Move tutorial-basic instructions out of the ubuntu installer file * new: Add typescript/start/hello section * chg: Small changes to the hello world tutorial * fix: Incorrect todo link to the ubuntu install script. rmv: whitespace * new: Add instructions on how to confirm the hello world installation * new: Add todo note for explaining the Controlled Context concept * new: Hello World Tutorial (phase1) * chg: Improvements to the ECS definitions * chg: General improvements to the ECS page * new: Add TechnicalNote custom mdx component * new: Merge modules+worldInjection into a single file. Write their text * fmt: Add notes on achieving docusaurus <details> CSS for components * fmt: Markdown formatting changes for the ECS and Systems pages * new: Add UnstyledDetails component * chg: Small wording change in the ECS page * new: Add source modification section. Improve module imports section * fix: Small typo in the engine page * chg: Small typo in the quickstart page * new: Add the "First System" section text * fmt: Refactor the folder structure to match the new learning path * fix: Sidebar ordering numbers * fmt: Move foreign folders into the _todo temporary subfolder * fmt: Reorganize the extras folder to build up to networking (sketch) * requested changes * chg: Reword `sub-projects` to `projects` * rmv: Remove test.js from the root folder * rmv: Remove Entity clarification for its definition * doc: improve todo note/comment about entity clarification alternatives * new: Add Congratulations page to the HelloWorld tutorial * chg: Convert the Extras section into the Basics section * fix: Missing imports in the new Basics pages * chg: Congrats and Basics pages formatting improvements * new: Physics Basics tutorial page * new: Debugging and Locations Basics tutorial pages sketches * new: Better instructions on the Physics Basics page * chg: Small changes to the files * chg: Wording and instructions changes to the Physics page * chg: Move locations instructions to the new basics/locations page * new: Basics/state early sketch (tbd) * new: Early sketch of the Intermediate tutorials structure * chg: Cleanup the folders to remove the _todo temporary folder * chg: Move the Basics tutorial out of Getting Started * chg: Remove worldInjection instructions * new: Add HelloWorld/Component page sketch * chg: Improvements to the HelloWorld/Component page * fix: Missing UnstyledDetails in the Basics section * doc: Add todo note to the HelloWorld/components page * chg: Improvements to the Quickstart guide * new: Intermediate Section structure/skeleton * fix: DocCardList on empty Networking category crashed the builder * chg: Remove leftover mentions to worldInjection * new: Add code sketch to the HelloComponent page * fmt: Remove incorrectly added folders * fix: Broken links and GettingStarted title * fmt: Small styling changes to the hello/component page * new: basics/Recap section * fix: Broken links on Recap and GettingStarted * chg: Small wording improvements * new: jsonID naming requirements * new: Component+Query pages for the HelloWorld guide * new: Component+Query sketch for the Basics guide * fix: Ubuntu Installation instructions command * chg: Edit pass. Small wording changes and fixes for all sections * new: Basics/component page and Basics/query skeleton * new: Basics/location creation instructions * chg: Improve the Basics/query page * new: Write the Basics/recap/query page * new: Write the Basics/recap/next page * new: Add ee-tutorial-hello/Step0 branch instructions * chg: Add A-to-B overview instructions for the HelloWorld/introduction * chg: Move modules/engine/testing into typescript/mastery/testing * chg: Move modules/engine/state to developer/typescript/ecs/state * new: Create developer/typescript/reactivity section * chg: Move parts of manual/ecs to the typescript/ecs intermediate guide * chg: Hello/query editing pass * fmt: Change Basics/physics to fit the CustomComponent previous code * chg: Remove noise from the developer/typescript index page * chg: Basics/state page improvements * new: Port tldraw list of events to execution order page * chg: Progress on the Basics/state page * chg: UX cleanup (phase1) * chg: UX cleanup (phase2) * fix: Leftover old code --------- Co-authored-by: Anselm Hook <[email protected]> Co-authored-by: Daniel Belmes <[email protected]>
1 parent 33c9f52 commit 12dca35

File tree

112 files changed

+2543
-403
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+2543
-403
lines changed

docs/_partials/defaultProjects.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Ethereal Engine has a few scenes that are installed by default.
2+
With the engine running, open the Studio by navigating to https://localhost:3000/studio, and you will see the engine's default project listed in that page.
3+
4+
Lets give them a test run:
5+
- Open one of the default project by clicking on its card
6+
- Click on one of the scenes to open it
7+
- Click on the `Play` button to enter the scene with an Avatar
8+
- Move around the scene with `WASD` and/or clicking on the ground

docs/_partials/installUbuntu.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
:::important
2+
Ethereal Engine is a web application.
3+
We are going to install and run a local version of the engine.
4+
But this setup might not reflect how you will use the engine on a day to day basis.
5+
:::
6+
7+
:::note
8+
These installation instructions assume you are using Ubuntu Linux.
9+
You can find alternative _(and more advanced)_ installation instructions for [Windows](/manual/install/windowsWSL), [Mac](/manual/install/macOSX) and [Linux](/manual/install/linux) in the Manual.
10+
:::
11+
12+
If you are on Ubuntu Linux, there is an automatic installation script to setup and run a local version of Ethereal Engine.
13+
Open a terminal window and run these two lines:
14+
> Make sure that you open the terminal in the folder where you want to install the engine
15+
```bash
16+
wget https://raw.githubusercontent.com/EtherealEngine/etherealengine/dev/scripts/ubuntu-install.sh && bash -i ./ubuntu-install.sh
17+
npm run reinit && npm run dev
18+
```
19+
You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000

docs/developer/typescript/01_gettingStarted/01_file.md

-2
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
sidebar_label: Quickstart
3+
---
4+
import UbuntuInstall from '../../../_partials/installUbuntu.md'
5+
import DefaultProjects from '../../../_partials/defaultProjects.md'
6+
7+
# Typescript Quickstart
8+
This QuickStart guide will teach you the basics of Ethereal Engine, and how to run the engine for the first time.
9+
10+
## Installation
11+
<UbuntuInstall />
12+
13+
## Projects
14+
### Default Projects
15+
<DefaultProjects />
16+
17+
### Install and Run the tutorial project
18+
Whether you installed the engine with method above, or with the installation instructions for your specific system, your next step will be to install the tutorial project.
19+
20+
:::danger
21+
This `HelloWorld` project should never be installed in a remote deployment.
22+
A local version of the engine is required to follow this introductory tutorial.
23+
:::
24+
25+
The previous commands will have the engine running locally.
26+
Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the tutorial's template project:
27+
```bash
28+
git clone -b Step0 https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello
29+
npm run dev
30+
```
31+
32+
You should now be able to see the `ee-tutorial-hello` project listed in Ethereal Engine's Studio by navigating to https://localhost:3000/studio.
33+
34+
## Confirm the installation
35+
Lets make sure that our `hello world` code is running:
36+
1. Open the project from the Studio by clicking on its card
37+
2. Create a new empty scene
38+
39+
You will know that the code is running if you can see a white sphere in the middle of the scene.
40+
41+
:::note
42+
You can also enter the scene and move around with an avatar by pressing the `Play` button in the editor like we did before.
43+
:::

docs/developer/typescript/01_gettingStarted/02_file2.md

-2
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { TechnicalNote } from '@site/src/components/TechnicalNote';
2+
3+
# The ECS Pattern
4+
The [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) is a pattern used to organize our code when writing software.
5+
In this pattern:
6+
- Logic is represented as `Systems`, and they define the behavior of the application
7+
- Data is represented as `Components` that have no behavior or identifiers attached to them
8+
- Components are attached to Entities
9+
- `Entities` are identifiers
10+
11+
<TechnicalNote title="Technical Summary">
12+
The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior.
13+
The behavior of the application is then controlled by having separate Systems (logic) that process that data.
14+
Systems don't need to know where that data is coming from. They only know what data is stored in the Components that they can operate on.
15+
</TechnicalNote>
16+
17+
:::note
18+
Clicking on the `Technical Summary` note right above will open a drop-down with information about what the ECS pattern is in more advanced/technical terms.
19+
20+
You will find a lot of these `Technical` drop-downs throughout the guides.
21+
Their goal is to give you extra information that is not mandatory to understand to follow the guide, but is very useful to achieve a deeper understanding of the content.
22+
23+
Don't worry if you don't fully understand what some of them explain just yet. We will get there.
24+
:::
25+
26+
## Creating an Entity
27+
Creating an Entity is as simple as calling the `createEntity()` function from Ethereal Engine's `ECS`.
28+
This function will return an identifier that can be used to group Components into a unique and distinct Object.
29+
```ts
30+
const entity = ECS.createEntity()
31+
```
32+
33+
## Adding Components
34+
Components represent data that has no behavior or identification.
35+
The way to attach Components to Entities is by calling the `setComponent` function from Ethereal Engine's `ECS`.
36+
37+
<TechnicalNote>
38+
The `setComponent` function will not return anything, but it will:
39+
- Add the given Component to the Entity.
40+
- Store the Component's data in the internal records of the ECS, so it can used by the engine or accessed through the API _(eg: with `getComponent` and similar functions)_.
41+
</TechnicalNote>
42+
43+
Ethereal Engine requires a specific set of Components in order to create an object that can be presented on the screen:
44+
- **VisibleComponent**
45+
- **TransformComponent**
46+
- **PrimitiveGeometryComponent** or **MeshComponent**
47+
- _(optional)_ **NameComponent**: Not required, but good practice.
48+
49+
50+
### `NameComponent`
51+
Gives a human-readable identifier to an Entity.
52+
Whatever name you add on this field is the name that will show up in the Studio and the debugger.
53+
They are not mandatory, but it is good practice to add them to all your entities.
54+
```ts
55+
ECS.setComponent(entity, NameComponent, 'hello-world')
56+
```
57+
<TechnicalNote title="Clarification">
58+
We said that an entity is an identifier, but we are also giving that identifier a `NameComponent`.
59+
Every Entity represents its internal "name" _(aka identifier)_ as an [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), which does not need to be human-readable.
60+
And `NameComponents` give a human-readable identifier to an Entity, independent of what its UUID is.
61+
</TechnicalNote>
62+
63+
64+
### `VisibleComponent`
65+
Gives the Entity the ability to be visible on the screen.
66+
Entities without this Component will be ignored by the renderer.
67+
```ts
68+
ECS.setComponent(entity, VisibleComponent)
69+
```
70+
71+
### `TransformComponent`
72+
In simple terms, `TransformComponents` give an Entity the ability to have a [position in the world](https://en.wikipedia.org/wiki/Transformation_matrix).
73+
There would be no way to position the Entity in 3D space without attaching this Component to the Entity.
74+
```ts
75+
ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) })
76+
```
77+
> In more technical terms, `TransformComponents` give the Entity the ability to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation).
78+
79+
### `PrimitiveGeometryComponent`
80+
This Component gives Entities a primitive "visual body".
81+
Entities without it would not have any [3D geometry](https://en.wikipedia.org/wiki/Polygon_mesh), so the renderer would not be able to draw them on the screen.
82+
```ts
83+
ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 })
84+
```
85+
> The `1` here means that we are creating a [`SphereGeometry`](https://github.com/EtherealEngine/etherealengine/blob/dev/packages/engine/src/scene/constants/GeometryTypeEnum.ts#L28) object.
86+
> We will create the component using a more readable name in the next section of the tutorial.
87+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
---
2+
sidebar_label: The Engine
3+
---
4+
import { TechnicalNote } from '@site/src/components/TechnicalNote';
5+
import { UnstyledDetails } from '@site/src/components/UnstyledDetails';
6+
7+
# Working with Ethereal Engine
8+
You will need three very important steps for creating a project with Ethereal Engine:
9+
1. Installing Ethereal Engine
10+
2. Installing (or creating) a project
11+
3. Modify and run the source code of your project
12+
13+
We already solved #1 and #2 in the [Quickstart](../quickstart) guide.
14+
Lets do a quick review of how #1 and #2 work, and we will start programming with the engine right after.
15+
16+
## Requirements and Dependencies
17+
We will use `git` and `npm` a lot throughout the guides on this website.
18+
19+
Whether you followed the Quickstart guide for Ubuntu, or installed the engine with the Manual instructions, you will have both `git` and `npm` already installed.
20+
21+
You don't need to understand either of them to get started. This guide will teach you what to do every time they are needed.
22+
Just remember that they are used a lot to work with the engine locally.
23+
24+
## Installing and running Ethereal Engine
25+
Ethereal Engine is a web application.
26+
Just like any other web application, it needs to be run in a server. And that server will provide access to the engine remotely to anyone with access to its address.
27+
28+
We will eventually learn how to work with "deployed" versions of the engine.
29+
But we need to follow this tutorial in a `local development server` instead.
30+
31+
That's exactly what the Quickstart installation guide automated for us.
32+
As the `localhost` part of the URL indicates, we are running a `local` version of the engine.
33+
34+
## Installing and running projects
35+
Ethereal Engine can be **extended** with projects.
36+
They are equivalent to the concept of "projects" in other engines, except they are modular like npm packages _(they are npm packages too)_.
37+
38+
The engine scans for projects mounted in the `/packages/projects/projects` sub-folder.
39+
This means that we can install and run new projects by executing the following commands inside our Ethereal Engine installation folder:
40+
```bash
41+
git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello
42+
npm run dev
43+
```
44+
:::note
45+
You will need to stop the engine and re-run it whenever you install a new project.
46+
:::
47+
48+
<TechnicalNote>
49+
Please note that, in the [Quickstart](../quickstart) guide, we cloned the `Step0` branch from the `ee-tutorial-hello` project specifically, and not the whole project.
50+
We did this by adding `-b Step0` to the `git clone` command:
51+
52+
```bash
53+
git clone -b Step0 https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello
54+
```
55+
56+
This step won't be needed for your own projects.
57+
</TechnicalNote>
58+
59+
These steps will:
60+
- Download a copy of the project's git repository, so the engine can load it
61+
- Install all `npm` packages required by the project
62+
- Run a local development version of the engine
63+
64+
:::note
65+
This is also the process recommended for installation of your own projects.
66+
The difference will be that, instead of starting your project from the minimal HelloWorld example like we are doing now, you will start from a pre-made template.
67+
:::
68+
69+
:::important
70+
Each project's source code is executed globally.
71+
This will become very important later on in this guide.
72+
:::
73+
74+
75+
## Programming with Ethereal Engine
76+
There are two very important steps to take in order to connect the source code of our project to the engine:
77+
- We need to import some Ethereal Engine's modules
78+
- We need to export our code so the engine can run it
79+
80+
### Project Configuration File
81+
Every project has an `xrengine.config.ts` file that defines how it will behave in the engine.
82+
There are multiple options available, but the important thing to remember is that our `src/Hello.ts` code will be connected to the engine from here.
83+
84+
<TechnicalNote title="Config File">
85+
86+
```ts title="ee-tutorial-hello/xrengine.config.ts"
87+
import type { ProjectConfigInterface } from '@etherealengine/projects/ProjectConfigInterface'
88+
89+
const config: ProjectConfigInterface = {
90+
onEvent: undefined,
91+
thumbnail: '/static/etherealengine_thumbnail.jpg',
92+
routes: {},
93+
services: undefined,
94+
databaseSeed: undefined,
95+
// highlight-start
96+
worldInjection: () => import('./src/Hello') // Import our Hello World code
97+
// highlight-end
98+
}
99+
100+
export default config
101+
```
102+
</TechnicalNote>
103+
104+
We don't need to know much more about this file for now. We will explore it further in the `Beyond the Basics` guide.
105+
106+
### Module Imports
107+
In this minimal tutorial we are adding a sphere primitive to the scene.
108+
As this sphere will be a `Spatial` object, we will import a few components from the Spatial engine module:
109+
110+
```ts title="ee-tutorial-hello/src/Hello.ts"
111+
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
112+
import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
113+
import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent'
114+
import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent'
115+
```
116+
We will be adding these Components to our Entity, and Components are part of the ECS pattern.
117+
As such, we will need to use the Ethereal Engine ECS management functions.
118+
The engine provides a convenient way to import all ECS related functions at once through the `ECS` [namespace](https://www.typescriptlang.org/docs/handbook/namespaces.html).
119+
```ts title="ee-tutorial-hello/src/Hello.ts"
120+
import { ECS } from '@etherealengine/ecs'
121+
```
122+
123+
## Modifying our Source Code
124+
We have learned how our minimal example works, but so far we haven't needed to modify any of its source code.
125+
This will be our first modification to the code of the project.
126+
127+
:::important
128+
This guide uses [`Project-based Learning`](https://en.wikipedia.org/wiki/Project-based_learning) as its core teaching philosophy.
129+
From now on, you will be actively modifying the source code of the `ee-tutorial-hello` in every step of the way.
130+
:::
131+
132+
Lets start with a simple change.
133+
We will modify our Sphere `PrimitiveGeometryComponent` to load our geometry with a name, instead of the hardcoded number `1` that we used before.
134+
135+
In order to do this, we need to:
136+
- Open the file `ee-tutorial-hello/src/Hello.ts` with a text editor.
137+
- Import the `GeometryTypeEnum` from the `scene/constants/` sub-module inside the `engine` module.
138+
- Replace the `1` with a call to the `SphereGeometry` name that is stored inside it `GeometryTypeEnum`.
139+
140+
Try to figure out the changes by yourself before looking at the solution.
141+
I don't expect you to know where that enum is stored, so here are some hints to make it easier:
142+
```ts
143+
// The full path to the GeometryTypeEnum is:
144+
'@etherealengine/engine/src/scene/constants/GeometryTypeEnum'
145+
146+
// Getting the ID number of a Sphere by its enum name will look like:
147+
GeometryTypeEnum.SphereGeometry
148+
149+
// To be certain that your changes are working, set the geometry to be a cylinder instead:
150+
GeometryTypeEnum.CylinderGeometry
151+
```
152+
> As we said before, you will need to stop the engine and re-run it whenever you _install_ a new project.
153+
> But you can just refresh the webpage when you update your source code and the engine will load your changes correctly.
154+
155+
:::note
156+
`VSCode` is the recommended editor for programming with Ethereal Engine.
157+
It is not required, but it is highly recommended.
158+
VSCode has support for some important features and plugins that make the Ethereal Engine programming workflow really smooth and featureful.
159+
:::
160+
161+
<TechnicalNote title="Solution">
162+
163+
The imports section of our code will now be:
164+
```ts title="ee-tutorial-hello/src/Hello.ts"
165+
// ... our other imports
166+
import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent'
167+
import { Vector3 } from 'three'
168+
// highlight-start
169+
import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum'
170+
// highlight-end
171+
```
172+
The `PrimitiveGeometryComponent` call will now be:
173+
```ts title="ee-tutorial-hello/src/Hello.ts"
174+
const entity = ECS.createEntity()
175+
// ... our other calls to setComponent
176+
// highlight-start
177+
ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry })
178+
// highlight-end
179+
```
180+
181+
<UnstyledDetails title="Full Solution">
182+
183+
```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers
184+
import { ECS } from '@etherealengine/ecs'
185+
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
186+
import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
187+
import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent'
188+
import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent'
189+
// highlight-start
190+
import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum'
191+
// highlight-end
192+
193+
const entity = ECS.createEntity()
194+
ECS.setComponent(entity, NameComponent, 'hello-world')
195+
ECS.setComponent(entity, VisibleComponent)
196+
ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) })
197+
// highlight-start
198+
ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry })
199+
// highlight-end
200+
```
201+
</UnstyledDetails>
202+
<!-- Full Solution End -->
203+
</TechnicalNote>
204+
<!-- Solution End -->
205+

0 commit comments

Comments
 (0)