### Install Node.js v20 with NVM Source: https://redwoodmmo.com/docs/getting-started/prerequisites Install and use Node.js v20 with NVM. The first block is for Windows, the second for Mac/Linux. Run these after installing NVM. ```bash nvm install 20 nvm use 20 ``` ```bash nvm install 20 ``` -------------------------------- ### Example configuration for packaged build Source: https://redwoodmmo.com/docs/features/game-servers/hosting/local Example Realm Instance Config snippet showing how to configure the local provider to use a packaged/cooked build. It sets the path and executable to the build output and leaves the project as an empty string. ```yaml game-servers: local: unreal: path: "C:\\Path\\To\\MyGame\\builds\\WindowsServer\\MyGame\\Binaries\\Win64" executable: "MyGameServer.exe" project: "" ``` -------------------------------- ### Create GameServerProxy with yarn cli create-proxy Source: https://redwoodmmo.com/docs/getting-started/running-with-backend Creates a GameServerProxy for the overworld game profile. The --start-on-boot flag starts the proxy immediately and on backend boot (admin only), while --proxy-ends ends the proxy when its backing GameServerCollection ends. This starts a shard/server for each zone (5 for this template), each running UnrealEditor.exe and consuming about 1.2GB RAM. ```bash yarn cli create-proxy overworld overworld --env project-name --start-on-boot --proxy-ends --public ``` -------------------------------- ### Enable corepack and install backend dependencies Source: https://redwoodmmo.com/docs/getting-started/installing Run these commands in the RedwoodBackend directory to enable corepack, verify yarn version 4.10.3 or later, and install dependencies. ```bash corepack enable ``` ```bash yarn --version 4.10.3 ``` ```bash yarn ``` -------------------------------- ### Run ngrok tunnel for Hathora development Source: https://redwoodmmo.com/docs/features/game-servers/hosting/hathora Starts an ngrok tunnel on port 3010 so the Realm Backend service can be reached by game servers on Hathora. Requires ngrok installed and on your PATH. ```bash ngrok http 3010 ``` -------------------------------- ### C++ Steam login: get client interface and call LoginWithSteam Source: https://redwoodmmo.com/docs/features/authentication/steam These two C++ steps are part of the Steam login setup: first obtain the active Redwood Client interface from the game subsystem, then call LoginWithSteam with an auth update delegate. Replace OnUpdate with your own callback to handle the auth update. ```cpp URedwoodClientInterface *ClientInterface = GetGameInstance()->GetSubsystem()->GetClientInterface(); ``` ```cpp URedwoodSteamClientInterface::LoginWithSteam(ClientInterface, FRedwoodAuthUpdateDelegate OnUpdate); ``` -------------------------------- ### Create pulumi.yaml with project name Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Create a deployment/pulumi.yaml file in the config folder (e.g., config/node/redwood-demo-kubernetes/deployment/pulumi.yaml) with the project name. Example shows project: "redwood-demo". ```yaml project: "" ``` ```yaml project: "redwood-demo" ``` -------------------------------- ### Example _config.json with parentNames Source: https://redwoodmmo.com/docs/configuration/overview Shows a _config.json file for a redwood-demo-production environment that inherits from production and cloud-do. The parentNames array defines the order of inheritance: default, then production (and its parents), then cloud-do, then the current environment. ```json { "parentNames": ["production", "cloud-do"] } ``` -------------------------------- ### RPG template game.yaml profiles example Source: https://redwoodmmo.com/docs/configuration/game-modes-and-maps Example game.yaml for the RPG template. Shows an overworld profile with multiple zones sharing maps and sharding settings (num-players-to-add-shard: 50, commented-out destroy-empty-shard), plus an instanced-dungeon profile with matchmaking enabled. ```yaml profiles: - id: "overworld" zones: variableCasing: "original" village: maps: - "overworld" outskirts: maps: - "overworld" mountain-pass: maps: - "overworld" forest: maps: - "overworld" mine: maps: - "mine" max-players-per-shard: 16 num-players-to-add-shard: 50 # num-minutes-to-destroy-empty-shard: 5 collection-ends-when-any-shard-ends: false data: - id: "instanced-dungeon" zones: variableCasing: "original" main: maps: - "dungeon" max-players-per-shard: 16 matchmaking-zone-name: "main" min-players-for-matchmaking: 1 data: ``` -------------------------------- ### Install Node.js dependencies with yarn Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Run this command in the RedwoodBackend directory to install dependencies. It automatically triggers a build; you can recompile manually with 'yarn build'. ```bash yarn ``` -------------------------------- ### Match template game.yaml profiles example Source: https://redwoodmmo.com/docs/configuration/game-modes-and-maps Example game.yaml for the Match template. Defines two profiles (elimination and control) each with a single zone and map, max players per shard, matchmaking settings, and a data key/value pair that is passed to the map load URL. ```yaml profiles: - id: "elimination" zones: main: maps: - "expanse" max-players-per-shard: 16 matchmaking-zone-name: "main" min-players-for-matchmaking: 1 data: Experience: "B_ShooterGame_Elimination" - id: "control" zones: main: maps: - "convolution" max-players-per-shard: 16 matchmaking-zone-name: "main" min-players-for-matchmaking: 1 data: Experience: "B_LyraShooterGame_ControlPoints" ``` -------------------------------- ### Example region configuration for production environment Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Example region configuration for a production environment. The name and ping variables are used in the GetRegions call in URedwoodClientGameSubsystem. The ping variable may need adjustment if using CloudFlare proxying. ```yaml region: provider-id: "sfo3" name: "US West" ping: "${director.frontend.connection.external.host}" # this might not be correct if you're using CloudFlare proxying (which Redwood uses by default when using the Cloudflare DNS provider) ``` -------------------------------- ### Create config environment inheriting from production and local Kubernetes config Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Create a new configuration environment that inherits from the 'production' preset and the local Kubernetes config environment. The first block is the template with a placeholder; the second is a concrete example using 'redwood-demo-kubernetes'. ```json { "parentNames": ["production", ""] } ``` ```json { "parentNames": ["production", "redwood-demo-kubernetes"] } ``` -------------------------------- ### Install K3s with Traefik disabled Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Use this command to install K3s while disabling the default Traefik ingress controller. This is required for K3s unmanaged clusters. Alternatively, you can modify /etc/systemd/system/k3s.service to add the --disable=traefik argument to the server command if K3s is already installed. ```bash curl -sfL https://get.k3s.io | sh -s - --disable=traefik ``` -------------------------------- ### Create game.yaml with profiles Source: https://redwoodmmo.com/docs/getting-started/installing Create a game.yaml file (e.g., RedwoodBackend/config/node/project-name/game.yaml) to define game modes. This example defines two profiles (elimination and control) with zones, matchmaking settings, and data. The variableCasing field preserves original zone names. ```yaml profiles: - id: "elimination" zones: # We recommend including this field under zones to ensure that the # name of a zone isn't transformed to camelCase (i.e. "my-zone" -> "myZone"). # When using this, make sure to use camelCase for other variables like syncItemsFromAllZones. variableCasing: "original" main: maps: - "expanse" max-players-per-shard: 16 matchmaking-zone-name: "main" min-players-for-matchmaking: 1 data: Experience: "B_ShooterGame_Elimination" - id: "control" zones: # We recommend including this field under zones to ensure that the # name of a zone isn't transformed to camelCase (i.e. "my-zone" -> "myZone"). # When using this, make sure to use camelCase for other variables like syncItemsFromAllZones. variableCasing: "original" main: maps: - "convolution" max-players-per-shard: 16 matchmaking-zone-name: "main" min-players-for-matchmaking: 1 data: Experience: "B_ShooterGame_ControlPoints" ``` -------------------------------- ### Example local secrets file format Source: https://redwoodmmo.com/docs/features/secrets/local Shows the expected INI-style key=value format for the local secrets file. Values are strings and should not be wrapped in quotes. Keys and values have trailing/leading whitespace automatically removed. ```ini my_secret=my_value secret_two=My value with spaces ``` -------------------------------- ### Configure DefaultEngine.ini for EOS Online Subsystem Source: https://redwoodmmo.com/docs/features/authentication/epic Add this configuration to your UE project's Config/DefaultEngine.ini to enable the EOS online subsystem without enabling EOS networking settings. As of Jan 2026, this basic config sets the default platform service to EOS and disables EOS Connect, sessions, and mirroring. Do not change the NetDriver as suggested in other Steam setup guides. ```ini [/Script/OnlineSubsystemEOS.EOSSettings] CacheDir=CacheDir DefaultArtifactName=GameName RTCBackgroundMode= TickBudgetInMilliseconds=0 bEnableOverlay=False bEnableSocialOverlay=False bEnableEditorOverlay=False bPreferPersistentAuth=False TitleStorageReadChunkLength=0 +Artifacts=(ArtifactName="GameName",ClientId="***",ClientSecret="***",ProductId="***",SandboxId="***",DeploymentId="***",ClientEncryptionKey="") -AuthScopeFlags=BasicProfile -AuthScopeFlags=FriendsList -AuthScopeFlags=Presence bUseEAS=True bUseEOSConnect=False bMirrorStatsToEOS=False bMirrorAchievementsToEOS=False bUseEOSSessions=False bMirrorPresenceToEAS=False SteamTokenType=Session [OnlineSubsystemEOS] bEnabled=true [OnlineSubsystem] DefaultPlatformService=EOS ``` -------------------------------- ### create-proxy output with proxy ID Source: https://redwoodmmo.com/docs/getting-started/running-with-backend Example output from the create-proxy command, showing the unique proxy ID (cm1ol7o270001xhxi5z3d7fw2) that can be used to stop the proxy without the --name argument. ```text [05:47:18.119] INFO (70364): Proxy created successfully: cm1ol7o270001xhxi5z3d7fw2 ``` -------------------------------- ### Get Redwood Client Interface in C++ Source: https://redwoodmmo.com/docs/features/authentication/epic Retrieves the active Redwood client interface from the game instance's RedwoodClientGameSubsystem. Required before calling LoginWithEOS. ```cpp URedwoodClientInterface *ClientInterface = GetGameInstance()->GetSubsystem()->GetClientInterface(); ``` -------------------------------- ### Configure docker.yaml for external container registry Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Template for docker.yaml in your config environment. Change every variable based on your setup. Use an external Container Registry (e.g., Docker Hub, GitHub Packages, or your own). ```yaml registry: url: "yourcr.com/container-registry" # Do not include a trailing slash secret-name: "redwood-container-registry-secret" auth: username: "yourcr-username" password: "yourcr-password" # This can be a secret in the secrets provider image-prefix: "${docker.registry.url}/redwood" ``` -------------------------------- ### ngrok terminal output showing Forwarding address Source: https://redwoodmmo.com/docs/features/game-servers/hosting/edgegap Example output from running `ngrok http 3010`. Note the **Forwarding** line, which provides the public URL (without `https://`) to use in the Realm Instance Config. ```text ngrok (Ctrl+C to quit) Policy Management Examples http://ngrok.com/apigwexamples Session Status online Account Mike Seese (Plan: Free) Update update available (version 3.14.0, Ctrl-U to update) Version 3.3.2 Latency - Web Interface http://127.0.0.1:4040 Forwarding https://***.ngrok-free.app -> http://localhost:3010 Connections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00 ``` ``` -------------------------------- ### Configure director.yaml for remote deployment Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Template for director.yaml in your config environment. Change every variable based on your setup. The external hosts must be fully qualified domain names (FQDNs), not IP addresses. ```yaml image-tag: "1.0.0" persistence: database: # this is what the cluster uses. if you're deploying the cluster to the same region/datacenter as your database # there may be faster, private connection details runtime-access: host: "" port: 5432 database: "" user: "" password: "" # this is what your local machine uses, so if you may need to use different public connection details # you might also need to add your IP address to the firewall for the database deployment-access: host: "" port: 5432 database: "" user: "" password: "" backend: connection: # this is publicly facing connection details for the director backend # which is primarily used to authenticate external realms (i.e. realms # in other clusters or player-hosted realms) external: host: "demos-director-backend.redwoodmmo.com" # this must be a FQD hostname, it cannot be an IP port: 443 tls: true frontend: # this is the publicly facing connection details for the director frontend # which is used by all clients when they launch the game connection: external: host: "demos-director-frontend.redwoodmmo.com" # this must be a FQD hostname, it cannot be an IP port: 443 tls: true ``` -------------------------------- ### game.yaml guilds and alliances configuration Source: https://redwoodmmo.com/docs/features/social/guilds-alliances Default configuration for the guilds and alliances system. Set `game.guilds.scoped-to-realm: true` to use PlayerCharacter IDs and make guilds realm-specific. The example shows all available options including tag casing, length, and alliance limits. ```yaml guilds: # Whether any of the guild features are enabled. enabled: true # By default, guilds and alliances are global to all realms (aka scoped to the Director) # If you want guilds and alliances to be specific to each realm, set this to true. # The data for guilds will still be stored in the Director database, but # they will be unique per realm and membership will use PlayerCharacter IDs # instead of PlayerIdentity IDs. scoped-to-realm: false # Allow players to create guilds; set to false if your game # either has no guilds or if you want to manage guilds # yourself. # If set to false, guild creation will need to be done with # an admin account (via the CLI, dashboard, or using the normal API). allow-guild-creation: true # The maximum number of guilds a player can be part of. max-guilds-per-player: 1 # Tags are short-handed representations of the guild. # e.g. "[TAG] Character Name" tags: allow: casing: force: "upper" # false | "upper" | "lower" lower: false # ignored if force-casing is set to "upper" upper: false # ignored if force-casing is set to "lower" numbers: true # set to false to disable special characters; setting to true does nothing; provide an array of allowed special characters special: - "_" length: min: 2 # must be set to >= 1 max: 4 # must be set to <= 10 and >= min alliances: # Whether any of the alliance features are enabled. enabled: true # Allow guilds to create alliances; set to false if your game # either has no alliances or if you want to manage alliances # yourself (i.e. the game only has 3 overall factions). # If set to false, alliance creation will need to be done with # an admin account (via the CLI, dashboard, or using the normal API). # Alliance updates and any admin actions in alliances will need to be done # with an admin account as well. allow-alliance-creation: true # Increase this number if you want to allow guilds to be in # multiple alliances. max-alliances-per-guild: 1 ``` -------------------------------- ### Build and package match-function Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Run these commands if you updated the `packages/match-function` source to build the backend and generate the prepackaged binaries. ```bash yarn build && yarn pkg:match-function ``` -------------------------------- ### Launch backend with Dev Initiator and yarn dev Source: https://redwoodmmo.com/docs/getting-started/running-with-backend Run these commands in the RedwoodBackend directory to launch the backend. Replace with the name of your config folder, and with the environment name (e.g., project-name). The ./ prefix may be optional depending on your terminal; macOS and Linux users can use dev-initiator-mac or dev-initiator-lin instead. Wait for the 'All services ready' log before proceeding. ```bash ./dev-initiator-win ``` ```bash yarn dev ``` -------------------------------- ### Sample yarn docker output Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Sample output from running `yarn docker redwood-demos-prod -l`, showing the building and pushing of three images to the registry with the 'latest' tag. ```bash $ yarn docker redwood-demos-prod -l Pulling latest base images... Initiating building & pushing 3 images to registry: registry.digitalocean.com at path: incanta-generic-cr Image 1/3: redwood-demos-core-runner:3.0.1-4 Checking registry... Building image... Pushing image... Adding 'latest' tag... Image 2/3: redwood-demos-match-function:3.0.1-4 Checking registry... Building image... Pushing image... Adding 'latest' tag... Image 3/3: redwood-demos-game-server-rpg:3.0.1-4 Checking registry... Building image... Pushing image... Adding 'latest' tag... Done in 396.92s. ``` -------------------------------- ### Pulumi preview output for local deployment Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Shows the expected output when running `yarn deploy` locally. The preview lists all resources that will be created, including Docker images, Kubernetes resources, and Helm releases. The user is prompted to confirm the update. ```text Created stack 'incanta/dev-mike' Previewing update (incanta/dev-mike) View in Browser (Ctrl+O): https://app.pulumi.com/incanta/redwood-demo/dev-mike/previews/2f235049-fc1c-49c7-9172-f20f374aed82 Type Name Plan + pulumi:pulumi:Stack redwood-demo-dev-mike create + ├─ docker:index:Image yourcr.com/container/redwood-dev-image create + ├─ docker:index:Image yourcr.com/container/game-server-image create + ├─ pulumi:providers:kubernetes k8s-provider-local create + ├─ kubernetes:core/v1:ConfigMap game-server-config-map-local create + ├─ kubernetes:helm.sh/v3:Release redis create + ├─ kubernetes:helm.sh/v3:Release ingress create + ├─ kubernetes:helm.sh/v3:Release open-match create + ├─ kubernetes:helm.sh/v3:Release mongo create + ├─ kubernetes:helm.sh/v3:Release agones-local create + ├─ kubernetes:core/v1:ConfigMap director-frontend-config-map-local create + ├─ kubernetes:core/v1:ServiceAccount realm-backend-account-local create + ├─ kubernetes:core/v1:ConfigMap director-backend-config-map-local create + ├─ kubernetes:rbac.authorization.k8s.io/v1:Role gameservers-allocations-role-local create + ├─ kubernetes:core/v1:ConfigMap match-function-config-map-local create + ├─ kubernetes:networking.k8s.io/v1:Ingress director-ingress-local create + ├─ kubernetes:agones.dev/v1:Fleet agones-fleet-local create + ├─ kubernetes:apps/v1:StatefulSet director-frontend-local create + ├─ kubernetes:autoscaling.agones.dev/v1:FleetAutoscaler agones-fleet-autoscaler-local create + ├─ kubernetes:apps/v1:StatefulSet match-function-local create + ├─ kubernetes:rbac.authorization.k8s.io/v1:RoleBinding read-gameservers-write-allocation-local create + ├─ kubernetes:core/v1:Service director-frontend-debug-local create + ├─ kubernetes:core/v1:Service director-frontend-local create + ├─ kubernetes:core/v1:Service match-function-debug-local create + ├─ kubernetes:core/v1:Service match-function-local create + ├─ kubernetes:apps/v1:StatefulSet director-backend-local create + ├─ kubernetes:core/v1:Service realm-backend-local create + ├─ kubernetes:core/v1:Service director-backend-debug-local create + └─ kubernetes:core/v1:Service director-backend-local create Outputs: k8sId: "Local Deployment" Resources: + 29 to create Do you want to perform this update? [Use arrows to move, type to filter] yes > no details ``` -------------------------------- ### Package game server for Hathora deployment Source: https://redwoodmmo.com/docs/features/game-servers/hosting/hathora Run this command from the `RedwoodBackend` directory to create a tarball `redwood-hathora-{timestamp}.tar.gz` for uploading as a Deployment on the Hathora Console. Replace `` with your configuration environment name. ```bash yarn package:hathora ``` -------------------------------- ### Build and package custom match function Source: https://redwoodmmo.com/docs/features/ticketing/matchmaking/open-match Commands to package a custom match function into a binary. Run these in the match-function package directory after creating your custom function. ```bash yarn build yarn pkg:match-function ``` -------------------------------- ### Linode: Get kubeconfig for cluster Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Run this command to retrieve and decode the kubeconfig for your Linode Kubernetes cluster. Replace $clusterID with your cluster ID. The output is saved to kubeconfig.yaml. ```bash linode-cli lke kubeconfig-view $clusterID --text | sed 1d | base64 --decode > kubeconfig.yaml ``` -------------------------------- ### Deploy Redwood backend with yarn deploy Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Run this command to deploy the Redwood backend. Replace with your configuration environment. ```bash yarn deploy ``` -------------------------------- ### yarn docker --help output Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Shows the help output for the `yarn docker` script, listing all available options such as `-t, --tag`, `-l, --latest`, `-o, --overwrite`, `-s, --skip-push`, and `-i, --images`. ```bash $ yarn docker --help Usage: yarn docker [options] Script for building, tagging, and pushing Redwood Docker images Arguments: config-environment The folder of the config environment located in `config/node` you want to use Options: -t, --tag Docker tag to use, otherwise the tag in the configuration will be used -l, --latest Also tag the image as 'latest' in the registry -o, --overwrite Specify whether or not you want to overwrite existing images in the registry with the same tag. Set to 'true' or 'false'. If set to false, existing images will be skipped and the script will continue. -s, --skip-push Skip pushing images to the registry -i, --images Optionally provide a CSV of image names to build, otherwise all will be built, can be a substring of the full image name (default: []) -h, --help display help for command Done in 16.87s. ``` -------------------------------- ### Hathora region blacklist configuration Source: https://redwoodmmo.com/docs/features/game-servers/hosting/hathora Configures the Realm Instance Config variable `game-servers.hathora.regions.blacklist` to omit the `Los_Angeles` region from available regions for server creation. Use this to restrict regions, for example to only US regions for lower CCUs. ```yaml regions: blacklist: - "Los_Angeles" ``` -------------------------------- ### Generate prepackaged binaries with yarn pkg Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely The full source code does not come with prepackaged binaries; you must call this command to generate them. ```bash yarn pkg ``` -------------------------------- ### Configure realm instance for Hathora Source: https://redwoodmmo.com/docs/features/game-servers/hosting/hathora Configures the backend connection and Hathora provider settings. Set the host to the ngrok forwarding address without https://, keep port at 443, and provide the Hathora app ID, secret, and dev token. Secrets should later be stored with the Secrets system. ```yaml backend: connection: external: host: "***.ngrok-free.app" # Copy the public **Forwarding** address from the `ngrok` terminal without the `https://` port: "443" # Keep this at 443, not 3010 tls: true game-servers: provider: "hathora" hathora: credentials: app-id: "app-***" # This is the AppId from Step 4 of Create a Hathora App app-secret: "secret-***" # This is the AppSecret from Step 4 of Create a Hathora App dev-token: "***" # This is the API Dev Token from Step 5 of Create a Hathora App ``` -------------------------------- ### Default local provider command Source: https://redwoodmmo.com/docs/features/game-servers/hosting/local The command executed by the local provider to run a game server. It uses the UnrealEditor executable with the project file and server flags. The port and sidecar port are placeholders that are replaced with generated values. ```bash ../Engine/Binaries/Binaries/Win64/UnrealEditor.exe C:\\Path\\To\\MyGame\\MyGame.uproject -server -port=7777 -SidecarPort=3020 ``` -------------------------------- ### Configure realm instance default.yaml Source: https://redwoodmmo.com/docs/getting-started/installing YAML configuration for realm/instances/default.yaml, specifying auth UUIDs, Unreal Engine paths, and matchmaking timeouts. Use double backslashes for Windows paths. ```yaml auth: id: "your-first-generated-uuid-here" secret: "your-second-generated-uuid-here" game-servers: ready-timeout-seconds: 300 local: unreal: path: "C:\\Program Files\\Epic Games\\UE_5.4\\Engine\\Binaries\\Win64" executable: "UnrealEditor.exe" project: "C:\\path\\to\\YourProject\\YourProject.uproject" ticketing: matchmaking: max-wait-until-make-shallow-match-ms: 15000 ticket-stale-time-ms: 120000 ``` -------------------------------- ### Realm Instance Override Configuration (default.yaml) Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Template for realm instance override file at `realm/instances/default.yaml`. Contains image tags, database access credentials (runtime and deployment), external connection details for backend and frontend, and game server image tag. ```yaml image-tag: "1.0.0" persistence: database: runtime-access: # this is what the cluster uses. if you're deploying the cluster to the same region/datacenter as your database # there may be faster, private connection details runtime-access: host: "" port: 5432 database: "" user: "" password: "" # this is what your local machine uses, so if you may need to use different public connection details # you might also need to add your IP address to the firewall for the database deployment-access: host: "" port: 5432 database: "" user: "" password: "" backend: # this is publicly facing connection details for this realm backend # which is primarily used if you're using an external game server # hosting provider (e.g. Hathora) so the sidecar can reach/authenticate # with the backend connection: external: host: "demos-rpg-realm-backend.redwoodmmo.com" # this must be a FQD hostname, it cannot be an IP port: 443 tls: true frontend: # this is the publicly facing connection details for this realm frontend # which is used by all clients in the main menu to authenticate and join the realm's # servers/matchmaking connection: external: host: "demos-rpg-realm-frontend.redwoodmmo.com" # this must be a FQD hostname, it cannot be an IP port: 443 tls: true game-servers: image-tag: "1.0.0" ``` -------------------------------- ### Add Pulumi Cloud settings to pulumi.yaml Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally If using Pulumi Cloud, add local-mode: false and org: "" to the pulumi.yaml file. For self-hosted Pulumi Cloud, also add url: "https://yourpulumicloud.com". ```yaml local-mode: false org: "" ``` ```yaml url: "https://yourpulumicloud.com" ``` -------------------------------- ### Deploy with yarn deploy Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Deploys the project to the cloud using the specified production configuration environment. Provisioning all resources may take a while. ```bash yarn deploy ``` -------------------------------- ### Create _config.json with parentNames Source: https://redwoodmmo.com/docs/getting-started/installing Create a _config.json file in your config environment (e.g., RedwoodBackend/config/node/project-name/_config.json) to specify the parent config environment. Use "standard" for Standard License or "default" for Custom License. ```json { "parentNames": ["standard"] } ``` ```json { "parentNames": ["default"] } ``` -------------------------------- ### Pulumi Configuration Template (pulumi.yaml) Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Template for `deployment/pulumi.yaml`. Sets local-mode to false, requires a Pulumi access token and org, and defines a stack name (e.g., 'prod'). ```yaml # yaml-language-server: $schema=./pulumi.yaml # The above comment prevents VSCode yaml language server # from thinking this should follow the Pulumi.yaml schema that # Pulumi CLI uses. # It's recommended to use an instance of Pulumi Cloud for production environments, which the below does local-mode: false access-token: "" # Get one by following https://www.pulumi.com/docs/pulumi-cloud/access-management/access-tokens/ org: "" stack: "prod" # at a minimum add this variable to differentiate with the default `dev` stack ``` -------------------------------- ### Create _config.json with parentNames Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Create a _config.json file in the new config folder (e.g., config/node/redwood-demo-kubernetes/_config.json) with parentNames pointing to the kubernetes environment and your custom environment. The order matters: kubernetes must come before your config env. ```json { "parentNames": ["kubernetes", "redwood-demo"] } ``` -------------------------------- ### Realm Instance Config YAML (europe.yaml) Source: https://redwoodmmo.com/docs/features/realms Minimal configuration for a new realm instance, overriding key, name, and auth credentials. The key must match the YAML filename without extension. Uncomment 'deployed: true' to activate the realm. Generate auth id and secret using 'yarn id' or a UUID generator. ```yaml key: "europe" # this should match the name of your `.yaml` file without the extension name: "Europe" # this is any human-friendly name # deployed: true # you need to uncomment this if you want this realm config to be active auth: id: "" # generate a value for this using `yarn id` or get one at https://www.uuidgenerator.net/ secret: "" # generate a value for this using `yarn id` or get one at https://www.uuidgenerator.net/ ``` -------------------------------- ### Deploy ejabberd with Dev Initiator Source: https://redwoodmmo.com/docs/features/social/text-chat Deploy the ejabberd server using the yarn deploy:chat command. Requires Rancher Desktop running and the simple-chat config inherited. ```bash yarn deploy:chat ``` -------------------------------- ### Check Node.js version Source: https://redwoodmmo.com/docs/getting-started/prerequisites Verify that the node executable is available and check its version. ```bash node --version ``` -------------------------------- ### Set cloud to custom in deployment/_index.yaml Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Add a deployment/_index.yaml file in your config environment with the content 'cloud: "custom"' to indicate a custom cloud deployment. ```yaml cloud: "custom" ``` -------------------------------- ### Configure hosts file for Redwood development Source: https://redwoodmmo.com/docs/getting-started/installing Add these lines to your hosts file to route Redwood's fictional hostnames to your development machine. Requires local admin privileges. ```text 127.0.0.1 director.localhost 127.0.0.1 director-backend.localhost 127.0.0.1 realm-default.localhost 127.0.0.1 realm-default-backend.localhost 127.0.0.1 chat.localhost 127.0.0.1 muc.chat.localhost ``` -------------------------------- ### Kubeconfig Configuration (instance.yaml) Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Template for adding kubeconfig to `config/node/yourenv/deployment/kubernetes/instances/.yaml`. The kubeconfig is obtained after provisioning the Kubernetes cluster. ```yaml kubeconfig: "" ``` -------------------------------- ### Cloudflare DNS Integration Template (dns.yaml) Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Template for `deployment/dns.yaml` to integrate with Cloudflare. Requires account ID and API token. If not used, DNS must be configured manually. ```yaml provider: "cloudflare" cloudflare: credentials: account-id: "" # https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/ token: "" # https://developers.cloudflare.com/fundamentals/api/get-started/create-token/ ``` -------------------------------- ### Realm Instance Config: Edgegap backend connection with ngrok host Source: https://redwoodmmo.com/docs/features/game-servers/hosting/edgegap Configuration for the Realm Instance Config (e.g. `realm/instances/default.yaml`) to point Edgegap servers to your local Dev Initiator via ngrok. Set `host` to the ngrok Forwarding address without `https://`, keep `port` at 443, and set `tls` to true. ```yaml backend: connection: external: host: "***.ngrok-free.app" # Copy the public **Forwarding** address from the `ngrok` terminal without the `https://` port: "443" # Keep this at 443, not 3010 tls: true ``` ``` -------------------------------- ### Configure macOS Unreal Engine path Source: https://redwoodmmo.com/docs/getting-started/installing YAML snippet showing the correct macOS path for the UnrealEditor binary, which is hidden inside the .app bundle. Use this instead of pointing to UnrealEditor.app. ```yaml game-servers: # ... local: unreal: path: "/path/to/UE/Engine/Binaries/Mac/UnrealEditor.app/Contents/MacOS" executable: "UnrealEditor" # ... ``` -------------------------------- ### Define overworld and instanced-dungeon profiles Source: https://redwoodmmo.com/docs/getting-started/installing YAML configuration for two profiles: 'overworld' and 'instanced-dungeon'. The overworld profile defines zones (village, outskirts, mountain-pass, forest, mine) with map assignments and item syncing, plus shard settings. The instanced-dungeon profile uses matchmaking with a parent profile and a single zone. ```yaml profiles: - id: "overworld" zones: # We recommend including this field under zones to ensure that the # name of a zone isn't transformed to camelCase (i.e. "my-zone" -> "myZone"). # When using this, make sure to use camelCase for other variables like syncItemsFromAllZones. variableCasing: "original" village: maps: - "overworld" syncItemsFromZones: - "outskirts" outskirts: maps: - "overworld" mountain-pass: maps: - "overworld" syncItemsFromZones: - "outskirts" forest: maps: - "overworld" mine: maps: - "mine" max-players-per-shard: 16 num-players-to-add-shard: 50 # num-minutes-to-destroy-empty-shard: 5 collection-ends-when-any-shard-ends: false data: - id: "instanced-dungeon" zones: # We recommend including this field under zones to ensure that the # name of a zone isn't transformed to camelCase (i.e. "my-zone" -> "myZone"). # When using this, make sure to use camelCase for other variables like syncItemsFromAllZones. variableCasing: "original" main: maps: - "dungeon" max-players-per-shard: 16 matchmaking-zone-name: "main" min-players-for-matchmaking: 1 parent-profile-id: "overworld" data: ``` -------------------------------- ### Define match profile Source: https://redwoodmmo.com/docs/getting-started/installing YAML configuration for a 'match' profile with a single zone, shard limit, and matchmaking settings. ```yaml profiles: - id: "match" zones: # We recommend including this field under zones to ensure that the # name of a zone isn't transformed to camelCase (i.e. "my-zone" -> "myZone"). # When using this, make sure to use camelCase for other variables like syncItemsFromAllZones. variableCasing: "original" main: maps: - "match" max-players-per-shard: 6 matchmaking-zone-name: "main" min-players-for-matchmaking: 1 ``` -------------------------------- ### Add chat host entries to etc/hosts Source: https://redwoodmmo.com/docs/features/social/text-chat Add these lines to the etc/hosts file to enable local development. This maps chat.localhost and muc.chat.localhost to localhost. ```text 127.0.0.1 chat.localhost 127.0.0.1 muc.chat.localhost ``` -------------------------------- ### Create _config.json for parent config environment Source: https://redwoodmmo.com/docs/features/game-servers/hosting/hathora Specifies the parent config environment name for the new Hathora config environment. Place this file at RedwoodBackend/config/node/project-name-hathora/_config.json. ```json { "parentNames": ["project-name"] } ``` -------------------------------- ### Default email configuration template Source: https://redwoodmmo.com/docs/features/transactional-email/overview Default configuration for `config/node/your-env/email/_index.yaml`. Set `provider` to "zeptomail" or "sendgrid" to enable email. Fill in contact details and template IDs. ```yaml # Can be "none", "zeptomail", and "sendgrid" provider: "none" contact: name: "Company" address: "1234 Address St" city: "City" state: "State" zip: "12345" # IDs for various templates; both providers will provide # an ID after you create the email template. templates: verify-email: "" email-addresses: no-reply: name: "Company" address: "no-reply@website.com" ``` -------------------------------- ### Define Kubernetes Cluster for Europe Source: https://redwoodmmo.com/docs/features/realms Create a new file in `config/node/your-game/deployment/kubernetes/instances` (e.g., `k8s-europe.yaml`) to define a Kubernetes cluster for a different region. The `id` should match the filename. ```yaml id: "k8s-europe" # this should match the name of the file enabled: true ``` -------------------------------- ### Run yarn docker command Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-remotely Runs the `yarn docker` script for the specified config environment, building and pushing Docker images to the configured container registry. ```bash yarn docker ``` -------------------------------- ### Package the sidecar with yarn pkg:sidecar Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Run this command only if you have access to the full source code of Redwood (not a Standard License). It packages the sidecar. ```bash yarn pkg:sidecar ``` -------------------------------- ### Pulumi deployment output Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Expected final output when the local Kubernetes deployment finishes, showing the k8sId output and resource creation count. ```text Outputs: k8sId: "Local Deployment" Resources: + 32 created Duration: 2m8s ``` -------------------------------- ### Call LoginWithEOS in C++ Source: https://redwoodmmo.com/docs/features/authentication/epic Calls the LoginWithEOS function with the client interface and an auth update delegate. Replace OnUpdate with your callback to handle the auth update. ```cpp URedwoodEOSClientInterface::LoginWithEOS(ClientInterface, FRedwoodAuthUpdateDelegate OnUpdate); ``` -------------------------------- ### redwood.json for packaged build Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Create a redwood.json file in the packaged build's project folder to override the Director Uri without modifying the Saved directory. ```json { "directorUri": "ws://director.localhost" } ``` -------------------------------- ### Create custom.ts with CustomTicketingFunction Source: https://redwoodmmo.com/docs/features/ticketing/custom Create a new file at packages/realm-frontend/src/routes/player/custom/custom.ts with this initial content. The flow function is a placeholder that throws an error; replace its contents as needed. You have access to the entire PlayerCharacter data. You can safely commit this file in your fork without conflicts, and do not modify default.ts. ```typescript import { CustomPlayerJoinData, CustomTicketingFunction } from "."; import { PlayerCharacter } from "@redwoodmmo/realm-db"; import { RealmFrontendManager } from "../../../realm-frontend-manager"; import fs from "fs"; import path from "path"; import { Logger } from "@redwoodmmo/common"; const flow: CustomTicketingFunction = async ( manager: RealmFrontendManager, character: PlayerCharacter ): Promise => { throw new Error("Custom module not implemented yet"); }; export default flow; ``` -------------------------------- ### Director Uri setting for local Kubernetes Source: https://redwoodmmo.com/docs/deploying-to-kubernetes/deploying-locally Change the Director Uri setting in UE Project Settings to this value so the client connects to the Kubernetes-hosted backend. ```text ws://director.localhost ``` -------------------------------- ### config-settings.json with extraDirs array Source: https://redwoodmmo.com/docs/configuration/overview Create this file in the RedwoodBackend root directory to specify a custom folder for your config environment. The extraDirs array contains the path to your project's config folder. Note the path uses double backslashes as shown. ```json { // ... any existing fields "extraDirs": [ "C:\\path\\to\\YourProject\\Config\\Backend" ] } ``` -------------------------------- ### redwood.json: override directorUri for packaged client Source: https://redwoodmmo.com/docs/features/game-servers/hosting/edgegap Contents of a `redwood.json` file to place in the packaged build at `WindowsClient/YourProjectName/redwood.json`. This points a pre-packaged client to a different Redwood Backend instance (e.g. for a conference without internet). Restart the game client after making this change. ```json { "directorUri": "ws://director.localhost:3001" } ``` ``` -------------------------------- ### Access a configuration variable with config.get Source: https://redwoodmmo.com/docs/configuration/overview Shows how to retrieve a configuration value in the Node.js service using the config.get method with a typed variable. The path is a dot-separated string representing the variable's location in the configuration structure. ```typescript const value: type = config.get("path.to.variable"); ``` -------------------------------- ### Configure Realm Instance to Use Kubernetes Cluster Source: https://redwoodmmo.com/docs/features/realms In the realm instance config (e.g., `config/node/your-game/realm/instances/europe.yaml`), specify the Kubernetes cluster ID to use for that realm. ```yaml k8s: id: "k8s-europe" ``` -------------------------------- ### Output Log warning: Network checksum mismatch Source: https://redwoodmmo.com/docs/features/game-servers/hosting/edgegap Warning that may appear in the Output Log when testing with Edgegap servers while running PIE. Search for `checksum mismatch` to diagnose connection issues; if present, package a Windows Client instead of using PIE. ```text LogNetPackageMap: Warning: GetObjectFromNetGUID: Network checksum mismatch. ``` ``` -------------------------------- ### Hosts file entries for europe realm Source: https://redwoodmmo.com/docs/features/realms Add these entries to your hosts file to resolve the realm hostnames. The key variable generates these hostnames. ```text 127.0.0.1 realm-europe.localhost 127.0.0.1 realm-europe-backend.localhost ```