Building the Portal Gate: Scene Graph Entities and Prefabs

In this lesson you'll learn to

  • βœ“Student can build the portal gate as an entity hierarchy with mesh components and save it as a reusable prefab stamped at all 5 booths.

Student can build the portal gate as an entity hierarchy with mesh components and save it as a reusable prefab stamped at all 5 booths.

πŸ“– Reference & full walkthrough: Building the Portal Gate: Scene Graph Entities and Prefabs

πŸ” Builds on: verse-scene-graph-intro + hierarchy-transforms (compile-passed set)

🧩 Your capstone piece: The portal-gate prefab reused at every zone booth


Entities & Components: Bolting Powers Onto Things in Verse

In Part 1 we learned the two big nouns: an entity is a thing in the world, and a component is a power you bolt onto it. Now let's write the real Verse. We'll do three things, in order:

  1. Write your own component (the most common thing you'll actually do).
  2. Read a component that's already on an entity.
  3. Add a component to an entity from code.

Keep The Grammar of Verse in the back of your mind β€” every line is still a sentence.

The most useful skill: writing your own component

<!-- section-art:the-most-useful-skill-writing-your-own-component --> Entities & Components: Bolting Powers Onto Things in Verse: The most useful skill: writing your own component

Bolt-On Component

Most of your Scene Graph code won't create entities from scratch. It will add behavior to entities you've already placed in the editor β€” by writing a custom component and bolting it on. So this is the first thing to learn.

In UEFN you make one by choosing Add Component > New Verse Component, then the Scene Graph Component template. That gives you a file. Here's what a real, complete one looks like β€” this is straight from Epic's own "make a platform disappear on a loop" example:

using { /Verse.org }
using { /Verse.org/Native }
using { /Verse.org/Simulation }
using { /Verse.org/SceneGraph }

# A Verse-authored component you can add to entities.
# It makes the entity appear and disappear on a loop.
disappear_on_loop_component := class<final_super>(component):

    # How long, in seconds, the entity stays hidden. @editable means
    # you can tweak this number in the editor without touching code.
    @editable
    var Duration<public>:float = 2.0

    # Runs when this component starts simulating in a running game.
    OnBeginSimulation<override>():void =
        spawn:
            RunLoop()

    RunLoop()<suspends>:void =
        loop:
            Sleep(Duration)
            GetEntity[].Hide()
            Sleep(Duration)
            GetEntity[].Show()```

Let's read it like sentences, top to bottom:

- **`disappear_on_loop_component := class<final_super>(component):`** β€” *"I'm defining a new kind of component called `disappear_on_loop_component`."* The part in the parentheses, `(component)`, means *"it's a kind of `component`"* β€” it inherits the base power. The label **`<final_super>`** is a required tag any time you make a component you intend to bolt onto an entity; it just promises the class sits directly on top of `component`. You'll write it every time, like a magic word.
- **`@editable var Duration<public>:float = 2.0`** β€” a setting. `var` means it can change; `:float` means it's a decimal number; `= 2.0` is its starting value. **`@editable`** is the gift: it makes `Duration` show up as a knob in the editor's Details panel, so a designer can change it without code.
- **`OnSimulate<override>()<suspends>:void =`** β€” a **lifetime method**. The Scene Graph calls this automatically once the component is up and running in the game. `<override>` says *"I'm replacing the empty default version."* `<suspends>` says *"this verb is allowed to pause and wait"* (remember effects from the grammar series). `:void` means it hands nothing back.
- **`loop:` ... `Sleep(Duration)`** β€” wait that many seconds. `Sleep` is a real Verse function for pausing.
- **`Entity.Hide()` / `Entity.Show()`** β€” here `Entity` is a built-in word every component has: it's *the entity this component is bolted onto*. (`Hide` and `Show` in this example are little helper verbs Epic defines just below, which flip the mesh on and off β€” we'll see how next.)

That one component, dropped onto any entity with a shape, makes it blink in and out forever. No entities created, no tree-walking β€” just *behavior bolted onto a thing.*

## Lifetime methods: the four moments the Scene Graph calls you

You saw `OnSimulate`. It's one of a small family of **lifetime methods** β€” moments in a component's life when the Scene Graph automatically runs your code. The main ones, in order:

- **`OnAddedToScene`** β€” the component just got added to the live scene. Good for early setup; after this, you're allowed to look around for other components.
- **`OnBeginSimulation`** β€” the component is about to start running. Good for instant, must-finish-now setup.
- **`OnSimulate`** β€” your main running logic. It's `<suspends>`, so this is where loops, waits, and ongoing behavior live.
- **`OnEndSimulation`** β€” things are shutting down; clean up here.

You only override the ones you need. Want something to happen once at startup? Override `OnBeginSimulation`. Want an ongoing loop? Override `OnSimulate`. (If you override `OnBeginSimulation`, it's polite to call the parent's version first with `(super:)OnBeginSimulation()`, which Epic's examples do.)

## Reading a component that's already there: `GetComponent`

Often your entity *already has* a power you want to poke at β€” a mesh, a light β€” and you just need a handle on it. That's **`GetComponent`**. Here are the `Hide`/`Show` helpers from that same Epic example, which show the pattern:

```verse
# Hide the entity by turning off its mesh.
(Entity:entity).Hide():void =
    if:
        Mesh := Entity.GetComponent[mesh_component]
    then:
        Mesh.Disable()

# Show the entity by turning its mesh back on.
(Entity:entity).Show():void =
    if:
        Mesh := Entity.GetComponent[mesh_component]
    then:
        Mesh.Enable()

Read Entity.GetComponent[mesh_component] as: "from this entity, get me its mesh_component." Two things to notice:

  1. It's written with square brackets [...], not round ones. In Verse, square brackets mark a verb that might fail β€” and getting a component can fail, because maybe the entity doesn't have one of that kind. That's why it lives inside an if:. Read the whole thing as: "if I can get a mesh_component, then disable it." If there's no mesh, the code safely skips. (This is the <decides> effect from the grammar series, in action.)
  2. Mesh.Disable() / Mesh.Enable() turn the power off and on. A mesh_component (and a light_component, and many others) can be enabled and disabled β€” that's how you make a thing vanish or reappear without deleting it.

Adding a component from code: AddComponents

You can also bolt a brand-new power onto an entity while the game runs, with AddComponents. Its real signature is AddComponents(Components:[]component):void β€” the []component means it takes an array of components (a list), so you wrap your one component in array{...}:

# Inside a component, give this entity a particle effect at startup.
# BlowingParticles is a Niagara effect exposed in Assets.digest.verse.
OnBeginSimulation<override>():void =
    (super:)OnBeginSimulation()
    VFX:particle_system_component = BlowingParticles:
        Entity := Entity
        AutoPlay := true
    Entity.AddComponents(array{VFX})

Read it: "make a new particle_system_component (named VFX) belonging to this Entity, set it to auto-play, then add it to the entity's list of components." Note Entity := Entity β€” every component must be told which entity it belongs to when you build it, because (per the docs) "components cannot be moved between parents." A component is born attached to exactly one entity for life.

The matching verb for entities is AddEntities (add child things, not powers) β€” that's a Part 3 topic, since it's really about the family tree.

The mental model, sharpened

<!-- section-art:the-mental-model-sharpened --> Entities & Components: Bolting Powers Onto Things in Verse: The mental model, sharpened

Component Attachment

Put the three verbs side by side and the system reads cleanly:

  • Define a power β†’ class<final_super>(component): with On... lifetime methods.
  • Read a power that's there β†’ Entity.GetComponent[some_component] (might fail, so guard with if:).
  • Add a power β†’ Entity.AddComponents(array{...}).

Everything else in the Scene Graph is variations on these. Lights, meshes, sounds, interactions β€” they're all just components you get, enable, disable, or add.

Why this helps you boss around an AI

You can now give precise instructions: "Write a class<final_super>(component) with an @editable var Speed:float, override OnSimulate<suspends>, and inside it GetComponent[mesh_component] and move it." That sentence is buildable as-is. The vague version β€” "make the thing move" β€” isn't. The more real component words you know, the sharper the work you can direct.

Quick recap

  • Make your own power with class<final_super>(component): and override lifetime methods (OnBeginSimulation, OnSimulate, ...).
  • @editable turns a var into an editor knob; var ... :float = 2.0 is the grammar from Part 1 of the grammar series.
  • GetComponent[...] reads a power that's already on an entity β€” square brackets because it can fail, so guard it with if:.
  • Components have Enable() / Disable() to flip them on and off without deleting anything.
  • AddComponents(array{...}) bolts new powers on; a component is born attached to one Entity and stays there.

Next: Hierarchy & Transforms β€” how things hang off each other in the tree, and how position actually works.

References

πŸ”’

Keep going β€” free

You've read the intro. The rest of this lesson is free for members. Sign in to continue and track your progress.

Sign in free to continue this lesson
Pass the quiz above to chart this quest in your Journal.

Sources

/guides/verse-scene-graph-entities-components
Source

Biloxi Studios original lesson

Guided course

Add this lesson to your free study plan.

🧭 The Keeper’s log

Quest complete? Chart your next heading from the 🧠 Center Village (Free) expedition.

β›΅ Take me there