Table of Contents¶
Overview¶
The GEM Manifest is a file in which an application defines its core attributes so that the GEM platform can present it correctly to the operator, and control the flow of people into and through the application as intended
It is created by the developer and packaged with the application server and client in a GEM Package which is distributed to locations for installation.
It is not intended to be edited by anyone other than the developer and doing so will probably not achieve the intended results.
The GEM manifest file in the package is only used during the "loadapp" installation process which loads a GEM package and populates the GEM Database with data about that experience. It is never read or used other than during that installation process. It is not included in the application client, server, or distributed to user devices.
General Specification¶
File Location: <package_root>/gem_manifest.yaml
Format: YAML
Current Schema Version: 3
Detailed Specification of Schema Version 3¶
The format of the file is a standard YAML file. This document assumes that the reader is familiar with the YAML format. As with any YAML file, the # character can be used to begin comments and the developer is free to include comments in the manifest file.
File Structure¶
The manifest file has a top-level structure containing only two top level fields:
schema_version: 3
experience:
- appname: "YourAppName"
# ... application configuration ...
- appname: "AnotherAppName"
# ... another application configuration ...
Top-Level Fields¶
schema_version (required)¶
Type: Integer
Description: Specifies the version of the manifest schema being used. This allows the GEM platform to properly parse the file format.
Valid Values: 3 (Schema versions 1 and 2 are deprecated)
Example:
schema_version: 3
experience (required)¶
Type: Array of experience objects
Description: An array containing one or more application/experience definitions. Each element in this array defines a complete GEM-enabled application with all its configuration parameters. At least one entry in this array is required.
Example:
experience:
- appname: "GemSimGame8Server"
# ... configuration for first experience ...
- appname: "GemSimGame2Server"
# ... configuration for second experience ...
In the simplest and most common case, the manifest file contains a single experience definition. However, there are times when a developer creates variations of a specific experience (shortened versions, director's cuts, etc) and the ability to include multiple experience variations in a single package is a great convenience. It keeps versions numbers consistent and makes sure that derivative builds made from the same code state are kept together and distributed together.
There is no functional difference between the developer having made separate packages with each experience variation distributed as a separate entity, and putting them all in a single package.
When placing multiple experiences in a single package, besides each having a unique appname, they can be differentiated by either referencing different executables in the package, or by referencing the same executable with different startup parameters, or some other combination of those options.
Experience Object Fields¶
Each object in the experience array contains the following fields:
appname (required)¶
Type: String
Description: Unique identifier for your application. This name is used internally by the GEM platform to reference this specific application/experience. It is never seen by users. It must not contain spaces.
Constraints: Must be unique across all applications in the system.
Example:
appname: "GemSimGame8Server"
official_name (optional)¶
Type: String OR Array of language/text objects
Description: The display name for your application that may be shown to users. Can be specified as either a simple string (defaults to English) or as an array of multilingual translations. This name is shown in the signup app and potentially other places.
Warning: Format 1, as documented below, is being deprecated in GEM 2 and to future-proof your package it is a good idea to use Format 2, with the language codes, even if only a single language is provide.
Format 1 - Simple String:
official_name: "Eight zone simulation"
Format 2 - Multilingual:
official_name:
- lang: "en"
text: "Eight zone simulation"
- lang: "zh-CN"
text: "八区模拟"
- lang: "fr"
text: "Simulation à huit zones"
Language Codes: Use standard language codes (e.g., "en", "en-US", "zh-CN", "fr", "fr-FR")
languages (optional)¶
Type: Array of strings
Description: List of language locales that your application supports. This indicates which languages the application content is available in. The selection of languages in the signup app will be based on this definition in the manifest.
Example:
languages:
- "en-US"
- "zh-TW"
- "fr-FR"
version (required)¶
Type: String
Description: Version number of your application. Used to track different versions of the same application. The version number, is baked into the app client, the app server, and registered in the GEM Database when the package is installed. When assigning headsets and starting app servers GEM makes sure that the GEM platform, the client, and the server are all seeing the same version number.
Format: The version number is an arbitrary string but it is highly recommended that developers use a simple numeric format that can be easily sorted and returns the same sort order whether sorted lexically or numerically.
Example:
version: "123210"
group_max (required)¶
Type: Integer (uint16)
Description: Maximum number of users that can be in a group simultaneously for this experience. This value can be overridden by the show operator in their show definition but should be set accurately in the manifest since that is the experience developers official definition of the maximum group size officially supported.
Example:
group_max: 8
avatars (optional)¶
Type: Array of avatar objects
Description: Defines the avatar options available for users in this experience. Each avatar consists of an ID, title, and image file path. The avatar data defined in the manifest is primarily used in the signup app to provide users an avatar selection screen when they are signing up for the experience.
Avatar Object Fields:
- id (uint64, required): Unique identifier for the avatar. Will be passed to the app as the user's choice
- title (string, required): Display name for the avatar
- image (string, required): Relative path to the avatar image file (from the package root)
Example:
avatars:
- id: 123
title: "Girl 1"
image: ./Avatars/Avatar1.png
- id: 124
title: "Boy 1"
image: ./Avatars/Avatar2.png
Note: Image files will be read and loaded into the database when the application is loaded.
aux_assets (optional)¶
Type: Array of auxiliary asset objects
Description: Defines additional assets (images, test files, etc.) that are used by the application but are not avatars.
Auxiliary Asset Object Fields:
- asset_id (string, required): Unique identifier for the asset (e.g., "suapp_background")
- asset_path (string, required): Relative path to the asset file (from the application directory)
Example:
aux_assets:
- asset_id: "suapp_background"
asset_path: ./AuxAssets/bg_image.jpg
Currently the only feature using the aux_asset list is the background image for the signup app. It must have an asset id of "suapp_background"
Note: Asset files will be read and loaded into the database when the application is loaded.
server_platforms (required)¶
Type: Array of server platform objects
Description: Defines the game server executable for supported platform (Windows, Linux, macOS). The GEM platform will launch the appropriate server based on the host operating system of the showrunner running the show.
Server Platform Object Fields:
- platform (string, required): Platform identifier. Valid values: "windows", "linux", "macos"
- server_path (string, required): Relative path to the server executable (from the package root)
- process_name (string, required): Name of the server process (used for process management)
- args (array of strings, optional): Command-line arguments to pass to the server executable
Example:
server_platforms:
- platform: "windows"
server_path: ./WindowsServer/WindowsServer/UE5_LittlePrinceMainServer.exe
process_name: UE5_LittlePrinceMainServer.exe
args:
- "-log"
- platform: "linux"
server_path: ./LinuxServer/LinuxServer/UE5_LittlePrinceMainServer.sh
process_name: UE5_LittlePrinceMainServer
args:
- "-log"
Note: The args array is application-specific and depends on how your game server accepts configuration.
client_platforms (optional)¶
Type: Array of client platform objects
Description: Defines the client executable for each supported platform. Used when the application has a client component. These are not currently used by the GEM platform. They are included in the package for the benefit of the operator. It is up to the operator to install the correct clients, from the package, on their devices. The version of the clients in a package are guaranteed to match the version numbers of the servers.
Client Platform Object Fields:
- platform (string, required): Platform identifier. Valid values: "windows", "linux", "macos"
- client_path (string, required): Relative path to the client executable (from the package root)
Example:
client_platforms:
- platform: "android"
client_path: ./viveClient/UE5_LittlePrinceMain-arm64.apk
stage_bounds (required)¶
Type: Stage box object
Description: Defines the overall bounding box for the entire physical stage area in which the experience takes place. Coordinates are in meters. This can be larger than the space actually used by the experience. It is primarily used to define the area displayed to the operator in the GUI monitoring dashboard. In existing experiences we have intentionally made it just a little larger than the actual stage size used for the experience so that the display can show users who have stepped out of bounds. The coordinates used are those defined by the VB+ map in use in the space.
Stage Box Object Fields:
- front_left: Point object with x and y coordinates (float64)
- rear_right: Point object with x and y coordinates (float64)
Example:
stage_bounds:
front_left:
x: 0.0
y: 0.0
rear_right:
x: 22.0
y: 11.0
This defines a stage that is 22 meters wide (x-axis) and 11 meters deep (y-axis).
zone_bounds (required)¶
Type: Array of zone bound objects
Description: Defines the physical boundaries for each zone on the stage. Zones are discrete areas where groups can be located during the experience.
Zone Bound Object Fields:
- index (uint16, required): Zone identifier/number
- bounds (stage box, required): The bounding box for this zone (same structure as stage_bounds)
Example:
zone_bounds:
- index: 0
bounds:
front_left:
x: 0.0
y: 0.0
rear_right:
x: 5.5
y: 5.5
- index: 1
bounds:
front_left:
x: 5.5
y: 0.0
rear_right:
x: 11.0
y: 5.5
Note: Zone indices do not need to be sequential or start at 0, but they should match the zone references used in zone_sequence.
zone_sequence (required)¶
Type: Array of game zone specification objects
Description: Defines the sequence of narrative segments or chapters in your experience. Each entry specifies which physical zone is used, how long it lasts, and its name.
Game Zone Specification Object Fields:
- name (string, required): Display name for this segment of the experience
- stage_zone (uint16, required): The physical zone index (must match an index in zone_bounds)
- duration (uint16, required): Duration of this segment in seconds.Primarily used for the progress bar on the GEM GUI and are not that important to the logic
- capacity (uint16, optional): Maximum number of groups that can be in this zone simultaneously (default: 1)
Example:
zone_sequence:
- name: "The Call to Adventure"
stage_zone: 0
duration: 120
- name: "Whispers of the Rainforest"
stage_zone: 1
duration: 180
- name: "Cypress Wall - Armory"
stage_zone: 2
duration: 283
capacity: 2
Notes:
- The experience progresses through the zones in the order defined in this array
- Groups move from one zone to the next as the experience unfolds
- Multiple zones can reference the same physical stage_zone, allowing zones to be reused for different parts of the narrative
- The capacity field allows multiple groups to occupy the same zone simultaneously (useful for larger zones or parallel experiences)
Complete Example¶
Here is a complete example of a gem_manifest.yaml file:
schema_version: 2
experience:
- appname: "LittlePrince"
official_name: "The Little Prince: A Call to Adventure"
languages:
- "en-US"
- "zh-CN"
- "ja-JP"
aux_assets:
- asset_id: "suapp_background"
asset_path: ./avatarImages/bg_image.jpg
version: "0.0.1"
group_max: 8
server_platforms:
- platform: "windows"
server_path: ./WindowsServer/WindowsServer/UE5_LittlePrinceMainServer.exe
process_name: UE5_LittlePrinceMainServer.exe
args:
- "-log"
- platform: "linux"
server_path: ./LinuxServer/LinuxServer/UE5_LittlePrinceMainServer.sh
process_name: UE5_LittlePrinceMainServer
args:
- "-log"
client_platforms:
- platform: "android"
client_path: ./viveClient/UE5_LittlePrinceMain-arm64.apk
stage_bounds:
front_left:
x: -11.0
y: -5.5
rear_right:
x: 11.0
y: 5.5
zone_bounds:
- index: 0
bounds:
front_left:
x: -11.0
y: 0.0
rear_right:
x: -5.5
y: 5.5
- index: 1
bounds:
front_left:
x: -5.5
y: 0.0
rear_right:
x: 0.0
y: 5.5
- index: 2
bounds:
front_left:
x: 0.0
y: 0.0
rear_right:
x: 5.5
y: 5.5
- index: 3
bounds:
front_left:
x: 5.5
y: 0
rear_right:
x: 11.0
y: 5.5
- index: 4
bounds:
front_left:
x: 5.5
y: -5.5
rear_right:
x: 11.0
y: 0
- index: 5
bounds:
front_left:
x: 0.0
y: -5.5
rear_right:
x: 5.5
y: 0
- index: 6
bounds:
front_left:
x: -5.5
y: -5.5
rear_right:
x: 0.0
y: 0.0
- index: 7
bounds:
front_left:
x: -11.0
y: -5.5
rear_right:
x: -5.5
y: 0
zone_sequence:
- name: "1. The Call to Adventure"
stage_zone: 0
duration: 126
- name: "2. Whispers of the Rainforest"
stage_zone: 1
duration: 127
- name: "3. Falling into the Desert"
stage_zone: 2
duration: 122
- name: "4. Wreckage and Wonders"
stage_zone: 3
duration: 150
- name: "5. The Merchant’s Curious Tent"
stage_zone: 4
duration: 137
- name: "6. All Aboard the Sky Train"
stage_zone: 5
duration: 141
- name: "7. The Astronomer's Observatory"
stage_zone: 6
duration: 135
- name: "8. The Field of Roses"
stage_zone: 7
duration: 135
- name: "9. Shadow of the Snake"
stage_zone: 0
duration: 137
- name: "10. The Lamplighter's Endless Night and the Geographer's Globe"
stage_zone: 1
duration: 165
- name: "11. The Businessman and the Drunkard’s Loop"
stage_zone: 2
duration: 152
- name: "12. The Vain Man and the King’s Decree"
stage_zone: 3
duration: 145
- name: "13. The Wild Roots of B-612"
stage_zone: 4
duration: 120
- name: "14. Taming the Volcanoes"
stage_zone: 5
duration: 111
- name: "15. The Cliff and the Rose"
stage_zone: 6
duration: 111
- name: "16. Farewell Among the Stars"
stage_zone: 7
duration: 154
avatars:
- id: 1
title: "Avatar 1"
image: ./avatarImages/Avatar_A_01.png
- id: 2
title: "Avatar 2"
image: ./avatarImages/Avatar_A_02.png
- id: 3
title: "Avatar 3"
image: ./avatarImages/Avatar_A_03.png
- id: 4
title: "Avatar 4"
image: ./avatarImages/Avatar_B_01.png
- id: 5
title: "Avatar 5"
image: ./avatarImages/Avatar_B_02.png
- id: 6
title: "Avatar 6"
image: ./avatarImages/Avatar_B_03.png
- id: 7
title: "Avatar 7"
image: ./avatarImages/Avatar_C_01.png
- id: 8
title: "Avatar 8"
image: ./avatarImages/Avatar_C_02.png
- id: 9
title: "Avatar 9"
image: ./avatarImages/Avatar_C_03.png