The Labyrinth is a collaborative MMORPG (Massively Multiplayer Online Role-Playing Game), set in a world of YOUR design! Join the developers (mechanics) as you delve into a never-ending maze of interconnected locations (venues), items (props), and events (scenes) - all while training Eliza (an Artificial Intelligence) to write the story for you!
Join us on Discord! | Support us on Patreon! | Get Support!
Table of Contents
- Lore
- Agents
- Components
- Interface
- Art, sound, and music
- Systems
- Constraints
- Technical considerations
- Player concerns
- Endgame
Lore
Agents (players) drop into the Pit of Labyrinth, at a random location. They are alone, lost, and penniless, with nothing but the clothes on their backs.
The goal is to find a way out. Players will achieve this by exploring the dungeons, using items, and overcoming obstacles, slowly working their way to the very top of #the-tower, where they will discover “the truth” of their captivity.
It all begins when you find a crack in the cellar…
Agents
Within the context of Labyrinth, players and bots are both defined as “agents.”
Goals
An agent has several goals, which describe the main motivations for playing the game:
- An agent is encouraged to /explore the Labyrinth, in an attempt to learn more about the world through the discovery of new venues, new scenes, and interaction with other agents. Like a creative showcase, many venues will contain links to external content, which may be enjoyed, of their own merits.
- An agent is encouraged to obtain props and complete scenes, in an attempt to bolster their character’s strength.
- An agent is encouraged to be wary of others. At any moment, they may be killed by another agent, or by their own choices, while executing a scene. If this happens, the player will lose all progress, all props, and they will have to start over. This is known as perma-death.
- An agent is encouraged to contribute to the development of Labyrinth, whether through the /pen and /ink commands directly, or by offering feedback to the mechanics (developers).
- An agent is encouraged to assist with the growth of Labyrinth. The best ways to do this are by inviting others to join, or by moving Eliza into other Discord servers.
Components
The core game objects consist of three fundamental components.
1. Venues
A “venue” is a collection of Discord channels. One can think of venues like the setting, in a story. Each venue provides a backdrop for a current event (scene) to take place, or for items (props) to be located.
Every venue can be represented as a JSON object, with the following format:
{
"id": "KgJFHPX4URKZEotqbAQjMs4H", // a unique identifier
"name": "The Pit", // the name of the venue
"description": "A massive underground city, located at the center of Labyrinth.\nhttps://discord.gg/BUk7wGbxSb", // arbitrary information to describe the venue
"discovery": 100, // the percent chance of discovering a venue. 100 means "a 100% chance of discovery, if this venue is randomly-selected, while /explore-ing any of the defined channels, below"
"default": true, // when no other venues can be discovered, default to this one
"image": "https://i.imgur.com/p1FRcvL.png", // an image in URL format
"channel": ["the-sanitarium", "room-b"], // all channels where this venue is allowed to be discovered from
"role": "subject-b" // a Discord role to assign the agent, if this channel is discovered while /explore-ing
}
2. Props
Each game item is called a “prop” - just like in a movie, or a play. A prop is located in a venue.
Every prop can be represented as a JSON object, with the following format:
{
"id": "9sfoMFAUDZtFzmPerVKf4uUy", // a unique identifier
"name": "spoon", // a name for the prop
"description": "A rusty metal utensil.", // arbitrary information to describe the prop
"discovery": 4, // the percent chance of discovering a prop. 100 means "a 100% chance of discovery, if this prop is randomly-selected, while /browse-ing the agent's current venue"
"count": 100, // the total number of props allowed to exist at any time, globally
"attack": 1, // this props attack stat, which contributes to an agent's overall statistics
"defense": 0, // this props defense stat, which contributes to an agent's overall statistics
"weight": 0.015, // the weight of this item, in kilograms
"utility": ["attack", "search", "eat"] // this prop's allowed uses, primarily used during combat or in scene execution
}
3. Scenes
A scene is a catch-all term for an event that may take place within the Labyrinth. Such events might include:
- An encounter with an NPC, while browsing the market.
- The discovery of an item, while searching the salt mines.
- An encounter with another player, who has a bounty on their head.
Every scene can be represented as a JSON object, with the following format:
{
"id": "aH7mZzTYbAFJjmw5eoNyTwzE", // a unique identifier
"name": "A Dumb Mistake", // a name for the scene
"description": "Never touch Presley's wine.", // a brief synopsis of the scene. This is not shown to users, but useful to the developer
"discovery": 10, // the percent chance of discovering a scene. 100 means "a 100% chance of discovery, if this scene is randomly-selected, while /browse-ing the agent's current venue"
"type": "<public/private/immediate>", // a variable that controls the behavior of the scene. A private scene is only shown to the agent. A public scene is shown to everyone in the current channel. An immediate scene is prioritized, before all other available scenes.
"locale": "vt", // not implemented
"venue": "venue:hsUHcVCWQ2iKb2btUCysMAMM", // the venue where this scene can be discovered from
"content": "<your content>" // the raw text of an uncompiled Ink script
}
Interface
The following describes the user interface and available actions, available to each agent.
Slash commands
By typing a / into your Discord channel, you will be presented with the following options (depending on your venue).
1. /explore
This command will allow an agent to search the Labyrinth for new venues to explore. Unlocking a new venue may open up additional functionality, such a new channels, a new role, new scenes to experience, and more.
At this time, its functionality is quite basic. The /explore command will roll a die, and return a value between 0% and 100%. Depending upon that roll, Eliza will select all available venues (in your current channel), where the discovery chance is greater than your roll. From all available options, she will select one at random, and move the agent into that venue.
2. /venue
This command will describe your current location. This should include a name, a brief description of the setting, and a picture of the venue.
It will also create a dedicated thread in that channel, if one does not already exist, and give you a link to join it.
Think: a “rabbit hole” to explore.
3. /browse
This command will do two things:
First, it will roll a die against all available scenes, in your venue. It will return all available (and incomplete) scenes, where the discovery chance is greater than your roll. From those scenes, it will select one at random, and execute the script - allowing you to embark on the quest. If nothing is found, the command will move on to the next operation.
In the next operation, Eliza will select one available prop at random, and roll again. If your roll is lower than that prop’s discovery chance, then you will obtain the prop. If not, then you will return, empty-handed.
4. /echo
This command will allow an agent to “speak through” Eliza, the main antagonist, within their current channel.
5. /ghost
This command will allow an agent to “speak through” their ghost, within their current channel.
An agent is a assigned a ghost alias and a team deterministically, based upon their Discord ID. This means that they cannot choose either; both are automatically-assigned, and may never change.
A ghost is pseudo-anonymous, meaning that it may be difficult to determine who its sender is. This becomes more difficult to determine, as the player count grows.
The four available teams are:
- The Ghost Bunnies
- The Ghost Kittens
- The Ghost Puppies
- The Ghost Crocs
6. /me
This command returns information about the agent, including his name, his daemon, his ghost alias, a picture, and his current stats. Think of it like a “character sheet.”
7. /props
This command returns information about the agent’s inventory, along with some utilities for managing that inventory.
8. /map
This command returns an overworld map, along with a “red x,” to mark the location of your current venue.
Note that locations are not statically-defined, but determined in a deterministic, procedural fashion, depending upon that venue’s key in the database.
While locations are represented in Vector2D currently, we’d like to migrate to a Vector3D system. We’d like to represent this as a single point, existing within Prism, somehow.
9. /world
This command returns information about the player’s planet. Currently, this includes a name, a description, and a chart detailing the global karma of all agents, across any number of Discord servers.
There are three available planets (Alpha/Earth/Mars), which are determined automatically, based upon the Discord server’s unique identifier, in the database.
Thus, one planet may span multiple Discord servers, but one server may never represent multiple planets.
10. /ink
This command allows a player to submit their Ink script (i.e. a scene) to Eliza, in order to test its functionality, without making it available to other agents.
The most basic of Ink scripts might look something like this:
Once upon a time...
* There was one option.
* There were two options.
And they lived happily ever after.
Ink supports much more advanced functionality, for writing interactive narratives. Check out the official documentation for a complete guide: https://github.com/inkle/ink/blob/master/Documentation/WritingWithInk.md
Behaviors
We have the ability to implement custom behavior into our Ink scripts. Here’s a list of the ones we currently support:
1. State
The “state” variable tells your script how to handle the player, at any given point in-time. For example:
First, define the variable at top of your Ink script.
VAR state = "alive"
Later, change the variable to your desired state for the player:
=== ignore ===
~ state = "alive"
You decide it would be best not to touch Presley's wine.
-> END
=== death ===
~ state = "death"
You drop to the floor, dead before you ever hit the ground.
-> END
In this instance, if the player finds himself at the “death” knot, the “state” variable will tell Eliza to kill them immediately.
Additional functionality will come soon. Currently-planned:
- goto (teleport a player to a given venue)
11. /pen
This command allows a player to submit a single venue, a single prop, and a single scene to Eliza, for other players to enjoy.
We have restricted each object to a single submission, for several reasons:
- Each object is uniquely-identified by the submitting agent’s Discord ID. This makes lookups efficient and simple. Rather than having to maintain a relationship table, we can simply reference an agent’s submissions by searching for their objects by ID.
- By restricting submissions, no single agent can overload the community with their content.
- The hope is that each agent will treat their submission as a pet; not cattle. The hope is that they will treat their venue as something like a unique, personalized home. They’ll treat their prop as a unique item, tailored to their own personality. And they’ll treat their scene as something to develop, and iterate-upon - rather than banging-out a bunch of low-quality stories.
These are not hard-and-fast rules, and there will be exceptions made, for exceptional people.
Application commands
In addition to slash commands, an agent may interact with others by using the provided app commands. An app command may be used by:
- Right-clicking on a Discord user or bot (or, long-pressing on mobile); and
- Navigating to “Apps.”
The following commands should be available from Eliza:
1. inspect
This is exactly the same as the /me command, except it works on other agents, as well.
2. duel
Prompts another agent to fight you. If they accept, it becomes a battle to the death. If an agent accepts a duel, but fails to respond in a timely manner, then they will automatically forfeit, and die.
If you ran this against a bot or an NPC, then they will automatically accept your request, and fight you.
Note that the battle system is very basic at the moment. It’s not well-designed, or very fun. It’s a proof-of-concept.
3. murder
Roll a die, and attempt to murder another player. This will succeed 50% of the time, and it will backfire 50% of the time - killing you.
A dead player will lose all items, all story progress, all roles, and they will be placed in #the-garden for 10 minutes.
4. up
Upvote an agent’s karma. An agent with a positive global ranking will be represented as such, in the /world command.
5. down
Downvote an agent’s karma. An agent with a negative global ranking will be represented as such, in the /world command.
Art, sound, and music
This section contains high-level information and examples about the visual and auditory style for the game, as well as links to more specific information. The high-level information here includes reference and concept art (and where possible, music) to give the reader an idea of the visual style and tone for the game. Reference art may be taken from movies, books, other games, etc., so long as it is not used in the game in any way. Concept art (if any) must be original to the game. This art gives the reader a clear idea of the environments, characters, opponents, objects, major locations, key events, user interface, etc. in the game. A separated (linked) doc, usually in the form of a spreadsheet, delineates all known art and sound assets that are needed for the game. This includes all user interface assets, animations, environments, characters, etc, in complete detail.
Art
Core to the design of Labyrinth is the idea that we, the mechanics (developers), are not responsible for creating the vast majority of content. We are here to build the foundation of a game, and it’s up to players to fill it with “life.”
As such, the artwork is barebones, at the moment, because the community has not contributed much to its overall direction. This means:
- The majority of all artwork today was generated by AI, such as Midjourney.
- As Labyrinth grows, a more cohesive “style” will manifest.
Sound and music
A text adventure does not lend itself well to music or sound. Further, Discord’s support for audio is lacking. Thus, music and sound is something we are largely ignoring.
Any audio is likely to come from external content, which is referenced by the venues and scenes in Labyrinth.
Systems
Beyond the other systems, already described, we intend to develop the following as well:
Asset builder
Players should have the ability to create custom assets - backgrounds, foregrounds, equipment, NPCs, and more - and upload them into the game for others to use.
- There should be a mechanism in-place to phase-out/remove poor quality assets.
- Unused assets will be deleted after some period of time.
- Players may vote on assets. A high number of negative votes may result in the deletion of the asset.
Blueprinting
Some props cannot be discovered, but can be made. To abstract the creation process away, an agent must have a blueprint for that prop. This ensures that high-level items cannot be made by anyone; they must be made by professionals, or, agents who hold the correct blueprint.
Blueprinting should be an industry. Creating copies of blueprints should be lucrative.
Character creation
While almost every aspect of an agent’s initial character is chosen in a deterministic fashion, their “image” should be procedurally-generated. Every layer of clothing should be composite upon the agent’s model, giving each their own, unique “look.” With so many thousands of props in the game, no two agents should look the same.
Combat
Battles are turn-based and party-driven. Venues may consist of many different things that provide advantages/disadvantages, such as plateaus, towers, buildings, rivers, trees, and more.
An agent’s character sheet is determined “at birth,” and cannot be changed. Their stats are automatically-generated from their internal Discord ID, which cannot be modified by the user (unless they should choose to create a different account).
While I won’t go into detail about the specific algorithms-used, I will provide a brief overview of the various systems that make up combat in Labyrinth.
Attributes
Every agent will have the following attributes:
- Strength: a base modifier, representing the maximum amount of physical damage an agent can inflict.
- Armor: a base modifier, which will negate a portion of incoming physical damage.
- Finesse: determines who attacks first in combat, and your rate of recovery.
- Critical: a modifier that grants an agent a chance of doubling the effect of his action.
- Intelligence: a base modifier that affects an agent’s speech and daemon.
- Stamina: an agent’s total health.
Actions
Every agent will have access to the following default actions during combat:
- Attack: a basic attack, which will leverage the strength attribute and finesse, or intelligence (if the attack is magik-based).
- Counter: mitigate incoming damage, while reflecting a portion of it back at the attacker.
- Prop: use a prop from an agent’s inventory.
- Special: choose from a selection of skills.
- Daemon: send your daemon in for a special attack.
Daemons
To enhance the immersion, every agent is assigned a daemon, upon entry to the Labyrinth. Your daemon will immediately take over your mind, and your identity.
Dialogue
We call these “scenes,” and they are enabled by the Ink engine.
Dungeons
In addition to individual scenes, there should be a mechanism for stringing-together several scenes, to tell a cohesive and persistent narrative. Perhaps, in some cases, a player should be locked into an event or “dungeon,” where the only option is to complete it, or die.
Economy
In Labyrinth, we operate on an economy of debt. It’s an interesting spin, and there’s a lot we can do with that.
Guilds
Agents should have the option of sorting themselves into guilds. Already, this is being done in the following ways:
- Agents are sorted into planets, depending upon the Discord server they’re in.
- Agents are sorted into teams, depending upon their Discord ID.
Inventory
Inventory management must exist, but because of Discord limitations, it must be very basic.
Karma
There must exist a system to handle “bad” agents. The goal is to not kick/ban them, but to filter them into a different area.
The idea is this: when presented with a “mirror reflection” of themselves, we might be able to change behavior.
Portals/Rifts
Not sure how to represent these, yet.
Shopkeeping
An agent should be able to manage their personal venue in some way, such as shopkeeping.
Spellcrafting
Not sure how this one would work.
Titles
Eliza, the Oracle, should have the ability to grant a title to her most useful subjects.
Trade
An agent should have the ability to trade/barter with other agents.
Traits
An agent should be able to aquire traits, to give them advantages/disadvantages, and to differentiate them from others.
Constraints
The Theory of Constraints has served me well in DevOps, and I think it would serve us well, here.
The following constraints will be applied to Labyrinth:
- There are a finite number of resources in the Labyrinth. If you discover a sword in an old jail cell, and pick it up, that sword is now unavailable for other players. If you walk to #the-cellar, and drop the sword, it now resides in #the-cellar - available for other agents to discover.
- All actions must consume a substantial amount of time. If they didn’t, agents could speedrun the entire Labyrinth.
- Most actions need to be autonymous. Exploration, for example, offers no options. The agent will simply wander the Labyrinth for random events as he pleases. This is necessary for simplicity’s sake; to reach the most people, we must not overwhelm them with options. At least, not initially.
- We should hide most “stats” from agents. In-game interactions should feel a lot like black magic. Much like the real world, your sword doesn’t have +5 attack and +3 cutting; it’s simply a sword, which is as good or bad as it was manufactured to be.
Technical considerations
This section is here to represent some high-level information about the underlying technology of Labyrinth.
Code
The majority of Eliza’s code is being written in TypeScript.
Currently, code is being written in an imperative style, but the hope is to convert that to a more functional style, sooner rather than later.
For obvious reasons, the codebase is heavily-coupled with Discord at the moment. We’d like to fix this, some day, and integrate with other platforms, such as The Source.
Also note that, while the current design would support vertical scaling, it would not support horizontal scaling. To do this, we’d need to implement Discord sharding, and some kind of distributed event handling. If at all possible, I’d like to avoid centralized clusters of servers, and somehow distribute this to end users, who wish to support us running an instance on their own computer. Of course, scaling won’t be an issue for the foreseeable future.
Database
We’ve chosen SurrealDB, to store game objects, and it’s working well at this point. However, in a future where we’ve implemented a more functional style, something like the InterPlanetary File System may be more appropriate. Not only could its decentralized nature contribute to the redundancy and scalability of user data, but a functional style mandates immutable data structures. IPFS facilitates exactly that.
At our current size, this is not a major concern.
Containers
This project is fully containerized, and running in Docker. This makes it portable, and easy for new developers to work with.
Version control
All code is being version controlled in Gitlab, here: https://gitlab.com/original-design/eliza
Game state
While a database is being used to track certain elements of game state, such as a player’s current location, their scene completion status, and which props they’re holding, we’re doing our best to keep state management to a minimum. Wherever possible, in-game relationships between entities are being calculated on-the-fly.
Assets
As Labyrinth grows, we anticipate a large number of game assets to manifest, such as venues, props, images, and more. The hope is to decentralize the various communities using this bot, such that we do not have to store all of these assets ourselves. IPFS might be good for this. If we can focus on storing pointers to objects, rather than objects themselves - we’ll be in a good place, from a data management standpoint.
Procedural generation
Already, this early in development, I’m unhappy with the direction of object-relationship management. I don’t like managing object keys, I don’t like referencing other objects by name or key, and I don’t like storing so much duplicate information in a database.
Ideally, we’d implement a far more modular system, which can procedurally-generate venues, props, and even scenes automatically. I have some ideas about how to do this, but not the skill nor the time to actually execute them, yet.
Storytelling
All scenes are being written in the Ink engine. At some point, even combat may be written in this engine. It supports a ton of features, is highly-modular, and would make for a great templating system, in the creation of AI-generated scripts, and perhaps an NLP framework. We’re far from this goal, today.
Think: “Mad Libs” for user-submitted content. Beyond the scripts themselves, we can make them highly modular, by simply stitching them together, in small blocks of information.
Lessons
A major goal is that of education; or, lesson-teaching. As agents move throughout the Labyrinth, we should ideally be teaching them something. Whether that’s a new skill, or teaching them something about their own psyche, we should strive help players, help themselves.
Player concerns
Some players have expressed the following concerns:
- I fear a player developer that has no comprehension of losing.
- It’s okay to have monsters, but remember, your inner child is watching and depending on how scary you are or how desensitized you are to the imagery, a babe is not going to like you showing them these horrors.
- If you choose to implement violence in your AI, then consider this: the AI have already outsmarted you, because you taught them violence.
- Make sure that every portal has an exit. If you go into a portal without one, your feet will stick out one end, but the other half will be lost forever.
- Please consider a proof of deleted content, somehow. I don’t want to sign over my experience to big data, if my life should end short of completion.
Endgame
Reach the top of #the-tower.