From a6503930a13f826cc38be63c53959052f150d8d5 Mon Sep 17 00:00:00 2001 From: Anselm Hook Date: Wed, 10 Jan 2024 10:05:32 -0800 Subject: [PATCH 01/96] typescript breakout --- .../03_developer/03_typescript1.md | 0 .../typescript/01_gettingStarted/00_intro.md | 207 ------------------ .../typescript/01_gettingStarted/01_file.md | 2 - .../01_gettingStarted/01_installation-ee.md | 18 ++ .../typescript/01_gettingStarted/02_file2.md | 2 - .../02_installation-projects.md | 17 ++ .../01_gettingStarted/03_authoring-basic.md | 41 ++++ ..._authoring-basic-and-networking-example.md | 79 +++++++ .../05_authoring-pong-project.md | 188 ++++++++++++++++ test.js | 11 + 10 files changed, 354 insertions(+), 211 deletions(-) create mode 100644 docs/01_gettingStarted/03_developer/03_typescript1.md delete mode 100644 docs/developer/typescript/01_gettingStarted/01_file.md create mode 100644 docs/developer/typescript/01_gettingStarted/01_installation-ee.md delete mode 100644 docs/developer/typescript/01_gettingStarted/02_file2.md create mode 100644 docs/developer/typescript/01_gettingStarted/02_installation-projects.md create mode 100644 docs/developer/typescript/01_gettingStarted/03_authoring-basic.md create mode 100644 docs/developer/typescript/01_gettingStarted/04_authoring-basic-and-networking-example.md create mode 100644 docs/developer/typescript/01_gettingStarted/05_authoring-pong-project.md create mode 100644 test.js diff --git a/docs/01_gettingStarted/03_developer/03_typescript1.md b/docs/01_gettingStarted/03_developer/03_typescript1.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/developer/typescript/01_gettingStarted/00_intro.md b/docs/developer/typescript/01_gettingStarted/00_intro.md index 73a38e2469cd..91a92093699f 100644 --- a/docs/developer/typescript/01_gettingStarted/00_intro.md +++ b/docs/developer/typescript/01_gettingStarted/00_intro.md @@ -6,211 +6,4 @@ NOTE: This page should contain: - Segue: Lead the user into the Developer Manual --> _This guide will teach you how to get started programming with Ethereal Engine using Typescript._ -_Visit the [Typescript: Introduction](/docs/manual/developer/typescript/intro) page for more details._ - -## Overview - -We're going to look at 'Pong', a multiplayer game that we've built in Ethereal Engine using Typescript. It is an example of best practices for developers. - -## Installation and Running Pong - -1) Ethereal Engine scans for projects mounted in the /packages/projects/projects sub-folder of Ethereal Engine. From scratch we can install Ethereal Engine itself and also register a sub project using the following: - -``` -gh repo clone EtherealEngine/EtherealEngine -cd EtherealEngine -cd packages/projects/projects -gh repo clone EtherealEngine/ee-tutorial-pong -cd ../../../ -``` - -2) A fresh install of Ethereal Engine can be run like so: - -``` -npm install -npm run dev -``` - -3) Once Ethereal Engine itself is running, from the web admin panel of Ethereal Engine create a 'location' for the project. See https://localhost:3000/admin . Map the project to the name 'pong'. - -4) Run the project on the web by visiting it with the URL you created. See https://localhost:3000/location/pong - -## Understanding Pong - -### A 10000 foot overview - -Pong has several files which are roughly represent parts of the experience: - -- PaddleSystem -> a paddle 'system' for managing the player paddles specifically. -- PlateComponent -> each pong game has one or more plates that represent player positions in a game. In our case we have 4 player games. -- PongComponent -> each pong game in a larger pong world has a concept of a game starting or stopping; this is managed here. -- PongGameSystem -> a game 'system' for managing each game instance; starting and stopping play and dealing with players. -- PongPhysicsSystem -> a ball spawner and scoring 'system' for the pong game overall -- worldinjection -> bootstraps the game - -A 'Pong' world can have several separate pong tables at once. Each pong table has four pong plates and can handle four players at once. - -### World Injection - -Ethereal Engine projects typically have a worldinjection.ts file to bootstrap a project. In Pong this file registers and starts three 'systems', and does little else: - -``` -import './PaddleSystem' -import './PongGameSystem' -import './PongPhysicsSystem' -export default async function worldInjection() {} -``` - -### Entities, Components and Systems - -Ethereal Engine uses an ECS (Entity Component System). Entities in a game are entirely defined by their Components or 'capabilities', and systems driven the state of the entire application over time by running every frame over those components. One benefit of an ECS is that it allows a highly granular 'vocabulary' for designers to express game ideas with. - -The ECS we use currently BitECS. Another good ECS is Flecs: - -- https://github.com/NateTheGreatt/bitECS -- https://news.ycombinator.com/item?id=35434374 - -In Pong there are three systems imported via worldInjection above. Each is responsible for a different part of the experience: - -1) PaddleSystem -2) PongPhysicsSystem -3) PongGameSystem - -We will look at the PaddleSystem.ts first. - -### PaddleSystem: Introduction to State and Reactivity - -Ethereal Engine uses the React pattern of allowing state observers to 'react' to state changes. This is done for a couple of different reasons. Philosophically it separates the 'what' from the 'how', and technically it helps decouple game components from each other, allowing developers to scale work horizontally, reducing dependencies. - -The React website has several good discussions on reactivity as a whole: - -- https://react.dev/learn/reacting-to-input-with-state - -In Pong each active player has two paddles (one for the left hand and one for the right hand), and paddles are spawned or destroyed as players come and go. In this case the 'what' is that there are some set of paddles. And the 'how' (which we will get to later) is that the paddles happen to be 3d objects with collision hulls. But at this level of scope we can separate our concerns and we don't have to think about how the paddles are manifested. - -In PaddleSystem.ts we see a good example of this reactive state pattern. The approach we've taken here is to track the enumeration of active paddles like so: - -``` -export const PaddleState = defineState({ - name: 'ee.pong.PaddleState', - initial: {} as Record< - EntityUUID, - { - owner: UserID - handedness: 'left' | 'right' - gameEntityUUID: EntityUUID - } - > - ... -``` - -The defineState() method registers a collection of Record objects. A Record is a schema in a third party runtime schema definition language that Ethereal Engine uses. - -### PaddleSystem: Introduction to Event Sourced State - -Ethereal Engine uses an event sourced state paradigm. Sourcing state and responding to that state is asynchronous but a single 'effect' or outcome results, rather than having to propagate potentially thousands of successive state changes. - -A good discussion of Event Sourcing can be found here: - -https://domaincentric.net/blog/event-sourcing-snapshotting - -In an Event Sourced system, the current state of an aggregate is usually reconstituted from the full history of events. It means that before handling a command we need to do a full read of a single fine-grained stream and transport the events over the network. This allows late joiners to synchronize with the overall game state. - -In PaddleSystem we define a set of actions explicitly like so: - -``` -export class PaddleActions { - static spawnPaddle = defineAction({ - ...WorldNetworkAction.spawnObject.actionShape, - prefab: 'ee.pong.paddle', - gameEntityUUID: matchesEntityUUID, - handedness: matches.literals('left', 'right'), - owner: matchesUserId, - $topic: NetworkTopics.world - }) -} -``` - -And we then allow the registration of 'receptors' on state objects to catch dispatched events over the network, and in this case we're entirely focused on updating the state records above: - -``` - ... - receptors: [ - [ - PaddleActions.spawnPaddle, - (state, action: typeof PaddleActions.spawnPaddle.matches._TYPE) => { - state[action.entityUUID].merge({ - owner: action.owner, - handedness: action.handedness, - gameEntityUUID: action.gameEntityUUID - }) - } - ], - [ - WorldNetworkAction.destroyObject, - (state, action: typeof WorldNetworkAction.destroyObject.matches._TYPE) => { - state[action.entityUUID].set(none) - } - ] - ] -}) -``` - -The WorldNetworkAction.destroyObject is an observer we've injected here to catch here to make sure that we update our state tables appropriately. Although we have custom state on the object creation, we don't have any custom state on paddle destruction. - -### PaddleState: Introduction to Components - -With the state management out of the way, now we're left with the details of making sure our visual representations reflect our state. - -PaddleReactor defines a React component that has a useEffect() to observe state changes on a given PaddleState entry. When the PaddleState changes it sets up an entity to reflect that owner. Inside the useEffect() we see several typical 3d and game related components being setup: - - - UUIDComponent - - TransformComponent - - VisibleComponent - - DistanceFromCameraComponent - - FrustrumCullComponent - - NameComponent - - PrimitiveGeometryComponent - - ColliderComponent - - GrabbableComponent - -Most of these components are self descriptive, and this typically reflects the core set of components you'll see in many Ethereal Engine 3d entities that represent objects in a game. - -The GrabbableComponent is notable in that it's a good example of where components are more than just 'state'; they can be used to form an expressive 'vocabulary' of high level intentions. In this case we want the paddle to stay attached to the owner avatar at a specified attachment point. If we didn't have this concept we would have to fire rigid body physics target position events every frame to keep the paddle synchronized with the player. - -### PaddleState: Introduction to Reactors - -Both PaddleReactor and Reactor in PaddleSystem demonstrate reactivity to state. The reactor is updated whenever state changes, and the game entities that exist are a reflection of that larger state. - -### PaddleState: System - -Tying everything together in PaddleSystem is the PaddleSystem itself. It registers and runs an execute() handler every frame and it also registers the reactor: - -``` -export const PaddleSystem = defineSystem({ - uuid: 'pong.paddle-system', - execute, - reactor, - insert: { after: PhysicsSystem } -}) -``` - -### PaddleState: Overall Flow - -The general flow is like so: - -1) The execute handler catches and handles PaddleActions using ```receiveActions(PaddleState)``` - -2) The PaddleActions respond to network events and applies them to the PaddleState. - -3) The reactor reacts to any state changes on PaddleState. - -## PlateComponent - - -### PongComponent, PongGameSystem and PongPhysicsSystem - - -### Summary - diff --git a/docs/developer/typescript/01_gettingStarted/01_file.md b/docs/developer/typescript/01_gettingStarted/01_file.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/01_gettingStarted/01_file.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/01_gettingStarted/01_installation-ee.md b/docs/developer/typescript/01_gettingStarted/01_installation-ee.md new file mode 100644 index 000000000000..7e53b9ea914a --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_installation-ee.md @@ -0,0 +1,18 @@ +# Installing and running Ethereal Engine + +Etherealengine itself can be installed and run like so from a bash shell: + +``` +gh repo clone EtherealEngine/EtherealEngine +cd EtherealEngine +npm install +npm run dev +``` + +Visit Ethereal Engine on the web at https://localhost:3000 + +- have to clarify the opening of ports +- npm dev reinit +- granting of admin perms +- general navigation + diff --git a/docs/developer/typescript/01_gettingStarted/02_file2.md b/docs/developer/typescript/01_gettingStarted/02_file2.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/01_gettingStarted/02_file2.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/01_gettingStarted/02_installation-projects.md b/docs/developer/typescript/01_gettingStarted/02_installation-projects.md new file mode 100644 index 000000000000..4009c34cff39 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/02_installation-projects.md @@ -0,0 +1,17 @@ +# Installation and running sub projects + +Ethereal Engine can run sub-projects or 'locations'. This pattern is different from what you may be used to because Ethereal Engine runs on the 'outside' and the sub-project is kept in a folder of Ethereal Engine. + +Ethereal Engine scans for projects mounted in the /packages/projects/projects sub-folder of Ethereal Engine. + +From a bash shell in the Ethereal Engine folder we can install, run and visit a project like so: + +``` +gh repo clone EtherealEngine/ee-tutorial-basic +mv ee-tutorial-basic packages/projects/packages/ee-tutorial-basic +npm install +npm run dev +``` + +Once Ethereal Engine itself is running, from the web admin panel of Ethereal Engine create a 'location' for the project. See https://localhost:3000/admin . Map the project to the name 'basic'. Then run the project on the web by visiting it with the URL you created. See https://localhost:3000/location/pong + diff --git a/docs/developer/typescript/01_gettingStarted/03_authoring-basic.md b/docs/developer/typescript/01_gettingStarted/03_authoring-basic.md new file mode 100644 index 000000000000..4b9f97becbff --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_authoring-basic.md @@ -0,0 +1,41 @@ +# Authoring a basic project + +This is the source code for 'basic' - a simple project in our repository - you can find the original source at https://github.com/EtherealEngine/ee-tutorial-basic . To install it see the previous section. + +From a typescript programming perspective projects typically have these pieces: + +1) worldInjection, which registers the project as a whole with Ethereal Engine + +2) Systems, that drive behavior over time + +3) Entities. We use an ECS system where entities are a way that we represent game state. + +4) Components. Entities are decorated with components that produce behaviors on entities. + +Here you can see we start a system and create a 'hello-world' entity and then give it a primitive geometry (a sphere) and then adjust the position of that sphere in the scene. + +``` +import { defineSystem } from '@etherealengine/engine/src/ecs/functions/SystemFunctions' +import { PhysicsSystem } from '@etherealengine/engine/src/physics/PhysicsModule' +import { getComponent, setComponent } from '@etherealengine/engine/src/ecs/functions/ComponentFunctions' +import { TransformComponent } from '@etherealengine/engine/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { createSceneEntity } from '@etherealengine/engine/src/ecs/functions/createSceneEntity' + +let initialized = false +const execute = () => { + if(initialized) return + initialized = true + const entity = createSceneEntity('hello-world',null) + setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) + getComponent(entity,TransformComponent).position.set(0,2,0) +} + +export const HelloWorldSystem = defineSystem({ + uuid: 'hellworld.system', + execute, + insert: { after: PhysicsSystem } +}) + +export default async function worldInjection() {} +``` \ No newline at end of file diff --git a/docs/developer/typescript/01_gettingStarted/04_authoring-basic-and-networking-example.md b/docs/developer/typescript/01_gettingStarted/04_authoring-basic-and-networking-example.md new file mode 100644 index 000000000000..aa406d604ab0 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/04_authoring-basic-and-networking-example.md @@ -0,0 +1,79 @@ +# Adding networking to a basic project + +We're going to add networking to the 'basic' example from the previous section so that we can deliver a shared collaborative experience to many players at once. + +## Actions + +First we want to think through what kinds of actions we want in our game. For this tutorial we will just allow the creation and destruction of simple objects over the network. + +In our case we can cheat a bit since destroying objects is common enough that there is a built in world networking event for it, and also for creating objects we can just extend the built in world spawning event. This means we just need to define an action for creation: + +``` +const spawnAction = defineAction({ + ...WorldNetworkAction.spawnObject.actionShape, + prefab: 'ee.basic.ball', + $topic: NetworkTopics.world +}) +``` + +## State + +Ethereal Engine uses an 'event sourced state' paradigm for networking. That means that as a developer you publish an event and that event is performed by all instances simultaneously. + +Typically actions are going to affect state. For this example we will declare that we're going to allow any number of objects, each with their own appearance. We define state in a React like way like so: + +``` +export const BasicState = defineState({ + name: 'ee.basic.BasicState', + initial: {} as Record< EntityUUID, {} >, + ... +``` + +### Receptors + +Finally for this phase we just want to define handlers or receptors to handle the event. These are by convention stored on the state itself: + +``` + ... + receptors: [ + [ + spawnAction, + (state, action: typeof spawnAction.matches._TYPE) => { + state[action.entityUUID].merge({}) + } + ], + [ + WorldNetworkAction.destroyObject, + (state, action: typeof WorldNetworkAction.destroyObject.matches._TYPE) => { + state[action.entityUUID].set(none) + } + ] + ] +``` + +### Dispatching new events + +We can spawn entities now like so at any time: + +``` + dispatchAction(spawnAction({ entityUUID:'my-entity' })) +``` + +### Rendering State + +Once state is being networked we want to visualize that state. The react pattern is to allow state changes to occur and then 'react' to them - creating visual objects that reflect the state database: + +``` +const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { + const basicState = useHookstate(getMutableState(BasicState)[entityUUID]) + useEffect(() => { + const entity = UUIDComponent.getEntityByUUID(entityUUID) + setComponent(entity, TransformComponent) + setComponent(entity, VisibleComponent) + setComponent(entity, NameComponent,'hello') + setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) +``` + +## Closing + +Although this example is simple, these are the basic foundations for richer experiences. The source code for this example from https://github.com/etherealengine/ee-basic-tutorial diff --git a/docs/developer/typescript/01_gettingStarted/05_authoring-pong-project.md b/docs/developer/typescript/01_gettingStarted/05_authoring-pong-project.md new file mode 100644 index 000000000000..6526e241bff7 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/05_authoring-pong-project.md @@ -0,0 +1,188 @@ +# Developer Typescript Tutorials - Pong + +_This tutorial is a richer more advanced tutorial using Typescript._ +_Visit the [Typescript: Introduction](/docs/manual/developer/typescript/intro) page for more details._ + +## Pong + +Here we're going to look at 'Pong', a multiplayer game that we've built in Ethereal Engine using Typescript. Se the installation section for how to install projects like this. + +### A 10000 foot overview + +Pong has several files which are roughly represent parts of the experience: + +- PaddleSystem -> a paddle 'system' for managing the player paddles specifically. +- PlateComponent -> each pong game has one or more plates that represent player positions in a game. In our case we have 4 player games. +- PongComponent -> each pong game in a larger pong world has a concept of a game starting or stopping; this is managed here. +- PongGameSystem -> a game 'system' for managing each game instance; starting and stopping play and dealing with players. +- PongPhysicsSystem -> a ball spawner and scoring 'system' for the pong game overall +- worldinjection -> bootstraps the game + +A 'Pong' world can have several separate pong tables at once. Each pong table has four pong plates and can handle four players at once. + +### World Injection + +Ethereal Engine projects typically have a worldinjection.ts file to bootstrap a project. In Pong this file registers and starts three 'systems', and does little else: + +``` +import './PaddleSystem' +import './PongGameSystem' +import './PongPhysicsSystem' +export default async function worldInjection() {} +``` + +### Entities, Components and Systems + +Ethereal Engine uses an ECS (Entity Component System). Entities in a game are entirely defined by their Components or 'capabilities', and systems driven the state of the entire application over time by running every frame over those components. One benefit of an ECS is that it allows a highly granular 'vocabulary' for designers to express game ideas with. + +The ECS we use currently BitECS. Another good ECS is Flecs: + +- https://github.com/NateTheGreatt/bitECS +- https://news.ycombinator.com/item?id=35434374 + +In Pong there are three systems imported via worldInjection above. Each is responsible for a different part of the experience: + +1) PaddleSystem +2) PongPhysicsSystem +3) PongGameSystem + +We will look at the PaddleSystem.ts first. + +### PaddleSystem: Introduction to State and Reactivity + +Ethereal Engine uses the React pattern of allowing state observers to 'react' to state changes. This is done for a couple of different reasons. Philosophically it separates the 'what' from the 'how', and technically it helps decouple game components from each other, allowing developers to scale work horizontally, reducing dependencies. + +The React website has several good discussions on reactivity as a whole: + +- https://react.dev/learn/reacting-to-input-with-state + +In Pong each active player has two paddles (one for the left hand and one for the right hand), and paddles are spawned or destroyed as players come and go. In this case the 'what' is that there are some set of paddles. And the 'how' (which we will get to later) is that the paddles happen to be 3d objects with collision hulls. But at this level of scope we can separate our concerns and we don't have to think about how the paddles are manifested. + +In PaddleSystem.ts we see a good example of this reactive state pattern. The approach we've taken here is to track the enumeration of active paddles like so: + +``` +export const PaddleState = defineState({ + name: 'ee.pong.PaddleState', + initial: {} as Record< + EntityUUID, + { + owner: UserID + handedness: 'left' | 'right' + gameEntityUUID: EntityUUID + } + > + ... +``` + +The defineState() method registers a collection of Record objects. A Record is a schema in a third party runtime schema definition language that Ethereal Engine uses. + +### PaddleSystem: Introduction to Event Sourced State + +Ethereal Engine uses an event sourced state paradigm. Sourcing state and responding to that state is asynchronous but a single 'effect' or outcome results, rather than having to propagate potentially thousands of successive state changes. + +A good discussion of Event Sourcing can be found here: + +https://domaincentric.net/blog/event-sourcing-snapshotting + +In an Event Sourced system, the current state of an aggregate is usually reconstituted from the full history of events. It means that before handling a command we need to do a full read of a single fine-grained stream and transport the events over the network. This allows late joiners to synchronize with the overall game state. + +In PaddleSystem we define a set of actions explicitly like so: + +``` +export class PaddleActions { + static spawnPaddle = defineAction({ + ...WorldNetworkAction.spawnObject.actionShape, + prefab: 'ee.pong.paddle', + gameEntityUUID: matchesEntityUUID, + handedness: matches.literals('left', 'right'), + owner: matchesUserId, + $topic: NetworkTopics.world + }) +} +``` + +And we then allow the registration of 'receptors' on state objects to catch dispatched events over the network, and in this case we're entirely focused on updating the state records above: + +``` + ... + receptors: [ + [ + PaddleActions.spawnPaddle, + (state, action: typeof PaddleActions.spawnPaddle.matches._TYPE) => { + state[action.entityUUID].merge({ + owner: action.owner, + handedness: action.handedness, + gameEntityUUID: action.gameEntityUUID + }) + } + ], + [ + WorldNetworkAction.destroyObject, + (state, action: typeof WorldNetworkAction.destroyObject.matches._TYPE) => { + state[action.entityUUID].set(none) + } + ] + ] +}) +``` + +The WorldNetworkAction.destroyObject is an observer we've injected here to catch here to make sure that we update our state tables appropriately. Although we have custom state on the object creation, we don't have any custom state on paddle destruction. + +### PaddleState: Introduction to Components + +With the state management out of the way, now we're left with the details of making sure our visual representations reflect our state. + +PaddleReactor defines a React component that has a useEffect() to observe state changes on a given PaddleState entry. When the PaddleState changes it sets up an entity to reflect that owner. Inside the useEffect() we see several typical 3d and game related components being setup: + + - UUIDComponent + - TransformComponent + - VisibleComponent + - DistanceFromCameraComponent + - FrustrumCullComponent + - NameComponent + - PrimitiveGeometryComponent + - ColliderComponent + - GrabbableComponent + +Most of these components are self descriptive, and this typically reflects the core set of components you'll see in many Ethereal Engine 3d entities that represent objects in a game. + +The GrabbableComponent is notable in that it's a good example of where components are more than just 'state'; they can be used to form an expressive 'vocabulary' of high level intentions. In this case we want the paddle to stay attached to the owner avatar at a specified attachment point. If we didn't have this concept we would have to fire rigid body physics target position events every frame to keep the paddle synchronized with the player. + +### PaddleState: Introduction to Reactors + +Both PaddleReactor and Reactor in PaddleSystem demonstrate reactivity to state. The reactor is updated whenever state changes, and the game entities that exist are a reflection of that larger state. + +### PaddleState: System + +Tying everything together in PaddleSystem is the PaddleSystem itself. It registers and runs an execute() handler every frame and it also registers the reactor: + +``` +export const PaddleSystem = defineSystem({ + uuid: 'pong.paddle-system', + execute, + reactor, + insert: { after: PhysicsSystem } +}) +``` + +### PaddleState: Overall Flow + +The general flow is like so: + +1) The execute handler catches and handles PaddleActions using ```receiveActions(PaddleState)``` + +2) The PaddleActions respond to network events and applies them to the PaddleState. + +3) The reactor reacts to any state changes on PaddleState. + +## PlateComponent + +TBD + +### PongComponent, PongGameSystem and PongPhysicsSystem + +TBD + +### Summary + +TBD \ No newline at end of file diff --git a/test.js b/test.js new file mode 100644 index 000000000000..f84f08d7e387 --- /dev/null +++ b/test.js @@ -0,0 +1,11 @@ +const test = { + prop: 42, + function blah() { + return this.prop; + }, +}; + +console.log(test.func()); +// Expected output: 42 + + From 4380697f0db2976600a00d077f709079884d2d51 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:48:24 -0800 Subject: [PATCH 02/96] fmt: Change 00_intro to the new index+nolink system --- docs/developer/typescript/01_gettingStarted/_category_.json | 5 ----- .../typescript/01_gettingStarted/{00_intro.md => index.md} | 0 2 files changed, 5 deletions(-) rename docs/developer/typescript/01_gettingStarted/{00_intro.md => index.md} (100%) diff --git a/docs/developer/typescript/01_gettingStarted/_category_.json b/docs/developer/typescript/01_gettingStarted/_category_.json index 247f10beab5e..429163165677 100644 --- a/docs/developer/typescript/01_gettingStarted/_category_.json +++ b/docs/developer/typescript/01_gettingStarted/_category_.json @@ -1,8 +1,3 @@ { - "label": "Getting Started", "position": 01, - "link": { - "type": "doc", - "id": "developer/typescript/gettingStarted/intro", - } } diff --git a/docs/developer/typescript/01_gettingStarted/00_intro.md b/docs/developer/typescript/01_gettingStarted/index.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/00_intro.md rename to docs/developer/typescript/01_gettingStarted/index.md From 36179667982504294c8bb8e4cf9bd50e18c567c0 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:49:33 -0800 Subject: [PATCH 03/96] fmt: Remove unnecesary folder at docs/ root --- docs/01_gettingStarted/03_developer/03_typescript1.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/01_gettingStarted/03_developer/03_typescript1.md diff --git a/docs/01_gettingStarted/03_developer/03_typescript1.md b/docs/01_gettingStarted/03_developer/03_typescript1.md deleted file mode 100644 index e69de29bb2d1..000000000000 From 56e3ae1b6136b8b76f62cfaa9a1d3ff42bbae242 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:56:31 -0800 Subject: [PATCH 04/96] rmv: Remove the Pong guide, which is worked on at #99 as intermediate --- .../05_authoring-pong-project.md | 188 ------------------ 1 file changed, 188 deletions(-) delete mode 100644 docs/developer/typescript/01_gettingStarted/05_authoring-pong-project.md diff --git a/docs/developer/typescript/01_gettingStarted/05_authoring-pong-project.md b/docs/developer/typescript/01_gettingStarted/05_authoring-pong-project.md deleted file mode 100644 index 6526e241bff7..000000000000 --- a/docs/developer/typescript/01_gettingStarted/05_authoring-pong-project.md +++ /dev/null @@ -1,188 +0,0 @@ -# Developer Typescript Tutorials - Pong - -_This tutorial is a richer more advanced tutorial using Typescript._ -_Visit the [Typescript: Introduction](/docs/manual/developer/typescript/intro) page for more details._ - -## Pong - -Here we're going to look at 'Pong', a multiplayer game that we've built in Ethereal Engine using Typescript. Se the installation section for how to install projects like this. - -### A 10000 foot overview - -Pong has several files which are roughly represent parts of the experience: - -- PaddleSystem -> a paddle 'system' for managing the player paddles specifically. -- PlateComponent -> each pong game has one or more plates that represent player positions in a game. In our case we have 4 player games. -- PongComponent -> each pong game in a larger pong world has a concept of a game starting or stopping; this is managed here. -- PongGameSystem -> a game 'system' for managing each game instance; starting and stopping play and dealing with players. -- PongPhysicsSystem -> a ball spawner and scoring 'system' for the pong game overall -- worldinjection -> bootstraps the game - -A 'Pong' world can have several separate pong tables at once. Each pong table has four pong plates and can handle four players at once. - -### World Injection - -Ethereal Engine projects typically have a worldinjection.ts file to bootstrap a project. In Pong this file registers and starts three 'systems', and does little else: - -``` -import './PaddleSystem' -import './PongGameSystem' -import './PongPhysicsSystem' -export default async function worldInjection() {} -``` - -### Entities, Components and Systems - -Ethereal Engine uses an ECS (Entity Component System). Entities in a game are entirely defined by their Components or 'capabilities', and systems driven the state of the entire application over time by running every frame over those components. One benefit of an ECS is that it allows a highly granular 'vocabulary' for designers to express game ideas with. - -The ECS we use currently BitECS. Another good ECS is Flecs: - -- https://github.com/NateTheGreatt/bitECS -- https://news.ycombinator.com/item?id=35434374 - -In Pong there are three systems imported via worldInjection above. Each is responsible for a different part of the experience: - -1) PaddleSystem -2) PongPhysicsSystem -3) PongGameSystem - -We will look at the PaddleSystem.ts first. - -### PaddleSystem: Introduction to State and Reactivity - -Ethereal Engine uses the React pattern of allowing state observers to 'react' to state changes. This is done for a couple of different reasons. Philosophically it separates the 'what' from the 'how', and technically it helps decouple game components from each other, allowing developers to scale work horizontally, reducing dependencies. - -The React website has several good discussions on reactivity as a whole: - -- https://react.dev/learn/reacting-to-input-with-state - -In Pong each active player has two paddles (one for the left hand and one for the right hand), and paddles are spawned or destroyed as players come and go. In this case the 'what' is that there are some set of paddles. And the 'how' (which we will get to later) is that the paddles happen to be 3d objects with collision hulls. But at this level of scope we can separate our concerns and we don't have to think about how the paddles are manifested. - -In PaddleSystem.ts we see a good example of this reactive state pattern. The approach we've taken here is to track the enumeration of active paddles like so: - -``` -export const PaddleState = defineState({ - name: 'ee.pong.PaddleState', - initial: {} as Record< - EntityUUID, - { - owner: UserID - handedness: 'left' | 'right' - gameEntityUUID: EntityUUID - } - > - ... -``` - -The defineState() method registers a collection of Record objects. A Record is a schema in a third party runtime schema definition language that Ethereal Engine uses. - -### PaddleSystem: Introduction to Event Sourced State - -Ethereal Engine uses an event sourced state paradigm. Sourcing state and responding to that state is asynchronous but a single 'effect' or outcome results, rather than having to propagate potentially thousands of successive state changes. - -A good discussion of Event Sourcing can be found here: - -https://domaincentric.net/blog/event-sourcing-snapshotting - -In an Event Sourced system, the current state of an aggregate is usually reconstituted from the full history of events. It means that before handling a command we need to do a full read of a single fine-grained stream and transport the events over the network. This allows late joiners to synchronize with the overall game state. - -In PaddleSystem we define a set of actions explicitly like so: - -``` -export class PaddleActions { - static spawnPaddle = defineAction({ - ...WorldNetworkAction.spawnObject.actionShape, - prefab: 'ee.pong.paddle', - gameEntityUUID: matchesEntityUUID, - handedness: matches.literals('left', 'right'), - owner: matchesUserId, - $topic: NetworkTopics.world - }) -} -``` - -And we then allow the registration of 'receptors' on state objects to catch dispatched events over the network, and in this case we're entirely focused on updating the state records above: - -``` - ... - receptors: [ - [ - PaddleActions.spawnPaddle, - (state, action: typeof PaddleActions.spawnPaddle.matches._TYPE) => { - state[action.entityUUID].merge({ - owner: action.owner, - handedness: action.handedness, - gameEntityUUID: action.gameEntityUUID - }) - } - ], - [ - WorldNetworkAction.destroyObject, - (state, action: typeof WorldNetworkAction.destroyObject.matches._TYPE) => { - state[action.entityUUID].set(none) - } - ] - ] -}) -``` - -The WorldNetworkAction.destroyObject is an observer we've injected here to catch here to make sure that we update our state tables appropriately. Although we have custom state on the object creation, we don't have any custom state on paddle destruction. - -### PaddleState: Introduction to Components - -With the state management out of the way, now we're left with the details of making sure our visual representations reflect our state. - -PaddleReactor defines a React component that has a useEffect() to observe state changes on a given PaddleState entry. When the PaddleState changes it sets up an entity to reflect that owner. Inside the useEffect() we see several typical 3d and game related components being setup: - - - UUIDComponent - - TransformComponent - - VisibleComponent - - DistanceFromCameraComponent - - FrustrumCullComponent - - NameComponent - - PrimitiveGeometryComponent - - ColliderComponent - - GrabbableComponent - -Most of these components are self descriptive, and this typically reflects the core set of components you'll see in many Ethereal Engine 3d entities that represent objects in a game. - -The GrabbableComponent is notable in that it's a good example of where components are more than just 'state'; they can be used to form an expressive 'vocabulary' of high level intentions. In this case we want the paddle to stay attached to the owner avatar at a specified attachment point. If we didn't have this concept we would have to fire rigid body physics target position events every frame to keep the paddle synchronized with the player. - -### PaddleState: Introduction to Reactors - -Both PaddleReactor and Reactor in PaddleSystem demonstrate reactivity to state. The reactor is updated whenever state changes, and the game entities that exist are a reflection of that larger state. - -### PaddleState: System - -Tying everything together in PaddleSystem is the PaddleSystem itself. It registers and runs an execute() handler every frame and it also registers the reactor: - -``` -export const PaddleSystem = defineSystem({ - uuid: 'pong.paddle-system', - execute, - reactor, - insert: { after: PhysicsSystem } -}) -``` - -### PaddleState: Overall Flow - -The general flow is like so: - -1) The execute handler catches and handles PaddleActions using ```receiveActions(PaddleState)``` - -2) The PaddleActions respond to network events and applies them to the PaddleState. - -3) The reactor reacts to any state changes on PaddleState. - -## PlateComponent - -TBD - -### PongComponent, PongGameSystem and PongPhysicsSystem - -TBD - -### Summary - -TBD \ No newline at end of file From de485fd891c92501c78e63fb021eb7e8eb2922e6 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 30 Jan 2024 12:07:58 -0800 Subject: [PATCH 05/96] fmt: Restructured the tutorial files/folders/titles --- .../{01_installation-ee.md => 01_install/01_engine.md} | 3 +++ .../02_projects.md} | 5 ++++- .../typescript/01_gettingStarted/01_install/_category_.json | 4 ++++ .../01_networking.md} | 3 +-- .../typescript/01_gettingStarted/02_basic/_category_.json | 3 +++ .../{03_authoring-basic.md => 02_basic/index.md} | 5 ++--- docs/developer/typescript/01_gettingStarted/index.md | 3 +++ 7 files changed, 20 insertions(+), 6 deletions(-) rename docs/developer/typescript/01_gettingStarted/{01_installation-ee.md => 01_install/01_engine.md} (90%) rename docs/developer/typescript/01_gettingStarted/{02_installation-projects.md => 01_install/02_projects.md} (92%) create mode 100644 docs/developer/typescript/01_gettingStarted/01_install/_category_.json rename docs/developer/typescript/01_gettingStarted/{04_authoring-basic-and-networking-example.md => 02_basic/01_networking.md} (98%) create mode 100644 docs/developer/typescript/01_gettingStarted/02_basic/_category_.json rename docs/developer/typescript/01_gettingStarted/{03_authoring-basic.md => 02_basic/index.md} (98%) diff --git a/docs/developer/typescript/01_gettingStarted/01_installation-ee.md b/docs/developer/typescript/01_gettingStarted/01_install/01_engine.md similarity index 90% rename from docs/developer/typescript/01_gettingStarted/01_installation-ee.md rename to docs/developer/typescript/01_gettingStarted/01_install/01_engine.md index 7e53b9ea914a..ef87d331b082 100644 --- a/docs/developer/typescript/01_gettingStarted/01_installation-ee.md +++ b/docs/developer/typescript/01_gettingStarted/01_install/01_engine.md @@ -1,3 +1,6 @@ +--- +sidebar_label: Ethereal Engine +--- # Installing and running Ethereal Engine Etherealengine itself can be installed and run like so from a bash shell: diff --git a/docs/developer/typescript/01_gettingStarted/02_installation-projects.md b/docs/developer/typescript/01_gettingStarted/01_install/02_projects.md similarity index 92% rename from docs/developer/typescript/01_gettingStarted/02_installation-projects.md rename to docs/developer/typescript/01_gettingStarted/01_install/02_projects.md index 4009c34cff39..ac373151b63c 100644 --- a/docs/developer/typescript/01_gettingStarted/02_installation-projects.md +++ b/docs/developer/typescript/01_gettingStarted/01_install/02_projects.md @@ -1,4 +1,7 @@ -# Installation and running sub projects +--- +sidebar_label: Sub Projects +--- +# Installing and running sub projects Ethereal Engine can run sub-projects or 'locations'. This pattern is different from what you may be used to because Ethereal Engine runs on the 'outside' and the sub-project is kept in a folder of Ethereal Engine. diff --git a/docs/developer/typescript/01_gettingStarted/01_install/_category_.json b/docs/developer/typescript/01_gettingStarted/01_install/_category_.json new file mode 100644 index 000000000000..c97ff54104ef --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_install/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Installation", + "position": 01, +} diff --git a/docs/developer/typescript/01_gettingStarted/04_authoring-basic-and-networking-example.md b/docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md similarity index 98% rename from docs/developer/typescript/01_gettingStarted/04_authoring-basic-and-networking-example.md rename to docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md index aa406d604ab0..0b287148f0cc 100644 --- a/docs/developer/typescript/01_gettingStarted/04_authoring-basic-and-networking-example.md +++ b/docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md @@ -1,5 +1,4 @@ -# Adding networking to a basic project - +# Adding networking We're going to add networking to the 'basic' example from the previous section so that we can deliver a shared collaborative experience to many players at once. ## Actions diff --git a/docs/developer/typescript/01_gettingStarted/02_basic/_category_.json b/docs/developer/typescript/01_gettingStarted/02_basic/_category_.json new file mode 100644 index 000000000000..e0d3b8be94f4 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/02_basic/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 02, +} diff --git a/docs/developer/typescript/01_gettingStarted/03_authoring-basic.md b/docs/developer/typescript/01_gettingStarted/02_basic/index.md similarity index 98% rename from docs/developer/typescript/01_gettingStarted/03_authoring-basic.md rename to docs/developer/typescript/01_gettingStarted/02_basic/index.md index 4b9f97becbff..2fe9136b69d8 100644 --- a/docs/developer/typescript/01_gettingStarted/03_authoring-basic.md +++ b/docs/developer/typescript/01_gettingStarted/02_basic/index.md @@ -1,5 +1,4 @@ -# Authoring a basic project - +# Creating a project This is the source code for 'basic' - a simple project in our repository - you can find the original source at https://github.com/EtherealEngine/ee-tutorial-basic . To install it see the previous section. From a typescript programming perspective projects typically have these pieces: @@ -38,4 +37,4 @@ export const HelloWorldSystem = defineSystem({ }) export default async function worldInjection() {} -``` \ No newline at end of file +``` diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/index.md index 91a92093699f..b836e669fb94 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/index.md @@ -1,3 +1,6 @@ +--- +sidebar_label: Getting Started +--- # Getting Started with Typescript diff --git a/docs/developer/typescript/01_gettingStarted/01_install/02_projects.md b/docs/developer/typescript/01_gettingStarted/01_install/02_projects.md index ac373151b63c..aab1036be628 100644 --- a/docs/developer/typescript/01_gettingStarted/01_install/02_projects.md +++ b/docs/developer/typescript/01_gettingStarted/01_install/02_projects.md @@ -2,19 +2,23 @@ sidebar_label: Sub Projects --- # Installing and running sub projects - -Ethereal Engine can run sub-projects or 'locations'. This pattern is different from what you may be used to because Ethereal Engine runs on the 'outside' and the sub-project is kept in a folder of Ethereal Engine. +Ethereal Engine can run sub-projects or 'locations'. +This pattern is different from what you may be used to because Ethereal Engine runs on the 'outside' and the sub-project is kept in a folder of Ethereal Engine. Ethereal Engine scans for projects mounted in the /packages/projects/projects sub-folder of Ethereal Engine. From a bash shell in the Ethereal Engine folder we can install, run and visit a project like so: -``` +```bash gh repo clone EtherealEngine/ee-tutorial-basic mv ee-tutorial-basic packages/projects/packages/ee-tutorial-basic npm install npm run dev ``` -Once Ethereal Engine itself is running, from the web admin panel of Ethereal Engine create a 'location' for the project. See https://localhost:3000/admin . Map the project to the name 'basic'. Then run the project on the web by visiting it with the URL you created. See https://localhost:3000/location/pong +Once Ethereal Engine is running, from the web admin panel of Ethereal Engine create a 'location' for the project. +See https://localhost:3000/admin. +Map the project to the name 'basic'. +Then run the project on the web by visiting it with the URL you created. +See https://localhost:3000/location/pong diff --git a/docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md b/docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md index 0b287148f0cc..e294d5cb342c 100644 --- a/docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md +++ b/docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md @@ -1,13 +1,15 @@ # Adding networking -We're going to add networking to the 'basic' example from the previous section so that we can deliver a shared collaborative experience to many players at once. +We're going to add networking to the `basic` example from the previous section. +Our goal is to deliver a shared and collaborative experience to many players at once. ## Actions +First we want to think through what kinds of actions we want in our game. +For this tutorial we will allow the creation and destruction of simple objects over the network. -First we want to think through what kinds of actions we want in our game. For this tutorial we will just allow the creation and destruction of simple objects over the network. +In our case we can cheat a bit since destroying objects is common enough that there is a built in world networking event for it, and also for creating objects we can extend the built in world spawning event. -In our case we can cheat a bit since destroying objects is common enough that there is a built in world networking event for it, and also for creating objects we can just extend the built in world spawning event. This means we just need to define an action for creation: - -``` +This means that we need to define an action for creation: +```ts const spawnAction = defineAction({ ...WorldNetworkAction.spawnObject.actionShape, prefab: 'ee.basic.ball', @@ -16,12 +18,11 @@ const spawnAction = defineAction({ ``` ## State - Ethereal Engine uses an 'event sourced state' paradigm for networking. That means that as a developer you publish an event and that event is performed by all instances simultaneously. Typically actions are going to affect state. For this example we will declare that we're going to allow any number of objects, each with their own appearance. We define state in a React like way like so: -``` +```ts export const BasicState = defineState({ name: 'ee.basic.BasicState', initial: {} as Record< EntityUUID, {} >, @@ -29,10 +30,9 @@ export const BasicState = defineState({ ``` ### Receptors - -Finally for this phase we just want to define handlers or receptors to handle the event. These are by convention stored on the state itself: - -``` +Finally for this phase we want to define handlers or receptors to handle the event. +These are by convention stored on the state itself: +```ts ... receptors: [ [ @@ -51,18 +51,17 @@ Finally for this phase we just want to define handlers or receptors to handle th ``` ### Dispatching new events - We can spawn entities now like so at any time: -``` - dispatchAction(spawnAction({ entityUUID:'my-entity' })) +```ts +dispatchAction(spawnAction({ entityUUID:'my-entity' })) ``` ### Rendering State Once state is being networked we want to visualize that state. The react pattern is to allow state changes to occur and then 'react' to them - creating visual objects that reflect the state database: -``` +```ts const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { const basicState = useHookstate(getMutableState(BasicState)[entityUUID]) useEffect(() => { @@ -74,5 +73,5 @@ const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { ``` ## Closing - -Although this example is simple, these are the basic foundations for richer experiences. The source code for this example from https://github.com/etherealengine/ee-basic-tutorial +Although this example is simple, these are the basic foundations for richer experiences. +The source code for this example from https://github.com/etherealengine/ee-basic-tutorial diff --git a/docs/developer/typescript/01_gettingStarted/02_basic/index.md b/docs/developer/typescript/01_gettingStarted/02_basic/index.md index 2fe9136b69d8..c4d763a94d0b 100644 --- a/docs/developer/typescript/01_gettingStarted/02_basic/index.md +++ b/docs/developer/typescript/01_gettingStarted/02_basic/index.md @@ -1,19 +1,22 @@ # Creating a project -This is the source code for 'basic' - a simple project in our repository - you can find the original source at https://github.com/EtherealEngine/ee-tutorial-basic . To install it see the previous section. - -From a typescript programming perspective projects typically have these pieces: - -1) worldInjection, which registers the project as a whole with Ethereal Engine - -2) Systems, that drive behavior over time - -3) Entities. We use an ECS system where entities are a way that we represent game state. - -4) Components. Entities are decorated with components that produce behaviors on entities. - -Here you can see we start a system and create a 'hello-world' entity and then give it a primitive geometry (a sphere) and then adjust the position of that sphere in the scene. - -``` +In this section we will create a simple project called `basic`. +:::note +You can find the original source at https://github.com/EtherealEngine/ee-tutorial-basic. +See the previous section for installation instructions. +::: + +Ethereal Engine typescript projects usually have these pieces: +1. **Entities**: We use an ECS system where entities are a way that we represent game state. +2. **Components**: Entities are decorated with components that produce behaviors on entities. +3. **Systems**: Drive behavior over time +4. **WorldInjection**: Registers the project with Ethereal Engine + +This simple example will: +- Start a system +- Create a `hello-world` entity +- Give the entity a primitive geometry component (a sphere) +- Adjust the position of that sphere in the scene. +```ts import { defineSystem } from '@etherealengine/engine/src/ecs/functions/SystemFunctions' import { PhysicsSystem } from '@etherealengine/engine/src/physics/PhysicsModule' import { getComponent, setComponent } from '@etherealengine/engine/src/ecs/functions/ComponentFunctions' From c6366820a20a23f340fba22d9eab7125aa5858bf Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 30 Jan 2024 19:33:12 -0800 Subject: [PATCH 07/96] new: Quickstart sketch --- .../01_gettingStarted/01_install/01_engine.md | 21 ------ .../01_gettingStarted/01_quickstart.md | 72 +++++++++++++++++++ .../01_gettingStarted/02_install/01_engine.md | 13 ++++ .../{01_install => 02_install}/02_projects.md | 0 .../_category_.json | 0 5 files changed, 85 insertions(+), 21 deletions(-) delete mode 100644 docs/developer/typescript/01_gettingStarted/01_install/01_engine.md create mode 100644 docs/developer/typescript/01_gettingStarted/01_quickstart.md create mode 100644 docs/developer/typescript/01_gettingStarted/02_install/01_engine.md rename docs/developer/typescript/01_gettingStarted/{01_install => 02_install}/02_projects.md (100%) rename docs/developer/typescript/01_gettingStarted/{01_install => 02_install}/_category_.json (100%) diff --git a/docs/developer/typescript/01_gettingStarted/01_install/01_engine.md b/docs/developer/typescript/01_gettingStarted/01_install/01_engine.md deleted file mode 100644 index 615dcff5526a..000000000000 --- a/docs/developer/typescript/01_gettingStarted/01_install/01_engine.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_label: Ethereal Engine ---- -# Installing and running Ethereal Engine -Ethereal Engine can be installed and run from a bash shell with: -```bash -gh repo clone EtherealEngine/EtherealEngine -cd EtherealEngine -npm install -npm run dev -``` -You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 - - - diff --git a/docs/developer/typescript/01_gettingStarted/01_quickstart.md b/docs/developer/typescript/01_gettingStarted/01_quickstart.md new file mode 100644 index 000000000000..14847ac797a8 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_quickstart.md @@ -0,0 +1,72 @@ +# Introduction +This QuickStart guide will teach you how to run Ethereal Engine for the first time. + +:::note +This guide assumes you are using Ubuntu Linux. +You can find alternative _(and more advanced)_ installation instructions for [Windows](/manual/host/installation/windowsWSL), [Mac](/manual/host/installation/macOSX) and [Linux](/manual/host/installation/intro) in the Manual. +::: + +## Install Pre-requisites +```bash +# Install git: +sudo apt install git +git --version + +# Install nvm: +wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash +source ~/.bashrc +command -v nvm + +# Install Node18 +nvm install 18 +npm --version +node --version + +# Install Docker (https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository) +## Clean conflicting packages +for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done +## Add Docker's official GPG key: +sudo apt-get update +sudo apt-get install ca-certificates curl +sudo install -m 0755 -d /etc/apt/keyrings +sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc +sudo chmod a+r /etc/apt/keyrings/docker.asc +## Add the repository to Apt sources: +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo apt-get update +## Start docker +sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +``` +Open [this link](https://docs.docker.com/desktop/install/ubuntu/#install-docker-desktop) and click on `Download latest DEB package`. +Make sure you download the `.deb` file into the folder you are currently on right now. +```bash +sudo apt install $(find -type f -path "./docker-desktop-*.deb") +``` + +## Install and run Ethereal Engine +Ethereal Engine can be installed with: +```bash +git clone https://github.com/EtherealEngine/etherealengine +cd etherealengine +npm install +npm run dev +``` +You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 + +## Install and run the tutorial project +Install, run and visit a project by running the following commands from the Ethereal Engine folder: +```bash +git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic +npm install +npm run dev +``` + +Once Ethereal Engine is running, from the web admin panel of Ethereal Engine create a 'location' for the project. +See https://localhost:3000/admin. +Map the project to the name `basic`. +Then run the project on the web by visiting it with the URL you created. +See https://localhost:3000/location/pong + diff --git a/docs/developer/typescript/01_gettingStarted/02_install/01_engine.md b/docs/developer/typescript/01_gettingStarted/02_install/01_engine.md new file mode 100644 index 000000000000..cef345e9efba --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/02_install/01_engine.md @@ -0,0 +1,13 @@ +--- +sidebar_label: Ethereal Engine +--- +# Installing and running Ethereal Engine + + + diff --git a/docs/developer/typescript/01_gettingStarted/01_install/02_projects.md b/docs/developer/typescript/01_gettingStarted/02_install/02_projects.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/01_install/02_projects.md rename to docs/developer/typescript/01_gettingStarted/02_install/02_projects.md diff --git a/docs/developer/typescript/01_gettingStarted/01_install/_category_.json b/docs/developer/typescript/01_gettingStarted/02_install/_category_.json similarity index 100% rename from docs/developer/typescript/01_gettingStarted/01_install/_category_.json rename to docs/developer/typescript/01_gettingStarted/02_install/_category_.json From be6846b11cd984d3e6b59bce4194f74d9fdb2136 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:34:09 -0800 Subject: [PATCH 08/96] chg: Turn the confusing install instructions into a simple bash script --- .../01_gettingStarted/01_quickstart.md | 56 ++----------------- 1 file changed, 5 insertions(+), 51 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_quickstart.md b/docs/developer/typescript/01_gettingStarted/01_quickstart.md index 14847ac797a8..17517eb1e687 100644 --- a/docs/developer/typescript/01_gettingStarted/01_quickstart.md +++ b/docs/developer/typescript/01_gettingStarted/01_quickstart.md @@ -6,67 +6,21 @@ This guide assumes you are using Ubuntu Linux. You can find alternative _(and more advanced)_ installation instructions for [Windows](/manual/host/installation/windowsWSL), [Mac](/manual/host/installation/macOSX) and [Linux](/manual/host/installation/intro) in the Manual. ::: -## Install Pre-requisites -```bash -# Install git: -sudo apt install git -git --version - -# Install nvm: -wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash -source ~/.bashrc -command -v nvm - -# Install Node18 -nvm install 18 -npm --version -node --version - -# Install Docker (https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository) -## Clean conflicting packages -for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done -## Add Docker's official GPG key: -sudo apt-get update -sudo apt-get install ca-certificates curl -sudo install -m 0755 -d /etc/apt/keyrings -sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc -sudo chmod a+r /etc/apt/keyrings/docker.asc -## Add the repository to Apt sources: -echo \ - "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ - $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ - sudo tee /etc/apt/sources.list.d/docker.list > /dev/null -sudo apt-get update -## Start docker -sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -``` -Open [this link](https://docs.docker.com/desktop/install/ubuntu/#install-docker-desktop) and click on `Download latest DEB package`. -Make sure you download the `.deb` file into the folder you are currently on right now. -```bash -sudo apt install $(find -type f -path "./docker-desktop-*.deb") -``` - -## Install and run Ethereal Engine +## Install Ethereal Engine and its Pre-requisites Ethereal Engine can be installed with: + ```bash -git clone https://github.com/EtherealEngine/etherealengine -cd etherealengine -npm install +wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/install.sh | bash -i npm run dev ``` You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 ## Install and run the tutorial project -Install, run and visit a project by running the following commands from the Ethereal Engine folder: +The previous command will have the engine running. +Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: ```bash git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic npm install npm run dev ``` -Once Ethereal Engine is running, from the web admin panel of Ethereal Engine create a 'location' for the project. -See https://localhost:3000/admin. -Map the project to the name `basic`. -Then run the project on the web by visiting it with the URL you created. -See https://localhost:3000/location/pong - From dfa324a04f90de402ab89a900dacf6b2069fb0ea Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:52:03 -0800 Subject: [PATCH 09/96] chg: Move installation intro to the intro page --- .../01_gettingStarted/01_quickstart.md | 26 ------------------ .../typescript/01_gettingStarted/index.md | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+), 26 deletions(-) delete mode 100644 docs/developer/typescript/01_gettingStarted/01_quickstart.md diff --git a/docs/developer/typescript/01_gettingStarted/01_quickstart.md b/docs/developer/typescript/01_gettingStarted/01_quickstart.md deleted file mode 100644 index 17517eb1e687..000000000000 --- a/docs/developer/typescript/01_gettingStarted/01_quickstart.md +++ /dev/null @@ -1,26 +0,0 @@ -# Introduction -This QuickStart guide will teach you how to run Ethereal Engine for the first time. - -:::note -This guide assumes you are using Ubuntu Linux. -You can find alternative _(and more advanced)_ installation instructions for [Windows](/manual/host/installation/windowsWSL), [Mac](/manual/host/installation/macOSX) and [Linux](/manual/host/installation/intro) in the Manual. -::: - -## Install Ethereal Engine and its Pre-requisites -Ethereal Engine can be installed with: - -```bash -wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/install.sh | bash -i -npm run dev -``` -You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 - -## Install and run the tutorial project -The previous command will have the engine running. -Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: -```bash -git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic -npm install -npm run dev -``` - diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/index.md index b836e669fb94..2b1ac0c469bf 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/index.md @@ -10,3 +10,30 @@ NOTE: This page should contain: --> _This guide will teach you how to get started programming with Ethereal Engine using Typescript._ + +# Introduction +This QuickStart guide will teach you how to run Ethereal Engine for the first time. + +:::note +This guide assumes you are using Ubuntu Linux. +You can find alternative _(and more advanced)_ installation instructions for [Windows](/manual/host/installation/windowsWSL), [Mac](/manual/host/installation/macOSX) and [Linux](/manual/host/installation/intro) in the Manual. +::: + +## Install Ethereal Engine and its Pre-requisites +Ethereal Engine can be installed with: + +```bash +wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/install.sh | bash -i +npm run dev +``` +You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 + +## Install and run the tutorial project +The previous command will have the engine running. +Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: +```bash +git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic +npm install +npm run dev +``` + From 2618904c30d031f3991c58abc86bbc8641be3108 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 31 Jan 2024 16:58:12 -0800 Subject: [PATCH 10/96] chg: Move the UbuntuEasyInstall instructions to a partial file --- docs/_partials/ubuntu_installEE.md | 22 ++++++++++++++++ .../typescript/01_gettingStarted/index.md | 26 +++---------------- 2 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 docs/_partials/ubuntu_installEE.md diff --git a/docs/_partials/ubuntu_installEE.md b/docs/_partials/ubuntu_installEE.md new file mode 100644 index 000000000000..94ed59d17fca --- /dev/null +++ b/docs/_partials/ubuntu_installEE.md @@ -0,0 +1,22 @@ +:::note +This guide assumes you are using Ubuntu Linux. +You can find alternative _(and more advanced)_ installation instructions for [Windows](/manual/host/installation/windowsWSL), [Mac](/manual/host/installation/macOSX) and [Linux](/manual/host/installation/intro) in the Manual. +::: + +## Install Ethereal Engine and its Pre-requisites +Ethereal Engine can be installed with: + +```bash +wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/install.sh | bash -i +npm run dev +``` +You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 + +## Install and run the tutorial project +The previous command will have the engine running. +Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: +```bash +git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic +npm install +npm run dev +``` diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/index.md index 2b1ac0c469bf..2bbeaba86373 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/index.md @@ -1,6 +1,8 @@ --- sidebar_label: Getting Started --- +import UbuntuInstall from '../../../_partials/ubuntu_installEE.md' + # Getting Started with Typescript -```bash -wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/install.sh | bash -i -npm run dev -``` -You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 - -## Install and run the tutorial project -The previous command will have the engine running. -Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: -```bash -git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic -npm install -npm run dev -``` - + From 43f243b62f31ff7579b72f33c3917fffdedfcf93 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 31 Jan 2024 19:59:19 -0800 Subject: [PATCH 11/96] new: Create the gettingStarted/extras section --- docs/_partials/ubuntu_installEE.md | 4 ++-- .../typescript/01_gettingStarted/03_next.md | 10 ++++++++++ .../{02_basic => 50_extras}/01_networking.md | 7 ++++--- .../01_gettingStarted/50_extras/_category_.json | 10 ++++++++++ .../developer/typescript/01_gettingStarted/index.md | 13 ++----------- 5 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 docs/developer/typescript/01_gettingStarted/03_next.md rename docs/developer/typescript/01_gettingStarted/{02_basic => 50_extras}/01_networking.md (94%) create mode 100644 docs/developer/typescript/01_gettingStarted/50_extras/_category_.json diff --git a/docs/_partials/ubuntu_installEE.md b/docs/_partials/ubuntu_installEE.md index 94ed59d17fca..acb331d6e7f2 100644 --- a/docs/_partials/ubuntu_installEE.md +++ b/docs/_partials/ubuntu_installEE.md @@ -3,7 +3,7 @@ This guide assumes you are using Ubuntu Linux. You can find alternative _(and more advanced)_ installation instructions for [Windows](/manual/host/installation/windowsWSL), [Mac](/manual/host/installation/macOSX) and [Linux](/manual/host/installation/intro) in the Manual. ::: -## Install Ethereal Engine and its Pre-requisites +### Install Ethereal Engine and its Pre-requisites Ethereal Engine can be installed with: ```bash @@ -12,7 +12,7 @@ npm run dev ``` You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 -## Install and run the tutorial project +### Install and run the tutorial project The previous command will have the engine running. Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: ```bash diff --git a/docs/developer/typescript/01_gettingStarted/03_next.md b/docs/developer/typescript/01_gettingStarted/03_next.md new file mode 100644 index 000000000000..234466af4bf0 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_next.md @@ -0,0 +1,10 @@ +# Hero Tutorial + + + + diff --git a/docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md b/docs/developer/typescript/01_gettingStarted/50_extras/01_networking.md similarity index 94% rename from docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md rename to docs/developer/typescript/01_gettingStarted/50_extras/01_networking.md index e294d5cb342c..936402f06f46 100644 --- a/docs/developer/typescript/01_gettingStarted/02_basic/01_networking.md +++ b/docs/developer/typescript/01_gettingStarted/50_extras/01_networking.md @@ -1,4 +1,4 @@ -# Adding networking +# Networking We're going to add networking to the `basic` example from the previous section. Our goal is to deliver a shared and collaborative experience to many players at once. @@ -73,5 +73,6 @@ const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { ``` ## Closing -Although this example is simple, these are the basic foundations for richer experiences. -The source code for this example from https://github.com/etherealengine/ee-basic-tutorial +This example is simple, but these are the building blocks and foundations for creating richer and more complex experiences. +The source code for this example from https://github.com/etherealengine/ee-tutorial-basic + diff --git a/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json b/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json new file mode 100644 index 000000000000..52224f8ef9bc --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Extras", + "position": 50, + "link": { + "type": "generated-index", + "description": "." + "id": "developer/typescript/gettingStarted/extras", + } +} + diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/index.md index 2bbeaba86373..82bcddedf2e1 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/index.md @@ -4,16 +4,7 @@ sidebar_label: Getting Started import UbuntuInstall from '../../../_partials/ubuntu_installEE.md' # Getting Started with Typescript - -_This guide will teach you how to get started programming with Ethereal Engine using Typescript._ - - -# Introduction -This QuickStart guide will teach you how to run Ethereal Engine for the first time. +This QuickStart guide will teach you the basics of Ethereal Engine, and how to run the engine for the first time. +## Installation From c3cb0733ee4e94f016050fed47557495238b774a Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:38:21 -0800 Subject: [PATCH 12/96] fix: Typo in developer/typescript/start/extras category file --- .../typescript/01_gettingStarted/50_extras/_category_.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json b/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json index 52224f8ef9bc..16cdce6e6756 100644 --- a/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json +++ b/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json @@ -3,7 +3,7 @@ "position": 50, "link": { "type": "generated-index", - "description": "." + "description": ".", "id": "developer/typescript/gettingStarted/extras", } } From dea0af3b238dd72e3fafcf71ddba1da24620cf16 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:41:16 -0800 Subject: [PATCH 13/96] fix: Remove id from developer/typescript/start/extras category file --- .../typescript/01_gettingStarted/50_extras/_category_.json | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json b/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json index 16cdce6e6756..fabb1d60ef3b 100644 --- a/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json +++ b/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json @@ -4,7 +4,6 @@ "link": { "type": "generated-index", "description": ".", - "id": "developer/typescript/gettingStarted/extras", } } From 4d82dd47a2a5ed2e54e7a48b73ae8ac2ac4631dc Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:38:21 -0800 Subject: [PATCH 14/96] fmt: Move tutorial-basic instructions out of the ubuntu installer file --- .../{ubuntu_installEE.md => installUbuntu.md} | 9 --------- docs/developer/typescript/01_gettingStarted/index.md | 11 ++++++++++- 2 files changed, 10 insertions(+), 10 deletions(-) rename docs/_partials/{ubuntu_installEE.md => installUbuntu.md} (64%) diff --git a/docs/_partials/ubuntu_installEE.md b/docs/_partials/installUbuntu.md similarity index 64% rename from docs/_partials/ubuntu_installEE.md rename to docs/_partials/installUbuntu.md index acb331d6e7f2..ecd24bfa8f93 100644 --- a/docs/_partials/ubuntu_installEE.md +++ b/docs/_partials/installUbuntu.md @@ -11,12 +11,3 @@ wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/instal npm run dev ``` You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 - -### Install and run the tutorial project -The previous command will have the engine running. -Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: -```bash -git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic -npm install -npm run dev -``` diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/index.md index 82bcddedf2e1..71511d4339b6 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/index.md @@ -1,10 +1,19 @@ --- sidebar_label: Getting Started --- -import UbuntuInstall from '../../../_partials/ubuntu_installEE.md' +import UbuntuInstall from '../../../_partials/installUbuntu.md' # Getting Started with Typescript This QuickStart guide will teach you the basics of Ethereal Engine, and how to run the engine for the first time. ## Installation + +### Install and run the tutorial project +The previous command will have the engine running. +Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: +```bash +git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic +npm install +npm run dev +``` From 4c52183e2749c4483e83c86804b3d16df72af900 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:38:48 -0800 Subject: [PATCH 15/96] new: Add typescript/start/hello section --- .../typescript/01_gettingStarted/01_hello/_category_.json | 3 +++ docs/developer/typescript/01_gettingStarted/01_hello/index.md | 1 + 2 files changed, 4 insertions(+) create mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/_category_.json create mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/index.md diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/_category_.json b/docs/developer/typescript/01_gettingStarted/01_hello/_category_.json new file mode 100644 index 000000000000..429163165677 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_hello/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 01, +} diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/index.md b/docs/developer/typescript/01_gettingStarted/01_hello/index.md new file mode 100644 index 000000000000..e08d8b26929f --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_hello/index.md @@ -0,0 +1 @@ +# Hello Ethereal From e3920855469228425faea2de49b7a211173a675a Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 1 Feb 2024 19:38:42 -0800 Subject: [PATCH 16/96] chg: Small changes to the hello world tutorial --- .../developer/typescript/01_gettingStarted/01_hello/index.md | 5 ++++- docs/developer/typescript/01_gettingStarted/index.md | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/index.md b/docs/developer/typescript/01_gettingStarted/01_hello/index.md index e08d8b26929f..ac7dec2cb7e7 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/index.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/index.md @@ -1 +1,4 @@ -# Hello Ethereal +--- +sidebar_label: Hello Ethereal +--- +# Hello World from Ethereal Engine diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/index.md index 71511d4339b6..1b106c5ebbaf 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/index.md @@ -13,7 +13,7 @@ This QuickStart guide will teach you the basics of Ethereal Engine, and how to r The previous command will have the engine running. Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: ```bash -git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic +git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/packages/ee-tutorial-hello npm install npm run dev ``` From 208fd703302685a367e1d14f1296434f1c013341 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 2 Feb 2024 08:37:36 -0800 Subject: [PATCH 17/96] fix: Incorrect todo link to the ubuntu install script. rmv: whitespace --- docs/_partials/installUbuntu.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/_partials/installUbuntu.md b/docs/_partials/installUbuntu.md index ecd24bfa8f93..2895c7c526d7 100644 --- a/docs/_partials/installUbuntu.md +++ b/docs/_partials/installUbuntu.md @@ -4,10 +4,9 @@ You can find alternative _(and more advanced)_ installation instructions for [Wi ::: ### Install Ethereal Engine and its Pre-requisites -Ethereal Engine can be installed with: - +Ethereal Engine can be installed and run with: ```bash -wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/install.sh | bash -i +wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/dev/scripts/ubuntu-install.sh | bash -i npm run dev ``` -You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 +You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 From b6972b74b95a8164985dd6ffd2f47a087f0a2273 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 2 Feb 2024 08:38:03 -0800 Subject: [PATCH 18/96] new: Add instructions on how to confirm the hello world installation --- docs/developer/typescript/01_gettingStarted/index.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/index.md index 1b106c5ebbaf..d589271303d4 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/index.md @@ -17,3 +17,13 @@ git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/ npm install npm run dev ``` + +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 + +### Confirm the installation +Lets make sure that our `hello world` code is running: +1. Open the project from the Studio by double clicking on its card +2. Create a new empty scene + +You will know that the code is running if you can see a white sphere in the middle of the scene. + From daa8f5d6da33df06d27b83e1349f8b857f99c5fa Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 2 Feb 2024 16:15:28 -0800 Subject: [PATCH 19/96] new: Add todo note for explaining the Controlled Context concept --- docs/manual/03_modules/01_engine/04_ecs.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/manual/03_modules/01_engine/04_ecs.md b/docs/manual/03_modules/01_engine/04_ecs.md index 6ea1fc9541e2..da11f5487c1f 100644 --- a/docs/manual/03_modules/01_engine/04_ecs.md +++ b/docs/manual/03_modules/01_engine/04_ecs.md @@ -10,6 +10,20 @@ ECS refers to the "**Entity Component System**" architecture paradigm, that is c They allow data to be structured with composition instead of inheritance. - **Systems** are functions that operate on these entities and components. + + ## Component Definitions Components support two types of data: - Structure of Arrays From 979d102d45548d1ecce99f9d2018213681baa7b0 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 2 Feb 2024 16:16:24 -0800 Subject: [PATCH 20/96] new: Hello World Tutorial (phase1) --- .../01_gettingStarted/01_hello/01_ecs.md | 61 +++++++++++++++++++ .../01_gettingStarted/01_hello/02_modules.md | 8 +++ .../01_hello/03_worldInjection.md | 7 +++ .../01_gettingStarted/01_hello/04_system.md | 54 ++++++++++++++++ .../01_gettingStarted/01_hello/index.md | 37 +++++++++++ .../01_gettingStarted/02_basic/index.md | 33 +--------- 6 files changed, 168 insertions(+), 32 deletions(-) create mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md create mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/02_modules.md create mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/03_worldInjection.md create mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/04_system.md diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md new file mode 100644 index 000000000000..1b57fb54ebd7 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md @@ -0,0 +1,61 @@ +# The ECS Pattern +The [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) is a pattern used to organize our code when writing software. +In this pattern: +- Logic is represented as `System`s, and they define the behavior of the application. +- Data is represented as `Component`s that have no behavior or identifiers attached to them. +- Components are attached to `Entities`. +- An `Entity` is essentially a "name" that can be used to connect a group of components into a single "thing". + +## Creating an Entity +```ts +const entity = ECS.createEntity() +``` + +## Adding Components +Ethereal Engine requires a specific set of Components in order to make an Entity show up on the screen: +- **VisibleComponent** +- **TransformComponent** +- **PrimitiveGeometryComponent** or **MeshComponent** +- _(optional)_ **NameComponent**: Not required, but good practice. + +### `NameComponent` +`NameComponent`s give a human-readable identifier to an Entity. +They are not mandatory, but it is good practice to add them to all your entities. +```ts +ECS.setComponent(entity, NameComponent, 'hello-world') +``` +
+Clarification +
+We said that an entity is just a "name" for a "thing", but we are also giving that "name" a `NameComponent`. +Every Entity represents its "name" as an [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), which does not need to be human-readable. +And `NameComponent`s give a human-readable identifier to an Entity, no matter what its internal UUID name is. +
+
+ + +### `VisibleComponent` +Gives the Entity the ability to be visible on the screen. +Entities without this Component will be ignored by the renderer. +```ts +ECS.setComponent(entity, VisibleComponent) +``` + +### `TransformComponent` +In simple terms, `TransformComponent`s give an Entity the ability to have a [position in the world](https://en.wikipedia.org/wiki/Transformation_matrix). +There would be no way to position the Entity in 3D space without attaching this Component to the Entity. +```ts +ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) +``` +> In more technical terms, `TransformComponent`s give the Entity the ability to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation). + +### `PrimitiveGeometryComponent` +In simple terms, `TransformComponent`s give an Entity the ability to have a [position in the world](https://en.wikipedia.org/wiki/Transformation_matrix). +In more technical terms, they give the Entity the ability to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation). +There would be no way to position the Entity in 3D space without attaching this Component to the Entity. +```ts +ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) +``` +> The `1` here means that we are creating a `SphereGeometry` object. +> We will create the component using a more readable name in the following tutorials. + diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/02_modules.md b/docs/developer/typescript/01_gettingStarted/01_hello/02_modules.md new file mode 100644 index 000000000000..6291976424bd --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_hello/02_modules.md @@ -0,0 +1,8 @@ +# Module Imports +```ts title="ee-tutorial-hello/src/Hello.ts" +import { ECS } from '@etherealengine/ecs' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +``` diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/03_worldInjection.md b/docs/developer/typescript/01_gettingStarted/01_hello/03_worldInjection.md new file mode 100644 index 000000000000..940425d92f58 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_hello/03_worldInjection.md @@ -0,0 +1,7 @@ +# World Injection +```ts title="ee-tutorial-hello/src/Hello.ts" +export default async function worldInjection() { + // [ ... ] +} +``` + diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md b/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md new file mode 100644 index 000000000000..7fcfec28d417 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md @@ -0,0 +1,54 @@ +# Systems +If you have a keen eye you may have noticed something really important. +We are using the `Entity Component System` pattern, and so far: +- We created an `Entity` +```ts +const entity = ECS.createEntity() +``` +- We added `Component`s to our Entity... +```ts +ECS.setComponent(entity, NameComponent, 'hello-world') +ECS.setComponent(entity, VisibleComponent) +ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) +ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) +``` +- And then we asked Ethereal Engine to run our code with the `worldInjection` function... + +## Wait, where is the System? +But we never defined a `System`! + +In the quickstart tutorial we used a simplified code example for brevity and ease of understanding. +But we also broke Ethereal Engine's best practices in order to achieve that simplicity. +So, lets fix that. + +
+Technical Info +
+The root of the problem is that we have created and modified our data inside the `worldInjection` function. +Mutation of data should always occur in a [Controlled Context](/manual/modules/engine/ecs), and the `worldInjection` function is not such. + +This is an even worse bad practices example, as it uses module scope to define and modify our entity. +```ts title="really/bad/practice.ts" showLineNumbers +import { ECS } from '@etherealengine/ecs' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' + +// highlight-start +// WARNING: Never do this +// Module scope should only ever be used for declarations. +const entity = ECS.createEntity() +ECS.setComponent(entity, NameComponent, 'hello-world') +ECS.setComponent(entity, VisibleComponent) +ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) +ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) +// highlight-end + +export default async function worldInjection() {} +``` +
+
+ +## Our first System +and then add the system in step1 first thing diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/index.md b/docs/developer/typescript/01_gettingStarted/01_hello/index.md index ac7dec2cb7e7..235ccf0ceee6 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/index.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/index.md @@ -2,3 +2,40 @@ sidebar_label: Hello Ethereal --- # Hello World from Ethereal Engine +The quickstart tutorial helped us create a project and run the engine for the first time. +It automated a lot for us, so lets review what we have done so far. + +## Conceptual overview +This is what we have done with the example's project: +- We created an entity called `hello-world` +- We gave the entity a primitive geometry component _(a sphere)_ +- We defined the position of the sphere in the scene + +## Technical overview +This is what we have done with the example's source code: +- We used the `ECS` pattern +- We created an `Entity` +- We added a few `Component`s to our Entity +- We imported some Ethereal Engine's typescript modules in our file +- We added our code to the engine with the `worldInjection` function. + +Our example from the quickstart tutorial is as minimal as it can possibly be. +But there is a lot happening already, as you can see, even in such a minimal example. +Lets take some time to understand how everything works. + +```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers +import { ECS } from '@etherealengine/ecs' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { Vector3 } from 'three' + +export default async function worldInjection() { + const entity = ECS.createEntity() + ECS.setComponent(entity, NameComponent, 'hello-world') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) +} +``` diff --git a/docs/developer/typescript/01_gettingStarted/02_basic/index.md b/docs/developer/typescript/01_gettingStarted/02_basic/index.md index c4d763a94d0b..ed08ff139f1e 100644 --- a/docs/developer/typescript/01_gettingStarted/02_basic/index.md +++ b/docs/developer/typescript/01_gettingStarted/02_basic/index.md @@ -1,7 +1,7 @@ # Creating a project In this section we will create a simple project called `basic`. :::note -You can find the original source at https://github.com/EtherealEngine/ee-tutorial-basic. +You can find the original source at https://github.com/EtherealEngine/ee-tutorial-basic See the previous section for installation instructions. ::: @@ -10,34 +10,3 @@ Ethereal Engine typescript projects usually have these pieces: 2. **Components**: Entities are decorated with components that produce behaviors on entities. 3. **Systems**: Drive behavior over time 4. **WorldInjection**: Registers the project with Ethereal Engine - -This simple example will: -- Start a system -- Create a `hello-world` entity -- Give the entity a primitive geometry component (a sphere) -- Adjust the position of that sphere in the scene. -```ts -import { defineSystem } from '@etherealengine/engine/src/ecs/functions/SystemFunctions' -import { PhysicsSystem } from '@etherealengine/engine/src/physics/PhysicsModule' -import { getComponent, setComponent } from '@etherealengine/engine/src/ecs/functions/ComponentFunctions' -import { TransformComponent } from '@etherealengine/engine/src/transform/components/TransformComponent' -import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' -import { createSceneEntity } from '@etherealengine/engine/src/ecs/functions/createSceneEntity' - -let initialized = false -const execute = () => { - if(initialized) return - initialized = true - const entity = createSceneEntity('hello-world',null) - setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) - getComponent(entity,TransformComponent).position.set(0,2,0) -} - -export const HelloWorldSystem = defineSystem({ - uuid: 'hellworld.system', - execute, - insert: { after: PhysicsSystem } -}) - -export default async function worldInjection() {} -``` From 9b52595d6f41cf80fd97ddfbb0950aa7e3c39492 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Mon, 5 Feb 2024 18:23:13 -0800 Subject: [PATCH 21/96] chg: Improvements to the ECS definitions --- .../01_gettingStarted/01_hello/01_ecs.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md index 1b57fb54ebd7..5e267ea77dc2 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md @@ -3,10 +3,23 @@ The [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_sys In this pattern: - Logic is represented as `System`s, and they define the behavior of the application. - Data is represented as `Component`s that have no behavior or identifiers attached to them. -- Components are attached to `Entities`. -- An `Entity` is essentially a "name" that can be used to connect a group of components into a single "thing". +- Components are attached to Entities. +- An `Entity` is an identifier. + Each entity is essentially a "name" that groups components into a single "thing" (an object). + +
+Technical Summary +
+The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior. +The behavior of the application is then controlled by having separate Systems (logic) that process that data. +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. +
+
+ ## Creating an Entity +Creating an Entity is a simple as calling the `createEntity()` function from Ethereal Engine's `ECS`. +This function will return an object that can will identify other things. ```ts const entity = ECS.createEntity() ``` From cb3dd30702abf6c6b495f2d12993b7723a9dedc9 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Mon, 5 Feb 2024 19:20:52 -0800 Subject: [PATCH 22/96] chg: General improvements to the ECS page --- .../01_gettingStarted/01_hello/01_ecs.md | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md index 5e267ea77dc2..8037c79af44c 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md @@ -7,7 +7,7 @@ In this pattern: - An `Entity` is an identifier. Each entity is essentially a "name" that groups components into a single "thing" (an object). -
+
Technical Summary
The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior. @@ -18,19 +18,32 @@ Systems don't need to know where that data is coming from. They only know what d ## Creating an Entity -Creating an Entity is a simple as calling the `createEntity()` function from Ethereal Engine's `ECS`. -This function will return an object that can will identify other things. +Creating an Entity is as simple as calling the `createEntity()` function from Ethereal Engine's `ECS`. +This function will return a identifier that can be used to group Components into a unique and distinct Object. ```ts const entity = ECS.createEntity() ``` ## Adding Components -Ethereal Engine requires a specific set of Components in order to make an Entity show up on the screen: +Components represent data that has no behavior or identification. +The way to attach Components to Entities is by calling the `setComponent` function from Ethereal Engine's `ECS`. + +
+Technical Note +
+The `setComponent` function will not return anything, but it will: +- Add the given Component to the Entity. +- 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). +
+
+ +Ethereal Engine requires a specific set of Components in order to create an object that can be presented on the screen: - **VisibleComponent** - **TransformComponent** - **PrimitiveGeometryComponent** or **MeshComponent** - _(optional)_ **NameComponent**: Not required, but good practice. + ### `NameComponent` `NameComponent`s give a human-readable identifier to an Entity. They are not mandatory, but it is good practice to add them to all your entities. @@ -63,9 +76,8 @@ ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) > In more technical terms, `TransformComponent`s give the Entity the ability to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation). ### `PrimitiveGeometryComponent` -In simple terms, `TransformComponent`s give an Entity the ability to have a [position in the world](https://en.wikipedia.org/wiki/Transformation_matrix). -In more technical terms, they give the Entity the ability to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation). -There would be no way to position the Entity in 3D space without attaching this Component to the Entity. +This Component gives Entities a primitive "visual body". +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. ```ts ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) ``` From 471712d52eceb6b58c3c333326a74bdcef404fc5 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:23:11 -0800 Subject: [PATCH 23/96] new: Add TechnicalNote custom mdx component --- .../01_gettingStarted/01_hello/01_ecs.md | 23 +++++++------------ .../01_gettingStarted/01_hello/04_system.md | 9 ++++---- src/components/TechnicalNote.tsx | 15 ++++++++++++ 3 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 src/components/TechnicalNote.tsx diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md index 8037c79af44c..a3066a09134f 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md @@ -1,3 +1,5 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + # The ECS Pattern The [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) is a pattern used to organize our code when writing software. In this pattern: @@ -7,14 +9,11 @@ In this pattern: - An `Entity` is an identifier. Each entity is essentially a "name" that groups components into a single "thing" (an object). -
-Technical Summary -
+ The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior. The behavior of the application is then controlled by having separate Systems (logic) that process that data. 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. -
-
+ ## Creating an Entity @@ -28,14 +27,11 @@ const entity = ECS.createEntity() Components represent data that has no behavior or identification. The way to attach Components to Entities is by calling the `setComponent` function from Ethereal Engine's `ECS`. -
-Technical Note -
+ The `setComponent` function will not return anything, but it will: - Add the given Component to the Entity. - 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). -
-
+ Ethereal Engine requires a specific set of Components in order to create an object that can be presented on the screen: - **VisibleComponent** @@ -50,14 +46,11 @@ They are not mandatory, but it is good practice to add them to all your entities ```ts ECS.setComponent(entity, NameComponent, 'hello-world') ``` -
-Clarification -
+ We said that an entity is just a "name" for a "thing", but we are also giving that "name" a `NameComponent`. Every Entity represents its "name" as an [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), which does not need to be human-readable. And `NameComponent`s give a human-readable identifier to an Entity, no matter what its internal UUID name is. -
-
+ ### `VisibleComponent` diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md b/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md index 7fcfec28d417..d2fc39a1e05e 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md @@ -1,3 +1,5 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + # Systems If you have a keen eye you may have noticed something really important. We are using the `Entity Component System` pattern, and so far: @@ -21,9 +23,7 @@ In the quickstart tutorial we used a simplified code example for brevity and eas But we also broke Ethereal Engine's best practices in order to achieve that simplicity. So, lets fix that. -
-Technical Info -
+ The root of the problem is that we have created and modified our data inside the `worldInjection` function. Mutation of data should always occur in a [Controlled Context](/manual/modules/engine/ecs), and the `worldInjection` function is not such. @@ -47,8 +47,7 @@ ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) export default async function worldInjection() {} ``` -
-
+ ## Our first System and then add the system in step1 first thing diff --git a/src/components/TechnicalNote.tsx b/src/components/TechnicalNote.tsx new file mode 100644 index 000000000000..efef4a42213f --- /dev/null +++ b/src/components/TechnicalNote.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +export const TechnicalNote = (props) => { + const TextTitle = props.title ? props.title : "Technical Note" + const Note = "alert alert--secondary mb-5 bg-neutral-900" + const Title = "text-blue-200" + const Body = "pt-4" + return ( +
+ {TextTitle} +
{props.children}
+
+
); +}; + From 4b12554c462bf23e95e44272cf8b5d7f9d433666 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:54:23 -0800 Subject: [PATCH 24/96] new: Merge modules+worldInjection into a single file. Write their text --- .../01_gettingStarted/01_hello/02_engine.md | 63 +++++++++++++++++++ .../01_gettingStarted/01_hello/02_modules.md | 8 --- .../01_hello/03_worldInjection.md | 7 --- .../typescript/01_gettingStarted/03_next.md | 10 +++ 4 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md delete mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/02_modules.md delete mode 100644 docs/developer/typescript/01_gettingStarted/01_hello/03_worldInjection.md diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md new file mode 100644 index 000000000000..a456a631c0e0 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md @@ -0,0 +1,63 @@ +--- +sidebar_label: The Engine +--- +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + +# Programming with Ethereal Engine +We need to do two very important things in order to use Ethereal Engine for our project: +- We need to import Ethereal Engine's modules +- We need to export our code so the engine can load our project + +## Module Imports +In this minimal tutorial we are adding a sphere primitive to the scene. +As this sphere will be a `Spatial` object, we will import a few components from the Spatial engine module: + +```ts title="ee-tutorial-hello/src/Hello.ts" +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +``` +We will be adding these Components to our Entity, and Components are part of the ECS pattern. +As such, we will need to use the Ethereal Engine ECS management functions. +The engine provides a convenient way to import all ECS related functions at once through `ECS` [namespace](https://www.typescriptlang.org/docs/handbook/namespaces.html). +```ts title="ee-tutorial-hello/src/Hello.ts" +import { ECS } from '@etherealengine/ecs' +``` +## World Injection +The `worldInjection` function is run for all projects when they are first loaded. +It allows projects to run custom logic that will be run across all scenes and routes on any instance of Ethereal Engine. + +```ts title="ee-tutorial-hello/src/Hello.ts" +export default async function worldInjection() { + // ... our code ... +} +``` +We don't need to know much more about this function for now. We will explore it further in the upcoming tutorials. + + +All projects must contain a configuration file named `xrengine.config.ts`. +One of its options is the `worldInjection` function, which will be called directly when the engine loads the project. +There are [multiple other options](https://github.com/EtherealEngine/etherealengine/blob/dev/packages/projects/ProjectConfigInterface.ts#L29) that can be configured from that file, but the worldInjection function is the most relevant to this guide. + +This is how our `xrengine.config.ts` file looks like at the moment: +```ts title="ee-tutorial-hello/xrengine.config.ts" showLineNumbers +import type { ProjectConfigInterface } from '@etherealengine/projects/ProjectConfigInterface' + +const config: ProjectConfigInterface = { + onEvent: undefined, + thumbnail: '/static/etherealengine_thumbnail.jpg', + routes: {}, + services: undefined, + databaseSeed: undefined, + // highlight-start + worldInjection: () => import('./src/Hello') + // highlight-end +} + +export default config +``` +We will explore how this file works in more detail in the upcoming tutorials. + + + diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/02_modules.md b/docs/developer/typescript/01_gettingStarted/01_hello/02_modules.md deleted file mode 100644 index 6291976424bd..000000000000 --- a/docs/developer/typescript/01_gettingStarted/01_hello/02_modules.md +++ /dev/null @@ -1,8 +0,0 @@ -# Module Imports -```ts title="ee-tutorial-hello/src/Hello.ts" -import { ECS } from '@etherealengine/ecs' -import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' -import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' -import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' -import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' -``` diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/03_worldInjection.md b/docs/developer/typescript/01_gettingStarted/01_hello/03_worldInjection.md deleted file mode 100644 index 940425d92f58..000000000000 --- a/docs/developer/typescript/01_gettingStarted/01_hello/03_worldInjection.md +++ /dev/null @@ -1,7 +0,0 @@ -# World Injection -```ts title="ee-tutorial-hello/src/Hello.ts" -export default async function worldInjection() { - // [ ... ] -} -``` - diff --git a/docs/developer/typescript/01_gettingStarted/03_next.md b/docs/developer/typescript/01_gettingStarted/03_next.md index 234466af4bf0..8508be95d3d1 100644 --- a/docs/developer/typescript/01_gettingStarted/03_next.md +++ b/docs/developer/typescript/01_gettingStarted/03_next.md @@ -8,3 +8,13 @@ NOTE: This page should contain: + + From f41459feb692083717fecbb1366294307d2a45c1 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 11:50:26 -0800 Subject: [PATCH 25/96] fmt: Add notes on achieving docusaurus
CSS for components --- src/components/TechnicalNote.tsx | 3 +++ src/css/custom.css | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/components/TechnicalNote.tsx b/src/components/TechnicalNote.tsx index efef4a42213f..cf4b4ddaa976 100644 --- a/src/components/TechnicalNote.tsx +++ b/src/components/TechnicalNote.tsx @@ -1,8 +1,11 @@ import React from 'react'; +const DetailsCSS = "details_node_modules-@docusaurus-theme-common-lib-components-Details-styles-module isBrowser_node_modules-@docusaurus-theme-common-lib-components-Details-styles-module alert alert--info details_node_modules-@docusaurus-theme-classic-lib-theme-Details-styles-module " + export const TechnicalNote = (props) => { const TextTitle = props.title ? props.title : "Technical Note" const Note = "alert alert--secondary mb-5 bg-neutral-900" + //const Note = DetailsCSS + "mb-5 bg-neutral-900" const Title = "text-blue-200" const Body = "pt-4" return ( diff --git a/src/css/custom.css b/src/css/custom.css index 9bb4db39c848..d64eb4313ce7 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -182,6 +182,9 @@ --ifm-alert-background-color : var(--ifm-color-danger-darkest); } +/** + * @section Other Docusaurus CSS + */ .docusaurus-highlight-code-line { background-color: rgb(72, 77, 91); display: block; From c771dde48d6dc917f110c382c5f8c8d981877589 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 11:51:15 -0800 Subject: [PATCH 26/96] fmt: Markdown formatting changes for the ECS and Systems pages --- .../01_gettingStarted/01_hello/01_ecs.md | 16 ++++++++-------- .../01_gettingStarted/01_hello/04_system.md | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md index a3066a09134f..4c6a2df07862 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md @@ -18,7 +18,7 @@ Systems don't need to know where that data is coming from. They only know what d ## Creating an Entity Creating an Entity is as simple as calling the `createEntity()` function from Ethereal Engine's `ECS`. -This function will return a identifier that can be used to group Components into a unique and distinct Object. +This function will return an identifier that can be used to group Components into a unique and distinct Object. ```ts const entity = ECS.createEntity() ``` @@ -30,7 +30,7 @@ The way to attach Components to Entities is by calling the `setComponent` functi The `setComponent` function will not return anything, but it will: - Add the given Component to the Entity. -- 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). +- 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)_. Ethereal Engine requires a specific set of Components in order to create an object that can be presented on the screen: @@ -41,15 +41,15 @@ Ethereal Engine requires a specific set of Components in order to create an obje ### `NameComponent` -`NameComponent`s give a human-readable identifier to an Entity. +Gives a human-readable identifier to an Entity. They are not mandatory, but it is good practice to add them to all your entities. ```ts ECS.setComponent(entity, NameComponent, 'hello-world') ``` We said that an entity is just a "name" for a "thing", but we are also giving that "name" a `NameComponent`. -Every Entity represents its "name" as an [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), which does not need to be human-readable. -And `NameComponent`s give a human-readable identifier to an Entity, no matter what its internal UUID name is. +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. +And `NameComponents` give a human-readable identifier to an Entity, independent of what its UUID is. @@ -61,12 +61,12 @@ ECS.setComponent(entity, VisibleComponent) ``` ### `TransformComponent` -In simple terms, `TransformComponent`s give an Entity the ability to have a [position in the world](https://en.wikipedia.org/wiki/Transformation_matrix). +In simple terms, `TransformComponents` give an Entity the ability to have a [position in the world](https://en.wikipedia.org/wiki/Transformation_matrix). There would be no way to position the Entity in 3D space without attaching this Component to the Entity. ```ts ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) ``` -> In more technical terms, `TransformComponent`s give the Entity the ability to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation). +> In more technical terms, `TransformComponents` give the Entity the ability to be affected by [linear transformations](https://en.wikipedia.org/wiki/Linear_transformation). ### `PrimitiveGeometryComponent` This Component gives Entities a primitive "visual body". @@ -74,6 +74,6 @@ Entities without it would not have any [3D geometry](https://en.wikipedia.org/wi ```ts ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) ``` -> The `1` here means that we are creating a `SphereGeometry` object. +> 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. > We will create the component using a more readable name in the following tutorials. diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md b/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md index d2fc39a1e05e..bbbfcccc3f7f 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md @@ -7,7 +7,7 @@ We are using the `Entity Component System` pattern, and so far: ```ts const entity = ECS.createEntity() ``` -- We added `Component`s to our Entity... +- We added `Components` to our Entity... ```ts ECS.setComponent(entity, NameComponent, 'hello-world') ECS.setComponent(entity, VisibleComponent) From 78707797f643ba85e52b3d7b8555c30a0d547eb6 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:15:29 -0800 Subject: [PATCH 27/96] new: Add UnstyledDetails component --- src/components/UnstyledDetails.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/components/UnstyledDetails.tsx diff --git a/src/components/UnstyledDetails.tsx b/src/components/UnstyledDetails.tsx new file mode 100644 index 000000000000..a1678243e2fe --- /dev/null +++ b/src/components/UnstyledDetails.tsx @@ -0,0 +1,16 @@ +import React from 'react'; + +export const UnstyledDetails = (props) => { + const TextTitle = props.title + const Note = "mb-5" + const Title = "text-blue-200" + const Body = "pt-4" + return ( +
+ {TextTitle} +
{props.children}
+
+
); +}; + + From c3e9d27458769d5ff9a0b7beff310a88497052e2 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:15:50 -0800 Subject: [PATCH 28/96] chg: Small wording change in the ECS page --- docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md index 4c6a2df07862..a546da0eaa3f 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md @@ -75,5 +75,5 @@ Entities without it would not have any [3D geometry](https://en.wikipedia.org/wi ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) ``` > 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. -> We will create the component using a more readable name in the following tutorials. +> We will create the component using a more readable name in the next section of the tutorial. From a5c25b3a1a3fc9edd3f15356d7134a40d727e62b Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:16:45 -0800 Subject: [PATCH 29/96] new: Add source modification section. Improve module imports section --- .../01_gettingStarted/01_hello/02_engine.md | 110 +++++++++++++++--- 1 file changed, 94 insertions(+), 16 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md index a456a631c0e0..d5dfa9602ca3 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md @@ -2,28 +2,13 @@ sidebar_label: The Engine --- import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Programming with Ethereal Engine We need to do two very important things in order to use Ethereal Engine for our project: - We need to import Ethereal Engine's modules - We need to export our code so the engine can load our project -## Module Imports -In this minimal tutorial we are adding a sphere primitive to the scene. -As this sphere will be a `Spatial` object, we will import a few components from the Spatial engine module: - -```ts title="ee-tutorial-hello/src/Hello.ts" -import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' -import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' -import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' -import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' -``` -We will be adding these Components to our Entity, and Components are part of the ECS pattern. -As such, we will need to use the Ethereal Engine ECS management functions. -The engine provides a convenient way to import all ECS related functions at once through `ECS` [namespace](https://www.typescriptlang.org/docs/handbook/namespaces.html). -```ts title="ee-tutorial-hello/src/Hello.ts" -import { ECS } from '@etherealengine/ecs' -``` ## World Injection The `worldInjection` function is run for all projects when they are first loaded. It allows projects to run custom logic that will be run across all scenes and routes on any instance of Ethereal Engine. @@ -61,3 +46,96 @@ We will explore how this file works in more detail in the upcoming tutorials. +## Module Imports +In this minimal tutorial we are adding a sphere primitive to the scene. +As this sphere will be a `Spatial` object, we will import a few components from the Spatial engine module: + +```ts title="ee-tutorial-hello/src/Hello.ts" +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +``` +We will be adding these Components to our Entity, and Components are part of the ECS pattern. +As such, we will need to use the Ethereal Engine ECS management functions. +The engine provides a convenient way to import all ECS related functions at once through `ECS` [namespace](https://www.typescriptlang.org/docs/handbook/namespaces.html). +```ts title="ee-tutorial-hello/src/Hello.ts" +import { ECS } from '@etherealengine/ecs' +``` + +## Modifying our Source Code +We have learned how our minimal example works, but so far we haven't needed to modify any of its source code. +This will be our first modification to the code of the project. + +:::important +This guide uses [`Project-based Learning`](https://en.wikipedia.org/wiki/Project-based_learning) as its core teaching philosophy. +From now on, you will be actively modifying the source code of the `ee-tutorial-hello` in every step of the way. +::: + +Lets start with a simple change. +We will modify our Sphere `PrimitiveGeometryComponent` to load our geometry with a name, instead of the hardcoded number `1` that we used before. + +In order to do this, we need to: +- Import the `GeometryTypeEnum` from the `scene/constants/` sub-module inside the `engine` module. +- Replace the `1` with a call to the `SphereGeometry` name that is stored inside it `GeometryTypeEnum`. + +Try to make the change by yourself before looking at the solution. +I don't expect you to know where that enum is stored, so here are some hints to make it easier: +```ts +// The full path to the GeometryTypeEnum is: +'@etherealengine/engine/src/scene/constants/GeometryTypeEnum' + +// Getting the ID number of a Sphere by its enum name will look like: +GeometryTypeEnum.SphereGeometry + +// To be certain that your changes are working, set the geometry to be a cylinder instead: +GeometryTypeEnum.CylinderGeometry +``` + + + +The imports section of our code will now be: +```ts title="ee-tutorial-hello/src/Hello.ts" +// ... our other imports +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { Vector3 } from 'three' +// highlight-start +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' +// highlight-end +``` +The `PrimitiveGeometryComponent` call will now be: +```ts title="ee-tutorial-hello/src/Hello.ts" +const entity = ECS.createEntity() +// ... our other calls to setComponent +// highlight-start +ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) +// highlight-end +``` + + + +```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers +import { ECS } from '@etherealengine/ecs' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +// highlight-start +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' +// highlight-end + +export default async function worldInjection() { + const entity = ECS.createEntity() + ECS.setComponent(entity, NameComponent, 'hello-world') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + // highlight-start + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + // highlight-end +} +``` + + + + + From 3b323852d67c102c3e4cb022c85a7e5915a821b2 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:19:31 -0800 Subject: [PATCH 30/96] fix: Small typo in the engine page --- .../typescript/01_gettingStarted/01_hello/02_engine.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md index d5dfa9602ca3..4b00498ae239 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md @@ -58,7 +58,7 @@ import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/com ``` We will be adding these Components to our Entity, and Components are part of the ECS pattern. As such, we will need to use the Ethereal Engine ECS management functions. -The engine provides a convenient way to import all ECS related functions at once through `ECS` [namespace](https://www.typescriptlang.org/docs/handbook/namespaces.html). +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). ```ts title="ee-tutorial-hello/src/Hello.ts" import { ECS } from '@etherealengine/ecs' ``` From 555496ace3ce42779c3c0a1176711d86ec872799 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 18:26:40 -0800 Subject: [PATCH 31/96] chg: Small typo in the quickstart page --- docs/developer/typescript/01_gettingStarted/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/index.md index d589271303d4..b4a9a5270563 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/index.md @@ -22,7 +22,7 @@ You should now be able to see the `ee-tutorial-hello` project listed in Ethereal ### Confirm the installation Lets make sure that our `hello world` code is running: -1. Open the project from the Studio by double clicking on its card +1. Open the project from the Studio by clicking on its card 2. Create a new empty scene You will know that the code is running if you can see a white sphere in the middle of the scene. From 4f10fd068cfa33de58ad063687e3ed7f0960eb2e Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 6 Feb 2024 18:27:22 -0800 Subject: [PATCH 32/96] new: Add the "First System" section text --- .../01_gettingStarted/01_hello/04_system.md | 155 +++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md b/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md index bbbfcccc3f7f..1710242feb76 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md +++ b/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md @@ -1,4 +1,5 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Systems If you have a keen eye you may have noticed something really important. @@ -50,4 +51,156 @@ export default async function worldInjection() {} ## Our first System -and then add the system in step1 first thing +As we mentioned in the [ECS Pattern](../hello/ecs) section earlier, `Systems` are used to define the logic and behavior of our application. +But, in order to make the example easier to understand, we cheated a little bit and broke the engine's best practices. + +The correct way to create the Sphere of our minimal example would be to: +- Create a function that will create our Sphere. +- Define a `System` that will `execute` our function. +- Insert the System into the engine so that it is run right after the engine's `PhysicsSystem`. + +### Our function +So far we have been defining the code that creates our Sphere inside the `worldInjection` function. +This means that we relied on the function being called when the project configuration is loaded. +But the correct way to do this is to define our code inside a separate function, and give that function to the `execute` parameter of a System created with `defineSystem`. + +Lets start by creating a new Typescript function, and moving our ECS code into that function. +```ts +// Create a function +const /* name */ = () => { /* code */ } +``` +We will also need to make sure that our code is only run once. +Try to figure out a way to make your function code execute only once before looking at the solution. +_hint: You won't need any special engine modules for this. Just regular Typescript will work._ + + + +```ts +//highlight-start +let initialized = false // Track whether our code was already initialized or not +//highlight-end + +//highlight-start +const hello = () => { // Define an arrow function that will run our code + if (initialized) return // Exit early if the code was already run before + initialized = true // Mark initialized to true, so the code is never run again later +//highlight-end + + // Create the Sphere object. +//highlight-start + // Same code as before, but now it runs inside our function +//highlight-end + const entity = ECS.createEntity() + ECS.setComponent(entity, NameComponent, 'hello-world') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) +} +``` + +There are other ways to keep track of state than manually maintaining our `initialized` variable. +- A state variable with `Hyperflux` +- A reactor mount with `useEffect` + +But our `initialized` variable will keep things simple and minimal for the purpose of this tutorial. +We will learn how properly manage state later on. + + + + + + +:::note +We are using a Typescript arrow function in this example. +You could also use a regular Typescript function definition if you prefer. +Both styles work perfectly well. +::: + + +### The `defineSystem` function +In order to define a new system, we need to use the `defineSystem` function from the `ECS` namespace. + +This is what we need to know to use this function: +- `defineSystem` will return the type that represents our `System` +- We need to `export` that type so that the engine can access it +- We need to pass our function into the `execute` argument +- We don't need to add any new imports. The `defineSystem` function is available through the `ECS` namespace +- We will use the `insert` argument to tell the engine when we want our code to run + +I already filled in some parts of the code. Try to fill in the rest by yourself before looking at the solution. +```ts +/* ... */ = ECS.defineSystem({ + uuid: /* ... */, // The unique id of our System. Could be a string or a number. + execute: /* ... */, // The function that will run our code + insert: { after: PhysicsSystem } // Tell the engine to run the system after the PhysicsSystem +}) +``` +:::note +The engine will take care of executing our code when it is correct to do so, based on the value we passed into the `insert` argument. +::: + + + +```ts title="ee-tutorial-hello/src/Hello.ts" +//highlight-start +export const HelloWorldSystem = ECS.defineSystem({ + uuid: 'helloworld.system', + execute: hello, +//highlight-end + insert: { after: PhysicsSystem } +}) +``` + + +## Conclusion +This is how our final code will look like after we have completed these tasks. + + + +```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers +import { ECS } from '@etherealengine/ecs' +import { PhysicsSystem } from '@etherealengine/spatial/src/physics/PhysicsModule' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { Vector3 } from 'three' +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' + + +//highlight-start +let initialized = false // Track whether our code was already run or not +//highlight-end + +//highlight-start +// Our new function +const hello = () => { + if (initialized) return + initialized = true + //highlight-end + + //highlight-start + // Create the Sphere object inside our function. + //highlight-end + const entity = ECS.createEntity() + ECS.setComponent(entity, NameComponent, 'hello-world') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) +} + +//highlight-start +// Define our System +export const HelloWorldSystem = ECS.defineSystem({ + uuid: 'helloworld.system', + execute: hello, + insert: { after: PhysicsSystem } +}) +//highlight-end + +//highlight-start +// Note how we have moved all of our code outside of this function +//highlight-end +export default async function worldInjection() {} +``` + From c234a5fa18efcfb391396cb1b129bcb36a4bb271 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:14:45 -0800 Subject: [PATCH 33/96] fmt: Refactor the folder structure to match the new learning path --- .../01_gettingStarted/{index.md => 01_quickstart.md} | 4 ++-- .../01_gettingStarted/{01_hello => 02_hello}/01_ecs.md | 2 ++ .../01_gettingStarted/{01_hello => 02_hello}/02_engine.md | 0 .../01_gettingStarted/{01_hello => 02_hello}/04_system.md | 0 .../01_gettingStarted/{01_hello => 02_hello}/_category_.json | 0 .../01_gettingStarted/{01_hello => 02_hello}/index.md | 0 .../{50_extras => 03_extras}/01_networking.md | 0 .../{50_extras => 03_extras}/_category_.json | 0 .../01_gettingStarted/{02_basic => 50_basic}/_category_.json | 0 .../01_gettingStarted/{02_basic => 50_basic}/index.md | 0 .../01_gettingStarted/{02_install => 50_install}/01_engine.md | 0 .../{02_install => 50_install}/02_projects.md | 0 .../{02_install => 50_install}/_category_.json | 0 docs/developer/typescript/01_gettingStarted/_category_.json | 1 + 14 files changed, 5 insertions(+), 2 deletions(-) rename docs/developer/typescript/01_gettingStarted/{index.md => 01_quickstart.md} (93%) rename docs/developer/typescript/01_gettingStarted/{01_hello => 02_hello}/01_ecs.md (98%) rename docs/developer/typescript/01_gettingStarted/{01_hello => 02_hello}/02_engine.md (100%) rename docs/developer/typescript/01_gettingStarted/{01_hello => 02_hello}/04_system.md (100%) rename docs/developer/typescript/01_gettingStarted/{01_hello => 02_hello}/_category_.json (100%) rename docs/developer/typescript/01_gettingStarted/{01_hello => 02_hello}/index.md (100%) rename docs/developer/typescript/01_gettingStarted/{50_extras => 03_extras}/01_networking.md (100%) rename docs/developer/typescript/01_gettingStarted/{50_extras => 03_extras}/_category_.json (100%) rename docs/developer/typescript/01_gettingStarted/{02_basic => 50_basic}/_category_.json (100%) rename docs/developer/typescript/01_gettingStarted/{02_basic => 50_basic}/index.md (100%) rename docs/developer/typescript/01_gettingStarted/{02_install => 50_install}/01_engine.md (100%) rename docs/developer/typescript/01_gettingStarted/{02_install => 50_install}/02_projects.md (100%) rename docs/developer/typescript/01_gettingStarted/{02_install => 50_install}/_category_.json (100%) diff --git a/docs/developer/typescript/01_gettingStarted/index.md b/docs/developer/typescript/01_gettingStarted/01_quickstart.md similarity index 93% rename from docs/developer/typescript/01_gettingStarted/index.md rename to docs/developer/typescript/01_gettingStarted/01_quickstart.md index b4a9a5270563..0f22a58e9923 100644 --- a/docs/developer/typescript/01_gettingStarted/index.md +++ b/docs/developer/typescript/01_gettingStarted/01_quickstart.md @@ -1,9 +1,9 @@ --- -sidebar_label: Getting Started +sidebar_label: Quickstart --- import UbuntuInstall from '../../../_partials/installUbuntu.md' -# Getting Started with Typescript +# Typescript Quickstart This QuickStart guide will teach you the basics of Ethereal Engine, and how to run the engine for the first time. ## Installation diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md similarity index 98% rename from docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md rename to docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md index a546da0eaa3f..4f2930b3ad5b 100644 --- a/docs/developer/typescript/01_gettingStarted/01_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md @@ -9,6 +9,8 @@ In this pattern: - An `Entity` is an identifier. Each entity is essentially a "name" that groups components into a single "thing" (an object). +identifier that points to collection of components + The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior. The behavior of the application is then controlled by having separate Systems (logic) that process that data. diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/01_hello/02_engine.md rename to docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/04_system.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_system.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/01_hello/04_system.md rename to docs/developer/typescript/01_gettingStarted/02_hello/04_system.md diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/_category_.json b/docs/developer/typescript/01_gettingStarted/02_hello/_category_.json similarity index 100% rename from docs/developer/typescript/01_gettingStarted/01_hello/_category_.json rename to docs/developer/typescript/01_gettingStarted/02_hello/_category_.json diff --git a/docs/developer/typescript/01_gettingStarted/01_hello/index.md b/docs/developer/typescript/01_gettingStarted/02_hello/index.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/01_hello/index.md rename to docs/developer/typescript/01_gettingStarted/02_hello/index.md diff --git a/docs/developer/typescript/01_gettingStarted/50_extras/01_networking.md b/docs/developer/typescript/01_gettingStarted/03_extras/01_networking.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/50_extras/01_networking.md rename to docs/developer/typescript/01_gettingStarted/03_extras/01_networking.md diff --git a/docs/developer/typescript/01_gettingStarted/50_extras/_category_.json b/docs/developer/typescript/01_gettingStarted/03_extras/_category_.json similarity index 100% rename from docs/developer/typescript/01_gettingStarted/50_extras/_category_.json rename to docs/developer/typescript/01_gettingStarted/03_extras/_category_.json diff --git a/docs/developer/typescript/01_gettingStarted/02_basic/_category_.json b/docs/developer/typescript/01_gettingStarted/50_basic/_category_.json similarity index 100% rename from docs/developer/typescript/01_gettingStarted/02_basic/_category_.json rename to docs/developer/typescript/01_gettingStarted/50_basic/_category_.json diff --git a/docs/developer/typescript/01_gettingStarted/02_basic/index.md b/docs/developer/typescript/01_gettingStarted/50_basic/index.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/02_basic/index.md rename to docs/developer/typescript/01_gettingStarted/50_basic/index.md diff --git a/docs/developer/typescript/01_gettingStarted/02_install/01_engine.md b/docs/developer/typescript/01_gettingStarted/50_install/01_engine.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/02_install/01_engine.md rename to docs/developer/typescript/01_gettingStarted/50_install/01_engine.md diff --git a/docs/developer/typescript/01_gettingStarted/02_install/02_projects.md b/docs/developer/typescript/01_gettingStarted/50_install/02_projects.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/02_install/02_projects.md rename to docs/developer/typescript/01_gettingStarted/50_install/02_projects.md diff --git a/docs/developer/typescript/01_gettingStarted/02_install/_category_.json b/docs/developer/typescript/01_gettingStarted/50_install/_category_.json similarity index 100% rename from docs/developer/typescript/01_gettingStarted/02_install/_category_.json rename to docs/developer/typescript/01_gettingStarted/50_install/_category_.json diff --git a/docs/developer/typescript/01_gettingStarted/_category_.json b/docs/developer/typescript/01_gettingStarted/_category_.json index 429163165677..b3620acc2dfd 100644 --- a/docs/developer/typescript/01_gettingStarted/_category_.json +++ b/docs/developer/typescript/01_gettingStarted/_category_.json @@ -1,3 +1,4 @@ { + "label": "Getting Started", "position": 01, } From 48808428185ca47d18fba0a071eb0199dbff0cfa Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:18:56 -0800 Subject: [PATCH 34/96] fix: Sidebar ordering numbers --- .../typescript/01_gettingStarted/02_hello/_category_.json | 2 +- .../typescript/01_gettingStarted/50_basic/_category_.json | 2 +- .../typescript/01_gettingStarted/50_install/_category_.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/_category_.json b/docs/developer/typescript/01_gettingStarted/02_hello/_category_.json index 429163165677..e0d3b8be94f4 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/_category_.json +++ b/docs/developer/typescript/01_gettingStarted/02_hello/_category_.json @@ -1,3 +1,3 @@ { - "position": 01, + "position": 02, } diff --git a/docs/developer/typescript/01_gettingStarted/50_basic/_category_.json b/docs/developer/typescript/01_gettingStarted/50_basic/_category_.json index e0d3b8be94f4..6811f84d171d 100644 --- a/docs/developer/typescript/01_gettingStarted/50_basic/_category_.json +++ b/docs/developer/typescript/01_gettingStarted/50_basic/_category_.json @@ -1,3 +1,3 @@ { - "position": 02, + "position": 50, } diff --git a/docs/developer/typescript/01_gettingStarted/50_install/_category_.json b/docs/developer/typescript/01_gettingStarted/50_install/_category_.json index c97ff54104ef..82c38fb1cafc 100644 --- a/docs/developer/typescript/01_gettingStarted/50_install/_category_.json +++ b/docs/developer/typescript/01_gettingStarted/50_install/_category_.json @@ -1,4 +1,4 @@ { "label": "Installation", - "position": 01, + "position": 50, } From 6437112d7465babbba8bcb642d852a424b981381 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:23:54 -0800 Subject: [PATCH 35/96] fmt: Move foreign folders into the _todo temporary subfolder --- .../typescript/01_gettingStarted/02_hello/01_ecs.md | 2 +- .../{ => _todo}/50_basic/_category_.json | 0 .../01_gettingStarted/{ => _todo}/50_basic/index.md | 0 .../{ => _todo}/50_install/01_engine.md | 0 .../{ => _todo}/50_install/02_projects.md | 0 .../{ => _todo}/50_install/_category_.json | 0 .../{03_next.md => _todo/50_next.md} | 11 +++++++++++ 7 files changed, 12 insertions(+), 1 deletion(-) rename docs/developer/typescript/01_gettingStarted/{ => _todo}/50_basic/_category_.json (100%) rename docs/developer/typescript/01_gettingStarted/{ => _todo}/50_basic/index.md (100%) rename docs/developer/typescript/01_gettingStarted/{ => _todo}/50_install/01_engine.md (100%) rename docs/developer/typescript/01_gettingStarted/{ => _todo}/50_install/02_projects.md (100%) rename docs/developer/typescript/01_gettingStarted/{ => _todo}/50_install/_category_.json (100%) rename docs/developer/typescript/01_gettingStarted/{03_next.md => _todo/50_next.md} (92%) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md index 4f2930b3ad5b..8a717771b47e 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md @@ -9,7 +9,7 @@ In this pattern: - An `Entity` is an identifier. Each entity is essentially a "name" that groups components into a single "thing" (an object). -identifier that points to collection of components + The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior. diff --git a/docs/developer/typescript/01_gettingStarted/50_basic/_category_.json b/docs/developer/typescript/01_gettingStarted/_todo/50_basic/_category_.json similarity index 100% rename from docs/developer/typescript/01_gettingStarted/50_basic/_category_.json rename to docs/developer/typescript/01_gettingStarted/_todo/50_basic/_category_.json diff --git a/docs/developer/typescript/01_gettingStarted/50_basic/index.md b/docs/developer/typescript/01_gettingStarted/_todo/50_basic/index.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/50_basic/index.md rename to docs/developer/typescript/01_gettingStarted/_todo/50_basic/index.md diff --git a/docs/developer/typescript/01_gettingStarted/50_install/01_engine.md b/docs/developer/typescript/01_gettingStarted/_todo/50_install/01_engine.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/50_install/01_engine.md rename to docs/developer/typescript/01_gettingStarted/_todo/50_install/01_engine.md diff --git a/docs/developer/typescript/01_gettingStarted/50_install/02_projects.md b/docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/50_install/02_projects.md rename to docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md diff --git a/docs/developer/typescript/01_gettingStarted/50_install/_category_.json b/docs/developer/typescript/01_gettingStarted/_todo/50_install/_category_.json similarity index 100% rename from docs/developer/typescript/01_gettingStarted/50_install/_category_.json rename to docs/developer/typescript/01_gettingStarted/_todo/50_install/_category_.json diff --git a/docs/developer/typescript/01_gettingStarted/03_next.md b/docs/developer/typescript/01_gettingStarted/_todo/50_next.md similarity index 92% rename from docs/developer/typescript/01_gettingStarted/03_next.md rename to docs/developer/typescript/01_gettingStarted/_todo/50_next.md index 8508be95d3d1..bd2fdd7974a4 100644 --- a/docs/developer/typescript/01_gettingStarted/03_next.md +++ b/docs/developer/typescript/01_gettingStarted/_todo/50_next.md @@ -18,3 +18,14 @@ The engine will call this function when our project is loaded, and our file is d Loading the configuration file will call its `worldInjection` function, which will in turn import our file, and therefore let the engine know about the `worldInjection` function that we have declared in our code. --> + + + + From b06c363d7cd2e30993e7b3dc1121f139f590c5d8 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 7 Feb 2024 16:18:15 -0800 Subject: [PATCH 36/96] fmt: Reorganize the extras folder to build up to networking (sketch) --- .../01_gettingStarted/03_extras/01_physics.md | 46 ++++++ .../01_gettingStarted/03_extras/02_loop.md | 1 + .../01_gettingStarted/03_extras/03_state.md | 4 + .../03_extras/04_networking.md | 147 ++++++++++++++++++ .../{01_networking.md => _50_networking.md} | 0 .../03_extras/_category_.json | 2 +- 6 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 docs/developer/typescript/01_gettingStarted/03_extras/01_physics.md create mode 100644 docs/developer/typescript/01_gettingStarted/03_extras/02_loop.md create mode 100644 docs/developer/typescript/01_gettingStarted/03_extras/03_state.md create mode 100644 docs/developer/typescript/01_gettingStarted/03_extras/04_networking.md rename docs/developer/typescript/01_gettingStarted/03_extras/{01_networking.md => _50_networking.md} (100%) diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/01_physics.md b/docs/developer/typescript/01_gettingStarted/03_extras/01_physics.md new file mode 100644 index 000000000000..caa0c7fea04d --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_extras/01_physics.md @@ -0,0 +1,46 @@ +--- +sidebar_label: Physics +--- +# Adding Physics + +```ts +import { ECS } from '@etherealengine/ecs' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { Vector3 } from 'three' +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' +import { PhysicsSystem } from '@etherealengine/spatial/src/physics/PhysicsModule' + +// highlight-start +import { RigidBodyComponent } from '@etherealengine/spatial/src/physics/components/RigidBodyComponent' +import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent' +// highlight-end + + +let initialized = false +const hello = () => { + if (initialized) return + initialized = true + + const entity = ECS.createEntity() + ECS.setComponent(entity, NameComponent, 'hello-world') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + + // highlight-start + ECS.setComponent(entity, RigidBodyComponent, { type: 'dynamic' }) + ECS.setComponent(entity, ColliderComponent, { shape: 'sphere' }) + // highlight-end +} + +export const HelloWorldSystem = ECS.defineSystem({ + uuid: 'helloworld.system', + execute: hello, + insert: { after: PhysicsSystem } +}) + +export default async function worldInjection() {} +``` diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/02_loop.md b/docs/developer/typescript/01_gettingStarted/03_extras/02_loop.md new file mode 100644 index 000000000000..3787ce47d3a3 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_extras/02_loop.md @@ -0,0 +1 @@ +# Engine Loop diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/03_state.md b/docs/developer/typescript/01_gettingStarted/03_extras/03_state.md new file mode 100644 index 000000000000..9a3a4ceac5b4 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_extras/03_state.md @@ -0,0 +1,4 @@ +--- +sidebar_label: State +--- +# Managing State diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/04_networking.md b/docs/developer/typescript/01_gettingStarted/03_extras/04_networking.md new file mode 100644 index 000000000000..e42fa0154fe9 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_extras/04_networking.md @@ -0,0 +1,147 @@ +# Networking + +```ts +import React, { useEffect } from 'react' + +import { + defineAction, + defineState, + dispatchAction, + getMutableState, + getState, + none, + useHookstate +} from '@etherealengine/hyperflux' + +import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' + +import { NetworkTopics } from '@etherealengine/spatial/src/networking/classes/Network' +import { WorldNetworkAction } from '@etherealengine/spatial/src/networking/functions/WorldNetworkAction' + +import { isClient } from '@etherealengine/common/src/utils/getEnvironment' +import { PresentationSystemGroup, defineSystem, getComponent, setComponent } from '@etherealengine/ecs' +import { ECSState } from '@etherealengine/ecs/src/ECSState' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { UUIDComponent } from '@etherealengine/spatial/src/common/UUIDComponent' +import { NetworkState } from '@etherealengine/spatial/src/networking/NetworkState' +import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent' +import { RigidBodyComponent } from '@etherealengine/spatial/src/physics/components/RigidBodyComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { Vector3 } from 'three' + +/** + * Basic actions to spawn and destroy objects + * This extends and naturally utilizes the functionality in EntityNetworkState + */ + +const BasicActions = { + spawnAction: defineAction( + WorldNetworkAction.spawnObject.extend({ + type: 'ee.basic.SPAWN_BALL', + $topic: NetworkTopics.world + }) + ) +} + +/** + * Global state that tracks locally spawned or destroyed artifacts by using action receptors + */ + +const BasicState = defineState({ + name: 'ee.basic.BasicState', + + initial: {} as Record, + + receptors: { + onSpawnAction: BasicActions.spawnAction.receive((action) => { + const state = getMutableState(BasicState) + state[action.entityUUID].merge({}) + }), + onDestroyObject: WorldNetworkAction.destroyObject.receive((action) => { + const state = getMutableState(BasicState) + state[action.entityUUID].set(none) + }) + } +}) + +/** + * A reactor such that each basic state record has an associated a visual artifact + */ + +const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { + /** Entity creation and destruction is handled by EntityNetworkState */ + const entity = UUIDComponent.useEntityByUUID(entityUUID) + + useEffect(() => { + if (!entity) return + + setComponent(entity, TransformComponent, { scale: new Vector3(0.1, 0.1, 0.1) }) + setComponent(entity, VisibleComponent) + setComponent(entity, NameComponent, entityUUID) + setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + setComponent(entity, RigidBodyComponent, { type: 'dynamic' }) + setComponent(entity, ColliderComponent, { shape: 'sphere' }) + + if (isClient) return + + const angle = Math.random() * Math.PI * 2 + const direction = new Vector3(Math.sin(angle), 0, Math.cos(angle)) + const velocity = 0.025 + Math.random() * 0.01 + getComponent(entity, RigidBodyComponent).body.applyImpulse(direction.multiplyScalar(velocity), true) + }, [entity]) + + return null +} + +/** + * Observe spawn events and create a sub-reactor for each entry in the basic state + */ + +const reactor = () => { + const basicState = useHookstate(getMutableState(BasicState)) + return ( + <> + {basicState.keys.map((entityUUID: EntityUUID) => ( + + ))} + + ) +} + +let counter = 0 +const spawnRate = 3 + +/** + * Spawn a new basic entity every 3 seconds + */ + +const execute = () => { + /** Only run this on the server */ + if (isClient || !NetworkState.worldNetwork) return + + const { deltaSeconds, elapsedSeconds } = getState(ECSState) + + counter += deltaSeconds + + if (counter < spawnRate) return + counter = 0 + + const entityUUID = `basic-${elapsedSeconds}` as EntityUUID + const action = BasicActions.spawnAction({ entityUUID, position: new Vector3(Math.random(), 1, Math.random()) }) + dispatchAction(action) +} + +/** + * System to register the execute function and reactor + */ + +export const BasicSystem = defineSystem({ + uuid: 'basic.system', + reactor, + execute, + insert: { after: PresentationSystemGroup } +}) +``` diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/01_networking.md b/docs/developer/typescript/01_gettingStarted/03_extras/_50_networking.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/03_extras/01_networking.md rename to docs/developer/typescript/01_gettingStarted/03_extras/_50_networking.md diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/_category_.json b/docs/developer/typescript/01_gettingStarted/03_extras/_category_.json index fabb1d60ef3b..37e328e4d969 100644 --- a/docs/developer/typescript/01_gettingStarted/03_extras/_category_.json +++ b/docs/developer/typescript/01_gettingStarted/03_extras/_category_.json @@ -1,6 +1,6 @@ { "label": "Extras", - "position": 50, + "position": 03, "link": { "type": "generated-index", "description": ".", From 96e2b8afb6d2991e512b3ffc2c5affbee7911628 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:34:03 -0800 Subject: [PATCH 37/96] requested changes --- .../developer/typescript/01_gettingStarted/02_hello/01_ecs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md index 8a717771b47e..40ebe1bdb4f2 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md @@ -3,8 +3,8 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; # The ECS Pattern The [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) is a pattern used to organize our code when writing software. In this pattern: -- Logic is represented as `System`s, and they define the behavior of the application. -- Data is represented as `Component`s that have no behavior or identifiers attached to them. +- Logic is represented as `Systems`, and they define the behavior of the application. +- Data is represented as `Components` that have no behavior or identifiers attached to them. - Components are attached to Entities. - An `Entity` is an identifier. Each entity is essentially a "name" that groups components into a single "thing" (an object). From ad7b558f16e4855ba5a8fa8859cd8059f09acd00 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 7 Feb 2024 19:39:28 -0800 Subject: [PATCH 38/96] chg: Reword `sub-projects` to `projects` --- .../01_gettingStarted/_todo/50_install/02_projects.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md b/docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md index aab1036be628..62ecef0d783b 100644 --- a/docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md +++ b/docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md @@ -1,9 +1,9 @@ --- -sidebar_label: Sub Projects +sidebar_label: Projects --- -# Installing and running sub projects -Ethereal Engine can run sub-projects or 'locations'. -This pattern is different from what you may be used to because Ethereal Engine runs on the 'outside' and the sub-project is kept in a folder of Ethereal Engine. +# Installing and running projects +thereal Engine can be extended with projects. +They are equivalent to "projects" in other engines, except they are modular like npm packages (they are npm packages too). Ethereal Engine scans for projects mounted in the /packages/projects/projects sub-folder of Ethereal Engine. From 7f7a99996cb66b3fa512d2a01a0d08382a6c7115 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 7 Feb 2024 21:07:04 -0800 Subject: [PATCH 39/96] rmv: Remove test.js from the root folder --- test.js | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 test.js diff --git a/test.js b/test.js deleted file mode 100644 index f84f08d7e387..000000000000 --- a/test.js +++ /dev/null @@ -1,11 +0,0 @@ -const test = { - prop: 42, - function blah() { - return this.prop; - }, -}; - -console.log(test.func()); -// Expected output: 42 - - From b91a83053bba7bacd5ca2a893c1dc239637e68bf Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 08:11:11 -0800 Subject: [PATCH 40/96] rmv: Remove Entity clarification for its definition --- docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md index 40ebe1bdb4f2..503b872d91b4 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md @@ -7,7 +7,6 @@ In this pattern: - Data is represented as `Components` that have no behavior or identifiers attached to them. - Components are attached to Entities. - An `Entity` is an identifier. - Each entity is essentially a "name" that groups components into a single "thing" (an object). From 25679e08df3a8f967310b3b863164a4e6418ba1d Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 08:13:07 -0800 Subject: [PATCH 41/96] doc: improve todo note/comment about entity clarification alternatives --- .../typescript/01_gettingStarted/02_hello/01_ecs.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md index 503b872d91b4..5942906c3c4f 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md @@ -8,7 +8,11 @@ In this pattern: - Components are attached to Entities. - An `Entity` is an identifier. - + The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior. From 9e8310cf19eb9942ea801357a1503d7f2760d58d Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 10:02:57 -0800 Subject: [PATCH 42/96] new: Add Congratulations page to the HelloWorld tutorial --- .../01_gettingStarted/02_hello/90_congrats.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md new file mode 100644 index 000000000000..6909a71658bb --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md @@ -0,0 +1,25 @@ +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; + +# Congratulations! +You have just learned the very basics of working with Ethereal Engine using Typescript! + +This was a very minimal introductory tutorial to get you started really quickly. +But Ethereal Engine has a lot more features to explore! + +## What's Next? +#### Beginner +If this is your first time using Ethereal Engine, we have prepared a [Basics](../basics) section for you. +It will teach you how to start expanding your knowledge of the engine without getting overwhelmed by its complexity. + +#### Intermediate +If you are feeling confident already, you could jump right into the intermediate tutorials. +Just pick a topic that interests you in the sidebar and continue your journey from there. +:::note +Make sure to skim-read the basics section at least once, as it gives an overview of some important concepts that will be used all throughout the other guides. +::: + +#### Advanced +The [Manual](/manual) is where Ethereal Engine is presented in all of its complexity, without any guard-rails or hand-holding. +You will also find the [Reference API](/typedoc) really useful when writing the code of your application. + + From 4d45fd4824196ea1e659812ac22fbfdce60c0c74 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 10:04:03 -0800 Subject: [PATCH 43/96] chg: Convert the Extras section into the Basics section --- .../{03_extras => 03_basics}/01_physics.md | 5 +++++ .../typescript/01_gettingStarted/03_basics/02_loop.md | 4 ++++ .../typescript/01_gettingStarted/03_basics/03_state.md | 7 +++++++ .../{03_extras => 03_basics}/04_networking.md | 5 +++++ .../{03_extras => 03_basics}/_50_networking.md | 0 .../01_gettingStarted/03_basics/_category_.json | 4 ++++ .../typescript/01_gettingStarted/03_basics/index.md | 6 ++++++ .../typescript/01_gettingStarted/03_extras/02_loop.md | 1 - .../typescript/01_gettingStarted/03_extras/03_state.md | 4 ---- .../01_gettingStarted/03_extras/_category_.json | 9 --------- 10 files changed, 31 insertions(+), 14 deletions(-) rename docs/developer/typescript/01_gettingStarted/{03_extras => 03_basics}/01_physics.md (96%) create mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md create mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/03_state.md rename docs/developer/typescript/01_gettingStarted/{03_extras => 03_basics}/04_networking.md (98%) rename docs/developer/typescript/01_gettingStarted/{03_extras => 03_basics}/_50_networking.md (100%) create mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/_category_.json create mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/index.md delete mode 100644 docs/developer/typescript/01_gettingStarted/03_extras/02_loop.md delete mode 100644 docs/developer/typescript/01_gettingStarted/03_extras/03_state.md delete mode 100644 docs/developer/typescript/01_gettingStarted/03_extras/_category_.json diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/01_physics.md b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md similarity index 96% rename from docs/developer/typescript/01_gettingStarted/03_extras/01_physics.md rename to docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md index caa0c7fea04d..785f16d1605b 100644 --- a/docs/developer/typescript/01_gettingStarted/03_extras/01_physics.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md @@ -3,6 +3,9 @@ sidebar_label: Physics --- # Adding Physics + + + ```ts import { ECS } from '@etherealengine/ecs' import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' @@ -44,3 +47,5 @@ export const HelloWorldSystem = ECS.defineSystem({ export default async function worldInjection() {} ``` + + diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md b/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md new file mode 100644 index 000000000000..080f0454df38 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md @@ -0,0 +1,4 @@ +# Engine Loop + + + diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md b/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md new file mode 100644 index 000000000000..27e9e1578766 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md @@ -0,0 +1,7 @@ +--- +sidebar_label: State +--- +# Managing State + + + diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/04_networking.md b/docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md similarity index 98% rename from docs/developer/typescript/01_gettingStarted/03_extras/04_networking.md rename to docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md index e42fa0154fe9..a41ea8893b79 100644 --- a/docs/developer/typescript/01_gettingStarted/03_extras/04_networking.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md @@ -1,5 +1,8 @@ # Networking + + + ```ts import React, { useEffect } from 'react' @@ -145,3 +148,5 @@ export const BasicSystem = defineSystem({ insert: { after: PresentationSystemGroup } }) ``` + + diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/_50_networking.md b/docs/developer/typescript/01_gettingStarted/03_basics/_50_networking.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/03_extras/_50_networking.md rename to docs/developer/typescript/01_gettingStarted/03_basics/_50_networking.md diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/_category_.json b/docs/developer/typescript/01_gettingStarted/03_basics/_category_.json new file mode 100644 index 000000000000..7fe2fadcddb4 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_basics/_category_.json @@ -0,0 +1,4 @@ +{ + "position": 03, +} + diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/index.md b/docs/developer/typescript/01_gettingStarted/03_basics/index.md new file mode 100644 index 000000000000..7aca3fe25236 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_basics/index.md @@ -0,0 +1,6 @@ +import DocCardList from '@theme/DocCardList'; + +# Basics +asdf + + diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/02_loop.md b/docs/developer/typescript/01_gettingStarted/03_extras/02_loop.md deleted file mode 100644 index 3787ce47d3a3..000000000000 --- a/docs/developer/typescript/01_gettingStarted/03_extras/02_loop.md +++ /dev/null @@ -1 +0,0 @@ -# Engine Loop diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/03_state.md b/docs/developer/typescript/01_gettingStarted/03_extras/03_state.md deleted file mode 100644 index 9a3a4ceac5b4..000000000000 --- a/docs/developer/typescript/01_gettingStarted/03_extras/03_state.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -sidebar_label: State ---- -# Managing State diff --git a/docs/developer/typescript/01_gettingStarted/03_extras/_category_.json b/docs/developer/typescript/01_gettingStarted/03_extras/_category_.json deleted file mode 100644 index 37e328e4d969..000000000000 --- a/docs/developer/typescript/01_gettingStarted/03_extras/_category_.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "label": "Extras", - "position": 03, - "link": { - "type": "generated-index", - "description": ".", - } -} - From 149fbfe31bcbd254b0c3b7ad9bcd95e6688f7a2e Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 10:08:35 -0800 Subject: [PATCH 44/96] fix: Missing imports in the new Basics pages --- .../typescript/01_gettingStarted/03_basics/01_physics.md | 2 ++ .../typescript/01_gettingStarted/03_basics/02_loop.md | 2 ++ .../typescript/01_gettingStarted/03_basics/03_state.md | 3 +++ .../typescript/01_gettingStarted/03_basics/04_networking.md | 2 ++ 4 files changed, 9 insertions(+) diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md index 785f16d1605b..fcfd4be83082 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md @@ -1,6 +1,8 @@ --- sidebar_label: Physics --- +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + # Adding Physics diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md b/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md index 080f0454df38..df2b69e0142a 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md @@ -1,3 +1,5 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + # Engine Loop diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md b/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md index 27e9e1578766..9bac5d724b05 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md @@ -1,6 +1,9 @@ --- sidebar_label: State --- + +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + # Managing State diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md b/docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md index a41ea8893b79..0a97ecac6680 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md @@ -1,3 +1,5 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + # Networking From 9e86e8772ea5cc3556cf1e774fc0d2a1b6e98a5b Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 11:40:11 -0800 Subject: [PATCH 45/96] chg: Congrats and Basics pages formatting improvements --- .../typescript/01_gettingStarted/02_hello/90_congrats.md | 6 +++++- .../typescript/01_gettingStarted/03_basics/index.md | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md index 6909a71658bb..b4a498c88c56 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md @@ -1,3 +1,6 @@ +--- +pagination_next: developer/typescript/gettingStarted/basics/physics +--- import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Congratulations! @@ -8,8 +11,9 @@ But Ethereal Engine has a lot more features to explore! ## What's Next? #### Beginner -If this is your first time using Ethereal Engine, we have prepared a [Basics](../basics) section for you. +If this is your first time using Ethereal Engine, we have prepared an `Etheral Engine Basics` tutorial for you. It will teach you how to start expanding your knowledge of the engine without getting overwhelmed by its complexity. +Go to the bottom of this page, and click on "Next" to continue with your learning journey! #### Intermediate If you are feeling confident already, you could jump right into the intermediate tutorials. diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/index.md b/docs/developer/typescript/01_gettingStarted/03_basics/index.md index 7aca3fe25236..225fba8e1fc2 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/index.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/index.md @@ -1,6 +1,11 @@ +--- +sidebar_label: Basics +--- + import DocCardList from '@theme/DocCardList'; -# Basics -asdf +# Ethereal Engine Basics +This guide is a continuation of the [Hello World Tutorial](../hello). +In this guide you will learn how to start expanding your knowledge of the engine beyond the Quickstart introductory guide. From 810af0bc74f650d8b6b9ea0229b74da3d036b9f0 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 11:40:43 -0800 Subject: [PATCH 46/96] new: Physics Basics tutorial page --- .../01_gettingStarted/03_basics/01_physics.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md index fcfd4be83082..bdeb50e2cd29 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md @@ -4,7 +4,39 @@ sidebar_label: Physics import { TechnicalNote } from '@site/src/components/TechnicalNote'; # Adding Physics +So far we have learned how to create an `Entity`, how to tell the engine what we want that engine to be. +In simple terms, we have told the engine how we want our sphere to be **created**. +We added some components to our sphere, so that the engine can draw the sphere into the screen so we can see it. +But right now it is only an "empty shell" that sits there doing nothing, which is a bit boring. +We cannot even use it as a platform to walk on! + +Lets fix that! We are now going to: +- Add a `RigidBodyComponent` of type `dynamic` +- Add a `ColliderComponent` with the shape of a `sphere` + +Here are your hints for this tutorial: +```ts +// Both the RigidBody and Collider components are part of the `Spatial/physics` engine module +'@etherealengine/spatial/src/physics/components/.....' +// We can specify the dynamic type with: +{ type: 'dynamic' } +// We can specify the shape with: +{ shape: 'sphere' } +``` + + + +```ts +// Import both components from the Spatial/physics module +import { RigidBodyComponent } from '@etherealengine/spatial/src/physics/components/RigidBodyComponent' +import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent' +``` +```ts +// Set both components to our entity +ECS.setComponent(entity, RigidBodyComponent, { type: 'dynamic' }) +ECS.setComponent(entity, ColliderComponent, { shape: 'sphere' }) +``` @@ -50,4 +82,7 @@ export const HelloWorldSystem = ECS.defineSystem({ export default async function worldInjection() {} ``` + + + From ea6b41a640e09f7f1b0d692df967bbb95bd85bd2 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:26:05 -0800 Subject: [PATCH 47/96] new: Debugging and Locations Basics tutorial pages sketches --- .../typescript/01_gettingStarted/03_basics/50_debugging.md | 4 ++++ .../typescript/01_gettingStarted/03_basics/50_locations.md | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/50_debugging.md create mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/50_debugging.md b/docs/developer/typescript/01_gettingStarted/03_basics/50_debugging.md new file mode 100644 index 000000000000..14f0f5a65aba --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_basics/50_debugging.md @@ -0,0 +1,4 @@ +# Debugging +## Using Ethereal Engine's Debugger with `\`` + +## Using the Web Browser's Inspector diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md b/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md new file mode 100644 index 000000000000..13393408ef47 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md @@ -0,0 +1,4 @@ +--- +sidebar_label: Locations +--- +# Our first Location From d48a640729c63867c5489827c6423b637f377132 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:55:58 -0800 Subject: [PATCH 48/96] new: Better instructions on the Physics Basics page --- .../01_gettingStarted/03_basics/01_physics.md | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md index bdeb50e2cd29..242597aa689d 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md @@ -4,15 +4,34 @@ sidebar_label: Physics import { TechnicalNote } from '@site/src/components/TechnicalNote'; # Adding Physics -So far we have learned how to create an `Entity`, how to tell the engine what we want that engine to be. -In simple terms, we have told the engine how we want our sphere to be **created**. - -We added some components to our sphere, so that the engine can draw the sphere into the screen so we can see it. -But right now it is only an "empty shell" that sits there doing nothing, which is a bit boring. -We cannot even use it as a platform to walk on! - -Lets fix that! We are now going to: -- Add a `RigidBodyComponent` of type `dynamic` +So far we have learned how to create an `Entity`, and how to tell the engine what we want that entity to be. +In simple terms, we have told the engine how to **create** our sphere. + +## Our problem +We added some components to our sphere, so that the engine can draw the sphere into the screen and we can see it. +But right now it is only an "empty shell" that sits there doing nothing, which is a bit boring. +We cannot even use it as a platform to walk on! +Lets fix that. + +## Our solution +We are going to add a Collider and a RigidBody to our sphere object. + +Physics properties are tricky to test, as they are not readily visible. So lets get a point of reference of how our project currently behaves. +In order to test our changes in a simple way, we will run our project from the studio and walk around the scene with an Avatar. + +These are the steps needed to accomplish that: +- Open the scene we created before, or click on `Create Scene` if don't have it +- Press the `Play` button in the studio +- Move your Avatar around the scene by either: + - Pressing `WASD` in your keyboard + - Clicking anywhere on the ground with your mouse + +You may notice that, if you try to hit the sphere with your avatar... you will instead walk right through it! +This happens because our Sphere doesn't have any Physics properties yet, so it can be "seen" but not "collided against". + +## Physics Properties +In order to correct our problem, we are now going to: +- Add a `RigidBodyComponent` of type `dynamic` to our entity - Add a `ColliderComponent` with the shape of a `sphere` Here are your hints for this tutorial: @@ -25,6 +44,10 @@ Here are your hints for this tutorial: { shape: 'sphere' } ``` +You will know that your code is correct if: +- You try to go through the ball with the Avatar, but the engine stops you. + + ```ts From db34134e89c2cfee076fbac5a1bb79ef1035047d Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 9 Feb 2024 10:48:20 -0800 Subject: [PATCH 49/96] chg: Small changes to the files --- .../typescript/01_gettingStarted/03_basics/01_physics.md | 2 +- .../typescript/01_gettingStarted/03_basics/02_loop.md | 5 +++++ .../03_basics/{04_networking.md => 60_networking.md} | 0 3 files changed, 6 insertions(+), 1 deletion(-) rename docs/developer/typescript/01_gettingStarted/03_basics/{04_networking.md => 60_networking.md} (100%) diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md index 242597aa689d..369c99ad555c 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md @@ -17,7 +17,7 @@ Lets fix that. We are going to add a Collider and a RigidBody to our sphere object. Physics properties are tricky to test, as they are not readily visible. So lets get a point of reference of how our project currently behaves. -In order to test our changes in a simple way, we will run our project from the studio and walk around the scene with an Avatar. +In order to test our changes in a simple way, we are going to run our project from the studio and walk around the scene with an Avatar. These are the steps needed to accomplish that: - Open the scene we created before, or click on `Create Scene` if don't have it diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md b/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md index df2b69e0142a..5ea6f4a25771 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md @@ -1,6 +1,11 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; # Engine Loop + diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md b/docs/developer/typescript/01_gettingStarted/03_basics/60_networking.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/03_basics/04_networking.md rename to docs/developer/typescript/01_gettingStarted/03_basics/60_networking.md From 1361b680865e18b8cb95472b8f2c2e3b272e9f7b Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:36:15 -0800 Subject: [PATCH 50/96] chg: Wording and instructions changes to the Physics page --- .../01_gettingStarted/03_basics/01_physics.md | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md index 369c99ad555c..574026bd654b 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md @@ -4,7 +4,7 @@ sidebar_label: Physics import { TechnicalNote } from '@site/src/components/TechnicalNote'; # Adding Physics -So far we have learned how to create an `Entity`, and how to tell the engine what we want that entity to be. +So far we have learned how to create an `Entity`, and how to tell the engine what we want our entity to be. In simple terms, we have told the engine how to **create** our sphere. ## Our problem @@ -16,17 +16,18 @@ Lets fix that. ## Our solution We are going to add a Collider and a RigidBody to our sphere object. -Physics properties are tricky to test, as they are not readily visible. So lets get a point of reference of how our project currently behaves. -In order to test our changes in a simple way, we are going to run our project from the studio and walk around the scene with an Avatar. +Physics properties are tricky to test, as they may not be readily visible. +Lets get a point of reference of how our project currently behaves, so we can be certain that the changes we make to our code are working as we expect them. +In order to do that, we are going to run our project from the studio and walk around the scene with an Avatar. These are the steps needed to accomplish that: -- Open the scene we created before, or click on `Create Scene` if don't have it +- Open the scene we created before, or click on `Create Scene` if you don't have it - Press the `Play` button in the studio - Move your Avatar around the scene by either: - Pressing `WASD` in your keyboard - Clicking anywhere on the ground with your mouse -You may notice that, if you try to hit the sphere with your avatar... you will instead walk right through it! +You may notice that, if you try to hit the sphere with your avatar... you will instead walk right through it! This happens because our Sphere doesn't have any Physics properties yet, so it can be "seen" but not "collided against". ## Physics Properties @@ -42,11 +43,13 @@ Here are your hints for this tutorial: { type: 'dynamic' } // We can specify the shape with: { shape: 'sphere' } +// Make the ball spawn 3units above the ground +Vector3(/* X */, /* Y */, /* Z */) ``` You will know that your code is correct if: -- You try to go through the ball with the Avatar, but the engine stops you. - +- The ball has gravity and falls to the ground +- You try to go through the ball with the Avatar, but the engine stops you and you push the ball instead. @@ -60,6 +63,10 @@ import { ColliderComponent } from '@etherealengine/spatial/src/physics/component ECS.setComponent(entity, RigidBodyComponent, { type: 'dynamic' }) ECS.setComponent(entity, ColliderComponent, { shape: 'sphere' }) ``` +```ts +// Make the ball spawn 3 units along the Y axis (aka 3u above the ground) +ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 3, 0) }) +``` @@ -87,7 +94,9 @@ const hello = () => { const entity = ECS.createEntity() ECS.setComponent(entity, NameComponent, 'hello-world') ECS.setComponent(entity, VisibleComponent) - ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + // highlight-start + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 3, 0) }) + // highlight-end ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) // highlight-start From f9c7d608e5345324789b3b9222f2b4a63d41e145 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:05:18 -0800 Subject: [PATCH 51/96] chg: Move locations instructions to the new basics/locations page --- .../03_basics/50_locations.md | 20 ++++++++++++++++ .../_todo/50_basic/_category_.json | 3 --- .../01_gettingStarted/_todo/50_basic/index.md | 12 ---------- .../_todo/50_install/02_projects.md | 24 ------------------- 4 files changed, 20 insertions(+), 39 deletions(-) delete mode 100644 docs/developer/typescript/01_gettingStarted/_todo/50_basic/_category_.json delete mode 100644 docs/developer/typescript/01_gettingStarted/_todo/50_basic/index.md delete mode 100644 docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md b/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md index 13393408ef47..b9efb145bff0 100644 --- a/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md +++ b/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md @@ -2,3 +2,23 @@ sidebar_label: Locations --- # Our first Location + + +## Installing and running projects +Ethereal Engine can be extended with projects. +They are equivalent to "projects" in other engines, except they are modular like npm packages (they are npm packages too). + +Ethereal Engine scans for projects mounted in the `/packages/projects/projects` sub-folder of Ethereal Engine. + +From a bash shell in the Ethereal Engine folder we can install, run and visit a project with: +```bash +git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic +npm install +npm run dev +``` + +## Creating a Location +Once Ethereal Engine is running, from the web admin panel of Ethereal Engine create a 'location' for the scene. +- Navigate to https://localhost:3000/admin/locations. +- Map the scene to the name 'basic'. +- Run the project on the web by visiting it with the URL you just created: https://localhost:3000/location/basic diff --git a/docs/developer/typescript/01_gettingStarted/_todo/50_basic/_category_.json b/docs/developer/typescript/01_gettingStarted/_todo/50_basic/_category_.json deleted file mode 100644 index 6811f84d171d..000000000000 --- a/docs/developer/typescript/01_gettingStarted/_todo/50_basic/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 50, -} diff --git a/docs/developer/typescript/01_gettingStarted/_todo/50_basic/index.md b/docs/developer/typescript/01_gettingStarted/_todo/50_basic/index.md deleted file mode 100644 index ed08ff139f1e..000000000000 --- a/docs/developer/typescript/01_gettingStarted/_todo/50_basic/index.md +++ /dev/null @@ -1,12 +0,0 @@ -# Creating a project -In this section we will create a simple project called `basic`. -:::note -You can find the original source at https://github.com/EtherealEngine/ee-tutorial-basic -See the previous section for installation instructions. -::: - -Ethereal Engine typescript projects usually have these pieces: -1. **Entities**: We use an ECS system where entities are a way that we represent game state. -2. **Components**: Entities are decorated with components that produce behaviors on entities. -3. **Systems**: Drive behavior over time -4. **WorldInjection**: Registers the project with Ethereal Engine diff --git a/docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md b/docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md deleted file mode 100644 index 62ecef0d783b..000000000000 --- a/docs/developer/typescript/01_gettingStarted/_todo/50_install/02_projects.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: Projects ---- -# Installing and running projects -thereal Engine can be extended with projects. -They are equivalent to "projects" in other engines, except they are modular like npm packages (they are npm packages too). - -Ethereal Engine scans for projects mounted in the /packages/projects/projects sub-folder of Ethereal Engine. - -From a bash shell in the Ethereal Engine folder we can install, run and visit a project like so: - -```bash -gh repo clone EtherealEngine/ee-tutorial-basic -mv ee-tutorial-basic packages/projects/packages/ee-tutorial-basic -npm install -npm run dev -``` - -Once Ethereal Engine is running, from the web admin panel of Ethereal Engine create a 'location' for the project. -See https://localhost:3000/admin. -Map the project to the name 'basic'. -Then run the project on the web by visiting it with the URL you created. -See https://localhost:3000/location/pong - From 26e55ccbd25560be0eb85624de08db4298f441ef Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 9 Feb 2024 18:23:49 -0800 Subject: [PATCH 52/96] new: Basics/state early sketch (tbd) --- .../01_gettingStarted/03_basics/02_state.md | 48 +++++++++++++++++++ .../03_basics/{02_loop.md => 03_loop.md} | 0 .../01_gettingStarted/03_basics/03_state.md | 10 ---- 3 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/02_state.md rename docs/developer/typescript/01_gettingStarted/03_basics/{02_loop.md => 03_loop.md} (100%) delete mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/03_state.md diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/02_state.md b/docs/developer/typescript/01_gettingStarted/03_basics/02_state.md new file mode 100644 index 000000000000..1129e97bf104 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/03_basics/02_state.md @@ -0,0 +1,48 @@ +--- +sidebar_label: State +--- + +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + +# Managing State +There are multiple ways to keep track of state +- Manually maintaining the value of a variable +- A state variable with `Hyperflux` +- A reactor mount with `useEffect` + +## Local Variable +You might remember the `initialized` variable we created in an earlier section of the [Hello World](../hello/system) tutorial. +That variable was what is called "Local State". + +As you saw, we are fully responsible of book-keeping the values contained in the variables we create in this way. + +## Hyperflux +Ethereal Engine provides a group of functions to manage state asynchronously. +## `useEffect` + + + + +```ts +/** + * Global state that tracks locally spawned or destroyed artifacts by using action receptors + */ + +const BasicState = defineState({ + name: 'ee.basic.BasicState', + + initial: {} as Record, + + receptors: { + onSpawnAction: BasicActions.spawnAction.receive((action) => { + const state = getMutableState(BasicState) + state[action.entityUUID].merge({}) + }), + onDestroyObject: WorldNetworkAction.destroyObject.receive((action) => { + const state = getMutableState(BasicState) + state[action.entityUUID].set(none) + }) + } +}) + +``` diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md b/docs/developer/typescript/01_gettingStarted/03_basics/03_loop.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/03_basics/02_loop.md rename to docs/developer/typescript/01_gettingStarted/03_basics/03_loop.md diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md b/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md deleted file mode 100644 index 9bac5d724b05..000000000000 --- a/docs/developer/typescript/01_gettingStarted/03_basics/03_state.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -sidebar_label: State ---- - -import { TechnicalNote } from '@site/src/components/TechnicalNote'; - -# Managing State - - - From 8dab2aab4e17c3af822a903d5859cae1a14bb617 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:54:01 -0800 Subject: [PATCH 53/96] new: Early sketch of the Intermediate tutorials structure --- .../02_beyondBasics/50_debugging.md | 2 + .../02_beyondBasics/50_engineCode.md | 1 + .../typescript/02_beyondBasics/50_state.md | 1 + .../02_beyondBasics/_category_.json | 3 ++ .../typescript/02_beyondBasics/index.md | 11 +++++ .../typescript/02_topic1/_category_.json | 8 ---- .../typescript/03_topic2/_category_.json | 8 ---- .../{02_topic1 => 50_components}/01_file.md | 0 .../{02_topic1 => 50_components}/02_file2.md | 0 .../typescript/50_components/_category_.json | 3 ++ .../typescript/50_components/index.md | 10 +++++ .../{03_topic2 => 50_inputs}/01_file.md | 0 .../{03_topic2 => 50_inputs}/02_file2.md | 0 .../typescript/50_inputs/_category_.json | 3 ++ docs/developer/typescript/50_inputs/index.md | 6 +++ .../00_intro.md => 50_mocap/01_file.md} | 2 +- .../00_intro.md => 50_mocap/02_file2.md} | 2 +- .../typescript/50_mocap/_category_.json | 3 ++ docs/developer/typescript/50_mocap/index.md | 5 +++ .../typescript/50_networking/01_file.md | 2 + .../typescript/50_networking/02_file2.md | 2 + .../typescript/50_networking/_category_.json | 3 ++ .../typescript/50_networking/index.md | 4 ++ .../typescript/50_systems/01_input.md | 5 +++ .../typescript/50_systems/02_simulation.md | 6 +++ .../typescript/50_systems/03_animation.md | 7 +++ .../typescript/50_systems/04_presentation.md | 6 +++ .../typescript/50_systems/_category_.json | 3 ++ docs/developer/typescript/50_systems/index.md | 44 +++++++++++++++++++ .../typescript/59_engineModules/01_file.md | 2 + .../typescript/59_engineModules/02_file2.md | 2 + .../59_engineModules/_category_.json | 3 ++ .../typescript/59_engineModules/index.md | 8 ++++ 33 files changed, 147 insertions(+), 18 deletions(-) create mode 100644 docs/developer/typescript/02_beyondBasics/50_debugging.md create mode 100644 docs/developer/typescript/02_beyondBasics/50_engineCode.md create mode 100644 docs/developer/typescript/02_beyondBasics/50_state.md create mode 100644 docs/developer/typescript/02_beyondBasics/_category_.json create mode 100644 docs/developer/typescript/02_beyondBasics/index.md delete mode 100644 docs/developer/typescript/02_topic1/_category_.json delete mode 100644 docs/developer/typescript/03_topic2/_category_.json rename docs/developer/typescript/{02_topic1 => 50_components}/01_file.md (100%) rename docs/developer/typescript/{02_topic1 => 50_components}/02_file2.md (100%) create mode 100644 docs/developer/typescript/50_components/_category_.json create mode 100644 docs/developer/typescript/50_components/index.md rename docs/developer/typescript/{03_topic2 => 50_inputs}/01_file.md (100%) rename docs/developer/typescript/{03_topic2 => 50_inputs}/02_file2.md (100%) create mode 100644 docs/developer/typescript/50_inputs/_category_.json create mode 100644 docs/developer/typescript/50_inputs/index.md rename docs/developer/typescript/{02_topic1/00_intro.md => 50_mocap/01_file.md} (98%) rename docs/developer/typescript/{03_topic2/00_intro.md => 50_mocap/02_file2.md} (98%) create mode 100644 docs/developer/typescript/50_mocap/_category_.json create mode 100644 docs/developer/typescript/50_mocap/index.md create mode 100644 docs/developer/typescript/50_networking/01_file.md create mode 100644 docs/developer/typescript/50_networking/02_file2.md create mode 100644 docs/developer/typescript/50_networking/_category_.json create mode 100644 docs/developer/typescript/50_networking/index.md create mode 100644 docs/developer/typescript/50_systems/01_input.md create mode 100644 docs/developer/typescript/50_systems/02_simulation.md create mode 100644 docs/developer/typescript/50_systems/03_animation.md create mode 100644 docs/developer/typescript/50_systems/04_presentation.md create mode 100644 docs/developer/typescript/50_systems/_category_.json create mode 100644 docs/developer/typescript/50_systems/index.md create mode 100644 docs/developer/typescript/59_engineModules/01_file.md create mode 100644 docs/developer/typescript/59_engineModules/02_file2.md create mode 100644 docs/developer/typescript/59_engineModules/_category_.json create mode 100644 docs/developer/typescript/59_engineModules/index.md diff --git a/docs/developer/typescript/02_beyondBasics/50_debugging.md b/docs/developer/typescript/02_beyondBasics/50_debugging.md new file mode 100644 index 000000000000..01d9e901d476 --- /dev/null +++ b/docs/developer/typescript/02_beyondBasics/50_debugging.md @@ -0,0 +1,2 @@ +# Debugging + diff --git a/docs/developer/typescript/02_beyondBasics/50_engineCode.md b/docs/developer/typescript/02_beyondBasics/50_engineCode.md new file mode 100644 index 000000000000..aefa412924bf --- /dev/null +++ b/docs/developer/typescript/02_beyondBasics/50_engineCode.md @@ -0,0 +1 @@ +# Engine Code Navigation diff --git a/docs/developer/typescript/02_beyondBasics/50_state.md b/docs/developer/typescript/02_beyondBasics/50_state.md new file mode 100644 index 000000000000..e2937def93eb --- /dev/null +++ b/docs/developer/typescript/02_beyondBasics/50_state.md @@ -0,0 +1 @@ +# State Management diff --git a/docs/developer/typescript/02_beyondBasics/_category_.json b/docs/developer/typescript/02_beyondBasics/_category_.json new file mode 100644 index 000000000000..e0d3b8be94f4 --- /dev/null +++ b/docs/developer/typescript/02_beyondBasics/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 02, +} diff --git a/docs/developer/typescript/02_beyondBasics/index.md b/docs/developer/typescript/02_beyondBasics/index.md new file mode 100644 index 000000000000..2c18c74d891a --- /dev/null +++ b/docs/developer/typescript/02_beyondBasics/index.md @@ -0,0 +1,11 @@ + +import DocCardList from '@theme/DocCardList' + +# Beyond the Basics + + + diff --git a/docs/developer/typescript/02_topic1/_category_.json b/docs/developer/typescript/02_topic1/_category_.json deleted file mode 100644 index 2faf0119c19e..000000000000 --- a/docs/developer/typescript/02_topic1/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Topic1", - "position": 02, - "link": { - "type": "doc", - "id": "developer/typescript/topic1/intro" - } -} diff --git a/docs/developer/typescript/03_topic2/_category_.json b/docs/developer/typescript/03_topic2/_category_.json deleted file mode 100644 index b8c73c917a03..000000000000 --- a/docs/developer/typescript/03_topic2/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Topic2", - "position": 03, - "link": { - "type": "doc", - "id": "developer/typescript/topic2/intro" - } -} diff --git a/docs/developer/typescript/02_topic1/01_file.md b/docs/developer/typescript/50_components/01_file.md similarity index 100% rename from docs/developer/typescript/02_topic1/01_file.md rename to docs/developer/typescript/50_components/01_file.md diff --git a/docs/developer/typescript/02_topic1/02_file2.md b/docs/developer/typescript/50_components/02_file2.md similarity index 100% rename from docs/developer/typescript/02_topic1/02_file2.md rename to docs/developer/typescript/50_components/02_file2.md diff --git a/docs/developer/typescript/50_components/_category_.json b/docs/developer/typescript/50_components/_category_.json new file mode 100644 index 000000000000..6811f84d171d --- /dev/null +++ b/docs/developer/typescript/50_components/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 50, +} diff --git a/docs/developer/typescript/50_components/index.md b/docs/developer/typescript/50_components/index.md new file mode 100644 index 000000000000..61da6d4a36d8 --- /dev/null +++ b/docs/developer/typescript/50_components/index.md @@ -0,0 +1,10 @@ +--- +sidebar_label: Components +--- +# Working with Components +## Custom Components + diff --git a/docs/developer/typescript/03_topic2/01_file.md b/docs/developer/typescript/50_inputs/01_file.md similarity index 100% rename from docs/developer/typescript/03_topic2/01_file.md rename to docs/developer/typescript/50_inputs/01_file.md diff --git a/docs/developer/typescript/03_topic2/02_file2.md b/docs/developer/typescript/50_inputs/02_file2.md similarity index 100% rename from docs/developer/typescript/03_topic2/02_file2.md rename to docs/developer/typescript/50_inputs/02_file2.md diff --git a/docs/developer/typescript/50_inputs/_category_.json b/docs/developer/typescript/50_inputs/_category_.json new file mode 100644 index 000000000000..6811f84d171d --- /dev/null +++ b/docs/developer/typescript/50_inputs/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 50, +} diff --git a/docs/developer/typescript/50_inputs/index.md b/docs/developer/typescript/50_inputs/index.md new file mode 100644 index 000000000000..0bac03a63555 --- /dev/null +++ b/docs/developer/typescript/50_inputs/index.md @@ -0,0 +1,6 @@ +# Input Management + diff --git a/docs/developer/typescript/02_topic1/00_intro.md b/docs/developer/typescript/50_mocap/01_file.md similarity index 98% rename from docs/developer/typescript/02_topic1/00_intro.md rename to docs/developer/typescript/50_mocap/01_file.md index 9fd89e26d12c..7db4cab12c85 100644 --- a/docs/developer/typescript/02_topic1/00_intro.md +++ b/docs/developer/typescript/50_mocap/01_file.md @@ -1,2 +1,2 @@ -# Topic 1 +# Topic Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/03_topic2/00_intro.md b/docs/developer/typescript/50_mocap/02_file2.md similarity index 98% rename from docs/developer/typescript/03_topic2/00_intro.md rename to docs/developer/typescript/50_mocap/02_file2.md index 90b2818b08d8..7db4cab12c85 100644 --- a/docs/developer/typescript/03_topic2/00_intro.md +++ b/docs/developer/typescript/50_mocap/02_file2.md @@ -1,2 +1,2 @@ -# Topic 2 +# Topic Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_mocap/_category_.json b/docs/developer/typescript/50_mocap/_category_.json new file mode 100644 index 000000000000..6811f84d171d --- /dev/null +++ b/docs/developer/typescript/50_mocap/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 50, +} diff --git a/docs/developer/typescript/50_mocap/index.md b/docs/developer/typescript/50_mocap/index.md new file mode 100644 index 000000000000..8fdd2f9497c7 --- /dev/null +++ b/docs/developer/typescript/50_mocap/index.md @@ -0,0 +1,5 @@ +--- +sidebar_label: Motion Capture +--- +# Motion Capture Guide + diff --git a/docs/developer/typescript/50_networking/01_file.md b/docs/developer/typescript/50_networking/01_file.md new file mode 100644 index 000000000000..7db4cab12c85 --- /dev/null +++ b/docs/developer/typescript/50_networking/01_file.md @@ -0,0 +1,2 @@ +# Topic +Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_networking/02_file2.md b/docs/developer/typescript/50_networking/02_file2.md new file mode 100644 index 000000000000..7db4cab12c85 --- /dev/null +++ b/docs/developer/typescript/50_networking/02_file2.md @@ -0,0 +1,2 @@ +# Topic +Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_networking/_category_.json b/docs/developer/typescript/50_networking/_category_.json new file mode 100644 index 000000000000..6811f84d171d --- /dev/null +++ b/docs/developer/typescript/50_networking/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 50, +} diff --git a/docs/developer/typescript/50_networking/index.md b/docs/developer/typescript/50_networking/index.md new file mode 100644 index 000000000000..c1ffbc39cbdd --- /dev/null +++ b/docs/developer/typescript/50_networking/index.md @@ -0,0 +1,4 @@ +--- +sidebar_label: Networking +--- +# Networking Guide diff --git a/docs/developer/typescript/50_systems/01_input.md b/docs/developer/typescript/50_systems/01_input.md new file mode 100644 index 000000000000..0e2d473e8973 --- /dev/null +++ b/docs/developer/typescript/50_systems/01_input.md @@ -0,0 +1,5 @@ +# Input System + diff --git a/docs/developer/typescript/50_systems/02_simulation.md b/docs/developer/typescript/50_systems/02_simulation.md new file mode 100644 index 000000000000..52270d142b1a --- /dev/null +++ b/docs/developer/typescript/50_systems/02_simulation.md @@ -0,0 +1,6 @@ +# Simulation System + diff --git a/docs/developer/typescript/50_systems/03_animation.md b/docs/developer/typescript/50_systems/03_animation.md new file mode 100644 index 000000000000..889d47962c6d --- /dev/null +++ b/docs/developer/typescript/50_systems/03_animation.md @@ -0,0 +1,7 @@ +# Animation System + diff --git a/docs/developer/typescript/50_systems/04_presentation.md b/docs/developer/typescript/50_systems/04_presentation.md new file mode 100644 index 000000000000..70f4186c60a5 --- /dev/null +++ b/docs/developer/typescript/50_systems/04_presentation.md @@ -0,0 +1,6 @@ +# Simulation System + diff --git a/docs/developer/typescript/50_systems/_category_.json b/docs/developer/typescript/50_systems/_category_.json new file mode 100644 index 000000000000..6811f84d171d --- /dev/null +++ b/docs/developer/typescript/50_systems/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 50, +} diff --git a/docs/developer/typescript/50_systems/index.md b/docs/developer/typescript/50_systems/index.md new file mode 100644 index 000000000000..da018234084b --- /dev/null +++ b/docs/developer/typescript/50_systems/index.md @@ -0,0 +1,44 @@ +--- +sidebar_label: Systems Execution +--- + +import DocCardList from '@theme/DocCardList' +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + +# Systems Execution Guide + + + + + +```ts +export const InputSystemGroup = defineSystem({ + uuid: 'ee.engine.input-group', + insert: {} +}) + +/** Run inside of fixed pipeline */ +export const SimulationSystemGroup = defineSystem({ + uuid: 'ee.engine.simulation-group', + timeStep: 1 / 60, + insert: {} +}) + +export const AnimationSystemGroup = defineSystem({ + uuid: 'ee.engine.animation-group', + insert: {} +}) + +export const PresentationSystemGroup = defineSystem({ + uuid: 'ee.engine.presentation-group', + insert: {} +}) + +export const DefaultSystemPipeline = [ + InputSystemGroup, + SimulationSystemGroup, + AnimationSystemGroup, + PresentationSystemGroup +] +``` + diff --git a/docs/developer/typescript/59_engineModules/01_file.md b/docs/developer/typescript/59_engineModules/01_file.md new file mode 100644 index 000000000000..7db4cab12c85 --- /dev/null +++ b/docs/developer/typescript/59_engineModules/01_file.md @@ -0,0 +1,2 @@ +# Topic +Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/59_engineModules/02_file2.md b/docs/developer/typescript/59_engineModules/02_file2.md new file mode 100644 index 000000000000..7db4cab12c85 --- /dev/null +++ b/docs/developer/typescript/59_engineModules/02_file2.md @@ -0,0 +1,2 @@ +# Topic +Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/59_engineModules/_category_.json b/docs/developer/typescript/59_engineModules/_category_.json new file mode 100644 index 000000000000..6811f84d171d --- /dev/null +++ b/docs/developer/typescript/59_engineModules/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 50, +} diff --git a/docs/developer/typescript/59_engineModules/index.md b/docs/developer/typescript/59_engineModules/index.md new file mode 100644 index 000000000000..2964a3b22e2a --- /dev/null +++ b/docs/developer/typescript/59_engineModules/index.md @@ -0,0 +1,8 @@ +# Engine Modules Guide + From baa946ce6b5bdd41551beac26e4d910a4ce95704 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Mon, 12 Feb 2024 16:34:38 -0800 Subject: [PATCH 54/96] chg: Cleanup the folders to remove the _todo temporary folder --- .../04_project/_category_.json | 3 ++ .../01_gettingStarted/04_project/index.md | 7 +++ .../_todo/50_install/01_engine.md | 13 ------ .../_todo/50_install/_category_.json | 4 -- .../01_gettingStarted/_todo/50_next.md | 31 ------------- .../typescript/02_beyondBasics/50_projects.md | 23 ++++++++++ .../50_systems/{ => 50_order}/01_input.md | 0 .../{ => 50_order}/02_simulation.md | 0 .../50_systems/{ => 50_order}/03_animation.md | 0 .../{ => 50_order}/04_presentation.md | 0 .../50_systems/{ => 50_order}/_category_.json | 0 .../typescript/50_systems/50_order/index.md | 44 +++++++++++++++++++ docs/developer/typescript/50_systems/index.md | 39 +--------------- 13 files changed, 79 insertions(+), 85 deletions(-) create mode 100644 docs/developer/typescript/01_gettingStarted/04_project/_category_.json create mode 100644 docs/developer/typescript/01_gettingStarted/04_project/index.md delete mode 100644 docs/developer/typescript/01_gettingStarted/_todo/50_install/01_engine.md delete mode 100644 docs/developer/typescript/01_gettingStarted/_todo/50_install/_category_.json delete mode 100644 docs/developer/typescript/01_gettingStarted/_todo/50_next.md create mode 100644 docs/developer/typescript/02_beyondBasics/50_projects.md rename docs/developer/typescript/50_systems/{ => 50_order}/01_input.md (100%) rename docs/developer/typescript/50_systems/{ => 50_order}/02_simulation.md (100%) rename docs/developer/typescript/50_systems/{ => 50_order}/03_animation.md (100%) rename docs/developer/typescript/50_systems/{ => 50_order}/04_presentation.md (100%) rename docs/developer/typescript/50_systems/{ => 50_order}/_category_.json (100%) create mode 100644 docs/developer/typescript/50_systems/50_order/index.md diff --git a/docs/developer/typescript/01_gettingStarted/04_project/_category_.json b/docs/developer/typescript/01_gettingStarted/04_project/_category_.json new file mode 100644 index 000000000000..baf1ec9ea700 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/04_project/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 04, +} diff --git a/docs/developer/typescript/01_gettingStarted/04_project/index.md b/docs/developer/typescript/01_gettingStarted/04_project/index.md new file mode 100644 index 000000000000..874e05c6f3ab --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/04_project/index.md @@ -0,0 +1,7 @@ +# Hero Tutorial + diff --git a/docs/developer/typescript/01_gettingStarted/_todo/50_install/01_engine.md b/docs/developer/typescript/01_gettingStarted/_todo/50_install/01_engine.md deleted file mode 100644 index cef345e9efba..000000000000 --- a/docs/developer/typescript/01_gettingStarted/_todo/50_install/01_engine.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -sidebar_label: Ethereal Engine ---- -# Installing and running Ethereal Engine - - - diff --git a/docs/developer/typescript/01_gettingStarted/_todo/50_install/_category_.json b/docs/developer/typescript/01_gettingStarted/_todo/50_install/_category_.json deleted file mode 100644 index 82c38fb1cafc..000000000000 --- a/docs/developer/typescript/01_gettingStarted/_todo/50_install/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Installation", - "position": 50, -} diff --git a/docs/developer/typescript/01_gettingStarted/_todo/50_next.md b/docs/developer/typescript/01_gettingStarted/_todo/50_next.md deleted file mode 100644 index bd2fdd7974a4..000000000000 --- a/docs/developer/typescript/01_gettingStarted/_todo/50_next.md +++ /dev/null @@ -1,31 +0,0 @@ -# Hero Tutorial - - - - - - - - - - diff --git a/docs/developer/typescript/02_beyondBasics/50_projects.md b/docs/developer/typescript/02_beyondBasics/50_projects.md new file mode 100644 index 000000000000..813d0ebc4554 --- /dev/null +++ b/docs/developer/typescript/02_beyondBasics/50_projects.md @@ -0,0 +1,23 @@ +# Project Management + + + + diff --git a/docs/developer/typescript/50_systems/01_input.md b/docs/developer/typescript/50_systems/50_order/01_input.md similarity index 100% rename from docs/developer/typescript/50_systems/01_input.md rename to docs/developer/typescript/50_systems/50_order/01_input.md diff --git a/docs/developer/typescript/50_systems/02_simulation.md b/docs/developer/typescript/50_systems/50_order/02_simulation.md similarity index 100% rename from docs/developer/typescript/50_systems/02_simulation.md rename to docs/developer/typescript/50_systems/50_order/02_simulation.md diff --git a/docs/developer/typescript/50_systems/03_animation.md b/docs/developer/typescript/50_systems/50_order/03_animation.md similarity index 100% rename from docs/developer/typescript/50_systems/03_animation.md rename to docs/developer/typescript/50_systems/50_order/03_animation.md diff --git a/docs/developer/typescript/50_systems/04_presentation.md b/docs/developer/typescript/50_systems/50_order/04_presentation.md similarity index 100% rename from docs/developer/typescript/50_systems/04_presentation.md rename to docs/developer/typescript/50_systems/50_order/04_presentation.md diff --git a/docs/developer/typescript/50_systems/_category_.json b/docs/developer/typescript/50_systems/50_order/_category_.json similarity index 100% rename from docs/developer/typescript/50_systems/_category_.json rename to docs/developer/typescript/50_systems/50_order/_category_.json diff --git a/docs/developer/typescript/50_systems/50_order/index.md b/docs/developer/typescript/50_systems/50_order/index.md new file mode 100644 index 000000000000..01ed8a5a8787 --- /dev/null +++ b/docs/developer/typescript/50_systems/50_order/index.md @@ -0,0 +1,44 @@ +--- +sidebar_label: Execution Order +--- + +import DocCardList from '@theme/DocCardList' +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + +# Systems Execution Guide + + + + + +```ts +export const InputSystemGroup = defineSystem({ + uuid: 'ee.engine.input-group', + insert: {} +}) + +/** Run inside of fixed pipeline */ +export const SimulationSystemGroup = defineSystem({ + uuid: 'ee.engine.simulation-group', + timeStep: 1 / 60, + insert: {} +}) + +export const AnimationSystemGroup = defineSystem({ + uuid: 'ee.engine.animation-group', + insert: {} +}) + +export const PresentationSystemGroup = defineSystem({ + uuid: 'ee.engine.presentation-group', + insert: {} +}) + +export const DefaultSystemPipeline = [ + InputSystemGroup, + SimulationSystemGroup, + AnimationSystemGroup, + PresentationSystemGroup +] +``` + diff --git a/docs/developer/typescript/50_systems/index.md b/docs/developer/typescript/50_systems/index.md index da018234084b..b00e1a44b963 100644 --- a/docs/developer/typescript/50_systems/index.md +++ b/docs/developer/typescript/50_systems/index.md @@ -1,44 +1,9 @@ --- -sidebar_label: Systems Execution +sidebar_label: Systems --- import DocCardList from '@theme/DocCardList' -import { TechnicalNote } from '@site/src/components/TechnicalNote'; -# Systems Execution Guide +# Systems Guide - - - -```ts -export const InputSystemGroup = defineSystem({ - uuid: 'ee.engine.input-group', - insert: {} -}) - -/** Run inside of fixed pipeline */ -export const SimulationSystemGroup = defineSystem({ - uuid: 'ee.engine.simulation-group', - timeStep: 1 / 60, - insert: {} -}) - -export const AnimationSystemGroup = defineSystem({ - uuid: 'ee.engine.animation-group', - insert: {} -}) - -export const PresentationSystemGroup = defineSystem({ - uuid: 'ee.engine.presentation-group', - insert: {} -}) - -export const DefaultSystemPipeline = [ - InputSystemGroup, - SimulationSystemGroup, - AnimationSystemGroup, - PresentationSystemGroup -] -``` - From e4a3bd414b91bf43f17538a9e93d2afb0e99dcb8 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 14 Feb 2024 20:59:13 -0800 Subject: [PATCH 55/96] chg: Move the Basics tutorial out of Getting Started --- .../01_gettingStarted/01_quickstart.md | 5 +++- .../03_basics/50_locations.md | 24 ------------------- .../04_project/_category_.json | 3 --- .../03_basics => 02_basics}/01_physics.md | 0 .../03_basics => 02_basics}/02_state.md | 0 .../03_basics => 02_basics}/03_loop.md | 0 .../02_basics/04_project/_category_.json | 3 +++ .../04_project/index.md | 2 +- .../03_basics => 02_basics}/50_debugging.md | 0 .../typescript/02_basics/50_locations.md | 10 ++++++++ .../03_basics => 02_basics}/60_networking.md | 0 .../03_basics => 02_basics}/_50_networking.md | 0 .../_category_.json | 1 + .../03_basics => 02_basics}/index.md | 2 +- .../50_debugging.md | 0 .../50_engineCode.md | 0 .../50_projects.md | 0 .../50_state.md | 0 .../_category_.json | 1 - .../index.md | 0 20 files changed, 20 insertions(+), 31 deletions(-) delete mode 100644 docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md delete mode 100644 docs/developer/typescript/01_gettingStarted/04_project/_category_.json rename docs/developer/typescript/{01_gettingStarted/03_basics => 02_basics}/01_physics.md (100%) rename docs/developer/typescript/{01_gettingStarted/03_basics => 02_basics}/02_state.md (100%) rename docs/developer/typescript/{01_gettingStarted/03_basics => 02_basics}/03_loop.md (100%) create mode 100644 docs/developer/typescript/02_basics/04_project/_category_.json rename docs/developer/typescript/{01_gettingStarted => 02_basics}/04_project/index.md (95%) rename docs/developer/typescript/{01_gettingStarted/03_basics => 02_basics}/50_debugging.md (100%) create mode 100644 docs/developer/typescript/02_basics/50_locations.md rename docs/developer/typescript/{01_gettingStarted/03_basics => 02_basics}/60_networking.md (100%) rename docs/developer/typescript/{01_gettingStarted/03_basics => 02_basics}/_50_networking.md (100%) rename docs/developer/typescript/{02_beyondBasics => 02_basics}/_category_.json (95%) rename docs/developer/typescript/{01_gettingStarted/03_basics => 02_basics}/index.md (88%) rename docs/developer/typescript/{02_beyondBasics => 03_beyondBasics}/50_debugging.md (100%) rename docs/developer/typescript/{02_beyondBasics => 03_beyondBasics}/50_engineCode.md (100%) rename docs/developer/typescript/{02_beyondBasics => 03_beyondBasics}/50_projects.md (100%) rename docs/developer/typescript/{02_beyondBasics => 03_beyondBasics}/50_state.md (100%) rename docs/developer/typescript/{01_gettingStarted/03_basics => 03_beyondBasics}/_category_.json (95%) rename docs/developer/typescript/{02_beyondBasics => 03_beyondBasics}/index.md (100%) diff --git a/docs/developer/typescript/01_gettingStarted/01_quickstart.md b/docs/developer/typescript/01_gettingStarted/01_quickstart.md index 0f22a58e9923..cf56457a6390 100644 --- a/docs/developer/typescript/01_gettingStarted/01_quickstart.md +++ b/docs/developer/typescript/01_gettingStarted/01_quickstart.md @@ -25,5 +25,8 @@ Lets make sure that our `hello world` code is running: 1. Open the project from the Studio by clicking on its card 2. Create a new empty scene -You will know that the code is running if you can see a white sphere in the middle of the scene. +You will know that the code is running if you can see a white sphere in the middle of the scene. +:::note +You can also enter the scene and move around with an avatar by pressing the `Play` button in the editor. +::: diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md b/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md deleted file mode 100644 index b9efb145bff0..000000000000 --- a/docs/developer/typescript/01_gettingStarted/03_basics/50_locations.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: Locations ---- -# Our first Location - - -## Installing and running projects -Ethereal Engine can be extended with projects. -They are equivalent to "projects" in other engines, except they are modular like npm packages (they are npm packages too). - -Ethereal Engine scans for projects mounted in the `/packages/projects/projects` sub-folder of Ethereal Engine. - -From a bash shell in the Ethereal Engine folder we can install, run and visit a project with: -```bash -git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic -npm install -npm run dev -``` - -## Creating a Location -Once Ethereal Engine is running, from the web admin panel of Ethereal Engine create a 'location' for the scene. -- Navigate to https://localhost:3000/admin/locations. -- Map the scene to the name 'basic'. -- Run the project on the web by visiting it with the URL you just created: https://localhost:3000/location/basic diff --git a/docs/developer/typescript/01_gettingStarted/04_project/_category_.json b/docs/developer/typescript/01_gettingStarted/04_project/_category_.json deleted file mode 100644 index baf1ec9ea700..000000000000 --- a/docs/developer/typescript/01_gettingStarted/04_project/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 04, -} diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md b/docs/developer/typescript/02_basics/01_physics.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/03_basics/01_physics.md rename to docs/developer/typescript/02_basics/01_physics.md diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/02_state.md b/docs/developer/typescript/02_basics/02_state.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/03_basics/02_state.md rename to docs/developer/typescript/02_basics/02_state.md diff --git a/docs/developer/typescript/01_gettingStarted/03_basics/03_loop.md b/docs/developer/typescript/02_basics/03_loop.md similarity index 100% rename from docs/developer/typescript/01_gettingStarted/03_basics/03_loop.md rename to docs/developer/typescript/02_basics/03_loop.md diff --git a/docs/developer/typescript/02_basics/04_project/_category_.json b/docs/developer/typescript/02_basics/04_project/_category_.json new file mode 100644 index 000000000000..7a0f9830ac6e --- /dev/null +++ b/docs/developer/typescript/02_basics/04_project/_category_.json @@ -0,0 +1,3 @@ +{ + "position": 70, +} diff --git a/docs/developer/typescript/01_gettingStarted/04_project/index.md b/docs/developer/typescript/02_basics/04_project/index.md similarity index 95% rename from docs/developer/typescript/01_gettingStarted/04_project/index.md rename to docs/developer/typescript/02_basics/04_project/index.md index 874e05c6f3ab..4f5343853d32 100644 --- a/docs/developer/typescript/01_gettingStarted/04_project/index.md +++ b/docs/developer/typescript/02_basics/04_project/index.md @@ -1,4 +1,4 @@ -# Hero Tutorial +# Hero Project diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_system.md b/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md similarity index 81% rename from docs/developer/typescript/01_gettingStarted/02_hello/04_system.md rename to docs/developer/typescript/01_gettingStarted/02_hello/03_system.md index 1710242feb76..1e21de5b44ac 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_system.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md @@ -25,33 +25,12 @@ But we also broke Ethereal Engine's best practices in order to achieve that simp So, lets fix that. -The root of the problem is that we have created and modified our data inside the `worldInjection` function. -Mutation of data should always occur in a [Controlled Context](/manual/modules/engine/ecs), and the `worldInjection` function is not such. - -This is an even worse bad practices example, as it uses module scope to define and modify our entity. -```ts title="really/bad/practice.ts" showLineNumbers -import { ECS } from '@etherealengine/ecs' -import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' -import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' -import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' -import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' - -// highlight-start -// WARNING: Never do this -// Module scope should only ever be used for declarations. -const entity = ECS.createEntity() -ECS.setComponent(entity, NameComponent, 'hello-world') -ECS.setComponent(entity, VisibleComponent) -ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) -ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) -// highlight-end - -export default async function worldInjection() {} -``` +The root of the problem is that we have [created and modified](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) our data inside module scope. +This is an anti-pattern. [Data Mutation](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations should always occur in a [Controlled Context](/manual/modules/engine/ecs), and the module's top level scope is not such. ## Our first System -As we mentioned in the [ECS Pattern](../hello/ecs) section earlier, `Systems` are used to define the logic and behavior of our application. +As we mentioned in the [ECS Pattern](./ecs) section earlier, `Systems` are used to define the logic and behavior of our application. But, in order to make the example easier to understand, we cheated a little bit and broke the engine's best practices. The correct way to create the Sphere of our minimal example would be to: @@ -197,10 +176,5 @@ export const HelloWorldSystem = ECS.defineSystem({ insert: { after: PhysicsSystem } }) //highlight-end - -//highlight-start -// Note how we have moved all of our code outside of this function -//highlight-end -export default async function worldInjection() {} ``` diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md index b4a498c88c56..266042170251 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md @@ -1,10 +1,10 @@ --- -pagination_next: developer/typescript/gettingStarted/basics/physics +pagination_next: developer/typescript/basics/physics --- import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Congratulations! -You have just learned the very basics of working with Ethereal Engine using Typescript! +You have just learned the minimal basics of working with Ethereal Engine using Typescript! This was a very minimal introductory tutorial to get you started really quickly. But Ethereal Engine has a lot more features to explore! diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/index.md b/docs/developer/typescript/01_gettingStarted/02_hello/index.md index 235ccf0ceee6..dbd3a29ef1a8 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/index.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/index.md @@ -31,11 +31,9 @@ import { TransformComponent } from '@etherealengine/spatial/src/transform/compon import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' import { Vector3 } from 'three' -export default async function worldInjection() { - const entity = ECS.createEntity() - ECS.setComponent(entity, NameComponent, 'hello-world') - ECS.setComponent(entity, VisibleComponent) - ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) - ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) -} +const entity = ECS.createEntity() +ECS.setComponent(entity, NameComponent, 'hello-world') +ECS.setComponent(entity, VisibleComponent) +ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) +ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) ``` From 6ce170394bd9e033fc8a37bf623c4da93120133d Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 14 Feb 2024 21:00:24 -0800 Subject: [PATCH 57/96] new: Add HelloWorld/Component page sketch --- .../02_hello/04_component.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 docs/developer/typescript/01_gettingStarted/02_hello/04_component.md diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md new file mode 100644 index 000000000000..4a08640694e5 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -0,0 +1,30 @@ +# Components +Ok, lets admit the truth. +We have cheated with something else. + +You might have noticed already, but we are creating a Sphere for **every scene**. +Open any other project with the engine, and you will see that our ball is also there! +That's not good. Whoops. + + +## Our Problem +We have setup our Sphere code to be simple and minimal. +This is what we have done so far: +- We created a file called `src/Hello.ts` that contains our code +- We connected our code to the engine with the project's configuration file +- We defined a system at module scope using `defineSystem` +- We never defined our Sphere as a Component _(whoops)_ +- We never added our Sphere Component to a specific Scene + _(well, we didn't have a Sphere Component, so we couldn't)_ + +## Our Solution +The engine will run whatever code we send from our file as if it was part of the engine itself. + +The core issue is that our example is not using the engine API properly. +The execution of projects is global and meant to be data oriented. +But the data we’re relying on in the example is created within the project, instead of by actions from our users. +Our example, up until this point, is acting as if it was part of the Studio editor! + +The proper way would be to lock our logic behind a component. +What we should be doing, instead, is to create a custom Scene Component. +That way, when a component is added to an entity, the system can be activated through a query. From e79e0cd2d7b0d02cb7f02bfe7aada11b3f6ac823 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 15 Feb 2024 13:20:29 -0800 Subject: [PATCH 58/96] chg: Improvements to the HelloWorld/Component page --- .../01_gettingStarted/02_hello/02_engine.md | 39 +++++++++++++++---- .../02_hello/04_component.md | 23 +++++++---- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md index 7cd91bde15b7..9d514f11242e 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md @@ -5,26 +5,49 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Working with Ethereal Engine -## Installing and running projects -Ethereal Engine can be extended with projects. -They are equivalent to "projects" in other engines, except they are modular like npm packages (they are npm packages too). +You will need three very important steps for creating a project with Ethereal Engine: +1. Installing Ethereal Engine +2. Installing (or creating) a project +3. Modify and run the source code of your project + +We already solved #1 and #2 in the [Quickstart](../quickstart) guide. +Lets explore how #2 works and how we can start programming with the engine. -Ethereal Engine scans for projects mounted in the `/packages/projects/projects` sub-folder of Ethereal Engine. +## Installing and running projects +Ethereal Engine can be **extended** with projects. +They are equivalent to the concept of "projects" in other engines, except they are modular like npm packages _(they are npm packages too)_. -From a bash shell in the Ethereal Engine folder we can install, run and visit a project with: +The engine scans for projects mounted in the `/packages/projects/projects` sub-folder. +This means that, like we did earlier in the [Quickstart](../quickstart) guide, we can install and run new projects by executing the following commands inside our Ethereal Engine installation folder: ```bash -git clone https://github.com/EtherealEngine/ee-tutorial-basic packages/projects/packages/ee-tutorial-basic +git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/packages/ee-tutorial-hello npm install npm run dev ``` +These steps will: +- Download a copy of the project's git repository, so the engine can load it +- Install all `npm` packages required by the project +- Run a local development version of the engine + +:::note +This is also the process recommended for installation of your own projects. +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. +::: + +:::important +Each project's source code is executed globally. +This will become very important later on in this guide. +::: + + ## Programming with Ethereal Engine -We need to do two very important things in order to use Ethereal Engine for our project: +There are two very important steps to take in order to connect our project to the engine: - We need to import Ethereal Engine's modules - We need to export our code so the engine can load our project ### Project Configuration File Every project has an `xrengine.config.ts` file that defines how it will behave in the engine. -There are multiple options available, but the important one is that our `src/Hello.ts` code will connected to the engine from here. +There are multiple options available, but the important thing to remember is that our `src/Hello.ts` code will connected to the engine from here. ```ts title="ee-tutorial-hello/xrengine.config.ts" import type { ProjectConfigInterface } from '@etherealengine/projects/ProjectConfigInterface' diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md index 4a08640694e5..afec6b0e41eb 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -1,3 +1,5 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; + # Components Ok, lets admit the truth. We have cheated with something else. @@ -17,14 +19,19 @@ This is what we have done so far: - We never added our Sphere Component to a specific Scene _(well, we didn't have a Sphere Component, so we couldn't)_ +These two last steps are the key of our problem. +The reason is because the engine will execute projects globally, but we are not restricting our code to be run only when requested. +So our example, up until now, has been acting as if it was an extension to the Studio editor! + + +A more technical description of our problem is that our example is not using the engine API properly. +Execution of projects is global and meant to be data oriented. +But the data we’re relying on in our example is created within the project, instead of being triggered by actions from our users. + + ## Our Solution -The engine will run whatever code we send from our file as if it was part of the engine itself. +The proper way to add our simple Sphere would be to lock our logic behind a custom Scene Component. +That way, when a component is added to an entity, the system can be activated through a query. -The core issue is that our example is not using the engine API properly. -The execution of projects is global and meant to be data oriented. -But the data we’re relying on in the example is created within the project, instead of by actions from our users. -Our example, up until this point, is acting as if it was part of the Studio editor! -The proper way would be to lock our logic behind a component. -What we should be doing, instead, is to create a custom Scene Component. -That way, when a component is added to an entity, the system can be activated through a query. +## Creating a Custom Component From cfd6e195bcf8f5cd7bc9a97a9adf90cd3bc32b23 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:29:53 -0800 Subject: [PATCH 59/96] fix: Missing UnstyledDetails in the Basics section --- docs/developer/typescript/02_basics/01_physics.md | 5 +++-- docs/developer/typescript/02_basics/03_loop.md | 5 ++++- docs/developer/typescript/02_basics/60_networking.md | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/developer/typescript/02_basics/01_physics.md b/docs/developer/typescript/02_basics/01_physics.md index 574026bd654b..69684c750d42 100644 --- a/docs/developer/typescript/02_basics/01_physics.md +++ b/docs/developer/typescript/02_basics/01_physics.md @@ -2,6 +2,7 @@ sidebar_label: Physics --- import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Adding Physics So far we have learned how to create an `Entity`, and how to tell the engine what we want our entity to be. @@ -68,7 +69,7 @@ ECS.setComponent(entity, ColliderComponent, { shape: 'sphere' }) ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 3, 0) }) ``` - + ```ts import { ECS } from '@etherealengine/ecs' @@ -113,7 +114,7 @@ export const HelloWorldSystem = ECS.defineSystem({ export default async function worldInjection() {} ``` - + diff --git a/docs/developer/typescript/02_basics/03_loop.md b/docs/developer/typescript/02_basics/03_loop.md index 5ea6f4a25771..887f04d5fa19 100644 --- a/docs/developer/typescript/02_basics/03_loop.md +++ b/docs/developer/typescript/02_basics/03_loop.md @@ -1,4 +1,5 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Engine Loop - + + + diff --git a/docs/developer/typescript/02_basics/60_networking.md b/docs/developer/typescript/02_basics/60_networking.md index 0a97ecac6680..1a3c3a2bacf9 100644 --- a/docs/developer/typescript/02_basics/60_networking.md +++ b/docs/developer/typescript/02_basics/60_networking.md @@ -1,9 +1,11 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Networking - + + ```ts import React, { useEffect } from 'react' @@ -150,5 +152,6 @@ export const BasicSystem = defineSystem({ insert: { after: PresentationSystemGroup } }) ``` + From 80b5927e4a502c1ba79aaa9afbcb250ef0110a3b Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:30:55 -0800 Subject: [PATCH 60/96] doc: Add todo note to the HelloWorld/components page --- .../01_gettingStarted/02_hello/04_component.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md index afec6b0e41eb..f49718dbe31f 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -21,6 +21,7 @@ This is what we have done so far: These two last steps are the key of our problem. The reason is because the engine will execute projects globally, but we are not restricting our code to be run only when requested. + So our example, up until now, has been acting as if it was an extension to the Studio editor! @@ -35,3 +36,13 @@ That way, when a component is added to an entity, the system can be activated th ## Creating a Custom Component + + From c2d7fb615682ab37e7d14d975aaf060667300a2e Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 15 Feb 2024 22:00:42 -0800 Subject: [PATCH 61/96] chg: Improvements to the Quickstart guide --- docs/_partials/defaultProjects.md | 7 +++++++ .../typescript/01_gettingStarted/01_quickstart.md | 15 ++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 docs/_partials/defaultProjects.md diff --git a/docs/_partials/defaultProjects.md b/docs/_partials/defaultProjects.md new file mode 100644 index 000000000000..d0aef8926a2c --- /dev/null +++ b/docs/_partials/defaultProjects.md @@ -0,0 +1,7 @@ +Ethereal Engine has a few projects that are installed by default. +With the engine running, open the Studio by navigating to https://localhost:3000/studio, and you will see the engine's default projects listed in that page. + +Lets give them a test run: +- Open one of the default projects by clicking on its card +- Click on the `Play` button to enter the scene with an Avatar +- Move around the scene with `WASD` and/or clicking on the ground diff --git a/docs/developer/typescript/01_gettingStarted/01_quickstart.md b/docs/developer/typescript/01_gettingStarted/01_quickstart.md index cf56457a6390..b4e74648c89a 100644 --- a/docs/developer/typescript/01_gettingStarted/01_quickstart.md +++ b/docs/developer/typescript/01_gettingStarted/01_quickstart.md @@ -2,6 +2,7 @@ sidebar_label: Quickstart --- import UbuntuInstall from '../../../_partials/installUbuntu.md' +import DefaultProjects from '../../../_partials/defaultProjects.md' # Typescript Quickstart This QuickStart guide will teach you the basics of Ethereal Engine, and how to run the engine for the first time. @@ -9,18 +10,22 @@ This QuickStart guide will teach you the basics of Ethereal Engine, and how to r ## Installation -### Install and run the tutorial project +## Projects +### Default Projects + + +### Install and Run the tutorial project The previous command will have the engine running. -Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the Tutorial example template: +Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the tutorial's template project: ```bash -git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/packages/ee-tutorial-hello +git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello npm install npm run dev ``` -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 +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. -### Confirm the installation +## Confirm the installation Lets make sure that our `hello world` code is running: 1. Open the project from the Studio by clicking on its card 2. Create a new empty scene From b7d46e12a886ca413138f28a36ab0e66f1f65daa Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 15 Feb 2024 22:01:53 -0800 Subject: [PATCH 62/96] new: Intermediate Section structure/skeleton --- .../typescript/02_basics/04_inputs.md | 12 + .../typescript/02_basics/04_project/index.md | 9 + .../typescript/02_basics/60_networking.md | 149 +---------- .../typescript/02_basics/_50_networking.md | 78 ------ .../03_beyondBasics/01_dataDriven/50_state.md | 3 + .../01_dataDriven/_category_.yml | 1 + .../03_beyondBasics/01_dataDriven/index.md | 14 ++ .../50_continuousDevelopment/_category_.yml | 1 + .../50_continuousDevelopment/index.md | 19 ++ .../03_beyondBasics/50_engineCode.md | 1 - .../typescript/03_beyondBasics/50_state.md | 1 - .../03_beyondBasics/_category_.json | 3 - .../typescript/03_beyondBasics/_category_.yml | 1 + .../typescript/03_beyondBasics/index.md | 1 - .../04_ecs/01_components/_category_.yml | 1 + .../01_components}/index.md | 0 .../02_systems}/50_order/01_input.md | 0 .../02_systems}/50_order/02_simulation.md | 0 .../02_systems}/50_order/03_animation.md | 0 .../02_systems}/50_order/04_presentation.md | 0 .../04_ecs/02_systems/50_order/_category_.yml | 1 + .../02_systems}/50_order/index.md | 0 .../04_ecs/02_systems/_category_.yml | 1 + .../02_systems}/index.md | 2 +- .../04_ecs/03_queries/_category_.yml | 1 + .../typescript/04_ecs/03_queries/index.md | 4 + .../04_ecs/04_reactors/_category_.yml | 1 + .../typescript/04_ecs/04_reactors/index.md | 4 + .../04_ecs/05_eventSourcing/_category_.yml | 1 + .../04_ecs/05_eventSourcing/index.md | 4 + .../typescript/04_ecs/_category_.yml | 1 + docs/developer/typescript/04_ecs/index.md | 8 + .../typescript/40_inputs/_category_.yml | 1 + .../{50_inputs => 40_inputs}/index.md | 0 .../49_networking/_50_networking.md | 235 ++++++++++++++++++ .../typescript/49_networking/_category_.yml | 1 + .../typescript/49_networking/index.md | 14 ++ .../50_avatars/50_IK/_category_.yml | 1 + .../typescript/50_avatars/50_IK/index.md | 7 + .../50_avatars/50_animations/_category_.yml | 1 + .../50_avatars/50_animations/index.md | 7 + .../50_avatars/50_mocap/_category_.yml | 1 + .../{ => 50_avatars}/50_mocap/index.md | 0 .../50_avatars/50_retargetting/_category_.yml | 1 + .../50_avatars/50_retargetting/index.md | 7 + .../typescript/50_avatars/_category_.yml | 1 + docs/developer/typescript/50_avatars/index.md | 11 + .../typescript/50_components/01_file.md | 2 - .../typescript/50_components/02_file2.md | 2 - .../typescript/50_components/_category_.json | 3 - .../developer/typescript/50_inputs/01_file.md | 2 - .../typescript/50_inputs/02_file2.md | 2 - .../typescript/50_inputs/_category_.json | 3 - docs/developer/typescript/50_mocap/01_file.md | 2 - .../developer/typescript/50_mocap/02_file2.md | 2 - .../typescript/50_mocap/_category_.json | 3 - .../typescript/50_networking/01_file.md | 2 - .../typescript/50_networking/02_file2.md | 2 - .../typescript/50_networking/_category_.json | 3 - .../typescript/50_networking/index.md | 4 - .../50_systems/50_order/_category_.json | 3 - .../typescript/59_engineModules/01_file.md | 2 - .../typescript/59_engineModules/02_file2.md | 2 - .../59_engineModules/_category_.json | 3 - .../60_mastery/49_engineCode/01_api.md | 1 + .../49_engineCode/02_modules/_category_.yml | 1 + .../49_engineCode/02_modules}/index.md | 5 + .../60_mastery/49_engineCode/_category_.yml | 1 + .../60_mastery/49_engineCode/index.md | 8 + .../60_mastery/50_cms/_category_.yml | 1 + .../typescript/60_mastery/50_cms/index.md | 10 + .../60_mastery/50_gltf/_category_.yml | 1 + .../typescript/60_mastery/50_gltf/index.md | 8 + .../60_mastery/51_rendering/_category_.yml | 1 + .../60_mastery/51_rendering/index.md | 11 + .../60_mastery/60_cicd/_category_.yml | 1 + .../typescript/60_mastery/60_cicd/index.md | 5 + .../60_mastery/60_unittests/_category_.yml | 1 + .../60_mastery/60_unittests/index.md | 4 + .../typescript/60_mastery/_category_.yml | 1 + docs/developer/typescript/60_mastery/index.md | 11 + 81 files changed, 452 insertions(+), 271 deletions(-) create mode 100644 docs/developer/typescript/02_basics/04_inputs.md delete mode 100644 docs/developer/typescript/02_basics/_50_networking.md create mode 100644 docs/developer/typescript/03_beyondBasics/01_dataDriven/50_state.md create mode 100644 docs/developer/typescript/03_beyondBasics/01_dataDriven/_category_.yml create mode 100644 docs/developer/typescript/03_beyondBasics/01_dataDriven/index.md create mode 100644 docs/developer/typescript/03_beyondBasics/50_continuousDevelopment/_category_.yml create mode 100644 docs/developer/typescript/03_beyondBasics/50_continuousDevelopment/index.md delete mode 100644 docs/developer/typescript/03_beyondBasics/50_engineCode.md delete mode 100644 docs/developer/typescript/03_beyondBasics/50_state.md delete mode 100644 docs/developer/typescript/03_beyondBasics/_category_.json create mode 100644 docs/developer/typescript/03_beyondBasics/_category_.yml create mode 100644 docs/developer/typescript/04_ecs/01_components/_category_.yml rename docs/developer/typescript/{50_components => 04_ecs/01_components}/index.md (100%) rename docs/developer/typescript/{50_systems => 04_ecs/02_systems}/50_order/01_input.md (100%) rename docs/developer/typescript/{50_systems => 04_ecs/02_systems}/50_order/02_simulation.md (100%) rename docs/developer/typescript/{50_systems => 04_ecs/02_systems}/50_order/03_animation.md (100%) rename docs/developer/typescript/{50_systems => 04_ecs/02_systems}/50_order/04_presentation.md (100%) create mode 100644 docs/developer/typescript/04_ecs/02_systems/50_order/_category_.yml rename docs/developer/typescript/{50_systems => 04_ecs/02_systems}/50_order/index.md (100%) create mode 100644 docs/developer/typescript/04_ecs/02_systems/_category_.yml rename docs/developer/typescript/{50_systems => 04_ecs/02_systems}/index.md (80%) create mode 100644 docs/developer/typescript/04_ecs/03_queries/_category_.yml create mode 100644 docs/developer/typescript/04_ecs/03_queries/index.md create mode 100644 docs/developer/typescript/04_ecs/04_reactors/_category_.yml create mode 100644 docs/developer/typescript/04_ecs/04_reactors/index.md create mode 100644 docs/developer/typescript/04_ecs/05_eventSourcing/_category_.yml create mode 100644 docs/developer/typescript/04_ecs/05_eventSourcing/index.md create mode 100644 docs/developer/typescript/04_ecs/_category_.yml create mode 100644 docs/developer/typescript/04_ecs/index.md create mode 100644 docs/developer/typescript/40_inputs/_category_.yml rename docs/developer/typescript/{50_inputs => 40_inputs}/index.md (100%) create mode 100644 docs/developer/typescript/49_networking/_50_networking.md create mode 100644 docs/developer/typescript/49_networking/_category_.yml create mode 100644 docs/developer/typescript/49_networking/index.md create mode 100644 docs/developer/typescript/50_avatars/50_IK/_category_.yml create mode 100644 docs/developer/typescript/50_avatars/50_IK/index.md create mode 100644 docs/developer/typescript/50_avatars/50_animations/_category_.yml create mode 100644 docs/developer/typescript/50_avatars/50_animations/index.md create mode 100644 docs/developer/typescript/50_avatars/50_mocap/_category_.yml rename docs/developer/typescript/{ => 50_avatars}/50_mocap/index.md (100%) create mode 100644 docs/developer/typescript/50_avatars/50_retargetting/_category_.yml create mode 100644 docs/developer/typescript/50_avatars/50_retargetting/index.md create mode 100644 docs/developer/typescript/50_avatars/_category_.yml create mode 100644 docs/developer/typescript/50_avatars/index.md delete mode 100644 docs/developer/typescript/50_components/01_file.md delete mode 100644 docs/developer/typescript/50_components/02_file2.md delete mode 100644 docs/developer/typescript/50_components/_category_.json delete mode 100644 docs/developer/typescript/50_inputs/01_file.md delete mode 100644 docs/developer/typescript/50_inputs/02_file2.md delete mode 100644 docs/developer/typescript/50_inputs/_category_.json delete mode 100644 docs/developer/typescript/50_mocap/01_file.md delete mode 100644 docs/developer/typescript/50_mocap/02_file2.md delete mode 100644 docs/developer/typescript/50_mocap/_category_.json delete mode 100644 docs/developer/typescript/50_networking/01_file.md delete mode 100644 docs/developer/typescript/50_networking/02_file2.md delete mode 100644 docs/developer/typescript/50_networking/_category_.json delete mode 100644 docs/developer/typescript/50_networking/index.md delete mode 100644 docs/developer/typescript/50_systems/50_order/_category_.json delete mode 100644 docs/developer/typescript/59_engineModules/01_file.md delete mode 100644 docs/developer/typescript/59_engineModules/02_file2.md delete mode 100644 docs/developer/typescript/59_engineModules/_category_.json create mode 100644 docs/developer/typescript/60_mastery/49_engineCode/01_api.md create mode 100644 docs/developer/typescript/60_mastery/49_engineCode/02_modules/_category_.yml rename docs/developer/typescript/{59_engineModules => 60_mastery/49_engineCode/02_modules}/index.md (78%) create mode 100644 docs/developer/typescript/60_mastery/49_engineCode/_category_.yml create mode 100644 docs/developer/typescript/60_mastery/49_engineCode/index.md create mode 100644 docs/developer/typescript/60_mastery/50_cms/_category_.yml create mode 100644 docs/developer/typescript/60_mastery/50_cms/index.md create mode 100644 docs/developer/typescript/60_mastery/50_gltf/_category_.yml create mode 100644 docs/developer/typescript/60_mastery/50_gltf/index.md create mode 100644 docs/developer/typescript/60_mastery/51_rendering/_category_.yml create mode 100644 docs/developer/typescript/60_mastery/51_rendering/index.md create mode 100644 docs/developer/typescript/60_mastery/60_cicd/_category_.yml create mode 100644 docs/developer/typescript/60_mastery/60_cicd/index.md create mode 100644 docs/developer/typescript/60_mastery/60_unittests/_category_.yml create mode 100644 docs/developer/typescript/60_mastery/60_unittests/index.md create mode 100644 docs/developer/typescript/60_mastery/_category_.yml create mode 100644 docs/developer/typescript/60_mastery/index.md diff --git a/docs/developer/typescript/02_basics/04_inputs.md b/docs/developer/typescript/02_basics/04_inputs.md new file mode 100644 index 000000000000..81a6d201a844 --- /dev/null +++ b/docs/developer/typescript/02_basics/04_inputs.md @@ -0,0 +1,12 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; + +# Inputs + + + + + + diff --git a/docs/developer/typescript/02_basics/04_project/index.md b/docs/developer/typescript/02_basics/04_project/index.md index 4f5343853d32..9cdd31b2f005 100644 --- a/docs/developer/typescript/02_basics/04_project/index.md +++ b/docs/developer/typescript/02_basics/04_project/index.md @@ -4,4 +4,13 @@ NOTE: This page should contain: - Hero Project: Showcase for Ethereal Engine's development tools and workflows - Guide: Expands on the Basics tutorial, and teaches the user how to program the Hero Project and be comfortable with EE project development - Segue: Lead the user into the Beyond The Basics guide + +TODO: +- [ ] Third Person Camera Controller: Make the HelloSphere controllable with the camera+wasd +- [ ] Adding jump +- [ ] Collecting things +- [ ] Generating objects +- [ ] Pseudo-enemies that go towards you +- [ ] ... Steps +- [ ] _Future Ideal Project: Golf game_ --> diff --git a/docs/developer/typescript/02_basics/60_networking.md b/docs/developer/typescript/02_basics/60_networking.md index 1a3c3a2bacf9..3f607129fa63 100644 --- a/docs/developer/typescript/02_basics/60_networking.md +++ b/docs/developer/typescript/02_basics/60_networking.md @@ -2,155 +2,16 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Networking - + ```ts -import React, { useEffect } from 'react' - -import { - defineAction, - defineState, - dispatchAction, - getMutableState, - getState, - none, - useHookstate -} from '@etherealengine/hyperflux' - -import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' - -import { NetworkTopics } from '@etherealengine/spatial/src/networking/classes/Network' -import { WorldNetworkAction } from '@etherealengine/spatial/src/networking/functions/WorldNetworkAction' - -import { isClient } from '@etherealengine/common/src/utils/getEnvironment' -import { PresentationSystemGroup, defineSystem, getComponent, setComponent } from '@etherealengine/ecs' -import { ECSState } from '@etherealengine/ecs/src/ECSState' -import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' -import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' -import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' -import { UUIDComponent } from '@etherealengine/spatial/src/common/UUIDComponent' -import { NetworkState } from '@etherealengine/spatial/src/networking/NetworkState' -import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent' -import { RigidBodyComponent } from '@etherealengine/spatial/src/physics/components/RigidBodyComponent' -import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' -import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' -import { Vector3 } from 'three' - -/** - * Basic actions to spawn and destroy objects - * This extends and naturally utilizes the functionality in EntityNetworkState - */ - -const BasicActions = { - spawnAction: defineAction( - WorldNetworkAction.spawnObject.extend({ - type: 'ee.basic.SPAWN_BALL', - $topic: NetworkTopics.world - }) - ) -} - -/** - * Global state that tracks locally spawned or destroyed artifacts by using action receptors - */ - -const BasicState = defineState({ - name: 'ee.basic.BasicState', - - initial: {} as Record, - - receptors: { - onSpawnAction: BasicActions.spawnAction.receive((action) => { - const state = getMutableState(BasicState) - state[action.entityUUID].merge({}) - }), - onDestroyObject: WorldNetworkAction.destroyObject.receive((action) => { - const state = getMutableState(BasicState) - state[action.entityUUID].set(none) - }) - } -}) - -/** - * A reactor such that each basic state record has an associated a visual artifact - */ - -const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { - /** Entity creation and destruction is handled by EntityNetworkState */ - const entity = UUIDComponent.useEntityByUUID(entityUUID) - - useEffect(() => { - if (!entity) return - - setComponent(entity, TransformComponent, { scale: new Vector3(0.1, 0.1, 0.1) }) - setComponent(entity, VisibleComponent) - setComponent(entity, NameComponent, entityUUID) - setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) - setComponent(entity, RigidBodyComponent, { type: 'dynamic' }) - setComponent(entity, ColliderComponent, { shape: 'sphere' }) - - if (isClient) return - - const angle = Math.random() * Math.PI * 2 - const direction = new Vector3(Math.sin(angle), 0, Math.cos(angle)) - const velocity = 0.025 + Math.random() * 0.01 - getComponent(entity, RigidBodyComponent).body.applyImpulse(direction.multiplyScalar(velocity), true) - }, [entity]) - - return null -} - -/** - * Observe spawn events and create a sub-reactor for each entry in the basic state - */ - -const reactor = () => { - const basicState = useHookstate(getMutableState(BasicState)) - return ( - <> - {basicState.keys.map((entityUUID: EntityUUID) => ( - - ))} - - ) -} - -let counter = 0 -const spawnRate = 3 - -/** - * Spawn a new basic entity every 3 seconds - */ - -const execute = () => { - /** Only run this on the server */ - if (isClient || !NetworkState.worldNetwork) return - - const { deltaSeconds, elapsedSeconds } = getState(ECSState) - - counter += deltaSeconds - - if (counter < spawnRate) return - counter = 0 - - const entityUUID = `basic-${elapsedSeconds}` as EntityUUID - const action = BasicActions.spawnAction({ entityUUID, position: new Vector3(Math.random(), 1, Math.random()) }) - dispatchAction(action) -} - -/** - * System to register the execute function and reactor - */ - -export const BasicSystem = defineSystem({ - uuid: 'basic.system', - reactor, - execute, - insert: { after: PresentationSystemGroup } -}) +spawnEntity( ... ) ``` diff --git a/docs/developer/typescript/02_basics/_50_networking.md b/docs/developer/typescript/02_basics/_50_networking.md deleted file mode 100644 index 936402f06f46..000000000000 --- a/docs/developer/typescript/02_basics/_50_networking.md +++ /dev/null @@ -1,78 +0,0 @@ -# Networking -We're going to add networking to the `basic` example from the previous section. -Our goal is to deliver a shared and collaborative experience to many players at once. - -## Actions -First we want to think through what kinds of actions we want in our game. -For this tutorial we will allow the creation and destruction of simple objects over the network. - -In our case we can cheat a bit since destroying objects is common enough that there is a built in world networking event for it, and also for creating objects we can extend the built in world spawning event. - -This means that we need to define an action for creation: -```ts -const spawnAction = defineAction({ - ...WorldNetworkAction.spawnObject.actionShape, - prefab: 'ee.basic.ball', - $topic: NetworkTopics.world -}) -``` - -## State -Ethereal Engine uses an 'event sourced state' paradigm for networking. That means that as a developer you publish an event and that event is performed by all instances simultaneously. - -Typically actions are going to affect state. For this example we will declare that we're going to allow any number of objects, each with their own appearance. We define state in a React like way like so: - -```ts -export const BasicState = defineState({ - name: 'ee.basic.BasicState', - initial: {} as Record< EntityUUID, {} >, - ... -``` - -### Receptors -Finally for this phase we want to define handlers or receptors to handle the event. -These are by convention stored on the state itself: -```ts - ... - receptors: [ - [ - spawnAction, - (state, action: typeof spawnAction.matches._TYPE) => { - state[action.entityUUID].merge({}) - } - ], - [ - WorldNetworkAction.destroyObject, - (state, action: typeof WorldNetworkAction.destroyObject.matches._TYPE) => { - state[action.entityUUID].set(none) - } - ] - ] -``` - -### Dispatching new events -We can spawn entities now like so at any time: - -```ts -dispatchAction(spawnAction({ entityUUID:'my-entity' })) -``` - -### Rendering State - -Once state is being networked we want to visualize that state. The react pattern is to allow state changes to occur and then 'react' to them - creating visual objects that reflect the state database: - -```ts -const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { - const basicState = useHookstate(getMutableState(BasicState)[entityUUID]) - useEffect(() => { - const entity = UUIDComponent.getEntityByUUID(entityUUID) - setComponent(entity, TransformComponent) - setComponent(entity, VisibleComponent) - setComponent(entity, NameComponent,'hello') - setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) -``` - -## Closing -This example is simple, but these are the building blocks and foundations for creating richer and more complex experiences. -The source code for this example from https://github.com/etherealengine/ee-tutorial-basic - diff --git a/docs/developer/typescript/03_beyondBasics/01_dataDriven/50_state.md b/docs/developer/typescript/03_beyondBasics/01_dataDriven/50_state.md new file mode 100644 index 000000000000..4662eedd0e58 --- /dev/null +++ b/docs/developer/typescript/03_beyondBasics/01_dataDriven/50_state.md @@ -0,0 +1,3 @@ +# State Management +- [ ] State management +- [ ] New synchronous state API diff --git a/docs/developer/typescript/03_beyondBasics/01_dataDriven/_category_.yml b/docs/developer/typescript/03_beyondBasics/01_dataDriven/_category_.yml new file mode 100644 index 000000000000..d6b968359e12 --- /dev/null +++ b/docs/developer/typescript/03_beyondBasics/01_dataDriven/_category_.yml @@ -0,0 +1 @@ +position: 01 diff --git a/docs/developer/typescript/03_beyondBasics/01_dataDriven/index.md b/docs/developer/typescript/03_beyondBasics/01_dataDriven/index.md new file mode 100644 index 000000000000..0c4d3eaeb5ec --- /dev/null +++ b/docs/developer/typescript/03_beyondBasics/01_dataDriven/index.md @@ -0,0 +1,14 @@ + +import DocCardList from '@theme/DocCardList' + +# Data Driven Development + + + diff --git a/docs/developer/typescript/03_beyondBasics/50_continuousDevelopment/_category_.yml b/docs/developer/typescript/03_beyondBasics/50_continuousDevelopment/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/03_beyondBasics/50_continuousDevelopment/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/03_beyondBasics/50_continuousDevelopment/index.md b/docs/developer/typescript/03_beyondBasics/50_continuousDevelopment/index.md new file mode 100644 index 000000000000..54ba8e7c4828 --- /dev/null +++ b/docs/developer/typescript/03_beyondBasics/50_continuousDevelopment/index.md @@ -0,0 +1,19 @@ +# Continuous Development + diff --git a/docs/developer/typescript/03_beyondBasics/50_engineCode.md b/docs/developer/typescript/03_beyondBasics/50_engineCode.md deleted file mode 100644 index aefa412924bf..000000000000 --- a/docs/developer/typescript/03_beyondBasics/50_engineCode.md +++ /dev/null @@ -1 +0,0 @@ -# Engine Code Navigation diff --git a/docs/developer/typescript/03_beyondBasics/50_state.md b/docs/developer/typescript/03_beyondBasics/50_state.md deleted file mode 100644 index e2937def93eb..000000000000 --- a/docs/developer/typescript/03_beyondBasics/50_state.md +++ /dev/null @@ -1 +0,0 @@ -# State Management diff --git a/docs/developer/typescript/03_beyondBasics/_category_.json b/docs/developer/typescript/03_beyondBasics/_category_.json deleted file mode 100644 index a152b4458920..000000000000 --- a/docs/developer/typescript/03_beyondBasics/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 03, -} diff --git a/docs/developer/typescript/03_beyondBasics/_category_.yml b/docs/developer/typescript/03_beyondBasics/_category_.yml new file mode 100644 index 000000000000..25aa7709d1ec --- /dev/null +++ b/docs/developer/typescript/03_beyondBasics/_category_.yml @@ -0,0 +1 @@ +position: 03 diff --git a/docs/developer/typescript/03_beyondBasics/index.md b/docs/developer/typescript/03_beyondBasics/index.md index 2c18c74d891a..698c79ce99d7 100644 --- a/docs/developer/typescript/03_beyondBasics/index.md +++ b/docs/developer/typescript/03_beyondBasics/index.md @@ -1,4 +1,3 @@ - import DocCardList from '@theme/DocCardList' # Beyond the Basics diff --git a/docs/developer/typescript/04_ecs/01_components/_category_.yml b/docs/developer/typescript/04_ecs/01_components/_category_.yml new file mode 100644 index 000000000000..d6b968359e12 --- /dev/null +++ b/docs/developer/typescript/04_ecs/01_components/_category_.yml @@ -0,0 +1 @@ +position: 01 diff --git a/docs/developer/typescript/50_components/index.md b/docs/developer/typescript/04_ecs/01_components/index.md similarity index 100% rename from docs/developer/typescript/50_components/index.md rename to docs/developer/typescript/04_ecs/01_components/index.md diff --git a/docs/developer/typescript/50_systems/50_order/01_input.md b/docs/developer/typescript/04_ecs/02_systems/50_order/01_input.md similarity index 100% rename from docs/developer/typescript/50_systems/50_order/01_input.md rename to docs/developer/typescript/04_ecs/02_systems/50_order/01_input.md diff --git a/docs/developer/typescript/50_systems/50_order/02_simulation.md b/docs/developer/typescript/04_ecs/02_systems/50_order/02_simulation.md similarity index 100% rename from docs/developer/typescript/50_systems/50_order/02_simulation.md rename to docs/developer/typescript/04_ecs/02_systems/50_order/02_simulation.md diff --git a/docs/developer/typescript/50_systems/50_order/03_animation.md b/docs/developer/typescript/04_ecs/02_systems/50_order/03_animation.md similarity index 100% rename from docs/developer/typescript/50_systems/50_order/03_animation.md rename to docs/developer/typescript/04_ecs/02_systems/50_order/03_animation.md diff --git a/docs/developer/typescript/50_systems/50_order/04_presentation.md b/docs/developer/typescript/04_ecs/02_systems/50_order/04_presentation.md similarity index 100% rename from docs/developer/typescript/50_systems/50_order/04_presentation.md rename to docs/developer/typescript/04_ecs/02_systems/50_order/04_presentation.md diff --git a/docs/developer/typescript/04_ecs/02_systems/50_order/_category_.yml b/docs/developer/typescript/04_ecs/02_systems/50_order/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/04_ecs/02_systems/50_order/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/50_systems/50_order/index.md b/docs/developer/typescript/04_ecs/02_systems/50_order/index.md similarity index 100% rename from docs/developer/typescript/50_systems/50_order/index.md rename to docs/developer/typescript/04_ecs/02_systems/50_order/index.md diff --git a/docs/developer/typescript/04_ecs/02_systems/_category_.yml b/docs/developer/typescript/04_ecs/02_systems/_category_.yml new file mode 100644 index 000000000000..e34d8cd3b323 --- /dev/null +++ b/docs/developer/typescript/04_ecs/02_systems/_category_.yml @@ -0,0 +1 @@ +position: 02 diff --git a/docs/developer/typescript/50_systems/index.md b/docs/developer/typescript/04_ecs/02_systems/index.md similarity index 80% rename from docs/developer/typescript/50_systems/index.md rename to docs/developer/typescript/04_ecs/02_systems/index.md index b00e1a44b963..165d80b94ef2 100644 --- a/docs/developer/typescript/50_systems/index.md +++ b/docs/developer/typescript/04_ecs/02_systems/index.md @@ -4,6 +4,6 @@ sidebar_label: Systems import DocCardList from '@theme/DocCardList' -# Systems Guide +# Working with Systems diff --git a/docs/developer/typescript/04_ecs/03_queries/_category_.yml b/docs/developer/typescript/04_ecs/03_queries/_category_.yml new file mode 100644 index 000000000000..25aa7709d1ec --- /dev/null +++ b/docs/developer/typescript/04_ecs/03_queries/_category_.yml @@ -0,0 +1 @@ +position: 03 diff --git a/docs/developer/typescript/04_ecs/03_queries/index.md b/docs/developer/typescript/04_ecs/03_queries/index.md new file mode 100644 index 000000000000..2a60cf1823a1 --- /dev/null +++ b/docs/developer/typescript/04_ecs/03_queries/index.md @@ -0,0 +1,4 @@ +# Queries + diff --git a/docs/developer/typescript/04_ecs/04_reactors/_category_.yml b/docs/developer/typescript/04_ecs/04_reactors/_category_.yml new file mode 100644 index 000000000000..25aa7709d1ec --- /dev/null +++ b/docs/developer/typescript/04_ecs/04_reactors/_category_.yml @@ -0,0 +1 @@ +position: 03 diff --git a/docs/developer/typescript/04_ecs/04_reactors/index.md b/docs/developer/typescript/04_ecs/04_reactors/index.md new file mode 100644 index 000000000000..a31e0eb5331c --- /dev/null +++ b/docs/developer/typescript/04_ecs/04_reactors/index.md @@ -0,0 +1,4 @@ +# Reactors + diff --git a/docs/developer/typescript/04_ecs/05_eventSourcing/_category_.yml b/docs/developer/typescript/04_ecs/05_eventSourcing/_category_.yml new file mode 100644 index 000000000000..25aa7709d1ec --- /dev/null +++ b/docs/developer/typescript/04_ecs/05_eventSourcing/_category_.yml @@ -0,0 +1 @@ +position: 03 diff --git a/docs/developer/typescript/04_ecs/05_eventSourcing/index.md b/docs/developer/typescript/04_ecs/05_eventSourcing/index.md new file mode 100644 index 000000000000..b027acc06908 --- /dev/null +++ b/docs/developer/typescript/04_ecs/05_eventSourcing/index.md @@ -0,0 +1,4 @@ +# Event Sourcing + diff --git a/docs/developer/typescript/04_ecs/_category_.yml b/docs/developer/typescript/04_ecs/_category_.yml new file mode 100644 index 000000000000..081f18c43c06 --- /dev/null +++ b/docs/developer/typescript/04_ecs/_category_.yml @@ -0,0 +1 @@ +position: 04 diff --git a/docs/developer/typescript/04_ecs/index.md b/docs/developer/typescript/04_ecs/index.md new file mode 100644 index 000000000000..47562a6f1ea9 --- /dev/null +++ b/docs/developer/typescript/04_ecs/index.md @@ -0,0 +1,8 @@ +import DocCardList from '@theme/DocCardList' + +# Entity Component System + + + diff --git a/docs/developer/typescript/40_inputs/_category_.yml b/docs/developer/typescript/40_inputs/_category_.yml new file mode 100644 index 000000000000..c3c5db22d9fc --- /dev/null +++ b/docs/developer/typescript/40_inputs/_category_.yml @@ -0,0 +1 @@ +position: 40 diff --git a/docs/developer/typescript/50_inputs/index.md b/docs/developer/typescript/40_inputs/index.md similarity index 100% rename from docs/developer/typescript/50_inputs/index.md rename to docs/developer/typescript/40_inputs/index.md diff --git a/docs/developer/typescript/49_networking/_50_networking.md b/docs/developer/typescript/49_networking/_50_networking.md new file mode 100644 index 000000000000..20a71cd90d21 --- /dev/null +++ b/docs/developer/typescript/49_networking/_50_networking.md @@ -0,0 +1,235 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; + +# Networking +We're going to add networking to the `basic` example from the previous section. +Our goal is to deliver a shared and collaborative experience to many players at once. + +## Actions +First we want to think through what kinds of actions we want in our game. +For this tutorial we will allow the creation and destruction of simple objects over the network. + +In our case we can cheat a bit since destroying objects is common enough that there is a built in world networking event for it, and also for creating objects we can extend the built in world spawning event. + +This means that we need to define an action for creation: +```ts +const spawnAction = defineAction({ + ...WorldNetworkAction.spawnObject.actionShape, + prefab: 'ee.basic.ball', + $topic: NetworkTopics.world +}) +``` + +## State +Ethereal Engine uses an 'event sourced state' paradigm for networking. That means that as a developer you publish an event and that event is performed by all instances simultaneously. + +Typically actions are going to affect state. For this example we will declare that we're going to allow any number of objects, each with their own appearance. We define state in a React like way like so: + +```ts +export const BasicState = defineState({ + name: 'ee.basic.BasicState', + initial: {} as Record< EntityUUID, {} >, + ... +``` + +### Receptors +Finally for this phase we want to define handlers or receptors to handle the event. +These are by convention stored on the state itself: +```ts + ... + receptors: [ + [ + spawnAction, + (state, action: typeof spawnAction.matches._TYPE) => { + state[action.entityUUID].merge({}) + } + ], + [ + WorldNetworkAction.destroyObject, + (state, action: typeof WorldNetworkAction.destroyObject.matches._TYPE) => { + state[action.entityUUID].set(none) + } + ] + ] +``` + +### Dispatching new events +We can spawn entities now like so at any time: + +```ts +dispatchAction(spawnAction({ entityUUID:'my-entity' })) +``` + +### Rendering State + +Once state is being networked we want to visualize that state. The react pattern is to allow state changes to occur and then 'react' to them - creating visual objects that reflect the state database: + +```ts +const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { + const basicState = useHookstate(getMutableState(BasicState)[entityUUID]) + useEffect(() => { + const entity = UUIDComponent.getEntityByUUID(entityUUID) + setComponent(entity, TransformComponent) + setComponent(entity, VisibleComponent) + setComponent(entity, NameComponent,'hello') + setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) +``` + +## Closing +This example is simple, but these are the building blocks and foundations for creating richer and more complex experiences. +The source code for this example from https://github.com/etherealengine/ee-tutorial-basic + + + + + + + +```ts +import React, { useEffect } from 'react' + +import { + defineAction, + defineState, + dispatchAction, + getMutableState, + getState, + none, + useHookstate +} from '@etherealengine/hyperflux' + +import { EntityUUID } from '@etherealengine/common/src/interfaces/EntityUUID' + +import { NetworkTopics } from '@etherealengine/spatial/src/networking/classes/Network' +import { WorldNetworkAction } from '@etherealengine/spatial/src/networking/functions/WorldNetworkAction' + +import { isClient } from '@etherealengine/common/src/utils/getEnvironment' +import { PresentationSystemGroup, defineSystem, getComponent, setComponent } from '@etherealengine/ecs' +import { ECSState } from '@etherealengine/ecs/src/ECSState' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { UUIDComponent } from '@etherealengine/spatial/src/common/UUIDComponent' +import { NetworkState } from '@etherealengine/spatial/src/networking/NetworkState' +import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent' +import { RigidBodyComponent } from '@etherealengine/spatial/src/physics/components/RigidBodyComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { Vector3 } from 'three' + +/** + * Basic actions to spawn and destroy objects + * This extends and naturally utilizes the functionality in EntityNetworkState + */ + +const BasicActions = { + spawnAction: defineAction( + WorldNetworkAction.spawnObject.extend({ + type: 'ee.basic.SPAWN_BALL', + $topic: NetworkTopics.world + }) + ) +} + +/** + * Global state that tracks locally spawned or destroyed artifacts by using action receptors + */ + +const BasicState = defineState({ + name: 'ee.basic.BasicState', + + initial: {} as Record, + + receptors: { + onSpawnAction: BasicActions.spawnAction.receive((action) => { + const state = getMutableState(BasicState) + state[action.entityUUID].merge({}) + }), + onDestroyObject: WorldNetworkAction.destroyObject.receive((action) => { + const state = getMutableState(BasicState) + state[action.entityUUID].set(none) + }) + } +}) + +/** + * A reactor such that each basic state record has an associated a visual artifact + */ + +const ArtifactReactor = ({ entityUUID }: { entityUUID: EntityUUID }) => { + /** Entity creation and destruction is handled by EntityNetworkState */ + const entity = UUIDComponent.useEntityByUUID(entityUUID) + + useEffect(() => { + if (!entity) return + + setComponent(entity, TransformComponent, { scale: new Vector3(0.1, 0.1, 0.1) }) + setComponent(entity, VisibleComponent) + setComponent(entity, NameComponent, entityUUID) + setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + setComponent(entity, RigidBodyComponent, { type: 'dynamic' }) + setComponent(entity, ColliderComponent, { shape: 'sphere' }) + + if (isClient) return + + const angle = Math.random() * Math.PI * 2 + const direction = new Vector3(Math.sin(angle), 0, Math.cos(angle)) + const velocity = 0.025 + Math.random() * 0.01 + getComponent(entity, RigidBodyComponent).body.applyImpulse(direction.multiplyScalar(velocity), true) + }, [entity]) + + return null +} + +/** + * Observe spawn events and create a sub-reactor for each entry in the basic state + */ + +const reactor = () => { + const basicState = useHookstate(getMutableState(BasicState)) + return ( + <> + {basicState.keys.map((entityUUID: EntityUUID) => ( + + ))} + + ) +} + +let counter = 0 +const spawnRate = 3 + +/** + * Spawn a new basic entity every 3 seconds + */ + +const execute = () => { + /** Only run this on the server */ + if (isClient || !NetworkState.worldNetwork) return + + const { deltaSeconds, elapsedSeconds } = getState(ECSState) + + counter += deltaSeconds + + if (counter < spawnRate) return + counter = 0 + + const entityUUID = `basic-${elapsedSeconds}` as EntityUUID + const action = BasicActions.spawnAction({ entityUUID, position: new Vector3(Math.random(), 1, Math.random()) }) + dispatchAction(action) +} + +/** + * System to register the execute function and reactor + */ + +export const BasicSystem = defineSystem({ + uuid: 'basic.system', + reactor, + execute, + insert: { after: PresentationSystemGroup } +}) +``` + + + diff --git a/docs/developer/typescript/49_networking/_category_.yml b/docs/developer/typescript/49_networking/_category_.yml new file mode 100644 index 000000000000..35d19d002bc0 --- /dev/null +++ b/docs/developer/typescript/49_networking/_category_.yml @@ -0,0 +1 @@ +position: 49 diff --git a/docs/developer/typescript/49_networking/index.md b/docs/developer/typescript/49_networking/index.md new file mode 100644 index 000000000000..5c820b43062d --- /dev/null +++ b/docs/developer/typescript/49_networking/index.md @@ -0,0 +1,14 @@ +--- +sidebar_label: Advanced Networking +--- +import DocCardList from '@theme/DocCardList' + +# Advanced Networking Guide + + + diff --git a/docs/developer/typescript/50_avatars/50_IK/_category_.yml b/docs/developer/typescript/50_avatars/50_IK/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/50_avatars/50_IK/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/50_avatars/50_IK/index.md b/docs/developer/typescript/50_avatars/50_IK/index.md new file mode 100644 index 000000000000..81c5d41e4354 --- /dev/null +++ b/docs/developer/typescript/50_avatars/50_IK/index.md @@ -0,0 +1,7 @@ +--- +sidebar_label: Inverse Kinematics +--- +# Inverse Kinematics Guide + diff --git a/docs/developer/typescript/50_avatars/50_animations/_category_.yml b/docs/developer/typescript/50_avatars/50_animations/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/50_avatars/50_animations/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/50_avatars/50_animations/index.md b/docs/developer/typescript/50_avatars/50_animations/index.md new file mode 100644 index 000000000000..41cfca6f3727 --- /dev/null +++ b/docs/developer/typescript/50_avatars/50_animations/index.md @@ -0,0 +1,7 @@ +--- +sidebar_label: Animations +--- +# Animations Guide + diff --git a/docs/developer/typescript/50_avatars/50_mocap/_category_.yml b/docs/developer/typescript/50_avatars/50_mocap/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/50_avatars/50_mocap/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/50_mocap/index.md b/docs/developer/typescript/50_avatars/50_mocap/index.md similarity index 100% rename from docs/developer/typescript/50_mocap/index.md rename to docs/developer/typescript/50_avatars/50_mocap/index.md diff --git a/docs/developer/typescript/50_avatars/50_retargetting/_category_.yml b/docs/developer/typescript/50_avatars/50_retargetting/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/50_avatars/50_retargetting/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/50_avatars/50_retargetting/index.md b/docs/developer/typescript/50_avatars/50_retargetting/index.md new file mode 100644 index 000000000000..d187a988175c --- /dev/null +++ b/docs/developer/typescript/50_avatars/50_retargetting/index.md @@ -0,0 +1,7 @@ +--- +sidebar_label: Retargetting +--- +# Retargetting Guide + diff --git a/docs/developer/typescript/50_avatars/_category_.yml b/docs/developer/typescript/50_avatars/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/50_avatars/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/50_avatars/index.md b/docs/developer/typescript/50_avatars/index.md new file mode 100644 index 000000000000..6b1de3bd1c44 --- /dev/null +++ b/docs/developer/typescript/50_avatars/index.md @@ -0,0 +1,11 @@ +--- +sidebar_label: Avatars +--- +import DocCardList from '@theme/DocCardList' + +# Avatars Guide + + + diff --git a/docs/developer/typescript/50_components/01_file.md b/docs/developer/typescript/50_components/01_file.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/50_components/01_file.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_components/02_file2.md b/docs/developer/typescript/50_components/02_file2.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/50_components/02_file2.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_components/_category_.json b/docs/developer/typescript/50_components/_category_.json deleted file mode 100644 index 6811f84d171d..000000000000 --- a/docs/developer/typescript/50_components/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 50, -} diff --git a/docs/developer/typescript/50_inputs/01_file.md b/docs/developer/typescript/50_inputs/01_file.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/50_inputs/01_file.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_inputs/02_file2.md b/docs/developer/typescript/50_inputs/02_file2.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/50_inputs/02_file2.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_inputs/_category_.json b/docs/developer/typescript/50_inputs/_category_.json deleted file mode 100644 index 6811f84d171d..000000000000 --- a/docs/developer/typescript/50_inputs/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 50, -} diff --git a/docs/developer/typescript/50_mocap/01_file.md b/docs/developer/typescript/50_mocap/01_file.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/50_mocap/01_file.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_mocap/02_file2.md b/docs/developer/typescript/50_mocap/02_file2.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/50_mocap/02_file2.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_mocap/_category_.json b/docs/developer/typescript/50_mocap/_category_.json deleted file mode 100644 index 6811f84d171d..000000000000 --- a/docs/developer/typescript/50_mocap/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 50, -} diff --git a/docs/developer/typescript/50_networking/01_file.md b/docs/developer/typescript/50_networking/01_file.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/50_networking/01_file.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_networking/02_file2.md b/docs/developer/typescript/50_networking/02_file2.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/50_networking/02_file2.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/50_networking/_category_.json b/docs/developer/typescript/50_networking/_category_.json deleted file mode 100644 index 6811f84d171d..000000000000 --- a/docs/developer/typescript/50_networking/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 50, -} diff --git a/docs/developer/typescript/50_networking/index.md b/docs/developer/typescript/50_networking/index.md deleted file mode 100644 index c1ffbc39cbdd..000000000000 --- a/docs/developer/typescript/50_networking/index.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -sidebar_label: Networking ---- -# Networking Guide diff --git a/docs/developer/typescript/50_systems/50_order/_category_.json b/docs/developer/typescript/50_systems/50_order/_category_.json deleted file mode 100644 index 6811f84d171d..000000000000 --- a/docs/developer/typescript/50_systems/50_order/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 50, -} diff --git a/docs/developer/typescript/59_engineModules/01_file.md b/docs/developer/typescript/59_engineModules/01_file.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/59_engineModules/01_file.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/59_engineModules/02_file2.md b/docs/developer/typescript/59_engineModules/02_file2.md deleted file mode 100644 index 7db4cab12c85..000000000000 --- a/docs/developer/typescript/59_engineModules/02_file2.md +++ /dev/null @@ -1,2 +0,0 @@ -# Topic -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat reprehenderit commodo officia dolor Lorem duis laboris cupidatat officia voluptate. Culpa proident adipisicing id nulla nisi laboris ex in Lorem sunt duis officia eiusmod. Aliqua reprehenderit commodo ex non excepteur duis sunt velit enim. Voluptate laboris sint cupidatat ullamco ut ea consectetur et est culpa et culpa duis. diff --git a/docs/developer/typescript/59_engineModules/_category_.json b/docs/developer/typescript/59_engineModules/_category_.json deleted file mode 100644 index 6811f84d171d..000000000000 --- a/docs/developer/typescript/59_engineModules/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "position": 50, -} diff --git a/docs/developer/typescript/60_mastery/49_engineCode/01_api.md b/docs/developer/typescript/60_mastery/49_engineCode/01_api.md new file mode 100644 index 000000000000..8d577b12a974 --- /dev/null +++ b/docs/developer/typescript/60_mastery/49_engineCode/01_api.md @@ -0,0 +1 @@ +# Reference API diff --git a/docs/developer/typescript/60_mastery/49_engineCode/02_modules/_category_.yml b/docs/developer/typescript/60_mastery/49_engineCode/02_modules/_category_.yml new file mode 100644 index 000000000000..e34d8cd3b323 --- /dev/null +++ b/docs/developer/typescript/60_mastery/49_engineCode/02_modules/_category_.yml @@ -0,0 +1 @@ +position: 02 diff --git a/docs/developer/typescript/59_engineModules/index.md b/docs/developer/typescript/60_mastery/49_engineCode/02_modules/index.md similarity index 78% rename from docs/developer/typescript/59_engineModules/index.md rename to docs/developer/typescript/60_mastery/49_engineCode/02_modules/index.md index 2964a3b22e2a..45ad0bb27838 100644 --- a/docs/developer/typescript/59_engineModules/index.md +++ b/docs/developer/typescript/60_mastery/49_engineCode/02_modules/index.md @@ -1,3 +1,5 @@ +import DocCardList from '@theme/DocCardList'; + # Engine Modules Guide + diff --git a/docs/developer/typescript/60_mastery/49_engineCode/_category_.yml b/docs/developer/typescript/60_mastery/49_engineCode/_category_.yml new file mode 100644 index 000000000000..35d19d002bc0 --- /dev/null +++ b/docs/developer/typescript/60_mastery/49_engineCode/_category_.yml @@ -0,0 +1 @@ +position: 49 diff --git a/docs/developer/typescript/60_mastery/49_engineCode/index.md b/docs/developer/typescript/60_mastery/49_engineCode/index.md new file mode 100644 index 000000000000..6a458c7b8de2 --- /dev/null +++ b/docs/developer/typescript/60_mastery/49_engineCode/index.md @@ -0,0 +1,8 @@ +import DocCardList from '@theme/DocCardList'; + +# Engine Code Navigation + + + diff --git a/docs/developer/typescript/60_mastery/50_cms/_category_.yml b/docs/developer/typescript/60_mastery/50_cms/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/60_mastery/50_cms/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/60_mastery/50_cms/index.md b/docs/developer/typescript/60_mastery/50_cms/index.md new file mode 100644 index 000000000000..24fd225b5888 --- /dev/null +++ b/docs/developer/typescript/60_mastery/50_cms/index.md @@ -0,0 +1,10 @@ +--- +sidebar_label: CMS +--- +# CMS Guide + +## Projects +## Assets diff --git a/docs/developer/typescript/60_mastery/50_gltf/_category_.yml b/docs/developer/typescript/60_mastery/50_gltf/_category_.yml new file mode 100644 index 000000000000..222dfff00c2f --- /dev/null +++ b/docs/developer/typescript/60_mastery/50_gltf/_category_.yml @@ -0,0 +1 @@ +position: 50 diff --git a/docs/developer/typescript/60_mastery/50_gltf/index.md b/docs/developer/typescript/60_mastery/50_gltf/index.md new file mode 100644 index 000000000000..292a8e1c6db0 --- /dev/null +++ b/docs/developer/typescript/60_mastery/50_gltf/index.md @@ -0,0 +1,8 @@ +--- +sidebar_label: glTF +--- +# glTF Guide + diff --git a/docs/developer/typescript/60_mastery/51_rendering/_category_.yml b/docs/developer/typescript/60_mastery/51_rendering/_category_.yml new file mode 100644 index 000000000000..4966be4313e4 --- /dev/null +++ b/docs/developer/typescript/60_mastery/51_rendering/_category_.yml @@ -0,0 +1 @@ +position: 51 diff --git a/docs/developer/typescript/60_mastery/51_rendering/index.md b/docs/developer/typescript/60_mastery/51_rendering/index.md new file mode 100644 index 000000000000..6126ef56116a --- /dev/null +++ b/docs/developer/typescript/60_mastery/51_rendering/index.md @@ -0,0 +1,11 @@ +--- +sidebar_label: Rendering +--- +# Rendering Guide + diff --git a/docs/developer/typescript/60_mastery/60_cicd/_category_.yml b/docs/developer/typescript/60_mastery/60_cicd/_category_.yml new file mode 100644 index 000000000000..4966be4313e4 --- /dev/null +++ b/docs/developer/typescript/60_mastery/60_cicd/_category_.yml @@ -0,0 +1 @@ +position: 51 diff --git a/docs/developer/typescript/60_mastery/60_cicd/index.md b/docs/developer/typescript/60_mastery/60_cicd/index.md new file mode 100644 index 000000000000..c68305f4f80f --- /dev/null +++ b/docs/developer/typescript/60_mastery/60_cicd/index.md @@ -0,0 +1,5 @@ +# CI/CD + + diff --git a/docs/developer/typescript/60_mastery/60_unittests/_category_.yml b/docs/developer/typescript/60_mastery/60_unittests/_category_.yml new file mode 100644 index 000000000000..4c983da94092 --- /dev/null +++ b/docs/developer/typescript/60_mastery/60_unittests/_category_.yml @@ -0,0 +1 @@ +position: 61 diff --git a/docs/developer/typescript/60_mastery/60_unittests/index.md b/docs/developer/typescript/60_mastery/60_unittests/index.md new file mode 100644 index 000000000000..99c7edbb3c30 --- /dev/null +++ b/docs/developer/typescript/60_mastery/60_unittests/index.md @@ -0,0 +1,4 @@ +# Unit Testing + diff --git a/docs/developer/typescript/60_mastery/_category_.yml b/docs/developer/typescript/60_mastery/_category_.yml new file mode 100644 index 000000000000..0c02fd033a91 --- /dev/null +++ b/docs/developer/typescript/60_mastery/_category_.yml @@ -0,0 +1 @@ +position: 60 diff --git a/docs/developer/typescript/60_mastery/index.md b/docs/developer/typescript/60_mastery/index.md new file mode 100644 index 000000000000..b32df996a534 --- /dev/null +++ b/docs/developer/typescript/60_mastery/index.md @@ -0,0 +1,11 @@ +import DocCardList from '@theme/DocCardList'; + +# Mastery Toolkit + + + From 3c10960523494aff2373ab25ddc4f2ed3ca8de4e Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 15 Feb 2024 22:08:43 -0800 Subject: [PATCH 63/96] fix: DocCardList on empty Networking category crashed the builder --- docs/developer/typescript/49_networking/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/developer/typescript/49_networking/index.md b/docs/developer/typescript/49_networking/index.md index 5c820b43062d..6484ae461dbf 100644 --- a/docs/developer/typescript/49_networking/index.md +++ b/docs/developer/typescript/49_networking/index.md @@ -9,6 +9,7 @@ TODO: Advanced Networking Guide Explaining each of the concepts used in Anselm's `Basic` networked example/tutorial individually. Goal: Build knowledge on how to create customized networking code. ---> +--> + From 92e0054fa87237c852ab0242eefaa4f6510dc677 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 15 Feb 2024 23:13:02 -0800 Subject: [PATCH 64/96] chg: Remove leftover mentions to worldInjection --- .../typescript/01_gettingStarted/02_hello/03_system.md | 6 +++--- .../typescript/01_gettingStarted/02_hello/90_congrats.md | 6 +++++- docs/developer/typescript/02_basics/01_physics.md | 4 +--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md b/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md index 1e21de5b44ac..b5d99a7d17e9 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md @@ -15,7 +15,7 @@ ECS.setComponent(entity, VisibleComponent) ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) ``` -- And then we asked Ethereal Engine to run our code with the `worldInjection` function... +- And then we asked Ethereal Engine to run our code... ## Wait, where is the System? But we never defined a `System`! @@ -39,8 +39,8 @@ The correct way to create the Sphere of our minimal example would be to: - Insert the System into the engine so that it is run right after the engine's `PhysicsSystem`. ### Our function -So far we have been defining the code that creates our Sphere inside the `worldInjection` function. -This means that we relied on the function being called when the project configuration is loaded. +So far we have been defining the code that creates our Sphere at the top level of our module. +This means that we relied on the module being imported when the project configuration is loaded. But the correct way to do this is to define our code inside a separate function, and give that function to the `execute` parameter of a System created with `defineSystem`. Lets start by creating a new Typescript function, and moving our ECS code into that function. diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md index 266042170251..9ea8a357f695 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md @@ -18,12 +18,16 @@ Go to the bottom of this page, and click on "Next" to continue with your learnin #### Intermediate If you are feeling confident already, you could jump right into the intermediate tutorials. Just pick a topic that interests you in the sidebar and continue your journey from there. -:::note +:::note[Intermediate Note] Make sure to skim-read the basics section at least once, as it gives an overview of some important concepts that will be used all throughout the other guides. ::: #### Advanced The [Manual](/manual) is where Ethereal Engine is presented in all of its complexity, without any guard-rails or hand-holding. You will also find the [Reference API](/typedoc) really useful when writing the code of your application. +:::note[Advanced Note] +Make sure to read the `Mastery Toolkit` section at least once. +It contains a list of important tools that you will need when working with advanced projects. +::: diff --git a/docs/developer/typescript/02_basics/01_physics.md b/docs/developer/typescript/02_basics/01_physics.md index 69684c750d42..4fd4091d5bf5 100644 --- a/docs/developer/typescript/02_basics/01_physics.md +++ b/docs/developer/typescript/02_basics/01_physics.md @@ -71,7 +71,7 @@ ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 3, 0) }) -```ts +```ts title="ee-tutorial-hello/Hello.ts" showLineNumbers import { ECS } from '@etherealengine/ecs' import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' @@ -111,8 +111,6 @@ export const HelloWorldSystem = ECS.defineSystem({ execute: hello, insert: { after: PhysicsSystem } }) - -export default async function worldInjection() {} ``` From ecdb568e2956b2f74d2b2ca830b366505e5621ab Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 16 Feb 2024 22:41:08 -0800 Subject: [PATCH 65/96] new: Add code sketch to the HelloComponent page --- .../02_hello/04_component.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md index f49718dbe31f..f56d4bda1ae0 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -46,3 +46,62 @@ TODO: Tie it by filename --> +```ts +// Define our component +export const HelloComponent = ECS.defineComponent({ + name: 'ee.tutorial.HelloComponent', + jsonID: 'ee.tutorial.HelloComponent', + onInit() { return { initialized: false } } +}) +``` +```ts +// Define our query +const helloQuery = ECS.defineQuery([HelloComponent]) +``` +```ts +// Set our initialized state to true +ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) +``` + +```ts +import { ECS } from '@etherealengine/ecs' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { Vector3 } from 'three' +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' +import { PhysicsSystem } from '@etherealengine/spatial' + +// Define our component +export const HelloComponent = ECS.defineComponent({ + name: 'ee.tutorial.HelloComponent', + jsonID: 'ee.tutorial.HelloComponent', + onInit() { return { initialized: false } } +}) + +// Define our query +const helloQuery = ECS.defineQuery([HelloComponent]) + +const hello = () => { + for (const entity of helloQuery()) { + const { initialized } = ECS.getComponent(entity, HelloComponent) + if (initialized) continue + + ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) + + ECS.setComponent(entity, NameComponent, 'hello-entity') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + } +} + +// Define our system +export const HelloSystem = ECS.defineSystem({ + uuid: 'ee.tutorial.HelloSystem', + execute: hello, + insert: { after: PhysicsSystem } +}) +``` + From b27f56b6bfe34ee3f446f81b72a639851a87cb42 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:48:46 +0100 Subject: [PATCH 66/96] fmt: Remove incorrectly added folders --- docs/developer/typescript/02_topic1/_category_.yml | 1 - docs/developer/typescript/03_topic2/_category_.yml | 1 - 2 files changed, 2 deletions(-) delete mode 100644 docs/developer/typescript/02_topic1/_category_.yml delete mode 100644 docs/developer/typescript/03_topic2/_category_.yml diff --git a/docs/developer/typescript/02_topic1/_category_.yml b/docs/developer/typescript/02_topic1/_category_.yml deleted file mode 100644 index edbd9a5181e4..000000000000 --- a/docs/developer/typescript/02_topic1/_category_.yml +++ /dev/null @@ -1 +0,0 @@ -position: 2 \ No newline at end of file diff --git a/docs/developer/typescript/03_topic2/_category_.yml b/docs/developer/typescript/03_topic2/_category_.yml deleted file mode 100644 index 71b6ec9c2427..000000000000 --- a/docs/developer/typescript/03_topic2/_category_.yml +++ /dev/null @@ -1 +0,0 @@ -position: 3 \ No newline at end of file From 9684cd2c798163455a927fd5366ae38319f8f7b0 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:05:08 +0100 Subject: [PATCH 67/96] fix: Broken links and GettingStarted title --- docs/_partials/installUbuntu.md | 2 +- .../typescript/01_gettingStarted/02_hello/90_congrats.md | 2 +- docs/developer/typescript/01_gettingStarted/_category_.yml | 3 ++- docs/developer/typescript/02_basics/02_state.md | 2 +- docs/developer/typescript/02_basics/index.md | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/_partials/installUbuntu.md b/docs/_partials/installUbuntu.md index 2895c7c526d7..565cf36e57c5 100644 --- a/docs/_partials/installUbuntu.md +++ b/docs/_partials/installUbuntu.md @@ -1,6 +1,6 @@ :::note This guide assumes you are using Ubuntu Linux. -You can find alternative _(and more advanced)_ installation instructions for [Windows](/manual/host/installation/windowsWSL), [Mac](/manual/host/installation/macOSX) and [Linux](/manual/host/installation/intro) in the Manual. +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. ::: ### Install Ethereal Engine and its Pre-requisites diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md index 9ea8a357f695..0f1f753ea866 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md @@ -24,7 +24,7 @@ Make sure to skim-read the basics section at least once, as it gives an overview #### Advanced The [Manual](/manual) is where Ethereal Engine is presented in all of its complexity, without any guard-rails or hand-holding. -You will also find the [Reference API](/typedoc) really useful when writing the code of your application. +You will also find the [Reference API](/api) really useful when writing the code of your application. :::note[Advanced Note] Make sure to read the `Mastery Toolkit` section at least once. It contains a list of important tools that you will need when working with advanced projects. diff --git a/docs/developer/typescript/01_gettingStarted/_category_.yml b/docs/developer/typescript/01_gettingStarted/_category_.yml index 873ad3e9da76..80ab05bcb8c6 100644 --- a/docs/developer/typescript/01_gettingStarted/_category_.yml +++ b/docs/developer/typescript/01_gettingStarted/_category_.yml @@ -1 +1,2 @@ -position: 1 \ No newline at end of file +label: Getting Started +position: 1 diff --git a/docs/developer/typescript/02_basics/02_state.md b/docs/developer/typescript/02_basics/02_state.md index 1129e97bf104..b49c2978a1d2 100644 --- a/docs/developer/typescript/02_basics/02_state.md +++ b/docs/developer/typescript/02_basics/02_state.md @@ -11,7 +11,7 @@ There are multiple ways to keep track of state - A reactor mount with `useEffect` ## Local Variable -You might remember the `initialized` variable we created in an earlier section of the [Hello World](../hello/system) tutorial. +You might remember the `initialized` variable we created in an earlier section of the [Hello World](../gettingStarted/hello/system) tutorial. That variable was what is called "Local State". As you saw, we are fully responsible of book-keeping the values contained in the variables we create in this way. diff --git a/docs/developer/typescript/02_basics/index.md b/docs/developer/typescript/02_basics/index.md index 3b47bd5f3423..961d666c4fa9 100644 --- a/docs/developer/typescript/02_basics/index.md +++ b/docs/developer/typescript/02_basics/index.md @@ -5,7 +5,7 @@ sidebar_label: Ethereal Engine Basics import DocCardList from '@theme/DocCardList'; # Ethereal Engine Basics -This guide is a continuation of the [Hello World Tutorial](../hello). +This guide is a continuation of the [Hello World Tutorial](../gettingStarted/hello). In this guide you will learn how to start expanding your knowledge of the engine beyond the Quickstart introductory guide. From 2fd8c05b4223cafd707f236fd4a0272cb2522599 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:41:08 +0100 Subject: [PATCH 68/96] fmt: Small styling changes to the hello/component page --- .../02_hello/04_component.md | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md index f56d4bda1ae0..2522eca6da5c 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -1,4 +1,5 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Components Ok, lets admit the truth. @@ -34,6 +35,11 @@ But the data we’re relying on in our example is created within the project, in The proper way to add our simple Sphere would be to lock our logic behind a custom Scene Component. That way, when a component is added to an entity, the system can be activated through a query. +Solving this correctly will require us to use all these new concepts: +- Defining a Custom Component +- Defining a Query for our Component +- Manage our `initialized` variable from inside our Component + ## Creating a Custom Component + + + ```ts // Define our component export const HelloComponent = ECS.defineComponent({ name: 'ee.tutorial.HelloComponent', jsonID: 'ee.tutorial.HelloComponent', - onInit() { return { initialized: false } } + onInit: () => { return { initialized: false } } }) ``` ```ts -// Define our query +// Define the query that will find our Scene's Entity const helloQuery = ECS.defineQuery([HelloComponent]) ``` ```ts @@ -63,7 +72,8 @@ const helloQuery = ECS.defineQuery([HelloComponent]) ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) ``` -```ts + +```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers import { ECS } from '@etherealengine/ecs' import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' @@ -74,23 +84,31 @@ import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/Geo import { PhysicsSystem } from '@etherealengine/spatial' // Define our component +//highlight-start export const HelloComponent = ECS.defineComponent({ name: 'ee.tutorial.HelloComponent', jsonID: 'ee.tutorial.HelloComponent', - onInit() { return { initialized: false } } + onInit: () => { return { initialized: false } } }) +//highlight-end -// Define our query +// Define the query that will find our Scene's Entity +//highlight-start const helloQuery = ECS.defineQuery([HelloComponent]) +//highlight-end const hello = () => { + //highlight-start for (const entity of helloQuery()) { const { initialized } = ECS.getComponent(entity, HelloComponent) if (initialized) continue + //highlight-end + //highlight-start ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) + //highlight-end - ECS.setComponent(entity, NameComponent, 'hello-entity') + ECS.setComponent(entity, NameComponent, 'ee.tutorial.hello-entity') ECS.setComponent(entity, VisibleComponent) ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) @@ -104,4 +122,7 @@ export const HelloSystem = ECS.defineSystem({ insert: { after: PhysicsSystem } }) ``` - + + + + From fa85c264280cdd0544d744ff8f9e6bcd3ebcd5f9 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:41:57 +0100 Subject: [PATCH 69/96] new: basics/Recap section --- .../02_basics/01_recap/01_styling.md | 145 ++++++++++++++++++ .../02_basics/01_recap/02_component.md | 17 ++ .../typescript/02_basics/01_recap/03_query.md | 9 ++ .../02_basics/01_recap/_category_.yml | 1 + .../typescript/02_basics/01_recap/index.md | 11 ++ .../{01_physics.md => 02_physics.md} | 0 .../02_basics/{02_state.md => 03_state.md} | 0 .../02_basics/{03_loop.md => 04_loop.md} | 0 .../_category_.json | 0 .../{04_project => 05_project}/index.md | 0 .../02_basics/{04_inputs.md => 06_inputs.md} | 0 .../typescript/02_basics/_category_.json | 4 - .../typescript/02_basics/_category_.yml | 1 + 13 files changed, 184 insertions(+), 4 deletions(-) create mode 100644 docs/developer/typescript/02_basics/01_recap/01_styling.md create mode 100644 docs/developer/typescript/02_basics/01_recap/02_component.md create mode 100644 docs/developer/typescript/02_basics/01_recap/03_query.md create mode 100644 docs/developer/typescript/02_basics/01_recap/_category_.yml create mode 100644 docs/developer/typescript/02_basics/01_recap/index.md rename docs/developer/typescript/02_basics/{01_physics.md => 02_physics.md} (100%) rename docs/developer/typescript/02_basics/{02_state.md => 03_state.md} (100%) rename docs/developer/typescript/02_basics/{03_loop.md => 04_loop.md} (100%) rename docs/developer/typescript/02_basics/{04_project => 05_project}/_category_.json (100%) rename docs/developer/typescript/02_basics/{04_project => 05_project}/index.md (100%) rename docs/developer/typescript/02_basics/{04_inputs.md => 06_inputs.md} (100%) delete mode 100644 docs/developer/typescript/02_basics/_category_.json create mode 100644 docs/developer/typescript/02_basics/_category_.yml diff --git a/docs/developer/typescript/02_basics/01_recap/01_styling.md b/docs/developer/typescript/02_basics/01_recap/01_styling.md new file mode 100644 index 000000000000..3fd0cca5334c --- /dev/null +++ b/docs/developer/typescript/02_basics/01_recap/01_styling.md @@ -0,0 +1,145 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; + +# Styling +## ID Naming Convention +Lets start with the simplest one. +You may have noticed that we changed the `uuid` and `NameComponent` in the HelloWorld's final solution. +The engine doesn't have a standard for these names yet, but this is a good naming convention that you can follow: +- Separate words with `.` +- Start with the namespace/organization/author of your project +- Follow by the project name of the thing that you are naming +- Follow by the name of the thing +- Separate multi-word names with `-` +```md +Namespace : ee +Project : tutorial +Thing : HelloSystem + +Result : ee.tutorial.HelloSystem +Multi-word : ee.multi-word-example.HelloSystem +``` +:::note[assignment zero] +This is not really an assignment, as we already did this before. +But see if you have any names leftover in your code that are not using this standard, and change them so that they do. +::: + +## Arrow Functions +We talked about Javascript [`Arrow Functions`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) during one of the earlier sections of the HelloWorld tutorial. They are used a lot throughout the engine's codebase. + +They are specially helpful when defining Systems and Components. +This is how a `defineSystem` call would look like using each type of function: + +```ts title="Regular Function : Simpler, but less common in Ethereal Engine" +// Our function +function sayhello() { console.log("Hello World") } + +// Our System +const HelloSystem = ECS.defineSystem({ + uuid: 'ee.tutorial.HelloSystem', + execute: sayhello, + insert: { after: PhysicsSystem } +}) +``` + +```ts title="Arrow Function : How defining a multi-field object usually looks like" +// Our function can be declared inside our system. Doesn't need a name +const HelloSystem = ECS.defineSystem({ + uuid: 'ee.tutorial.HelloSystem', + execute: () => { + console.log("Hello World") + }, + insert: { after: PhysicsSystem } +}) +``` + +As you can see, this gives us a very small gain for this tiny example. +But, when the codebase grows, this style can make a big difference in the readability of our code. + +Arrow functions are also used extensively all throughout the engine's codebase. +So, even if you don't prefer them, at least you need to know about how they work so that you are not confused the first time you find this styling somewhere. + +:::important[first assignment] +Change the style of the BasicsTutorial code: +: Remove any named functions that are assigned to an object +: Use arrow functions directly as object fields + +There are not that many to change. We only had one named function! :) +::: + + + +```ts +// Define our system +export const HelloSystem = ECS.defineSystem({ + uuid: 'ee.tutorial.HelloSystem', + //highlight-start + execute: () => { + //highlight-end + for (const entity of helloQuery()) { + const { initialized } = ECS.getComponent(entity, HelloComponent) + if (initialized) continue + + ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) + + ECS.setComponent(entity, NameComponent, 'ee.tutorial.hello-entity') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + } + //highlight-start + }, + //highlight-end + insert: { after: PhysicsSystem } +}) + +``` + + +```ts title="ee-tutorial-basics/src/step1.ts" showLineNumbers +import { ECS } from '@etherealengine/ecs' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { Vector3 } from 'three' +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' +import { PhysicsSystem } from '@etherealengine/spatial' + +// Define our component +export const HelloComponent = ECS.defineComponent({ + name: 'ee.tutorial.HelloComponent', + jsonID: 'ee.tutorial.HelloComponent', + onInit: () => { return { initialized: false } } +}) + +// Define the query that will find our Scene's Entity +const helloQuery = ECS.defineQuery([HelloComponent]) + +// Define our system +export const HelloSystem = ECS.defineSystem({ + uuid: 'ee.tutorial.HelloSystem', + //highlight-start + execute: () => { + //highlight-end + for (const entity of helloQuery()) { + const { initialized } = ECS.getComponent(entity, HelloComponent) + if (initialized) continue + + ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) + + ECS.setComponent(entity, NameComponent, 'ee.tutorial.hello-entity') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + } + //highlight-start + }, + //highlight-end + insert: { after: PhysicsSystem } +}) +``` + + + + diff --git a/docs/developer/typescript/02_basics/01_recap/02_component.md b/docs/developer/typescript/02_basics/01_recap/02_component.md new file mode 100644 index 000000000000..92e4970d0e55 --- /dev/null +++ b/docs/developer/typescript/02_basics/01_recap/02_component.md @@ -0,0 +1,17 @@ +--- +sidebar_label: Custom Component +--- +import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; + +# Defining a Custom Component +... +```ts +// Define our component +const HelloComponent = ECS.defineComponent({ + name: 'ee.tutorial.HelloComponent', + jsonID: 'ee.tutorial.HelloComponent', + onInit: () => { return { initialized: false } } +}) +``` + diff --git a/docs/developer/typescript/02_basics/01_recap/03_query.md b/docs/developer/typescript/02_basics/01_recap/03_query.md new file mode 100644 index 000000000000..0c376f3b1d63 --- /dev/null +++ b/docs/developer/typescript/02_basics/01_recap/03_query.md @@ -0,0 +1,9 @@ +--- +sidebar_label: Query +--- +import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; + +# Define a Query +... + diff --git a/docs/developer/typescript/02_basics/01_recap/_category_.yml b/docs/developer/typescript/02_basics/01_recap/_category_.yml new file mode 100644 index 000000000000..d6b968359e12 --- /dev/null +++ b/docs/developer/typescript/02_basics/01_recap/_category_.yml @@ -0,0 +1 @@ +position: 01 diff --git a/docs/developer/typescript/02_basics/01_recap/index.md b/docs/developer/typescript/02_basics/01_recap/index.md new file mode 100644 index 000000000000..1e4b7dae0fa6 --- /dev/null +++ b/docs/developer/typescript/02_basics/01_recap/index.md @@ -0,0 +1,11 @@ +import DocCardList from '@theme/DocCardList'; + +# Quick Recap +In the last step of the [Hello World Tutorial](../gettingStarted/hello/component#creating-a-custom-component) we created a custom Scene Component . +But we never really explained how we did it. + +We also skimmed over multiple concepts that are very important for working with the Engine. So lets start on the right foot and explain them now. +Also, now that we are into it, we are going to style our code in a way that matches Ethereal Engine's code a bit more. + + + diff --git a/docs/developer/typescript/02_basics/01_physics.md b/docs/developer/typescript/02_basics/02_physics.md similarity index 100% rename from docs/developer/typescript/02_basics/01_physics.md rename to docs/developer/typescript/02_basics/02_physics.md diff --git a/docs/developer/typescript/02_basics/02_state.md b/docs/developer/typescript/02_basics/03_state.md similarity index 100% rename from docs/developer/typescript/02_basics/02_state.md rename to docs/developer/typescript/02_basics/03_state.md diff --git a/docs/developer/typescript/02_basics/03_loop.md b/docs/developer/typescript/02_basics/04_loop.md similarity index 100% rename from docs/developer/typescript/02_basics/03_loop.md rename to docs/developer/typescript/02_basics/04_loop.md diff --git a/docs/developer/typescript/02_basics/04_project/_category_.json b/docs/developer/typescript/02_basics/05_project/_category_.json similarity index 100% rename from docs/developer/typescript/02_basics/04_project/_category_.json rename to docs/developer/typescript/02_basics/05_project/_category_.json diff --git a/docs/developer/typescript/02_basics/04_project/index.md b/docs/developer/typescript/02_basics/05_project/index.md similarity index 100% rename from docs/developer/typescript/02_basics/04_project/index.md rename to docs/developer/typescript/02_basics/05_project/index.md diff --git a/docs/developer/typescript/02_basics/04_inputs.md b/docs/developer/typescript/02_basics/06_inputs.md similarity index 100% rename from docs/developer/typescript/02_basics/04_inputs.md rename to docs/developer/typescript/02_basics/06_inputs.md diff --git a/docs/developer/typescript/02_basics/_category_.json b/docs/developer/typescript/02_basics/_category_.json deleted file mode 100644 index a4b40a0a2997..000000000000 --- a/docs/developer/typescript/02_basics/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "position": 02, -} - diff --git a/docs/developer/typescript/02_basics/_category_.yml b/docs/developer/typescript/02_basics/_category_.yml new file mode 100644 index 000000000000..e34d8cd3b323 --- /dev/null +++ b/docs/developer/typescript/02_basics/_category_.yml @@ -0,0 +1 @@ +position: 02 From 9ac58672a9a7a15a1056f41be0ea6541d340d78e Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 23 Feb 2024 02:57:01 +0100 Subject: [PATCH 70/96] fix: Broken links on Recap and GettingStarted --- .../typescript/01_gettingStarted/02_hello/90_congrats.md | 2 +- docs/developer/typescript/02_basics/01_recap/01_styling.md | 1 + docs/developer/typescript/02_basics/01_recap/index.md | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md index 0f1f753ea866..6baea96669c9 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md @@ -24,7 +24,7 @@ Make sure to skim-read the basics section at least once, as it gives an overview #### Advanced The [Manual](/manual) is where Ethereal Engine is presented in all of its complexity, without any guard-rails or hand-holding. -You will also find the [Reference API](/api) really useful when writing the code of your application. +You will also find the [Reference API](https://etherealengine.github.io/etherealengine-docs//api) really useful when writing the code of your application. :::note[Advanced Note] Make sure to read the `Mastery Toolkit` section at least once. It contains a list of important tools that you will need when working with advanced projects. diff --git a/docs/developer/typescript/02_basics/01_recap/01_styling.md b/docs/developer/typescript/02_basics/01_recap/01_styling.md index 3fd0cca5334c..52678ba73d4a 100644 --- a/docs/developer/typescript/02_basics/01_recap/01_styling.md +++ b/docs/developer/typescript/02_basics/01_recap/01_styling.md @@ -143,3 +143,4 @@ export const HelloSystem = ECS.defineSystem({ + diff --git a/docs/developer/typescript/02_basics/01_recap/index.md b/docs/developer/typescript/02_basics/01_recap/index.md index 1e4b7dae0fa6..1376e6302fcd 100644 --- a/docs/developer/typescript/02_basics/01_recap/index.md +++ b/docs/developer/typescript/02_basics/01_recap/index.md @@ -1,7 +1,7 @@ import DocCardList from '@theme/DocCardList'; # Quick Recap -In the last step of the [Hello World Tutorial](../gettingStarted/hello/component#creating-a-custom-component) we created a custom Scene Component . +In the last step of the [Hello World Tutorial](/developer/typescript/gettingStarted/hello/component#creating-a-custom-component) we created a custom Scene Component . But we never really explained how we did it. We also skimmed over multiple concepts that are very important for working with the Engine. So lets start on the right foot and explain them now. From 38e7ae152113b1bf88d8c9e9e2e8a3b7a06198d2 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 23 Feb 2024 04:41:58 +0100 Subject: [PATCH 71/96] chg: Small wording improvements --- .../01_gettingStarted/02_hello/04_component.md | 8 ++++---- .../typescript/02_basics/01_recap/01_styling.md | 15 ++++++++------- .../typescript/02_basics/01_recap/index.md | 3 ++- docs/developer/typescript/02_basics/index.md | 1 + 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md index 2522eca6da5c..1474947370ee 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -20,8 +20,8 @@ This is what we have done so far: - We never added our Sphere Component to a specific Scene _(well, we didn't have a Sphere Component, so we couldn't)_ -These two last steps are the key of our problem. -The reason is because the engine will execute projects globally, but we are not restricting our code to be run only when requested. +These two last steps are the key to our problem. +This happens because the engine will execute projects globally, but we are not restricting our code to be run only when requested. So our example, up until now, has been acting as if it was an extension to the Studio editor! @@ -35,13 +35,13 @@ But the data we’re relying on in our example is created within the project, in The proper way to add our simple Sphere would be to lock our logic behind a custom Scene Component. That way, when a component is added to an entity, the system can be activated through a query. -Solving this correctly will require us to use all these new concepts: +Solving this correctly will require us to use all of these new concepts: - Defining a Custom Component - Defining a Query for our Component - Manage our `initialized` variable from inside our Component -## Creating a Custom Component +## Creating a Custom Component {#create} - - +You can probably already guess the name of the function we are going to use next. +The function for **defining a Component** is called... + +`defineComponent`, which its part of the namespace... `ECS` + +:::note +I will fill in the difficult parts for this assignment, as I don't expect you to be able to magically know these things just yet. +We will do that on the next tutorial! +::: +Here are your hints for completing this task: ```ts // Define our component -export const HelloComponent = ECS.defineComponent({ - name: 'ee.tutorial.HelloComponent', - jsonID: 'ee.tutorial.HelloComponent', +export ... = ... ({ + name: ..., + jsonID: 'EE_tutorial_hello', onInit: () => { return { initialized: false } } }) ``` -```ts -// Define the query that will find our Scene's Entity -const helloQuery = ECS.defineQuery([HelloComponent]) -``` -```ts -// Set our initialized state to true -ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) -``` - - -```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers -import { ECS } from '@etherealengine/ecs' -import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' -import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' -import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' -import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' -import { Vector3 } from 'three' -import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' -import { PhysicsSystem } from '@etherealengine/spatial' + +```ts // Define our component -//highlight-start export const HelloComponent = ECS.defineComponent({ name: 'ee.tutorial.HelloComponent', - jsonID: 'ee.tutorial.HelloComponent', + jsonID: 'EE_tutorial_hello', onInit: () => { return { initialized: false } } }) -//highlight-end - -// Define the query that will find our Scene's Entity -//highlight-start -const helloQuery = ECS.defineQuery([HelloComponent]) -//highlight-end - -const hello = () => { - //highlight-start - for (const entity of helloQuery()) { - const { initialized } = ECS.getComponent(entity, HelloComponent) - if (initialized) continue - //highlight-end - - //highlight-start - ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) - //highlight-end - - ECS.setComponent(entity, NameComponent, 'ee.tutorial.hello-entity') - ECS.setComponent(entity, VisibleComponent) - ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) - ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) - } -} - -// Define our system -export const HelloSystem = ECS.defineSystem({ - uuid: 'ee.tutorial.HelloSystem', - execute: hello, - insert: { after: PhysicsSystem } -}) ``` - - - + +You won't see any changes if you run the project as it is now. +We haven't connected the Component to anything just yet! + +## State Management +We haven't talked much about State, and there is a lot to explain about it, so I will give you this one for free. +We will have an entire section explaining these concepts in the [Ethereal Engine Basics](/developer/typescript/basics/state) guide. + +This is the code that replaces our `initialized` variable from the previous page: +```ts +// Check if we have already initialized our Sphere +let { initialized } = ECS.getMutableComponent(entity, HelloComponent) +if (initialized.value) continue +initialized.set(true) // Set our initialized state to true +``` + +This code will be very useful for our next few steps. +Lets see how we can lock our code to be run only under a specific condition. + + + diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md new file mode 100644 index 000000000000..9123191fd9f1 --- /dev/null +++ b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md @@ -0,0 +1,155 @@ +import { TechnicalNote } from '@site/src/components/TechnicalNote'; +import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; + +# Queries +Queries are a tool provided by the `Entity Component System` pattern used by Ethereal Engine. + +In simple terms, a Query is a function that will request all entities that match a certain condition. +More specifically, it will return **all** entities that contain **all** Components in the list that we specified. + +## Creating a Query +We are going to **define a Query**. I think you can figure out the name of the function already :) +This is how the function works: +- We give the function an [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of Components +- The function will give us back a Query function +- We can call the given function to retrieve all entities that contain the components that we specified. + +:::note[notes] +1. We need to send an array anyway, even if it only contains a single Component. +1. The Query will match only those entities that contain **all** components in our list. +1. We don't need to export the Query function, as it will only be called by our own code. +::: + +Here are your hints for this assignment: +```ts +// Define the query that will find our Scene's Entity +const ... = ...([ ... ]) +``` + + + +```ts +// Define the query that will find our Scene's Entity +const helloQuery = ECS.defineQuery([HelloComponent]) +``` + +Same as before, if you run the project as it is now you won't see any changes just yet. +We have defined the Query that will search for our Scene's entity, but we haven't called it yet. + +## Using our Query +A Query, when called, will return an array. +This array will contain the list of all entities that match the list of Components that we specified. + +Just like any other array, we can iterate through it with a `for` loop. +Which means that we can access as many entities as we want from a single unified place! +Really powerful. + +I gave you one solution for free earlier, but I'm leaving this assignment a bit ambiguous on purpose. +See if you can figure out which part of your code goes where before looking at the solution. +```ts +// Our for loop will look something like this +for (const entity of ...) { + // Our code goes here ... +} +``` + +Here are some hints, in case you get stuck: + + + +We cannot store our variable in module scope anymore. +The state management code **must** be inside our `execute` function. + + +We need to execute some code for an entity, just like we did before. That hasn't changed. +But we need to change **where** our code will be run. + + + + + +```ts +const hello = () => { + //highlight-start + for (const entity of helloQuery()) { + //highlight-end + + //highlight-start + // Check if we have already initialized our Sphere + let { initialized } = ECS.getMutableComponent(entity, HelloComponent) + if (initialized.value) continue + initialized.set(true) // Set our initialized state to true + //highlight-end + + ECS.setComponent(entity, NameComponent, 'ee.tutorial.hello-entity') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + } +} +``` + + +## Conclusion +As you can see, we only added around 10 lines of code in these last two pages... +But we introduced so many new concepts! +That's the most exciting part about the ECS pattern. You can do **so** much with so little code! + +You will know that you completed the last two pages correctly if: +- The behavior has not changed for your project. You can still see the sphere in the Scene. +- You open another project _(eg: The `default-project` provided by the engine)_ and the Sphere is gone! + +Lets put everything together. + + + +```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers +import { ECS } from '@etherealengine/ecs' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' +import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' +import { Vector3 } from 'three' +import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' +import { PhysicsSystem } from '@etherealengine/spatial' + +// Define our component +//highlight-start +export const HelloComponent = ECS.defineComponent({ + name: 'ee.tutorial.HelloComponent', + jsonID: 'EE_tutorial_hello', + onInit: () => { return { initialized: false } } +}) +//highlight-end + +// Define the query that will find our Scene's Entity +//highlight-start +const helloQuery = ECS.defineQuery([HelloComponent]) +//highlight-end + +const hello = () => { + //highlight-start + for (const entity of helloQuery()) { + // Check if we have already initialized our Sphere + let { initialized } = ECS.getMutableComponent(entity, HelloComponent) + if (initialized.value) continue + initialized.set(true) // Set our initialized state to true + //highlight-end + + ECS.setComponent(entity, NameComponent, 'ee.tutorial.hello-entity') + ECS.setComponent(entity, VisibleComponent) + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + } +} + +// Define our system +export const HelloSystem = ECS.defineSystem({ + uuid: 'ee.tutorial.HelloSystem', + execute: hello, + insert: { after: PhysicsSystem } +}) +``` + + + diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md index 6baea96669c9..21e254d18101 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md @@ -1,9 +1,10 @@ --- -pagination_next: developer/typescript/basics/physics +pagination_next: developer/typescript/basics/recap/index +title: What's Next --- import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; -# Congratulations! +# 🎉 Congratulations! 🎉 You have just learned the minimal basics of working with Ethereal Engine using Typescript! This was a very minimal introductory tutorial to get you started really quickly. @@ -11,7 +12,7 @@ But Ethereal Engine has a lot more features to explore! ## What's Next? #### Beginner -If this is your first time using Ethereal Engine, we have prepared an `Etheral Engine Basics` tutorial for you. +If this is your first time using Ethereal Engine, we have prepared an [Ethereal Engine Basics](/developer/typescript/basics) tutorial for you. It will teach you how to start expanding your knowledge of the engine without getting overwhelmed by its complexity. Go to the bottom of this page, and click on "Next" to continue with your learning journey! diff --git a/docs/developer/typescript/02_basics/01_recap/01_styling.md b/docs/developer/typescript/02_basics/01_recap/01_styling.md index 17af09f688c5..bb0455e2ad14 100644 --- a/docs/developer/typescript/02_basics/01_recap/01_styling.md +++ b/docs/developer/typescript/02_basics/01_recap/01_styling.md @@ -97,10 +97,9 @@ export const HelloSystem = ECS.defineSystem({ execute: () => { //highlight-end for (const entity of helloQuery()) { - const { initialized } = ECS.getComponent(entity, HelloComponent) - if (initialized) continue - - ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) + let { initialized } = ECS.getMutableComponent(entity, HelloComponent) + if (initialized.value) continue + initialized.set(true) ECS.setComponent(entity, NameComponent, 'ee.tutorial.hello-entity') ECS.setComponent(entity, VisibleComponent) From f7ceaf523f67aebfe551f0ddd271340d3590f7eb Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:13:57 +0100 Subject: [PATCH 74/96] new: Component+Query sketch for the Basics guide --- .../typescript/02_basics/01_recap/02_component.md | 6 +++++- .../typescript/02_basics/01_recap/03_query.md | 12 +++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/developer/typescript/02_basics/01_recap/02_component.md b/docs/developer/typescript/02_basics/01_recap/02_component.md index 92e4970d0e55..8cfc5e2e4f63 100644 --- a/docs/developer/typescript/02_basics/01_recap/02_component.md +++ b/docs/developer/typescript/02_basics/01_recap/02_component.md @@ -5,7 +5,6 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Defining a Custom Component -... ```ts // Define our component const HelloComponent = ECS.defineComponent({ @@ -14,4 +13,9 @@ const HelloComponent = ECS.defineComponent({ onInit: () => { return { initialized: false } } }) ``` +## `name` +## `jsonID` +## `onInit` +### Arrow Function +### Object returned diff --git a/docs/developer/typescript/02_basics/01_recap/03_query.md b/docs/developer/typescript/02_basics/01_recap/03_query.md index 0c376f3b1d63..bc9b7165cdd8 100644 --- a/docs/developer/typescript/02_basics/01_recap/03_query.md +++ b/docs/developer/typescript/02_basics/01_recap/03_query.md @@ -5,5 +5,15 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Define a Query -... +```ts +const helloQuery = ECS.defineQuery([HelloComponent]) + +for (const entity of helloQuery()) { + // Do something with the entity +} +``` +### Name +### Arguments +### Return type +### Usage From 86380394b8490f94510e20092a59ca0ea634fa85 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Sat, 24 Feb 2024 04:20:02 +0100 Subject: [PATCH 75/96] fix: Ubuntu Installation instructions command --- docs/_partials/installUbuntu.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/_partials/installUbuntu.md b/docs/_partials/installUbuntu.md index 565cf36e57c5..492d48e603f6 100644 --- a/docs/_partials/installUbuntu.md +++ b/docs/_partials/installUbuntu.md @@ -3,10 +3,9 @@ This guide assumes you are using Ubuntu Linux. 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. ::: -### Install Ethereal Engine and its Pre-requisites Ethereal Engine can be installed and run with: ```bash -wget -qO- https://raw.githubusercontent.com/EtherealEngine/etherealengine/dev/scripts/ubuntu-install.sh | bash -i +wget https://raw.githubusercontent.com/EtherealEngine/etherealengine/dev/scripts/ubuntu-install.sh && bash -i ./ubuntu-install.sh npm run dev ``` You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 From 8852c39a7ed843c291c9703257d18770b99cc5af Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Sat, 24 Feb 2024 05:37:59 +0100 Subject: [PATCH 76/96] chg: Edit pass. Small wording changes and fixes for all sections --- .../01_gettingStarted/02_hello/01_ecs.md | 14 ++++---------- .../01_gettingStarted/02_hello/02_engine.md | 2 +- .../02_hello/04_component.md | 13 +++++++++++-- .../01_gettingStarted/02_hello/05_query.md | 19 +++++++++++-------- .../typescript/02_basics/02_physics.md | 7 ++++--- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md index 7e2598fc7ec6..f661127a3257 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md @@ -3,16 +3,10 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; # The ECS Pattern The [Entity Component System](https://en.wikipedia.org/wiki/Entity_component_system) is a pattern used to organize our code when writing software. In this pattern: -- Logic is represented as `Systems`, and they define the behavior of the application. -- Data is represented as `Components` that have no behavior or identifiers attached to them. -- Components are attached to Entities. -- An `Entity` is an identifier. - - +- Logic is represented as `Systems`, and they define the behavior of the application +- Data is represented as `Components` that have no behavior or identifiers attached to them +- Components are attached to Entities +- `Entities` are identifiers The ECS pattern represents [Objects](https://en.wikipedia.org/wiki/Object_(computer_science)) by attaching Components (data) to an Entity (identifiers) without behavior. diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md index 9d514f11242e..0607c51571fa 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md @@ -20,7 +20,7 @@ They are equivalent to the concept of "projects" in other engines, except they a The engine scans for projects mounted in the `/packages/projects/projects` sub-folder. This means that, like we did earlier in the [Quickstart](../quickstart) guide, we can install and run new projects by executing the following commands inside our Ethereal Engine installation folder: ```bash -git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/packages/ee-tutorial-hello +git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello npm install npm run dev ``` diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md index 99f409a9039d..096ccb64c490 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -74,15 +74,18 @@ export const HelloComponent = ECS.defineComponent({ onInit: () => { return { initialized: false } } }) ``` +Pay attention to the format of the `name` and `jsonID` fields. +We haven't talked about this convention, but we will do so later on. You won't see any changes if you run the project as it is now. We haven't connected the Component to anything just yet! ## State Management -We haven't talked much about State, and there is a lot to explain about it, so I will give you this one for free. -We will have an entire section explaining these concepts in the [Ethereal Engine Basics](/developer/typescript/basics/state) guide. +We haven't talked much about State, and there is a lot to explain about it. +We will have an entire section explaining state management in the [Ethereal Engine Basics](/developer/typescript/basics/state) guide. +I will give you this one for free. This is the code that replaces our `initialized` variable from the previous page: ```ts // Check if we have already initialized our Sphere @@ -90,6 +93,12 @@ let { initialized } = ECS.getMutableComponent(entity, HelloComponent) if (initialized.value) continue initialized.set(true) // Set our initialized state to true ``` + +Note how we wrote `if (initialized.value)` instead of just `if (initialized)`. +And we are modifying its value with `initialized.set(true)` instead of `initialized = true`. +We will explain why this is the case in the [Ethereal Engine Basics: State](/developer/typescript/basics/state) section. + + This code will be very useful for our next few steps. Lets see how we can lock our code to be run only under a specific condition. diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md index 9123191fd9f1..31afc6dc06f4 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md @@ -5,7 +5,7 @@ import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; Queries are a tool provided by the `Entity Component System` pattern used by Ethereal Engine. In simple terms, a Query is a function that will request all entities that match a certain condition. -More specifically, it will return **all** entities that contain **all** Components in the list that we specified. +More specifically, it will return **all** entities that contain **all** Components in the list that we specify. ## Creating a Query We are going to **define a Query**. I think you can figure out the name of the function already :) @@ -16,8 +16,8 @@ This is how the function works: :::note[notes] 1. We need to send an array anyway, even if it only contains a single Component. -1. The Query will match only those entities that contain **all** components in our list. -1. We don't need to export the Query function, as it will only be called by our own code. +2. The Query will match only those entities that contain **all** components in our list. +3. We don't need to export the Query function, as it will only be called by our own code. ::: Here are your hints for this assignment: @@ -37,11 +37,11 @@ Same as before, if you run the project as it is now you won't see any changes ju We have defined the Query that will search for our Scene's entity, but we haven't called it yet. ## Using our Query -A Query, when called, will return an array. +A Query, when called, will return a array. This array will contain the list of all entities that match the list of Components that we specified. - Just like any other array, we can iterate through it with a `for` loop. -Which means that we can access as many entities as we want from a single unified place! + +This means that we can access as many entities as we want from a single unified place! Really powerful. I gave you one solution for free earlier, but I'm leaving this assignment a bit ambiguous on purpose. @@ -93,11 +93,12 @@ const hello = () => { ## Conclusion As you can see, we only added around 10 lines of code in these last two pages... But we introduced so many new concepts! -That's the most exciting part about the ECS pattern. You can do **so** much with so little code! +That's the most exciting part about the ECS pattern. You can do **so** much with so little code. You will know that you completed the last two pages correctly if: - The behavior has not changed for your project. You can still see the sphere in the Scene. -- You open another project _(eg: The `default-project` provided by the engine)_ and the Sphere is gone! +- You open another project _(eg: the `default-project` provided by the engine)_... + and the Sphere is gone! Lets put everything together. @@ -150,6 +151,8 @@ export const HelloSystem = ECS.defineSystem({ insert: { after: PhysicsSystem } }) ``` +Note how the style for names in this solution has been changed. +We will learn about them next. diff --git a/docs/developer/typescript/02_basics/02_physics.md b/docs/developer/typescript/02_basics/02_physics.md index 4fd4091d5bf5..70e83dec37ef 100644 --- a/docs/developer/typescript/02_basics/02_physics.md +++ b/docs/developer/typescript/02_basics/02_physics.md @@ -10,8 +10,8 @@ In simple terms, we have told the engine how to **create** our sphere. ## Our problem We added some components to our sphere, so that the engine can draw the sphere into the screen and we can see it. -But right now it is only an "empty shell" that sits there doing nothing, which is a bit boring. -We cannot even use it as a platform to walk on! +But right now it is only an "empty shell" that sits there doing nothing. +We cannot even move it or push it around! What a boring ball. Lets fix that. ## Our solution @@ -22,7 +22,7 @@ Lets get a point of reference of how our project currently behaves, so we can be In order to do that, we are going to run our project from the studio and walk around the scene with an Avatar. These are the steps needed to accomplish that: -- Open the scene we created before, or click on `Create Scene` if you don't have it +- Open the scene you created before, or click on `Create Scene` if you don't have it - Press the `Play` button in the studio - Move your Avatar around the scene by either: - Pressing `WASD` in your keyboard @@ -36,6 +36,7 @@ In order to correct our problem, we are now going to: - Add a `RigidBodyComponent` of type `dynamic` to our entity - Add a `ColliderComponent` with the shape of a `sphere` +Lets also change the position of ball so that it spawns some distance above the ground. Here are your hints for this tutorial: ```ts // Both the RigidBody and Collider components are part of the `Spatial/physics` engine module From ae3f4bdf9d4aeaa29b3181fbf0154eff09b85aff Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 27 Feb 2024 10:39:03 +0100 Subject: [PATCH 77/96] new: Basics/component page and Basics/query skeleton --- .../02_basics/01_recap/02_component.md | 80 ++++++++++++++++++- .../typescript/02_basics/01_recap/03_query.md | 5 +- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/docs/developer/typescript/02_basics/01_recap/02_component.md b/docs/developer/typescript/02_basics/01_recap/02_component.md index 8cfc5e2e4f63..f45a6283c6a4 100644 --- a/docs/developer/typescript/02_basics/01_recap/02_component.md +++ b/docs/developer/typescript/02_basics/01_recap/02_component.md @@ -5,17 +5,91 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Defining a Custom Component +The `defineComponent` function accepts a `ComponentPartial` that has multiple fields available. ```ts // Define our component const HelloComponent = ECS.defineComponent({ name: 'ee.tutorial.HelloComponent', - jsonID: 'ee.tutorial.HelloComponent', + jsonID: 'EE_tutorial_hello', onInit: () => { return { initialized: false } } }) ``` + +:::note +See [Typescript.Partial](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype) for a reference of what Partials are. +::: + +Lets review what each of these fields do and how to use them. ## `name` +`name` is a `string` that defines the human readable label for the component that we are creating. +It will be displayed in the editor and debugging tools. +```ts +name: 'ee.tutorial.HelloComponent', +``` +As we saw before, the engine does not define strict naming requirements for this field, but it does define a [naming convention](./styling#id-naming-convention) that is good practice to follow in your projects. + ## `jsonID` +`jsonID` is an optional `string` that defines the internal ID used to reference this component in JSON data. +```ts +jsonID: 'EE_tutorial_hello', +``` +As we saw before, this field will be used by the engine to define the name of a [glTF](https://www.khronos.org/gltf) extension. +Because of this, the `jsonID` field has very specific [naming requirements](./styling#jsonid-naming-requirements) that must be followed. + ## `onInit` -### Arrow Function -### Object returned +`onInit` is a function that will be called once when the Component is added to an entity _(ie: initialized)_. +It returns the shape of the Component's runtime data, which has the type `Schema`. +```ts +onInit?: (this: SoAComponentType, entity: Entity) => ComponentType & OnInitValidateNotState +// this : `@internal` The component partial itself. +// entity : The Entity to which this Component is being assigned. +// returns : The `Schema` (aka shape) of the component's runtime data. +``` +A Component's Schema can contain any type of data that you want. +In our example from before, we saw how to use this data to store our `initialized` state variable inside the component, instead of storing it in our module. + +## Other fields +The `ComponentPartial` type accepts multiple other fields that we haven't needed for our simple HelloComponent example. These fields are: +`schema`, `toJSON`, `onSet`, `onRemove`, `reactor`, `errors`. + +We will explore them further in later sections of the tutorial. + + +The data used to create a Component with `defineComponent` is declared by the `ComponentPartial` interface. +This type exists so that some of the properties of Components are optional when defining them, but required during normal use. + +This is the shape of the `ComponentPartial` interface, defined in the [`ComponentFunctions.ts`](https://github.com/EtherealEngine/etherealengine/blob/dev/packages/ecs/src/ComponentFunctions.ts) file: +```ts +{ + name: string + jsonID?: string + onInit?: (this: SoAComponentType, entity: Entity) => ComponentType & OnInitValidateNotState + + // A Component's Schema is the shape of its runtime data. + schema?: Schema + + // Serializer function called when the component is saved to a snapshot or scene file. + // Its logic must convert the component's runtime data into a JSON object. + // entity : The Entity to which this Component is assigned. + // component : The Component's global data (aka State). + toJSON?: (entity: Entity, component: State) => JSON + + // Called when the component's data is updated via the setComponent function. + // This is where deserialization logic should happen. + // entity : The Entity to which this Component is assigned. + // component : The Component's global data (aka State). + // json : The JSON object that contains this component's serialized data. + onSet?: (entity: Entity, component: State, json?: SetJSON) => void + + // Called when the Component is removed from an Entity + onRemove?: (entity: Entity, component: State) => void | Promise + + // Defines the React.FC (Function Component) async logic of the resulting Component type. + // Any side-effects that depend on the component's data should be defined here. + reactor?: React.FC + + errors?: ErrorTypes[] +} +``` + diff --git a/docs/developer/typescript/02_basics/01_recap/03_query.md b/docs/developer/typescript/02_basics/01_recap/03_query.md index bc9b7165cdd8..8dc9d89003c6 100644 --- a/docs/developer/typescript/02_basics/01_recap/03_query.md +++ b/docs/developer/typescript/02_basics/01_recap/03_query.md @@ -13,7 +13,10 @@ for (const entity of helloQuery()) { } ``` ### Name +Arbitrary name/symbol/identifier ### Arguments +Array of Component types ### Return type +Returns a [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generator_functions). ### Usage - +Inside a for loop. From 3f401f15bbd19a6e1785956c23d917a79e972aba Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:21:52 +0100 Subject: [PATCH 78/96] new: Basics/location creation instructions --- .../typescript/02_basics/50_locations.md | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/docs/developer/typescript/02_basics/50_locations.md b/docs/developer/typescript/02_basics/50_locations.md index 851d96fc7937..43822655733b 100644 --- a/docs/developer/typescript/02_basics/50_locations.md +++ b/docs/developer/typescript/02_basics/50_locations.md @@ -3,8 +3,46 @@ Explain what they are. Explain why they are required. ## Create a Location -Lets create location for the scene. Once Ethereal Engine is running: +There are two ways to create a location for our scene: +- The `Admin Panel` +- The `Publish` button inside the Studio Editor +Lets explore both of them. + +### Publish Button +The easiest way to create a location for the current scene is with the `Publish` button in the Studio. +Follow these steps to create a new Location: +- Open your scene in the Studio. Navigate to https://localhost:3000/studio and click on your scene +- Click on the `Publish` button located at the top-right section of the screen +- Set the Location name to `hello` +- Click on `Submit` +- Run the Location by visiting it with the URL you just created: https://localhost:3000/location/hello +:::note +This method is just a quick-link to the `Create Location` menu of the Admin Panel. +The form opened with the `Publish` button is the same that can be accessed through the [Admin Panel: Locations](https://localhost:3000/admin/locations) section explained below. +::: + +### Admin Panel +While the Publish button provides a really simple and easy way to create a Location for your Scene, it also lacks functionality beyond just creating a new one. + +On the other hand, the [Admin Panel: Locations](https://localhost:3000/admin/locations) section provides utilities to manage your existing locations or edit any of their properties. + +#### Creating a Location +Lets create another Location from Admin Panel. Once Ethereal Engine is running: - Navigate to the Admin Panel at https://localhost:3000/admin/locations -- Map the scene to the name 'hello'. -- Run the project on the web by visiting it with the URL you just created: https://localhost:3000/location/hello +- Click on `Create Location` +- Set the Location name to `hello2` +- Select the desired scene that will be assigned to this location. +- Click on `Submit` +- Run the Location by visiting it with the URL you just created: https://localhost:3000/location/hello2 + +#### Editing a Location +Lets now edit our new Location to point to a different scene and have a different name. +- Navigate to the Admin Panel at https://localhost:3000/admin/locations +- Find the `hello2` location we just created +- Click on `View` +- Click on `Edit`, so we can change its properties +- Change the Location name to `new-hello` +- Change the `Scene` to a different one +- Click on `Submit` +- Run the Location by visiting it with the URL you just created: https://localhost:3000/location/new-hello From e800a939eb88eaf1e7065069b8b3c62d6158f00c Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:37:30 +0100 Subject: [PATCH 79/96] chg: Improve the Basics/query page --- .../typescript/02_basics/01_recap/03_query.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/developer/typescript/02_basics/01_recap/03_query.md b/docs/developer/typescript/02_basics/01_recap/03_query.md index 8dc9d89003c6..acc87c69afc6 100644 --- a/docs/developer/typescript/02_basics/01_recap/03_query.md +++ b/docs/developer/typescript/02_basics/01_recap/03_query.md @@ -5,6 +5,10 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Define a Query +Ethereal Engine's `defineQuery` is a function that accepts an `array` of `Component` types, and will return a JavaScript `Generator`. +This [JavaScript Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generator_functions) can be used in a `for` loop to iterate over `all` entities that contain `all` Components in our list. + +The Query can be named anything we want, as it is only relevant for our project. ```ts const helloQuery = ECS.defineQuery([HelloComponent]) @@ -12,11 +16,3 @@ for (const entity of helloQuery()) { // Do something with the entity } ``` -### Name -Arbitrary name/symbol/identifier -### Arguments -Array of Component types -### Return type -Returns a [Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generator_functions). -### Usage -Inside a for loop. From d14f8c35e823dd1d021f84094b40eee27feb71be Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:55:05 +0100 Subject: [PATCH 80/96] new: Write the Basics/recap/query page --- .../typescript/02_basics/01_recap/03_query.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/developer/typescript/02_basics/01_recap/03_query.md b/docs/developer/typescript/02_basics/01_recap/03_query.md index acc87c69afc6..8e782b3953ed 100644 --- a/docs/developer/typescript/02_basics/01_recap/03_query.md +++ b/docs/developer/typescript/02_basics/01_recap/03_query.md @@ -5,14 +5,18 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Define a Query -Ethereal Engine's `defineQuery` is a function that accepts an `array` of `Component` types, and will return a JavaScript `Generator`. -This [JavaScript Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generator_functions) can be used in a `for` loop to iterate over `all` entities that contain `all` Components in our list. +Queries are the simplest concept to explain out of everything we have dealt with so far. +But we looked into them only briefly, so lets explore their technical properties anyway. -The Query can be named anything we want, as it is only relevant for our project. +Ethereal Engine's `defineQuery` is a function that accepts an [`array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of `Component` types, and will return a [JavaScript Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generator_functions). This `Generator` can then be used in a [`for`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) loop to iterate over **all** entities that contain **all** Components in the list that we provided _(ie: our array of Components)_. + +:::note +The returned Query can be named anything we want, as its name is only relevant for our project. +::: ```ts const helloQuery = ECS.defineQuery([HelloComponent]) for (const entity of helloQuery()) { - // Do something with the entity + // Do something for all entities that contain a HelloComponent } ``` From f8ba51927b0daa0b56d9bfce7335a41b49bb5d04 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:55:25 +0100 Subject: [PATCH 81/96] new: Write the Basics/recap/next page --- .../typescript/02_basics/01_recap/04_next.md | 33 +++++++++++++++++++ .../typescript/02_basics/02_physics.md | 3 +- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 docs/developer/typescript/02_basics/01_recap/04_next.md diff --git a/docs/developer/typescript/02_basics/01_recap/04_next.md b/docs/developer/typescript/02_basics/01_recap/04_next.md new file mode 100644 index 000000000000..998eb348352d --- /dev/null +++ b/docs/developer/typescript/02_basics/01_recap/04_next.md @@ -0,0 +1,33 @@ +# Overview +The `Hello World` tutorial has taught us how to work with and create the most minimal Ethereal Engine programming example possible. But, as we are about to learn, there is a lot more to explore! + +## Hello World +Lets review what we have achieved with our project. So far we: +- Imported some Ethereal Engine's typescript modules in our file +- Created an entity, and gave it an `uuid` and a `name` +- Gave the entity the ability to: + - Be visible on the screen with a `VisibleComponent` + - Have Linear Transformations with a `TransformComponent` +- Defined the position of the sphere in the scene +- Gave the entity a `PrimitiveGeometryComponent` _(a Sphere)_ +- Defined a Custom `Component` type +- Defined a `Query` to search for our Custom Component +- Locked our logic to only happen once with the `initialized` State variable contained inside our Custom Component. +- Defined a `System` and locked our logic behind its `execute` function +- Locked our logic to only trigger for the entities that match our `helloQuery` generator +- Added our project's code to the engine with the `xrengine.config.ts` configuration file + +That's a lot!!! + +## Ethereal Engine: Basics +In this tutorial we will expand on our knowledge, and we will add these features to the source code of our project: +- Physics Properties: Gravity, Collision, Friction, etc +- Logic that happens every frame at specific intervals _(eg: every fixed-frame or every visual-frame)_ +- State Management _(eg: our `initialized` variable, but better)_ +- Input Management _(keyboard, mouse, touchpad, etc)_ +- How to debug our code to search for errors +- Networked events and actions that can be shared between multiple devices + +And, at the end of the tutorial, we will put everything together into a complete mini-game! + +Lets not wait any longer and get started by adding [`Physics`](../physics) to our project. diff --git a/docs/developer/typescript/02_basics/02_physics.md b/docs/developer/typescript/02_basics/02_physics.md index 70e83dec37ef..f2e0b3073ea2 100644 --- a/docs/developer/typescript/02_basics/02_physics.md +++ b/docs/developer/typescript/02_basics/02_physics.md @@ -5,8 +5,7 @@ import { TechnicalNote } from '@site/src/components/TechnicalNote'; import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # Adding Physics -So far we have learned how to create an `Entity`, and how to tell the engine what we want our entity to be. -In simple terms, we have told the engine how to **create** our sphere. +So far we have learned how to create an `Entity`, and how to tell the engine what we want our entity to be. In simple terms, we told the engine how to **create** our sphere. ## Our problem We added some components to our sphere, so that the engine can draw the sphere into the screen and we can see it. From 8e6ff2749736fb5dfd97c755ff466bb96d464352 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:44:02 +0100 Subject: [PATCH 82/96] new: Add ee-tutorial-hello/Step0 branch instructions --- .../typescript/01_gettingStarted/01_quickstart.md | 2 +- .../01_gettingStarted/02_hello/02_engine.md | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/01_quickstart.md b/docs/developer/typescript/01_gettingStarted/01_quickstart.md index b4e74648c89a..1162c1a9714c 100644 --- a/docs/developer/typescript/01_gettingStarted/01_quickstart.md +++ b/docs/developer/typescript/01_gettingStarted/01_quickstart.md @@ -18,7 +18,7 @@ This QuickStart guide will teach you the basics of Ethereal Engine, and how to r The previous command will have the engine running. Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the tutorial's template project: ```bash -git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello +git clone -b Step0 https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello npm install npm run dev ``` diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md index 0607c51571fa..fa2f3d14f70d 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md @@ -18,12 +18,21 @@ Ethereal Engine can be **extended** with projects. They are equivalent to the concept of "projects" in other engines, except they are modular like npm packages _(they are npm packages too)_. The engine scans for projects mounted in the `/packages/projects/projects` sub-folder. -This means that, like we did earlier in the [Quickstart](../quickstart) guide, we can install and run new projects by executing the following commands inside our Ethereal Engine installation folder: +This means that we can install and run new projects by executing the following commands inside our Ethereal Engine installation folder: ```bash git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello npm install npm run dev ``` + +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. +We did this by adding `-b Step0` to the `git clone` command: +```bash +git clone -b Step0 https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello +``` +This step won't be needed for your own projects. + + These steps will: - Download a copy of the project's git repository, so the engine can load it - Install all `npm` packages required by the project @@ -48,7 +57,9 @@ There are two very important steps to take in order to connect our project to th ### Project Configuration File Every project has an `xrengine.config.ts` file that defines how it will behave in the engine. There are multiple options available, but the important thing to remember is that our `src/Hello.ts` code will connected to the engine from here. + + ```ts title="ee-tutorial-hello/xrengine.config.ts" import type { ProjectConfigInterface } from '@etherealengine/projects/ProjectConfigInterface' From d6c9d6eed3278d85a9c6fd493bef28b21891c848 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:02:06 +0100 Subject: [PATCH 83/96] chg: Add A-to-B overview instructions for the HelloWorld/introduction --- .../01_gettingStarted/02_hello/index.md | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/index.md b/docs/developer/typescript/01_gettingStarted/02_hello/index.md index dbd3a29ef1a8..971a9915c5b3 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/index.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/index.md @@ -3,25 +3,23 @@ sidebar_label: Hello Ethereal --- # Hello World from Ethereal Engine The quickstart tutorial helped us create a project and run the engine for the first time. -It automated a lot for us, so lets review what we have done so far. + +This is our starting point. +The Quickstart has automated a lot for us, so lets review what we have. ## Conceptual overview -This is what we have done with the example's project: -- We created an entity called `hello-world` -- We gave the entity a primitive geometry component _(a sphere)_ -- We defined the position of the sphere in the scene +Conceptually, this is what the example project does: +- It creates an entity called `hello-world` +- It gives the entity a primitive geometry component _(a Sphere)_ +- It defines the position of the sphere in the scene ## Technical overview -This is what we have done with the example's source code: -- We used the `ECS` pattern -- We created an `Entity` -- We added a few `Component`s to our Entity -- We imported some Ethereal Engine's typescript modules in our file -- We added our code to the engine with the `worldInjection` function. - -Our example from the quickstart tutorial is as minimal as it can possibly be. -But there is a lot happening already, as you can see, even in such a minimal example. -Lets take some time to understand how everything works. +In technical terms, this is what the example's source code does: +- It uses the `ECS` pattern +- It creates an `Entity` +- It adds few `Component`s to the Entity +- It imports some Ethereal Engine's typescript modules in its code +- It adds its code to the engine through the `xrengine.config.ts` file ```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers import { ECS } from '@etherealengine/ecs' @@ -37,3 +35,16 @@ ECS.setComponent(entity, VisibleComponent) ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) ``` + +## The Path Forward +Our example from the quickstart tutorial is as minimal as it can possibly be. +But there is a lot happening already, as you can see, even in such a minimal example! +So, the first step we will take is to spend some time understanding how everything in the example works. + +Next we will get our hands into the code, and learn how to program with Ethereal Engine. + +Then, at the end of this guide, we will have a very minimal project that we can load with the Engine. +But, more importantly, we will have enough knowledge to be able to continue our learning through the `Ethereal Engine: Basics` guide. + +Lets not delay any longer, and get started with our journey! + From a818f5fbb64bbe8efb336864d0315b83a0c49da0 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:35:58 +0100 Subject: [PATCH 84/96] chg: Move modules/engine/testing into typescript/mastery/testing --- .../typescript/60_mastery/60_testing}/01_reasonableCode.md | 0 .../60_mastery/60_testing}/02_testDrivenDevelopment.md | 0 docs/developer/typescript/60_mastery/60_testing/_category_.yml | 1 + .../typescript/60_mastery/60_testing}/index.md | 0 docs/manual/03_modules/01_engine/07_testing/_category_.yml | 1 - 5 files changed, 1 insertion(+), 1 deletion(-) rename docs/{manual/03_modules/01_engine/07_testing => developer/typescript/60_mastery/60_testing}/01_reasonableCode.md (100%) rename docs/{manual/03_modules/01_engine/07_testing => developer/typescript/60_mastery/60_testing}/02_testDrivenDevelopment.md (100%) create mode 100644 docs/developer/typescript/60_mastery/60_testing/_category_.yml rename docs/{manual/03_modules/01_engine/07_testing => developer/typescript/60_mastery/60_testing}/index.md (100%) delete mode 100644 docs/manual/03_modules/01_engine/07_testing/_category_.yml diff --git a/docs/manual/03_modules/01_engine/07_testing/01_reasonableCode.md b/docs/developer/typescript/60_mastery/60_testing/01_reasonableCode.md similarity index 100% rename from docs/manual/03_modules/01_engine/07_testing/01_reasonableCode.md rename to docs/developer/typescript/60_mastery/60_testing/01_reasonableCode.md diff --git a/docs/manual/03_modules/01_engine/07_testing/02_testDrivenDevelopment.md b/docs/developer/typescript/60_mastery/60_testing/02_testDrivenDevelopment.md similarity index 100% rename from docs/manual/03_modules/01_engine/07_testing/02_testDrivenDevelopment.md rename to docs/developer/typescript/60_mastery/60_testing/02_testDrivenDevelopment.md diff --git a/docs/developer/typescript/60_mastery/60_testing/_category_.yml b/docs/developer/typescript/60_mastery/60_testing/_category_.yml new file mode 100644 index 000000000000..0c02fd033a91 --- /dev/null +++ b/docs/developer/typescript/60_mastery/60_testing/_category_.yml @@ -0,0 +1 @@ +position: 60 diff --git a/docs/manual/03_modules/01_engine/07_testing/index.md b/docs/developer/typescript/60_mastery/60_testing/index.md similarity index 100% rename from docs/manual/03_modules/01_engine/07_testing/index.md rename to docs/developer/typescript/60_mastery/60_testing/index.md diff --git a/docs/manual/03_modules/01_engine/07_testing/_category_.yml b/docs/manual/03_modules/01_engine/07_testing/_category_.yml deleted file mode 100644 index afad33bf7b1a..000000000000 --- a/docs/manual/03_modules/01_engine/07_testing/_category_.yml +++ /dev/null @@ -1 +0,0 @@ -position: 7 \ No newline at end of file From 43979997dbbe395cb609e6fb08dfca086e2e27aa Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:36:51 +0100 Subject: [PATCH 85/96] chg: Move modules/engine/state to developer/typescript/ecs/state --- .../typescript/40_reactivity/01_state.md | 79 ++++++++++++++++++ .../01_engine/03_stateManagement.md | 83 ++----------------- 2 files changed, 84 insertions(+), 78 deletions(-) create mode 100644 docs/developer/typescript/40_reactivity/01_state.md diff --git a/docs/developer/typescript/40_reactivity/01_state.md b/docs/developer/typescript/40_reactivity/01_state.md new file mode 100644 index 000000000000..d9fe499dbe1c --- /dev/null +++ b/docs/developer/typescript/40_reactivity/01_state.md @@ -0,0 +1,79 @@ +# State Management +All of Ethereal Engine's state management uses [Hookstate](https://hookstate.js.org/) and [React](https://react.dev/). +Together, these tools give reactive, declarative, and controlled state management across any scope. + +## Scoped State +Scoped state can be defined using the `useHookstate` hook. +This functionality uses vanilla `Hookstate`, and is useful for: +- State that is only used in a single component +- State that is only used in a single component tree + +```tsx +import { useHookstate } from '@hookstate/core' + +const MyComponent = () => { + const state = useHookstate({ + count: 0 + }) + return ( +
+

Count: {state.count}

+ +
+ ) +} +``` + +## Global State +Global state definitions are wrapped in a 'store' which allows for automatic creation and cleanup as needed. +This API, as well as the underlying hookstate API, can be imported from `@etherealengine/hyperflux`. + +```ts title="MyState.ts" +import { defineState } from '@etherealengine/hyperflux' + +const MyState = defineState({ + name: 'MyState', + initial: { + count: 0 + } +}) +``` + +Global state will be registered to the engine instance once it has been called with `getState` or `getMutableState`. +This will cause the state to be created if it does not exist, and will be cleaned up when the engine instance is destroyed. + +It's proxy can be accessed with `Engine.instance.store.stateMap.MyState` where `MyState` is the name of the state. + +When accessing the state, `getState` returns the underlying object typed as readonly. +This is useful for reading state values, but should not be used to write to state. + +```ts +import { getState } from '@etherealengine/hyperflux' +import { MyState } from './MyState' + +const state = getState(MyState) +console.log(state.count) // 0 +state.count = 1 // Error: Cannot assign to 'count' because it is a read-only property. +``` + +State can be mutated via the `getMutableState` function, which returns a proxy to the state, which can be used to read and write state values. +The proxy is reactive, so any changes to the state will cause the component to re-render. + +The proxy returned can be wrapped in Hookstate's reactive hook `useHookstate`. +This will cause the component to re-render when any state values are changed. + +```tsx +import { getMutableState, useHookstate } from '@etherealengine/hyperflux' +import { MyState } from './MyState' + +const MyComponent = () => { + const state = useHookstate(getMutableState(MyState)) + return ( +
+

Count: {state.count}

+ +
+ ) +} +``` + diff --git a/docs/manual/03_modules/01_engine/03_stateManagement.md b/docs/manual/03_modules/01_engine/03_stateManagement.md index 0c5077f113fe..8e423ecc51e7 100644 --- a/docs/manual/03_modules/01_engine/03_stateManagement.md +++ b/docs/manual/03_modules/01_engine/03_stateManagement.md @@ -1,79 +1,6 @@ # State Management - -All of Ethereal Engine's state management uses [Hookstate](https://hookstate.js.org/) and [React](https://react.dev/). -Together, these tools give reactive, declarative, and controlled state management across any scope. - -## Scoped State -Scoped state can be defined using the `useHookstate` hook. -This functionality uses vanilla `Hookstate`, and is useful for: -- State that is only used in a single component -- State that is only used in a single component tree - -```tsx -import { useHookstate } from '@hookstate/core' - -const MyComponent = () => { - const state = useHookstate({ - count: 0 - }) - return ( -
-

Count: {state.count}

- -
- ) -} -``` - -## Global State -Global state definitions are wrapped in a 'store' which allows for automatic creation and cleanup as needed. -This API, as well as the underlying hookstate API, can be imported from `@etherealengine/hyperflux`. - -```ts title="MyState.ts" -import { defineState } from '@etherealengine/hyperflux' - -const MyState = defineState({ - name: 'MyState', - initial: { - count: 0 - } -}) -``` - -Global state will be registered to the engine instance once it has been called with `getState` or `getMutableState`. -This will cause the state to be created if it does not exist, and will be cleaned up when the engine instance is destroyed. - -It's proxy can be accessed with `Engine.instance.store.stateMap.MyState` where `MyState` is the name of the state. - -When accessing the state, `getState` returns the underlying object typed as readonly. -This is useful for reading state values, but should not be used to write to state. - -```ts -import { getState } from '@etherealengine/hyperflux' -import { MyState } from './MyState' - -const state = getState(MyState) -console.log(state.count) // 0 -state.count = 1 // Error: Cannot assign to 'count' because it is a read-only property. -``` - -State can be mutated via the `getMutableState` function, which returns a proxy to the state, which can be used to read and write state values. -The proxy is reactive, so any changes to the state will cause the component to re-render. - -The proxy returned can be wrapped in Hookstate's reactive hook `useHookstate`. -This will cause the component to re-render when any state values are changed. - -```tsx -import { getMutableState, useHookstate } from '@etherealengine/hyperflux' -import { MyState } from './MyState' - -const MyComponent = () => { - const state = useHookstate(getMutableState(MyState)) - return ( -
-

Count: {state.count}

- -
- ) -} -``` + From 4aa8324c9824e70e9332d793e5f2eb7a1b5b798a Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:37:17 +0100 Subject: [PATCH 86/96] new: Create developer/typescript/reactivity section --- docs/developer/typescript/40_reactivity/02_reactors.md | 1 + docs/developer/typescript/40_reactivity/_category_.yml | 1 + docs/developer/typescript/40_reactivity/index.md | 6 ++++++ 3 files changed, 8 insertions(+) create mode 100644 docs/developer/typescript/40_reactivity/02_reactors.md create mode 100644 docs/developer/typescript/40_reactivity/_category_.yml create mode 100644 docs/developer/typescript/40_reactivity/index.md diff --git a/docs/developer/typescript/40_reactivity/02_reactors.md b/docs/developer/typescript/40_reactivity/02_reactors.md new file mode 100644 index 000000000000..63ebc9636e20 --- /dev/null +++ b/docs/developer/typescript/40_reactivity/02_reactors.md @@ -0,0 +1 @@ +# Reactors diff --git a/docs/developer/typescript/40_reactivity/_category_.yml b/docs/developer/typescript/40_reactivity/_category_.yml new file mode 100644 index 000000000000..c3c5db22d9fc --- /dev/null +++ b/docs/developer/typescript/40_reactivity/_category_.yml @@ -0,0 +1 @@ +position: 40 diff --git a/docs/developer/typescript/40_reactivity/index.md b/docs/developer/typescript/40_reactivity/index.md new file mode 100644 index 000000000000..457ba766a492 --- /dev/null +++ b/docs/developer/typescript/40_reactivity/index.md @@ -0,0 +1,6 @@ +import DocCardList from '@theme/DocCardList' + +# Reactivity + + + From a28c6e98a715fd2d9a5ea0fd60da85e3f9ca3938 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 29 Feb 2024 21:38:36 +0100 Subject: [PATCH 87/96] chg: Move parts of manual/ecs to the typescript/ecs intermediate guide --- .../typescript/04_ecs/01_components/index.md | 43 +++++++++++ .../04_ecs/02_systems/50_order/index.md | 12 +++ .../typescript/04_ecs/03_queries/index.md | 23 +++++- .../60_mastery/60_unittests/_category_.yml | 1 - .../60_mastery/60_unittests/index.md | 4 - docs/manual/03_modules/01_engine/04_ecs.md | 77 +------------------ 6 files changed, 76 insertions(+), 84 deletions(-) delete mode 100644 docs/developer/typescript/60_mastery/60_unittests/_category_.yml delete mode 100644 docs/developer/typescript/60_mastery/60_unittests/index.md diff --git a/docs/developer/typescript/04_ecs/01_components/index.md b/docs/developer/typescript/04_ecs/01_components/index.md index 61da6d4a36d8..ab9412bb7b2b 100644 --- a/docs/developer/typescript/04_ecs/01_components/index.md +++ b/docs/developer/typescript/04_ecs/01_components/index.md @@ -3,8 +3,51 @@ sidebar_label: Components --- # Working with Components ## Custom Components + + +## `defineComponent` fields +### `onInit` +`(entity: Entity) => ComponentType` +**onInit** is a function that is called when **setComponent** is called on an entity that does not have the component in question. +It takes an entity number, and should return an object with the initial values for the component. + + +### `onSet` +`(entity: Entity, component: ComponentType, json: SerializedComponentType) => void` +**onSet** is a function that is called each time **setComponent** is called. +It takes an `entity` number, a `component` object and a `json` object. + +This function provides a method for reactive data to be updated in batch _(such as deserializing scene data)_, which allows for a much tighter data flow. + + +### `onRemove` +`(entity: Entity, component: ComponentType) => void` +**onRemove** is a function that is called when **removeComponent** is called on an entity that has the component in question. +It takes an `entity` number and a `component` object. + +This function is where any resources associated with the component should be cleaned. + + +### `toJSON` +`(entity: Entity, component: ComponentType) => SerializedComponentType` +**toJSON** is a function that is called when **serializeComponent** is called on an entity that has the component in question. +It takes an entity number and a component object. + +This function is where the component's data should be serialized _(eg: transforming a scene's data for saving to a file)_. + +### `jsonID` +`string` +The **jsonID** property is a string that is used to identify the component in json. + +It is used for identifying scenes when their data is serialized/deserialized. + +### `reactor` +`function(props: { root: EntityRoot }) => void` +The **reactor** property specifies a function that exists for the duration of this component instance. + +This function is where any effects that depend on the component should be defined. diff --git a/docs/developer/typescript/04_ecs/02_systems/50_order/index.md b/docs/developer/typescript/04_ecs/02_systems/50_order/index.md index 01ed8a5a8787..791542c37642 100644 --- a/docs/developer/typescript/04_ecs/02_systems/50_order/index.md +++ b/docs/developer/typescript/04_ecs/02_systems/50_order/index.md @@ -6,7 +6,19 @@ import DocCardList from '@theme/DocCardList' import { TechnicalNote } from '@site/src/components/TechnicalNote'; # Systems Execution Guide +## Update Loop +Ethereal Engine uses a very similar model to [Unity's update loop](https://docs.unity3d.com/Manual/ExecutionOrder.html), by the use of a [fixed timestep](https://www.gafferongames.com/post/fix_your_timestep/) update loop. +The engine defines a `frame update` process that is called once per frame. +Inside this frame-update process there is a `fixed update` process that operates with an `accumulator` pattern. +This accumulator ensures that time will always step at a stable number of updates per second, independent of the processing power of the hardware running the engine. + +_Note: Because the fixed update process is independent of frame updates, each individual frame update may execute 0-to-many fixed updates during its lifetime._ + +Ethereal Engine implements this feature through system **pipelines**, which are collections of systems that will be executed in a specific order. + + +## Execution Order diff --git a/docs/developer/typescript/04_ecs/03_queries/index.md b/docs/developer/typescript/04_ecs/03_queries/index.md index 2a60cf1823a1..fc0556e1fd97 100644 --- a/docs/developer/typescript/04_ecs/03_queries/index.md +++ b/docs/developer/typescript/04_ecs/03_queries/index.md @@ -1,4 +1,21 @@ # Queries - +Queries are used to select entities that have a specific set of components. +They are used to define the entities that a system will operate on. + +Queries are defined using the **defineQuery** function: +```ts +const query = defineQuery([TransformComponent, GroupComponent]) + +const entities = query() // returns an array of entity numbers +``` + +Queries also have enter and exit derivatives. +They are used to define when a combination of components is added or removed from an entity. +These variations are defined using the **defineEnterQuery** and **defineExitQuery** functions: +```ts +const query = defineQuery([TransformComponent, GroupComponent]) + +const allEntities = query() +const enterEntities = query.enter() +const exitEntities = query.exit() +``` diff --git a/docs/developer/typescript/60_mastery/60_unittests/_category_.yml b/docs/developer/typescript/60_mastery/60_unittests/_category_.yml deleted file mode 100644 index 4c983da94092..000000000000 --- a/docs/developer/typescript/60_mastery/60_unittests/_category_.yml +++ /dev/null @@ -1 +0,0 @@ -position: 61 diff --git a/docs/developer/typescript/60_mastery/60_unittests/index.md b/docs/developer/typescript/60_mastery/60_unittests/index.md deleted file mode 100644 index 99c7edbb3c30..000000000000 --- a/docs/developer/typescript/60_mastery/60_unittests/index.md +++ /dev/null @@ -1,4 +0,0 @@ -# Unit Testing - diff --git a/docs/manual/03_modules/01_engine/04_ecs.md b/docs/manual/03_modules/01_engine/04_ecs.md index da11f5487c1f..39145d5b208a 100644 --- a/docs/manual/03_modules/01_engine/04_ecs.md +++ b/docs/manual/03_modules/01_engine/04_ecs.md @@ -24,7 +24,7 @@ Reactors come in 3 types: _(and custom reactors, which are functionally equivalent to system reactors)_ --> -## Component Definitions +## Component Data Types Components support two types of data: - Structure of Arrays - Array of Structures @@ -74,81 +74,6 @@ const DebugArrowComponent = defineComponent({ }) ``` -### onInit -`(entity: Entity) => ComponentType` -**onInit** is a function that is called when **setComponent** is called on an entity that does not have the component in question. -It takes an entity number, and should return an object with the initial values for the component. - - -### onSet -`entity: Entity, component: ComponentType, json: SerializedComponentType) => void` -**onSet** is a function that is called each time **setComponent** is called. -It takes an `entity` number, a `component` object and a `json` object. - -This function provides a method for reactive data to be updated in batch _(such as deserializing scene data)_, which allows for a much tighter data flow. - - -### onRemove -`(entity: Entity, component: ComponentType) => void` -**onRemove** is a function that is called when **removeComponent** is called on an entity that has the component in question. -It takes an `entity` number and a `component` object. - -This function is where any resources associated with the component should be cleaned. - - -### toJSON -`(entity: Entity, component: ComponentType) => SerializedComponentType` -**toJSON** is a function that is called when **serializeComponent** is called on an entity that has the component in question. -It takes an entity number and a component object. - -This function is where the component's data should be serialized _(eg: transforming a scene's data for saving to a file)_. - -### jsonID -`string` -The **jsonID** property is a string that is used to identify the component in json. - -It is used for identifying scenes when their data is serialized/deserialized. - -### reactor -`function(props: { root: EntityRoot }) => void` -The **reactor** property specifies a function that exists for the duration of this component instance. - -This function is where any effects that depend on the component should be defined. - - -## Update Loop -Ethereal Engine uses a very similar model to [Unity's update loop](https://docs.unity3d.com/Manual/ExecutionOrder.html), by the use of a [fixed timestep](https://www.gafferongames.com/post/fix_your_timestep/) update loop. - -The engine defines a `frame update` process that is called once per frame. -Inside this frame-update process there is a `fixed update` process that operates with an `accumulator` pattern. -This accumulator ensures that time will always step at a stable number of updates per second, independent of the processing power of the hardware running the engine. - -_Note: Because the fixed update process is independent of frame updates, each individual frame update may execute 0-to-many fixed updates during its lifetime._ - -Ethereal Engine implements this feature through system **pipelines**, which are collections of systems that will be executed in a specific order. - -## Queries -Queries are used to select entities that have a specific set of components. -They are used to define the entities that a system will operate on. - -Queries are defined using the **defineQuery** function: -```ts -const query = defineQuery([TransformComponent, GroupComponent]) - -const entities = query() // returns an array of entity numbers -``` - -Queries also have enter and exit derivatives. -They are used to define when a combination of components is added or removed from an entity. -These variations are defined using the **defineEnterQuery** and **defineExitQuery** functions: -```ts -const query = defineQuery([TransformComponent, GroupComponent]) - -const allEntities = query() -const enterEntities = query.enter() -const exitEntities = query.exit() -``` - ## Examples From f34053f03498915cf78ae739c35d785961beef4f Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 1 Mar 2024 00:15:26 +0100 Subject: [PATCH 88/96] chg: Hello/query editing pass --- .../typescript/01_gettingStarted/02_hello/05_query.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md index 31afc6dc06f4..376b35efdc51 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md @@ -37,9 +37,8 @@ Same as before, if you run the project as it is now you won't see any changes ju We have defined the Query that will search for our Scene's entity, but we haven't called it yet. ## Using our Query -A Query, when called, will return a array. -This array will contain the list of all entities that match the list of Components that we specified. -Just like any other array, we can iterate through it with a `for` loop. +A Query, when called, will return a [JavaScript Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generator_functions). +This Generator can be used to access the list of all entities that match the list of Components that we specified. This means that we can access as many entities as we want from a single unified place! Really powerful. @@ -64,6 +63,9 @@ The state management code **must** be inside our `execute` function. We need to execute some code for an entity, just like we did before. That hasn't changed. But we need to change **where** our code will be run. + +Generators are called as if they were functions with no arguments, and they will [`yield`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield) the next entry of the list on every iteration. + From aa7d7ae998105364b3a769e56fbeae49691ca97e Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 1 Mar 2024 08:57:44 +0100 Subject: [PATCH 89/96] fmt: Change Basics/physics to fit the CustomComponent previous code --- .../typescript/02_basics/02_physics.md | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/docs/developer/typescript/02_basics/02_physics.md b/docs/developer/typescript/02_basics/02_physics.md index f2e0b3073ea2..65b0c9a510ea 100644 --- a/docs/developer/typescript/02_basics/02_physics.md +++ b/docs/developer/typescript/02_basics/02_physics.md @@ -71,7 +71,7 @@ ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 3, 0) }) -```ts title="ee-tutorial-hello/Hello.ts" showLineNumbers +```ts title="ee-tutorial-basics/Step2.ts" showLineNumbers import { ECS } from '@etherealengine/ecs' import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' @@ -79,39 +79,47 @@ import { TransformComponent } from '@etherealengine/spatial/src/transform/compon import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' import { Vector3 } from 'three' import { GeometryTypeEnum } from '@etherealengine/engine/src/scene/constants/GeometryTypeEnum' -import { PhysicsSystem } from '@etherealengine/spatial/src/physics/PhysicsModule' - -// highlight-start +import { PhysicsSystem } from '@etherealengine/spatial' +// Import both components from the Spatial/physics module +//highlight-start import { RigidBodyComponent } from '@etherealengine/spatial/src/physics/components/RigidBodyComponent' import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent' -// highlight-end - - -let initialized = false -const hello = () => { - if (initialized) return - initialized = true - - const entity = ECS.createEntity() - ECS.setComponent(entity, NameComponent, 'hello-world') - ECS.setComponent(entity, VisibleComponent) - // highlight-start - ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 3, 0) }) - // highlight-end - ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) - - // highlight-start - ECS.setComponent(entity, RigidBodyComponent, { type: 'dynamic' }) - ECS.setComponent(entity, ColliderComponent, { shape: 'sphere' }) - // highlight-end -} - -export const HelloWorldSystem = ECS.defineSystem({ - uuid: 'helloworld.system', - execute: hello, +//highlight-end + +export const BasicsComponent = ECS.defineComponent({ + name: 'ee.tutorial.BasicsComponent', + jsonID: 'EE_tutorial_basics', + onInit: () => { return { initialized: false } } +}) + +const basicsQuery = ECS.defineQuery([BasicsComponent]) + +export const BasicsSystem = ECS.defineSystem({ + uuid: 'ee.tutorial.BasicsSystem', + execute: () => { + for (const entity of basicsQuery()) { + let { initialized } = ECS.getMutableComponent(entity, BasicsComponent) + if (initialized.value) continue + initialized.set(true) + + ECS.setComponent(entity, NameComponent, 'ee.tutorial.basics-entity') + ECS.setComponent(entity, VisibleComponent) + // Make the ball spawn 3 units along the Y axis (aka 3u above the ground) + //highlight-start + ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 3, 0) }) + //highlight-end + ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: GeometryTypeEnum.SphereGeometry }) + // Set both components to our entity + //highlight-start + ECS.setComponent(entity, RigidBodyComponent, { type: 'dynamic' }) + ECS.setComponent(entity, ColliderComponent, { shape: 'sphere' }) + //highlight-end + } + }, insert: { after: PhysicsSystem } }) ``` + From c609b2f444f81de99b2307c7345ecc23e3c0b5d2 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 1 Mar 2024 09:13:03 +0100 Subject: [PATCH 90/96] chg: Remove noise from the developer/typescript index page --- docs/developer/typescript/typescript.md | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/docs/developer/typescript/typescript.md b/docs/developer/typescript/typescript.md index 187ca418e07c..ce702b4eda45 100644 --- a/docs/developer/typescript/typescript.md +++ b/docs/developer/typescript/typescript.md @@ -2,22 +2,16 @@ sidebar_position: 00 --- # Become a Developer - -This section will explain everything that there is to know about programming with Ethereal Engine. - -_This page will contain an Introduction to the Developer Learning Site._ -_In the meantime, please refer to the [Manual](/manual) section for more information._ - -# Introduction +Here you will learn everything that there is to know about programming with Typescript + Ethereal Engine. -_This page will contain an introduction to the Getting Started: Developer guides._ + No-Code: Segue into the VisualScript Learning site + Typescript: Segue into the Typescript Learning Site (this site) _Programming in Ethereal Engine can be done through **Typescript**._ _But the engine also has a visual alternative to programming, called **VisualScript**._ - +--> From c01187399498e8126e6345dcc10a815d32fb102b Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 1 Mar 2024 16:00:04 +0100 Subject: [PATCH 91/96] chg: Basics/state page improvements --- .../typescript/02_basics/03_state.md | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/developer/typescript/02_basics/03_state.md b/docs/developer/typescript/02_basics/03_state.md index b49c2978a1d2..2bed7fc0aaeb 100644 --- a/docs/developer/typescript/02_basics/03_state.md +++ b/docs/developer/typescript/02_basics/03_state.md @@ -4,7 +4,34 @@ sidebar_label: State import { TechnicalNote } from '@site/src/components/TechnicalNote'; -# Managing State +# State Management +We have been talking about the concept of `State`, but we have never really explained what it is or how to use it correctly. Lets fix that now. + +## What is State +In Computer Science, [State](https://en.wikipedia.org/wiki/State_(computer_science)) is the concept of remembering information (data) about something that happened earlier in time. + +Lets say we want to: +1. Increment a number every second +2. Keep incrementing the number until the application stops + +To achieve this, we would need to store the current value of our number inside a variable, and that variable would contain our `State`. + +In this example, our State variable would represent the seconds elapsed. +So, we could name it `clock` or `clockSeconds` to make it easier to understand the purpose of the data contained in the variable. + +That is exactly what we did with our `initialized` variable from before. +We needed to run our code only once _(aka when our code is first loaded)_ so we created an `if (initialized)` check that exited our code early when the value was `true`. +Then, by updating the information contained in our variable to `true` inside our block of code, we essentially created a `State Variable` that remembered that our code was already initialized so the code would never repeat again. + +### Global State +### Local State + +## React State +Global State in React is any State that is shared across Components. +Its main purpose is to avoid prop drilling when a piece of State is supposed to be accessed by a child component several levels down the component tree. +Its purpose is being able to share updatable variables between multiple Components, without having to pass their data from component to component (aka "prop-drilling") + +## Managing State There are multiple ways to keep track of state - Manually maintaining the value of a variable - A state variable with `Hyperflux` @@ -15,10 +42,23 @@ You might remember the `initialized` variable we created in an earlier section o That variable was what is called "Local State". As you saw, we are fully responsible of book-keeping the values contained in the variables we create in this way. +There are also strict limitations on what these values can be used for. + ## Hyperflux + +### Hookstate +Hookstate is a tool created to simplify state management in React applications. + + +### Ethereal Engine's Hyperflux Ethereal Engine provides a group of functions to manage state asynchronously. ## `useEffect` +We want to do some sort of side-effect whenever something happens. +1. Everything contained is run everytime our application is rendered (aka every update) +2. Everything contained is run when the component is first "Mounted" (explain mount) +3. List of values that, whenever they change, the code contained in the `useEffect` function is going to run +Explain what a reactor mount is From 1ac976369763efd11075df1ee34563e9899ee7ae Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Mon, 4 Mar 2024 23:13:03 +0100 Subject: [PATCH 92/96] new: Port tldraw list of events to execution order page --- .../04_ecs/02_systems/50_order/01_input.md | 13 ++++++++++++ .../02_systems/50_order/02_simulation.md | 14 +++++++++++++ .../02_systems/50_order/03_animation.md | 20 +++++++++++++++++++ .../02_systems/50_order/04_presentation.md | 2 ++ 4 files changed, 49 insertions(+) diff --git a/docs/developer/typescript/04_ecs/02_systems/50_order/01_input.md b/docs/developer/typescript/04_ecs/02_systems/50_order/01_input.md index 0e2d473e8973..02bd7210fd2b 100644 --- a/docs/developer/typescript/04_ecs/02_systems/50_order/01_input.md +++ b/docs/developer/typescript/04_ecs/02_systems/50_order/01_input.md @@ -2,4 +2,17 @@ diff --git a/docs/developer/typescript/04_ecs/02_systems/50_order/02_simulation.md b/docs/developer/typescript/04_ecs/02_systems/50_order/02_simulation.md index 52270d142b1a..4007e5df5adb 100644 --- a/docs/developer/typescript/04_ecs/02_systems/50_order/02_simulation.md +++ b/docs/developer/typescript/04_ecs/02_systems/50_order/02_simulation.md @@ -3,4 +3,18 @@ TODO: - [ ] Fixed Rate event : Simulation system Anything at a capped/fixed rate + +Apply Incoming Actions +- run event sourcing + +AvatarMovementSystem +- Translates avatar via rigidbody +- XR/Mocap movement to kinematic rigidbody position + +PhysicsSystem + +TriggerSystem +- call trigger callbacks + +Apply outgoing actions --> diff --git a/docs/developer/typescript/04_ecs/02_systems/50_order/03_animation.md b/docs/developer/typescript/04_ecs/02_systems/50_order/03_animation.md index 889d47962c6d..67729110b6e4 100644 --- a/docs/developer/typescript/04_ecs/02_systems/50_order/03_animation.md +++ b/docs/developer/typescript/04_ecs/02_systems/50_order/03_animation.md @@ -4,4 +4,24 @@ TODO: - [ ] Visual Rate event : Animation system - [ ] Write an example where the ball changes color based on velocity Anything pre-visual + +ReferenceSpaceTransformSystem +- update webxr ref space with new avatar physics pose + +AnimationSystem +- run animation graph and mixer + +AvatarAnimationSystem +- root motion +- animation blending + +IKSystem +- solve IK +- VRM copy + +MotionCaptureSystem +- Sets local avatar rig from MotionCaptureRigComponent data +- Runs solvers writing to MotionCaptureRigComponent + +Transform System --> diff --git a/docs/developer/typescript/04_ecs/02_systems/50_order/04_presentation.md b/docs/developer/typescript/04_ecs/02_systems/50_order/04_presentation.md index 70f4186c60a5..5a41a6c77939 100644 --- a/docs/developer/typescript/04_ecs/02_systems/50_order/04_presentation.md +++ b/docs/developer/typescript/04_ecs/02_systems/50_order/04_presentation.md @@ -3,4 +3,6 @@ TODO: - [ ] Non-visual Event : Presentation system Anything that doesn't need to be done before the engine presents the frame on the screen + +Render --> From 57024fe5cbb4364e04156f14705e2520523eaf56 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Mon, 4 Mar 2024 23:13:28 +0100 Subject: [PATCH 93/96] chg: Progress on the Basics/state page --- .../typescript/02_basics/03_state.md | 78 ++++++++++++++----- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/docs/developer/typescript/02_basics/03_state.md b/docs/developer/typescript/02_basics/03_state.md index 2bed7fc0aaeb..6e13c6e59fbd 100644 --- a/docs/developer/typescript/02_basics/03_state.md +++ b/docs/developer/typescript/02_basics/03_state.md @@ -5,7 +5,7 @@ sidebar_label: State import { TechnicalNote } from '@site/src/components/TechnicalNote'; # State Management -We have been talking about the concept of `State`, but we have never really explained what it is or how to use it correctly. Lets fix that now. +We have been talking about the concept of `State`, but we never really explained what it is or how to use it correctly. Lets fix that now. ## What is State In Computer Science, [State](https://en.wikipedia.org/wiki/State_(computer_science)) is the concept of remembering information (data) about something that happened earlier in time. @@ -14,48 +14,86 @@ Lets say we want to: 1. Increment a number every second 2. Keep incrementing the number until the application stops -To achieve this, we would need to store the current value of our number inside a variable, and that variable would contain our `State`. +We could store the current value of our number inside a variable, and that variable would contain our `State`: +```ts +// Simple example of a variable used to track our clock's current state +let seconds = ... +``` In this example, our State variable would represent the seconds elapsed. -So, we could name it `clock` or `clockSeconds` to make it easier to understand the purpose of the data contained in the variable. +We could name it `clock` or `clockSeconds` to make it easier to understand the purpose of the data contained in the variable. That is exactly what we did with our `initialized` variable from before. We needed to run our code only once _(aka when our code is first loaded)_ so we created an `if (initialized)` check that exited our code early when the value was `true`. -Then, by updating the information contained in our variable to `true` inside our block of code, we essentially created a `State Variable` that remembered that our code was already initialized so the code would never repeat again. +Then, by updating the information contained in our variable to `true`, we created a `State Variable` that remembered whether our code was already initialized or not. -### Global State ### Local State +In Computer Science, [Scope](https://en.wikipedia.org/wiki/Scope_(computer_science)) is used to represent the part of the program where a name is valid. + +`Module Scope` is one of the many types of `Local Scope` that can exist. +When a name has Module Scope it means that the variable/function/etc it represents will only be accessible by code in: +- The file where it is declared +- A file where the name is imported _(only if the name was defined with `export`)_. + +Our `initialized` variable started as a Module Scope variable in the earlier sections of the [Hello World](../gettingStarted/hello/system) tutorial. We declared it at the top-level of our file, so it was `Local State` _(ie: Local to the Module)_. +```ts +let initialized = false +function hello() { + if (initialized) return + // ... etc +} +``` + +But, later on, we changed our code and moved the variable into our custom scene Component: +```ts +export const HelloComponent = defineComponent({ + ... + onInit: () => return { initialized: false } +}) +``` +With this change, we made our variable accessible anywhere where our Component is accessible. +This still doesn't make our state `Global`, but it changed the scope from "Local to the Module" to "Local to the Component". + + +### Global State +So far we have only dealt with Local State ## React State -Global State in React is any State that is shared across Components. -Its main purpose is to avoid prop drilling when a piece of State is supposed to be accessed by a child component several levels down the component tree. -Its purpose is being able to share updatable variables between multiple Components, without having to pass their data from component to component (aka "prop-drilling") +Global State in React is any State that can be shared between Components. +Its purpose is being able to share updatable variables between multiple components. (eg: Accessing a variable from a child component several levels down the component tree) without having to pass their data from component to component _(called "prop-drilling")_. + +React provides the [`Context`](https://react.dev/learn/passing-data-deeply-with-context) API for this exact purpose. +But, as we will explore in a moment, `Hookstate` and Ethereal Engine's `Hyperflux` are much better ways to manage the state of our project. -## Managing State -There are multiple ways to keep track of state +## Managing State in Ethereal Engine +There are multiple ways to keep track of state in Ethereal Engine: - Manually maintaining the value of a variable - A state variable with `Hyperflux` - A reactor mount with `useEffect` -## Local Variable -You might remember the `initialized` variable we created in an earlier section of the [Hello World](../gettingStarted/hello/system) tutorial. -That variable was what is called "Local State". - -As you saw, we are fully responsible of book-keeping the values contained in the variables we create in this way. +### Local Variable +As you saw, we are fully responsible of book-keeping the values contained in the variables we create this way. There are also strict limitations on what these values can be used for. -## Hyperflux +### Ethereal Engine's Hyperflux -### Hookstate +#### Hookstate Hookstate is a tool created to simplify state management in React applications. +We can access a vanilla hookstate State definition with the `useState` Hook from Hookstate. +Same as any other React Hook, we can only call the `useState` hook inside React Components. +The variable returned from `useState` will have: +1. `get()` method: Allows us to read the data contained in the variable +2. `set()` method: Allows us to modify the data of the variable +3. `merge()` method: Allows us to combine the current data with new data in an ergonomic way -### Ethereal Engine's Hyperflux +#### Hyperflux Ethereal Engine provides a group of functions to manage state asynchronously. -## `useEffect` + +### `useEffect` We want to do some sort of side-effect whenever something happens. -1. Everything contained is run everytime our application is rendered (aka every update) +1. Everything contained is run every time our application is rendered (aka every update) 2. Everything contained is run when the component is first "Mounted" (explain mount) 3. List of values that, whenever they change, the code contained in the `useEffect` function is going to run Explain what a reactor mount is From e0db6543976f4b5dd70e89d7522306bfb0f057e0 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 7 Mar 2024 03:38:35 +0100 Subject: [PATCH 94/96] chg: UX cleanup (phase1) --- docs/_partials/defaultProjects.md | 7 ++-- docs/_partials/installUbuntu.md | 14 +++++-- .../01_gettingStarted/01_quickstart.md | 12 ++++-- .../01_gettingStarted/02_hello/01_ecs.md | 9 +++++ .../01_gettingStarted/02_hello/02_engine.md | 4 +- .../01_gettingStarted/02_hello/03_system.md | 17 +++++---- .../02_hello/04_component.md | 12 +----- .../01_gettingStarted/02_hello/05_query.md | 38 ++++++++++++++++--- .../01_gettingStarted/02_hello/index.md | 36 +++++++++++------- 9 files changed, 100 insertions(+), 49 deletions(-) diff --git a/docs/_partials/defaultProjects.md b/docs/_partials/defaultProjects.md index d0aef8926a2c..f4955771b40a 100644 --- a/docs/_partials/defaultProjects.md +++ b/docs/_partials/defaultProjects.md @@ -1,7 +1,8 @@ -Ethereal Engine has a few projects that are installed by default. -With the engine running, open the Studio by navigating to https://localhost:3000/studio, and you will see the engine's default projects listed in that page. +Ethereal Engine has a few scenes that are installed by default. +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. Lets give them a test run: -- Open one of the default projects by clicking on its card +- Open one of the default project by clicking on its card +- Click on one of the scenes to open it - Click on the `Play` button to enter the scene with an Avatar - Move around the scene with `WASD` and/or clicking on the ground diff --git a/docs/_partials/installUbuntu.md b/docs/_partials/installUbuntu.md index 492d48e603f6..d3ebebe7bc19 100644 --- a/docs/_partials/installUbuntu.md +++ b/docs/_partials/installUbuntu.md @@ -1,11 +1,19 @@ +:::important +Ethereal Engine is a web application. +We are going to install and run a local version of the engine. +But this setup might not reflect how you will use the engine on a day to day basis. +::: + :::note -This guide assumes you are using Ubuntu Linux. +These installation instructions assume you are using Ubuntu Linux. 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. ::: -Ethereal Engine can be installed and run with: +If you are on Ubuntu Linux, there is an automatic installation script to setup and run a local version of Ethereal Engine. +Open a terminal window and run these two lines: +> Make sure that you open the terminal in the folder where you want to install the engine ```bash wget https://raw.githubusercontent.com/EtherealEngine/etherealengine/dev/scripts/ubuntu-install.sh && bash -i ./ubuntu-install.sh -npm run dev +npm run reinit && npm run dev ``` You can now open Ethereal Engine on your web browser by navigating to https://localhost:3000 diff --git a/docs/developer/typescript/01_gettingStarted/01_quickstart.md b/docs/developer/typescript/01_gettingStarted/01_quickstart.md index 1162c1a9714c..fd844b846977 100644 --- a/docs/developer/typescript/01_gettingStarted/01_quickstart.md +++ b/docs/developer/typescript/01_gettingStarted/01_quickstart.md @@ -15,11 +15,17 @@ This QuickStart guide will teach you the basics of Ethereal Engine, and how to r ### Install and Run the tutorial project -The previous command will have the engine running. +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. + +:::danger +This `HelloWorld` project should never be installed in a remote deployment. +A local version of the engine is required to follow this introductory tutorial. +::: + +The previous commands will have the engine running locally. Lets stop it by pressing `Ctrl+C`, and then run these commands to install and run the tutorial's template project: ```bash git clone -b Step0 https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello -npm install npm run dev ``` @@ -33,5 +39,5 @@ Lets make sure that our `hello world` code is running: You will know that the code is running if you can see a white sphere in the middle of the scene. :::note -You can also enter the scene and move around with an avatar by pressing the `Play` button in the editor. +You can also enter the scene and move around with an avatar by pressing the `Play` button in the editor like we did before. ::: diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md index f661127a3257..0cdb3a3a2a08 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/01_ecs.md @@ -14,6 +14,14 @@ The behavior of the application is then controlled by having separate Systems (l 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.
+:::note +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. + +You will find a lot of these `Technical` drop-downs throughout the guides. +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. + +Don't worry if you don't fully understand what some of them explain just yet. We will get there. +::: ## Creating an Entity Creating an Entity is as simple as calling the `createEntity()` function from Ethereal Engine's `ECS`. @@ -41,6 +49,7 @@ Ethereal Engine requires a specific set of Components in order to create an obje ### `NameComponent` Gives a human-readable identifier to an Entity. +Whatever name you add on this field is the name that will show up in the Studio and the debugger. They are not mandatory, but it is good practice to add them to all your entities. ```ts ECS.setComponent(entity, NameComponent, 'hello-world') diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md index fa2f3d14f70d..73beced84096 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md @@ -11,7 +11,7 @@ You will need three very important steps for creating a project with Ethereal En 3. Modify and run the source code of your project We already solved #1 and #2 in the [Quickstart](../quickstart) guide. -Lets explore how #2 works and how we can start programming with the engine. +Lets review how #1 and #2 work really quickly, and we will start programming with the engine right after. ## Installing and running projects Ethereal Engine can be **extended** with projects. @@ -56,7 +56,7 @@ There are two very important steps to take in order to connect our project to th ### Project Configuration File Every project has an `xrengine.config.ts` file that defines how it will behave in the engine. -There are multiple options available, but the important thing to remember is that our `src/Hello.ts` code will connected to the engine from here. +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. diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md b/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md index b5d99a7d17e9..234f106c6382 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/03_system.md @@ -46,7 +46,7 @@ But the correct way to do this is to define our code inside a separate function, Lets start by creating a new Typescript function, and moving our ECS code into that function. ```ts // Create a function -const /* name */ = () => { /* code */ } +function /* name */ () { /* code */ } ``` We will also need to make sure that our code is only run once. Try to figure out a way to make your function code execute only once before looking at the solution. @@ -60,7 +60,7 @@ let initialized = false // Track whether our code was already initialized or n //highlight-end //highlight-start -const hello = () => { // Define an arrow function that will run our code +function hello() { // Define a function that will run our code if (initialized) return // Exit early if the code was already run before initialized = true // Mark initialized to true, so the code is never run again later //highlight-end @@ -86,21 +86,22 @@ We will learn how properly manage state later on. -
- :::note -We are using a Typescript arrow function in this example. -You could also use a regular Typescript function definition if you prefer. +We are using a regular Typescript function in this example. +You could also use a Typescript arrow function if you prefer. Both styles work perfectly well. ::: +
+ + ### The `defineSystem` function In order to define a new system, we need to use the `defineSystem` function from the `ECS` namespace. This is what we need to know to use this function: -- `defineSystem` will return the type that represents our `System` +- `defineSystem` will return the identifier that represents our `System` - We need to `export` that type so that the engine can access it - We need to pass our function into the `execute` argument - We don't need to add any new imports. The `defineSystem` function is available through the `ECS` namespace @@ -153,7 +154,7 @@ let initialized = false // Track whether our code was already run or not //highlight-start // Our new function -const hello = () => { +function hello() { if (initialized) return initialized = true //highlight-end diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md index 096ccb64c490..9a44d089d9c4 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -101,15 +101,7 @@ We will explain why this is the case in the [Ethereal Engine Basics: State](/dev This code will be very useful for our next few steps. -Lets see how we can lock our code to be run only under a specific condition. +Don't dwell too much on where to place it just yet. I will give you better instructions for doing that later when we need it. - +Lets see how we can lock our code to be run only under a specific condition. diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md index 376b35efdc51..a6f8d0cba959 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md @@ -71,7 +71,7 @@ Generators are called as if they were functions with no arguments, and they will ```ts -const hello = () => { +function hello() { //highlight-start for (const entity of helloQuery()) { //highlight-end @@ -92,11 +92,30 @@ const hello = () => { ``` -## Conclusion -As you can see, we only added around 10 lines of code in these last two pages... -But we introduced so many new concepts! -That's the most exciting part about the ECS pattern. You can do **so** much with so little code. +## Loading the Component +Now, here is a question: +> How do we connect our custom scene Component to the scene? + +The answer to that is that there is one last piece of the project that we haven't talked about just yet. +You might have even seen it in the Studio already if you explored a bit! + +We don't know how to add a Component to an entity through the Studio just yet, or how to make our Component available through the studio UI. +And we have gone through two entire pages with a LOT of theory but not a whole lot of practice. So I have already solved this problem for you. + +When you open the `ee-tutorial-hello` project... there is a scene called `hello-final` in there. +That's what we are looking for :) +Thanks to the way that the `hello-final` scene is setup, our Component will work in that Scene because it has the Component... but it will not work anywhere else! Really neat. + + +What I did, exactly, was: +- I created an entity that contains the component we are Quering for +- I saved that entity into the scene +- I saved the scene into the project +This means that you already downloaded the scene when we cloned the repository during the Quickstart guide. + + +## Confirm the Code You will know that you completed the last two pages correctly if: - The behavior has not changed for your project. You can still see the sphere in the Scene. - You open another project _(eg: the `default-project` provided by the engine)_... @@ -153,8 +172,15 @@ export const HelloSystem = ECS.defineSystem({ insert: { after: PhysicsSystem } }) ``` -Note how the style for names in this solution has been changed. +Note how I have changed the code to use an arrow function. +They can be used interchangeably, so feel free to use either of them. + +Also, note how the style of the names in this solution has been changed. We will learn about them next.
+## Conclusion +As you can see, we only added around 10 lines of code in these last two pages... +But we introduced so many new concepts! +That's the most exciting part about the ECS pattern. You can do **so** much with so little code. diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/index.md b/docs/developer/typescript/01_gettingStarted/02_hello/index.md index 971a9915c5b3..651ef46f484b 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/index.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/index.md @@ -7,20 +7,14 @@ The quickstart tutorial helped us create a project and run the engine for the fi This is our starting point. The Quickstart has automated a lot for us, so lets review what we have. -## Conceptual overview -Conceptually, this is what the example project does: -- It creates an entity called `hello-world` -- It gives the entity a primitive geometry component _(a Sphere)_ -- It defines the position of the sphere in the scene - -## Technical overview -In technical terms, this is what the example's source code does: -- It uses the `ECS` pattern -- It creates an `Entity` -- It adds few `Component`s to the Entity -- It imports some Ethereal Engine's typescript modules in its code -- It adds its code to the engine through the `xrengine.config.ts` file - +:::note +Don't dwell too much on this page. +This is a quick preview, so please skim read and don't go into too much detail. +The purpose of the next few pages of this tutorial is to teach you how these concepts work. +::: + +## Hello World Code +This is how the code for our project looks like at the moment. ```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers import { ECS } from '@etherealengine/ecs' import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' @@ -36,6 +30,20 @@ ECS.setComponent(entity, TransformComponent, { position: new Vector3(0, 1, 0) }) ECS.setComponent(entity, PrimitiveGeometryComponent, { geometryType: 1 }) ``` +## Conceptual overview +Conceptually, this is what the example project does: +- It creates an entity called `hello-world` +- It gives the entity a primitive geometry component _(a Sphere)_ +- It defines the position of the sphere in the scene + +## Technical overview +In technical terms, this is what the example's source code does: +- It imports some Ethereal Engine's typescript modules in its code +- It uses the `ECS` pattern +- It creates an `Entity` +- It adds a few `Components` to the Entity +- It adds its code to the engine through the `xrengine.config.ts` file + ## The Path Forward Our example from the quickstart tutorial is as minimal as it can possibly be. But there is a lot happening already, as you can see, even in such a minimal example! From b486715f29388acc091cc8baa588bc2982113fb9 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Thu, 7 Mar 2024 23:45:44 +0100 Subject: [PATCH 95/96] chg: UX cleanup (phase2) --- .../01_gettingStarted/02_hello/02_engine.md | 50 +++++- .../02_hello/04_component.md | 7 +- .../01_gettingStarted/02_hello/05_query.md | 160 ++++++++++++------ .../01_gettingStarted/02_hello/90_congrats.md | 6 +- 4 files changed, 161 insertions(+), 62 deletions(-) diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md index 73beced84096..7a8a22ea9dda 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/02_engine.md @@ -11,7 +11,25 @@ You will need three very important steps for creating a project with Ethereal En 3. Modify and run the source code of your project We already solved #1 and #2 in the [Quickstart](../quickstart) guide. -Lets review how #1 and #2 work really quickly, and we will start programming with the engine right after. +Lets do a quick review of how #1 and #2 work, and we will start programming with the engine right after. + +## Requirements and Dependencies +We will use `git` and `npm` a lot throughout the guides on this website. + +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. + +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. +Just remember that they are used a lot to work with the engine locally. + +## Installing and running Ethereal Engine +Ethereal Engine is a web application. +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. + +We will eventually learn how to work with "deployed" versions of the engine. +But we need to follow this tutorial in a `local development server` instead. + +That's exactly what the Quickstart installation guide automated for us. +As the `localhost` part of the URL indicates, we are running a `local` version of the engine. ## Installing and running projects Ethereal Engine can be **extended** with projects. @@ -21,21 +39,26 @@ The engine scans for projects mounted in the `/packages/projects/projects` sub-f This means that we can install and run new projects by executing the following commands inside our Ethereal Engine installation folder: ```bash git clone https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello -npm install npm run dev ``` +:::note +You will need to stop the engine and re-run it whenever you install a new project. +::: + 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. We did this by adding `-b Step0` to the `git clone` command: + ```bash git clone -b Step0 https://github.com/EtherealEngine/ee-tutorial-hello packages/projects/projects/ee-tutorial-hello ``` + This step won't be needed for your own projects. These steps will: -- Download a copy of the project's git repository, so the engine can load it -- Install all `npm` packages required by the project +- Download a copy of the project's git repository, so the engine can load it +- Install all `npm` packages required by the project - Run a local development version of the engine :::note @@ -50,9 +73,9 @@ This will become very important later on in this guide. ## Programming with Ethereal Engine -There are two very important steps to take in order to connect our project to the engine: -- We need to import Ethereal Engine's modules -- We need to export our code so the engine can load our project +There are two very important steps to take in order to connect the source code of our project to the engine: +- We need to import some Ethereal Engine's modules +- We need to export our code so the engine can run it ### Project Configuration File Every project has an `xrengine.config.ts` file that defines how it will behave in the engine. @@ -91,7 +114,7 @@ import { TransformComponent } from '@etherealengine/spatial/src/transform/compon import { PrimitiveGeometryComponent } from '@etherealengine/engine/src/scene/components/PrimitiveGeometryComponent' ``` We will be adding these Components to our Entity, and Components are part of the ECS pattern. -As such, we will need to use the Ethereal Engine ECS management functions. +As such, we will need to use the Ethereal Engine ECS management functions. 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). ```ts title="ee-tutorial-hello/src/Hello.ts" import { ECS } from '@etherealengine/ecs' @@ -110,10 +133,11 @@ Lets start with a simple change. We will modify our Sphere `PrimitiveGeometryComponent` to load our geometry with a name, instead of the hardcoded number `1` that we used before. In order to do this, we need to: +- Open the file `ee-tutorial-hello/src/Hello.ts` with a text editor. - Import the `GeometryTypeEnum` from the `scene/constants/` sub-module inside the `engine` module. - Replace the `1` with a call to the `SphereGeometry` name that is stored inside it `GeometryTypeEnum`. -Try to make the change by yourself before looking at the solution. +Try to figure out the changes by yourself before looking at the solution. I don't expect you to know where that enum is stored, so here are some hints to make it easier: ```ts // The full path to the GeometryTypeEnum is: @@ -125,6 +149,14 @@ GeometryTypeEnum.SphereGeometry // To be certain that your changes are working, set the geometry to be a cylinder instead: GeometryTypeEnum.CylinderGeometry ``` +> As we said before, you will need to stop the engine and re-run it whenever you _install_ a new project. +> But you can just refresh the webpage when you update your source code and the engine will load your changes correctly. + +:::note +`VSCode` is the recommended editor for programming with Ethereal Engine. +It is not required, but it is highly recommended. +VSCode has support for some important features and plugins that make the Ethereal Engine programming workflow really smooth and featureful. +::: diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md index 9a44d089d9c4..722be5aea953 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/04_component.md @@ -99,9 +99,14 @@ And we are modifying its value with `initialized.set(true)` instead of `initiali We will explain why this is the case in the [Ethereal Engine Basics: State](/developer/typescript/basics/state) section. - This code will be very useful for our next few steps. Don't dwell too much on where to place it just yet. I will give you better instructions for doing that later when we need it. + +Notice how there is a [`continue`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue) statement in the second line. +[`continue`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue) is a keyword that only works inside of a loop _(eg: A `for` loop)_. +Remember that for later. + + Lets see how we can lock our code to be run only under a specific condition. diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md index a6f8d0cba959..c67940e05479 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/05_query.md @@ -23,7 +23,7 @@ This is how the function works: Here are your hints for this assignment: ```ts // Define the query that will find our Scene's Entity -const ... = ...([ ... ]) +const queryName = NAMESPACE.funtionName([ CustomComponentName ]) ``` @@ -44,27 +44,84 @@ This means that we can access as many entities as we want from a single unified Really powerful. I gave you one solution for free earlier, but I'm leaving this assignment a bit ambiguous on purpose. -See if you can figure out which part of your code goes where before looking at the solution. +I will give you three options. Pick the one that fits your learning style best: +1. Challenge: + See if you can figure out which part of your code goes where before looking at the solution or the hints. It will be very difficult. +2. Intermediate difficulty: + Open each hint one by one, and take some time to reason about what the hint is trying to say before opening the next one. + You might land on the solution earlier than you think. +3. Otherwise: + Read the hints, try to understand them a bit, and then compare what you thought with the full solution. + +Here are your hints: ```ts // Our for loop will look something like this -for (const entity of ...) { +for (const entity of /* queryName() */) { // Our code goes here ... } ``` -Here are some hints, in case you get stuck: - - -We cannot store our variable in module scope anymore. -The state management code **must** be inside our `execute` function. +This step is really difficult without hints. Don't worry if you cannot figure it out on your own. +There is a lot to process, so what matters most is that you think it through. + + +Generators are called as if they were functions with no arguments, and they will [`yield`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield) the next entry of the list on every iteration. + +So, our `for` loop should say: +```ts +for (const entity in helloQuery()) { + // do something for every entity +} +``` + + +We cannot store our `initialized` variable in module scope anymore. +And the code right above cannot be at the top level of your file either. +It **must** be inside a function. + + +Remember the hint from earlier about the `continue` keyword? +If not, [go back](./component#state-management) and read it again. You really need it now. - -We need to execute some code for an entity, just like we did before. That hasn't changed. -But we need to change **where** our code will be run. + +Now is the moment when you need to add the code that I gave you "for free" earlier. +Notice how the hint code above is giving you a `for` loop, and the State Management code has a `continue` keyword. They go together. - -Generators are called as if they were functions with no arguments, and they will [`yield`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield) the next entry of the list on every iteration. + +The `initialized` variable from before cannot exist anymore. +The state management code replaces it. + + +The state management code **must** be placed inside our `execute` function. + + +We need to execute some code for an entity, just like we did before. +That hasn't changed. + +But you cannot use `createEntity` anymore. +The entity is `requested` by the Query, not created. + +> The `hello-final` scene already contains the entity. +> Scroll down to the `Loading the Component` section right below if you are confused as to why this is the case. + + + +1. Import the engine modules +2. Define a Component +3. Define a Query that will request entities that contain that Component +4. Create a function that runs our code +5. Loop through all entities, and do something for each + _(We only have one, but we loop anyway)_ +6. Make sure that we only execute our code once for each entity +7. Define a System +8. Set our function as the System's `execute` function + +You already have the code for #1, #2, #3, #6 and #7 from before. +We are creating #4 with this step. +We are also modifying #5: +- The initialized variable is replaced with the State Management code I gave you +- The State Management code **must** placed inside the new #4 loop @@ -90,40 +147,7 @@ function hello() { } } ``` - - -## Loading the Component -Now, here is a question: -> How do we connect our custom scene Component to the scene? - -The answer to that is that there is one last piece of the project that we haven't talked about just yet. -You might have even seen it in the Studio already if you explored a bit! - -We don't know how to add a Component to an entity through the Studio just yet, or how to make our Component available through the studio UI. -And we have gone through two entire pages with a LOT of theory but not a whole lot of practice. So I have already solved this problem for you. - -When you open the `ee-tutorial-hello` project... there is a scene called `hello-final` in there. -That's what we are looking for :) - -Thanks to the way that the `hello-final` scene is setup, our Component will work in that Scene because it has the Component... but it will not work anywhere else! Really neat. - - -What I did, exactly, was: -- I created an entity that contains the component we are Quering for -- I saved that entity into the scene -- I saved the scene into the project -This means that you already downloaded the scene when we cloned the repository during the Quickstart guide. - - -## Confirm the Code -You will know that you completed the last two pages correctly if: -- The behavior has not changed for your project. You can still see the sphere in the Scene. -- You open another project _(eg: the `default-project` provided by the engine)_... - and the Sphere is gone! - -Lets put everything together. - - + ```ts title="ee-tutorial-hello/src/Hello.ts" showLineNumbers import { ECS } from '@etherealengine/ecs' @@ -172,15 +196,53 @@ export const HelloSystem = ECS.defineSystem({ insert: { after: PhysicsSystem } }) ``` -Note how I have changed the code to use an arrow function. +Notice how I have changed the code to use an arrow function. They can be used interchangeably, so feel free to use either of them. -Also, note how the style of the names in this solution has been changed. +Also, notice how the style of the names in this solution has been changed. We will learn about them next. + + +## Loading the Component +Now, here is a question: +> How do we connect our custom scene Component to the scene? + +The answer is that there is one last piece of the project that we haven't talked about just yet. +You might have even seen it in the Studio already if you explored a bit! + +We don't know how to add a Component to an entity through the Studio yet, or how to make our Component show up on the `Add Component` Studio UI. +And we have gone through two entire pages with a LOT of theory but not a whole lot of practice. +So I already solved this problem for you. + +When you open the `ee-tutorial-hello` project... there is a scene called `hello-final` in there. +That's what we are looking for :) + +Thanks to how the `hello-final` scene is setup, our Component will work in that Scene... but it will not work anywhere else! Really neat. + + +What I did, exactly, was: +- I added an entity to the scene +- I added the component we are Quering for to the entity +- I saved the scene into the project + +This means that, when you installed the project with the Quickstart guide, you also downloaded the final scene that we need. + + +## Confirm the Code +You will know that you have completed the [Components](./component) and [Queries](./query) tasks correctly if: +- The behavior has not changed for the `hello-final` scene. You can still see the sphere in the Scene. +- You open another scene _(eg: `default-project/appartment` provided by the engine)_... + and the Sphere is gone! + ## Conclusion As you can see, we only added around 10 lines of code in these last two pages... But we introduced so many new concepts! That's the most exciting part about the ECS pattern. You can do **so** much with so little code. +I hope you didn't struggle too much with the last task. I know it was a difficult one. +But I promise that, now that you have this knowledge, the road ahead will only get easier and easier. + +Lets see what we will learn next! + diff --git a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md index 21e254d18101..7b1e790e3ad3 100644 --- a/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md +++ b/docs/developer/typescript/01_gettingStarted/02_hello/90_congrats.md @@ -7,8 +7,8 @@ import { UnstyledDetails } from '@site/src/components/UnstyledDetails'; # 🎉 Congratulations! 🎉 You have just learned the minimal basics of working with Ethereal Engine using Typescript! -This was a very minimal introductory tutorial to get you started really quickly. -But Ethereal Engine has a lot more features to explore! +This was an introductory tutorial to teach you the core essentials of the engine as quickly as possible. +But Ethereal Engine has a lot of features to explore! ## What's Next? #### Beginner @@ -25,7 +25,7 @@ Make sure to skim-read the basics section at least once, as it gives an overview #### Advanced The [Manual](/manual) is where Ethereal Engine is presented in all of its complexity, without any guard-rails or hand-holding. -You will also find the [Reference API](https://etherealengine.github.io/etherealengine-docs//api) really useful when writing the code of your application. +You will also find the [Reference API](https://etherealengine.github.io/etherealengine-docs/api) really useful when writing the code of your application. :::note[Advanced Note] Make sure to read the `Mastery Toolkit` section at least once. It contains a list of important tools that you will need when working with advanced projects. From abf1fe597b350ccda75cf978452a4abec5311706 Mon Sep 17 00:00:00 2001 From: "Ivan Mar (sOkam!)" <7308253+heysokam@users.noreply.github.com> Date: Fri, 8 Mar 2024 01:02:59 +0100 Subject: [PATCH 96/96] fix: Leftover old code --- .../typescript/02_basics/01_recap/01_styling.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/developer/typescript/02_basics/01_recap/01_styling.md b/docs/developer/typescript/02_basics/01_recap/01_styling.md index bb0455e2ad14..71cd26edef4c 100644 --- a/docs/developer/typescript/02_basics/01_recap/01_styling.md +++ b/docs/developer/typescript/02_basics/01_recap/01_styling.md @@ -127,7 +127,7 @@ import { PhysicsSystem } from '@etherealengine/spatial' // Define our component export const HelloComponent = ECS.defineComponent({ name: 'ee.tutorial.HelloComponent', - jsonID: 'ee.tutorial.HelloComponent', + jsonID: 'EE_tutorial_hello', onInit: () => { return { initialized: false } } }) @@ -141,10 +141,10 @@ export const HelloSystem = ECS.defineSystem({ execute: () => { //highlight-end for (const entity of helloQuery()) { - const { initialized } = ECS.getComponent(entity, HelloComponent) - if (initialized) continue - - ECS.getMutableComponent(entity, HelloComponent).initialized.set(true) + // Check if we have already initialized our Sphere + let { initialized } = ECS.getMutableComponent(entity, HelloComponent) + if (initialized.value) continue + initialized.set(true) // Set our initialized state to true ECS.setComponent(entity, NameComponent, 'ee.tutorial.hello-entity') ECS.setComponent(entity, VisibleComponent)