Skip to content

Core Concepts

Slashscreen edited this page May 11, 2023 · 1 revision

Entities

Skelerealms runs on a pseudo-ECS system, very similar to the idea of GameObjects and MonoBehaviours in Unity. For a more in-depth explanation of why this approach is taken, see the Worlds section of this document, but, in short, Having important things in the game as entities allows then to persist even when the scene they should be a part of is unloaded. Anything that should be expected to stay in the same state when the player leaves the scene and then returns should be an entity, like an item on the ground, an NPC sitting in a chair, or a chest's contents.

Components

Entities are built of of Components, which are reusable chunks of code that can be applied to an entity, either giving it some tag or property, or giving an entity some amount of functionalty. For example, an NPC entity could be given, say, a HealthComponent, a Damageable component, and an InventoryComponent. The same InventoryComponent could also be used in a Chest entity.

Puppets

Entities don't themselves appear in a scene, or have any appearance at all. So, how do they appear in the world for the player to interact with? Simple: the concept of puppets! If an entity can be described as a brain of sorts, then the puppet is the body. The brain sends commands to the body, say, to control muscles, and the body sends feedback to the brain, such as touch. The same idea applies here- the entity issues commands to the puppet to interact with a loaded scene (for example, move to this spot), and in return, the puppet will send feedback for anything that happens in the world space (damage, rigid body contact, etc).

Let's look closer at an NPC for example:

  • The NPC Entity controls an NPC's AI, what spot it wants to go to, its response to seeing a player.
  • The puppet controls navigating the Navmesh to reach some point that the entity has determined it wants to go to.

A built-in PuppetSpawnerComponent is included to handle spawning, managing, and despawning puppets.
A puppet can be quite literally any .tscn, so go nuts! Particle effects, rigidbodies, etc.

Entity cleanup

But what happens when an entity is no longer necessary to keep track of? For example, a book on a bookshelf in a dungeon all the way across the map. Skelerealms provides two solutions for this problem:

  1. Entities are loaded lazy-style: They are only fetched from disk or the save file when they are referenced by something else.
  2. Entities keep an internal "activity timer"- if they aren't referenced by something else and nothing about them is changed for a certain amount of time (5 minutes by default), the entity will be flagged, and next time the game saves, the entity's state will be saved, and then the entity will be removed.

For more information, see the Saving and Loading article.

Worlds

The Problem

One of the main challenges an Open World RPG engine faces is the persistence of actors/objects when their scene is unloaded. For example, the player drops a potion on the ground in Room A, and then walks through a door to Room B. A loading screen is seen, and Room A is unloaded, and Room B is loaded. Then, the player walks back into Room A, loading it back in. The player expects the potion to still be on the ground. However, by default, the potion will not be there - it was unloaded along with Room A, and since it was not on the ground in the .tscn file that defines Room A, the potion will not be loaded back in. Not good! How do we avoid this?

The Solution

The answer is deceptively simple. Everything the player would expect to be where they left it is made an Enitiy - see that section for more info. Every entity records its position, and the world it is in. A world is simply the name of the scene that the entity belongs to.

Let's take a look at the potion problem again:

  1. When the player enters Room A, the game's active scene is set to "Room A".
  2. When the potion is dropped (or more accurately, when it's in the player's inventory), the potion item entity's world is set to "Room A".
  3. The player leaves Room A into Room B. The game's active scene is set to "Room B".
  4. The entity checks against the game's active room - they are not the same, and so the entity realizes that it isn't in the right scene, and so it despawns the mesh laying on the ground.
  5. The player returns to Room A, and the game's active world changes accordingly.
  6. The potion entity sees that the game scene is now the same as the potion, meaning it's now in the right scene. It spawns the potion mesh at the entity's position, right where the player left it! Problem solved!

RefIDs vs BaseIDs

The system is based around BaseIDs and RefIDs, like Creation Kit. If you are already familiar with the way CK works, it's basically the same thing. If not, read on.
A BaseID is an ID corresponding to what type of object something is - say, a crab, or a hat item.
A RefID is an ID of a specific entity- say, an NPC named Old Pop Wiggleberry.
Another way to think about it is that a BaseID refers to an object, but a RefID refers to the object.
You can get an entity by the RefID via the EntityManager singleton, but you can't get a list of entities with a BaseID.

Ref Data

Ref Data is a way to store the info of a kind of entity on disk - this corresponds to the BaseID.

Instances

Instances are ways to store the default state of a specific entity on the disk - this corresponds to RefID.

World Objects

If entities are divorced from the scene they are in, how am I supposed to manually place Items and NPCs in the world? So I have to edit every Instance's position by hand?
Not at all! Skelerealms provides tools to help you place down and position several kinds of entities called, uncreatively, WorldObjects. See the Editor Tools article for more information.

Covens (Factions)

Covens are Skelerealms' equivalent of Creation Kit's Faction system, and operate similarly. Essentially, they are groups of NPCs that behave similarly, and have similar opinions about certain things. This seems a bit abstract, but think of them like teams - for example Team Red doesn't like Team Blue, and all members of Team Red will fight Team Blue members on sight. Team Green doesn't like spiders, and will attack all spiders on sight. The player has done a lot of quests for Team Orange, and to all members of Team Orange will like the player.
See the Covens article for more information.

Quests

Unlike Creation Kit, Skelerealms does not rely on the Quest system to operate and effectively store progress. While the framework was designed with use of the quest journal in mind, it is unnecessary, and you can forego it if you wish.
Quests are powered by one of my other plugins, JournalGD - refer to that wiki on that repo for more information. To see how it's incorporated into Skelerelams, see The Journal article.

Project Scene Layout

SceneLayout

This is the layout of the scene that is used by Skelerealms. let's go over each part:

Navigation Master

This is in charge of out-of-scene navigation. Its duties are:

  • Keep track of the points and connections that you set up with the navigation network tool.
  • Calculate a path between worlds from one point to another.

It is comprised of nodes each corresponding to a World (see above). The nodes that are below the World nodes are arranged into a K-D tree to allow for efficient nearest-point searches.

Entity Manager

This is the most important component of the Skelerealms Core system. It keeps track of all entities within the game, and handles tree pruning, loading entities, removing entities, etc. All of its children are Entities. Entities are comprised of Components. A specific component (PuppetSpawnerComponent) has a puppet that it controls, when necessary. The dotted line signifies that the puppet can be safely unparented from and reparented to the master, for anything that may need that functionality, like moving platforms.

Quest Engine

This is from JournalGD. The quest engine:

  • Keeps track of quests done and in progress.
  • Updates quest