From d855fa1f3223222ddd4be8539b922d4d53bac083 Mon Sep 17 00:00:00 2001 From: Mihai Damaschin Date: Fri, 10 Jul 2026 22:53:36 -0400 Subject: [PATCH 1/2] Add The Riftbreaker dedicated server template Adds an AMP Generic module template for The Riftbreaker dedicated server (Steam app 4114030). Supports Windows and Linux (Windows-only binary run via Wine + Xvfb on Linux, with vcrun2022 and d3dcompiler_47 installed by winetricks). Server settings, campaign/mission/difficulty and Steam vs LAN/direct networking are configurable from the AMP UI. --- riftbreaker.kvp | 127 ++++++++++++++++++++++ riftbreakerconfig.json | 182 ++++++++++++++++++++++++++++++++ riftbreakermetaconfig.json | 8 ++ riftbreakerports.json | 9 ++ riftbreakertemplatesettings.cfg | 23 ++++ riftbreakerupdates.json | 63 +++++++++++ riftbreakerwinescript.sh | 53 ++++++++++ 7 files changed, 465 insertions(+) create mode 100644 riftbreaker.kvp create mode 100644 riftbreakerconfig.json create mode 100644 riftbreakermetaconfig.json create mode 100644 riftbreakerports.json create mode 100644 riftbreakertemplatesettings.cfg create mode 100644 riftbreakerupdates.json create mode 100644 riftbreakerwinescript.sh diff --git a/riftbreaker.kvp b/riftbreaker.kvp new file mode 100644 index 000000000..8f32e4a8a --- /dev/null +++ b/riftbreaker.kvp @@ -0,0 +1,127 @@ +Meta.DisplayName=The Riftbreaker +Meta.Description=The Riftbreaker Dedicated Server +Meta.OS=Windows, Linux +Meta.AarchSupport=Unknown +Meta.Arch=x86_64 +Meta.Author=CostcoFanboy +Meta.URL=https://store.steampowered.com/app/780310/The_Riftbreaker/ +Meta.DisplayImageSource=steam:780310 +Meta.EndpointURIFormat= +Meta.ConfigManifest=riftbreakerconfig.json +Meta.MetaConfigManifest=riftbreakermetaconfig.json +Meta.ConfigRoot=riftbreaker.kvp +Meta.MinAMPVersion=2.6.0.0 +Meta.SpecificDockerImage=cubecoders/ampbase:wine-stable +Meta.DockerRequired=False +Meta.DockerBaseReadOnly=False +Meta.ContainerPolicy=SupportedOnWindows, RecommendedOnLinux +Meta.ContainerPolicyReason=The dedicated server is a Windows-only application that requires Wine (ideally the latest stable from winehq.org), the Visual C++ 2022 runtime and D3D compiler (installed via winetricks), and Xvfb to run on Linux. Using a container avoids the need for you to install these dependencies on the host. +Meta.ExtraSetupStepsURI= +Meta.Prerequisites=[] +Meta.ExtraContainerPackages=[] +Meta.ConfigReleaseState=NotSpecified +Meta.NoCommercialUsage=False +Meta.ConfigVersion=1 +Meta.ReleaseNotes= +Meta.BreakingReleaseNotes= +Meta.AppConfigId=5393dee1-c3f9-424f-ae78-ca6f7a7e2ea2 +Meta.ImportableExtensions=[] +Meta.AppIsMultiIPAware=False +App.DisplayName=The Riftbreaker +App.RootDir=./riftbreaker/ +App.BaseDirectory=./riftbreaker/4114030/ +App.SteamWorkshopDownloadLocation= +App.ExecutableWin=4114030\bin\DedicatedServer.exe +App.ExecutableLinux=/usr/bin/xvfb-run +App.WorkingDir=4114030/bin +App.LinuxCommandLineArgs=-a wine "./DedicatedServer.exe" +App.WindowsCommandLineArgs= +App.CommandLineArgs={{$PlatformArgs}} cli=1 config=config.cfg +App.UseLinuxIOREDIR=False +App.AppSettings={} +App.EnvironmentVariables={"WINEPREFIX":"{{$FullRootDir}}.wine","WINEARCH":"win64","WINEDEBUG":"-all","WINEDLLOVERRIDES":"mscoree,mshtml=","SteamAppId":"780310"} +App.CommandLineParameterFormat=-{0}={1} +App.CommandLineParameterDelimiter= +App.ExitMethod=OS_CLOSE +App.ExitMethodWindows=None +App.ExitTimeout=30 +App.ExitString=exit +App.ExitFile=app_exit.lck +App.RestartDelaySeconds=0 +App.HasWriteableConsole=False +App.HasReadableConsole=True +App.UDPLogger=False +App.SupportsLiveSettingsChanges=False +App.LiveSettingChangeCommandFormat= +App.ForceIPBinding=False +App.SupportsIPv6=False +App.ApplicationIPBinding=0.0.0.0 +App.Ports=@IncludeJson[riftbreakerports.json] +App.AdminPortRef=0 +App.PrimaryApplicationPortRef=GamePort +App.UniversalSleepApplicationUDPPortRef=0 +App.UniversalSleepSteamQueryPortRef=0 +App.MaxUsers=4 +App.UseRandomAdminPassword=False +App.PersistRandomPassword=False +App.RemoteAdminPassword= +App.AdminMethod=STDIO +App.IgnoreSTDOUTAfterRCON=False +App.AdminLoginTransform=None +App.StripANSIControlCodes=True +App.LoginTransformPrefix= +App.RCONConnectDelaySeconds=5 +App.RCONConnectRetrySeconds=5 +App.RCONHeartbeatMinutes=0 +App.RCONHeartbeatCommand=ping +App.RCONSelectIPMethod=Default +App.TelnetLoginFormat={0} +App.TelnetNewLineType=Default +App.TailLogFilePath={{$FullBaseDir}}userdata/exor_logs.txt +App.UpdateSources=@IncludeJson[riftbreakerupdates.json] +App.PreStartStages=[] +App.CommandTriggers={} +App.UserActions=[] +App.ForceUpdate=False +App.ForceUpdateReason= +App.Compatibility=None +App.SteamUpdateAnonymousLogin=True +App.SteamForceLoginPrompt=False +App.RapidStartup=False +App.SmartExcludeExemptions=[".cfg",".conf",".config",".ini",".json",".xml",".properties",".kvp",".yml",".yaml",".toml",".lua"] +App.SmartExcludeSupported=True +App.DumpFullChildProcessTree=False +App.MonitorChildProcessName=^{{$WineBaseDir}}bin\\DedicatedServer\.exe.*$ +App.MonitorDirectChildOnly=False +App.SupportsUniversalSleep=False +App.UseSteamQueryForStatus=False +App.WakeupMode=Any +App.ApplicationReadyMode=RegexMatch +App.QuiesceCommand= +App.DequiesceCommand= +App.QuiesceSettleDelayMilliseconds=5000 +Console.FilterMatchRegex= +Console.FilterMatchReplacement= +Console.ThrowawayMessageRegex=^\[[\d:.]+\] \[info\] ConfigVarRegistry\.cpp:\d+ - Warning: accessing undefined ConfigVariable:.*$ +Console.AppReadyRegex=^\[[\d:.]+\] \[info\] ControllerState\.cpp:\d+ - \[ControllerState\] activating: ServerGameplayState$ +Console.UserJoinRegex= +Console.UserLeaveRegex= +Console.UserChatRegex= +Console.UpdateAvailableRegex= +Console.PreConnectRegex= +Console.ConnectIPRegex= +Console.MetricsRegex= +Console.ServerInfoRegex= +Console.ServerAuthURLPromptRegex= +Console.ServerAuthAckRegex= +Console.ConsoleFormatRegex= +Console.DownloadProgressRegex= +Console.HideFromConsoleRegex= +Console.SuppressLogAtStart=False +Console.UserActions={} +Limits.SleepMode=False +Limits.SleepOnStart=False +Limits.SleepDelayMinutes=5 +Limits.DozeDelay=2 +Limits.AutoRetryCount=2 +Limits.SleepStartThresholdSeconds=25 diff --git a/riftbreakerconfig.json b/riftbreakerconfig.json new file mode 100644 index 000000000..1b8303418 --- /dev/null +++ b/riftbreakerconfig.json @@ -0,0 +1,182 @@ +[ + { + "DisplayName": "Server Name", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Server Settings:dns:1", + "Description": "The publicly visible server name shown to players (e.g. in the in-game server browser)", + "Keywords": "server,name,servername,hostname", + "FieldName": "ServerName", + "InputType": "text", + "ParamFieldName": "ServerName", + "DefaultValue": "AMP Powered Riftbreaker Server", + "EnumValues": {} + }, + { + "DisplayName": "Server Password", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Server Settings:dns:1", + "Description": "Password required to connect to the server. Leave blank for no password", + "Keywords": "server,password,serverpassword", + "FieldName": "ServerPassword", + "InputType": "password", + "ParamFieldName": "ServerPassword", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "RCON Password", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Server Settings:dns:1", + "Description": "Password for remote console (RCON) commands. Clients must set the same password in-game via 'server_rcon_password' before they can run 'rcon '. Leave blank to disable remote commands. Note: this is the game's own in-game RCON and is not used by AMP's console", + "Keywords": "rcon,remote,console,command,password", + "FieldName": "RconPassword", + "InputType": "password", + "ParamFieldName": "RconPassword", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Player Limit", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Server Settings:dns:1", + "Description": "Maximum number of players allowed on the server. The officially supported maximum is 4 - each additional player can severely impact performance. Increase beyond 4 at your own risk", + "Keywords": "max,players,limit,count,slots,server_max_players_count", + "FieldName": "$MaxUsers", + "InputType": "number", + "MinValue": "1", + "MaxValue": "16", + "ParamFieldName": "MaxPlayers", + "DefaultValue": "4", + "Suffix": "players", + "EnumValues": {} + }, + { + "DisplayName": "Networking Mode", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Server Settings:dns:1", + "Description": "How players connect. 'Steam Server Browser' uses Steam's relay/P2P networking - it needs only outbound internet access (no port forwarding) and players join from the in-game Multiplayer > Server Browser. 'LAN / Direct Connect' disables Steam networking - players join with connect \"\" in the game console and the Game Port (6321) must be reachable", + "Keywords": "steam,lan,direct,connect,networking,mode,disable_steam,p2p,relay", + "FieldName": "DisableSteam", + "InputType": "enum", + "ParamFieldName": "DisableSteam", + "DefaultValue": "0", + "EnumValues": { + "0": "Steam Server Browser (recommended - no port forwarding)", + "1": "LAN / Direct Connect (requires Game Port 6321 open)" + } + }, + { + "DisplayName": "List In Server Browser", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Server Settings:dns:1", + "Description": "If enabled, the server is publicly listed in the in-game server browser. Disable to keep the server private", + "Keywords": "broadcast,public,private,listed,visible,server_broadcast_enabled", + "FieldName": "Broadcast", + "InputType": "checkbox", + "ParamFieldName": "Broadcast", + "DefaultValue": "1", + "EnumValues": { + "False": "0", + "True": "1" + } + }, + { + "DisplayName": "Pause When Empty", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Server Settings:dns:1", + "Description": "If enabled, the server pauses the game simulation while no players are connected. This prevents your base from being attacked while you are away and resumes automatically when someone joins", + "Keywords": "pause,empty,idle,afk,server_pause_game_when_empty", + "FieldName": "PauseWhenEmpty", + "InputType": "checkbox", + "ParamFieldName": "PauseWhenEmpty", + "DefaultValue": "1", + "EnumValues": { + "False": "0", + "True": "1" + } + }, + { + "DisplayName": "Game Mode / Campaign", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Game Settings:videogame_asset:2", + "Description": "The campaign type to host. Story Campaign is the guided co-op story. Open Campaign and Survival both require a Starting Mission to be selected below. Make sure your Difficulty selection matches the chosen mode", + "Keywords": "campaign,mode,story,open,survival,game", + "FieldName": "Campaign", + "InputType": "enum", + "ParamFieldName": "Campaign", + "DefaultValue": "mp_story/mp_story", + "EnumValues": { + "mp_story/mp_story": "Story Campaign (co-op)", + "open/open": "Open Campaign (choose a Starting Mission)", + "mp_survival/mp_survival": "Survival (choose a Starting Mission)" + } + }, + { + "DisplayName": "Starting Mission / Biome", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Game Settings:videogame_asset:2", + "Description": "The starting mission/biome. Required for Open Campaign (campaigns/open/...) and Survival (survival/...). Leave as 'None' for the Story Campaign. The prefix must match your Game Mode selection above", + "Keywords": "mission,biome,map,starting,start", + "FieldName": "Mission", + "InputType": "enum", + "ParamFieldName": "Mission", + "DefaultValue": "", + "EnumValues": { + "": "None - for Story Campaign (default)", + "campaigns/open/headquarters_jungle": "Open Campaign: Jungle", + "campaigns/open/headquarters_desert": "Open Campaign: Desert", + "campaigns/open/headquarters_acid": "Open Campaign: Acid", + "campaigns/open/headquarters_ice": "Open Campaign: Ice", + "campaigns/open/headquarters_swamp": "Open Campaign: Swamp", + "campaigns/open/headquarters_caverns": "Open Campaign: Caverns", + "campaigns/open/headquarters_metallic": "Open Campaign: Metallic", + "survival/jungle": "Survival: Jungle", + "survival/acid": "Survival: Acid", + "survival/desert": "Survival: Desert", + "survival/magma": "Survival: Magma", + "survival/ice": "Survival: Ice", + "survival/metallic": "Survival: Metallic", + "survival/caverns": "Survival: Caverns", + "survival/swamp": "Survival: Swamp", + "survival/swamp_lakes": "Survival: Swamp Lakes" + } + }, + { + "DisplayName": "Difficulty", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Game Settings:videogame_asset:2", + "Description": "The difficulty level. IMPORTANT: pick the entry that matches your Game Mode - Story uses the 'Story:' options, Open Campaign uses the 'Open Campaign:' options, and Survival uses the 'Survival:' options. A mismatched value may be ignored by the game", + "Keywords": "difficulty,hard,easy,normal,brutal,coop", + "FieldName": "Difficulty", + "InputType": "enum", + "ParamFieldName": "Difficulty", + "DefaultValue": "coop_campaign_brutal", + "EnumValues": { + "coop_campaign_easy": "Story: Easy", + "coop_campaign_normal": "Story: Normal", + "coop_campaign_hard": "Story: Hard", + "coop_campaign_brutal": "Story: Brutal (default)", + "easy": "Open Campaign: Easy", + "normal": "Open Campaign: Normal", + "hard": "Open Campaign: Hard", + "brutal": "Open Campaign: Brutal", + "coop_easy": "Survival: Easy", + "coop_normal": "Survival: Normal", + "coop_hard": "Survival: Hard", + "coop_brutal": "Survival: Brutal" + } + }, + { + "DisplayName": "Additional Server Settings", + "Category": "The Riftbreaker:stadia_controller", + "Subcategory": "Advanced:build:3", + "Description": "Extra config lines added verbatim to config.cfg, one per line, e.g. set autosave_timer \"10\". To load an existing save instead of starting a new game, add a line like set mission_save \"SAVE_NAME\" and set Game Mode/Mission/Difficulty appropriately. See the EXOR Studios dedicated server guide for all available parameters", + "Keywords": "additional,custom,advanced,extra,settings,cvars,mission_save", + "FieldName": "UserSettings", + "InputType": "Textarea", + "IsFlagArgument": false, + "ParamFieldName": "UserSettings", + "DefaultValue": "", + "EnumValues": {} + } +] diff --git a/riftbreakermetaconfig.json b/riftbreakermetaconfig.json new file mode 100644 index 000000000..9821a275b --- /dev/null +++ b/riftbreakermetaconfig.json @@ -0,0 +1,8 @@ +[ + { + "ConfigFile": "config.cfg", + "AutoMap": true, + "ConfigType": "template", + "ConfigFileTemplate": "riftbreaker/AMP_config.cfg" + } +] diff --git a/riftbreakerports.json b/riftbreakerports.json new file mode 100644 index 000000000..f5083e062 --- /dev/null +++ b/riftbreakerports.json @@ -0,0 +1,9 @@ +[ + { + "Protocol": "Both", + "Port": 6321, + "Ref": "GamePort", + "Name": "Game Port", + "Description": "Port used for direct/LAN game connections (TCP and UDP). Required only for LAN / Direct Connect mode. Steam Server Browser mode uses Steam's relay/P2P networking and needs only outbound internet access (no port forwarding)." + } +] diff --git a/riftbreakertemplatesettings.cfg b/riftbreakertemplatesettings.cfg new file mode 100644 index 000000000..c48ec9386 --- /dev/null +++ b/riftbreakertemplatesettings.cfg @@ -0,0 +1,23 @@ +// This file is managed by AMP. Configure settings through the AMP web interface. +// The game ignores everything after // on a line, so those lines act as toggles. +// Do not remove the 'set app_mode "server"' line - the server needs it to start +// headless instead of waiting at the menu. +// +// Advanced/extra options can be added via "Additional Server Settings" in the AMP UI. +// See the EXOR Studios dedicated server guide for the full list of parameters. + +set app_mode "server" + +set server_name "{{ServerName}}" +set server_password "{{ServerPassword}}" +set server_rcon_password "{{RconPassword}}" +set server_max_players_count "{{MaxPlayers}}" +set server_broadcast_enabled "{{Broadcast}}" +set server_pause_game_when_empty "{{PauseWhenEmpty}}" +set disable_steam "{{DisableSteam}}" + +set campaign "{{Campaign}}" +set mission "{{Mission}}" +set difficulty "{{Difficulty}}" + +{{UserSettings}} diff --git a/riftbreakerupdates.json b/riftbreakerupdates.json new file mode 100644 index 000000000..0177fb639 --- /dev/null +++ b/riftbreakerupdates.json @@ -0,0 +1,63 @@ +[ + { + "UpdateStageName": "SteamCMD Download", + "UpdateSourcePlatform": "All", + "UpdateSource": "SteamCMD", + "UpdateSourceData": "4114030", + "UpdateSourceArgs": "4114030", + "ForceDownloadPlatform": "Windows", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Config Template Download", + "UpdateSourcePlatform": "All", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/CostcoFanboy/AMPTemplates/main/riftbreakertemplatesettings.cfg", + "UpdateSourceTarget": "{{$FullRootDir}}", + "UpdateSourceArgs": "AMP_config.cfg", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Initialise Wine", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"WINEPREFIX=\\\"{{$FullRootDir}}.wine\\\" WINEARCH=win64 WINEDLLOVERRIDES=\\\"mscoree,mshtml=\\\" WINEDEBUG=-all /usr/bin/wineboot --init --update\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Winescript Download", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/CostcoFanboy/AMPTemplates/main/riftbreakerwinescript.sh", + "UpdateSourceTarget": "{{$FullInstanceDir}}", + "UpdateSourceArgs": "winescript.sh", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Windows Components", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "./winescript.sh", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create Save/Log Link", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "cmd.exe", + "UpdateSourceArgs": "/C mkdir \"%UserProfile%\\Documents\\The Riftbreaker\" > NUL 2>&1 & rd /S /Q \"{{$FullBaseDir}}userdata\" > NUL 2>&1 & mklink /J \"{{$FullBaseDir}}userdata\" \"%UserProfile%\\Documents\\The Riftbreaker\" > NUL 2>&1", + "SkipOnFailure": true + }, + { + "UpdateStageName": "Create Save/Log Link", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"mkdir -p \\\"{{$FullRootDir}}.wine/drive_c/users/amp/Documents/The Riftbreaker\\\" >/dev/null 2>&1; cd riftbreaker/4114030 && rm -rf userdata >/dev/null 2>&1; ln -sfn \\\"../.wine/drive_c/users/amp/Documents/The Riftbreaker\\\" userdata >/dev/null 2>&1\"", + "SkipOnFailure": true + } +] diff --git a/riftbreakerwinescript.sh b/riftbreakerwinescript.sh new file mode 100644 index 000000000..b067d196a --- /dev/null +++ b/riftbreakerwinescript.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Installs the Windows runtime components required by The Riftbreaker dedicated +# server (a Windows-only application) into the Wine prefix so it can run on Linux. +# The Wine prefix itself is created/updated by the separate "Initialise Wine" update +# stage (wineboot --init --update), which never resets the prefix so saves survive. +# A marker file makes this script idempotent - the (slow) winetricks install runs +# only once per prefix and is skipped on subsequent updates. + +SCRIPT_NAME=$(echo \"$0\" | xargs readlink -f) +SCRIPTDIR=$(dirname "$SCRIPT_NAME") + +export WINEPREFIX="$SCRIPTDIR/riftbreaker/.wine" +export WINEARCH=win64 +export WINEDLLOVERRIDES="mscoree,mshtml=" +export WINEDEBUG=-all + +MARKER="$WINEPREFIX/.rb-runtime-done" +[[ -f "$MARKER" ]] && exit 0 + +# winetricks needs a display, so spin up a temporary virtual framebuffer. +exec 6>display.log +/usr/bin/Xvfb -displayfd 6 -nolisten tcp -nolisten unix & +XVFB_PID=$! +while [[ ! -s display.log ]]; do + sleep 1 +done +read -r DPY_NUM < display.log +rm display.log +export DISPLAY=:$DPY_NUM + +[[ -f winetricks ]] && rm -f winetricks +wget -q https://raw.githubusercontent.com/Winetricks/winetricks/refs/tags/20260125/src/winetricks +chmod +x winetricks + +echo "" > winescript_log.txt 2>&1 +for PACKAGE in vcrun2022 d3dcompiler_47; do + ./winetricks -q $PACKAGE >> winescript_log.txt 2>&1 +done +rm -rf ~/.cache/winetricks + +# Only mark the runtime install complete if the key DLLs are actually present. +# This way a transient winetricks/download failure retries on the next update +# instead of being permanently skipped by the marker check above. +SYS32="$WINEPREFIX/drive_c/windows/system32" +if [[ -f "$SYS32/d3dcompiler_47.dll" && -f "$SYS32/vcruntime140.dll" ]]; then + touch "$MARKER" +fi + +exec 6>&- +kill $XVFB_PID + +exit 0 From 318f567ffa92215f73ff8645fed499f77fce62c1 Mon Sep 17 00:00:00 2001 From: Mihai Damaschin Date: Sat, 11 Jul 2026 00:07:34 -0400 Subject: [PATCH 2/2] Riftbreaker: point fetch URLs upstream and tidy config Switch the config-template and winescript fetch URLs to the CubeCoders repo, drop the winetricks marker in favour of the same re-run-each-update approach the other winescripts use, and trim the config comments and setting descriptions. --- riftbreakerconfig.json | 34 ++++++++++++++++----------------- riftbreakerports.json | 2 +- riftbreakertemplatesettings.cfg | 9 ++------- riftbreakerupdates.json | 4 ++-- riftbreakerwinescript.sh | 32 +++++++------------------------ 5 files changed, 29 insertions(+), 52 deletions(-) diff --git a/riftbreakerconfig.json b/riftbreakerconfig.json index 1b8303418..6ee535684 100644 --- a/riftbreakerconfig.json +++ b/riftbreakerconfig.json @@ -3,7 +3,7 @@ "DisplayName": "Server Name", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Server Settings:dns:1", - "Description": "The publicly visible server name shown to players (e.g. in the in-game server browser)", + "Description": "Sets the server name shown to players in the server browser", "Keywords": "server,name,servername,hostname", "FieldName": "ServerName", "InputType": "text", @@ -15,7 +15,7 @@ "DisplayName": "Server Password", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Server Settings:dns:1", - "Description": "Password required to connect to the server. Leave blank for no password", + "Description": "Sets the password required to join the server. Leave blank for no password", "Keywords": "server,password,serverpassword", "FieldName": "ServerPassword", "InputType": "password", @@ -27,7 +27,7 @@ "DisplayName": "RCON Password", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Server Settings:dns:1", - "Description": "Password for remote console (RCON) commands. Clients must set the same password in-game via 'server_rcon_password' before they can run 'rcon '. Leave blank to disable remote commands. Note: this is the game's own in-game RCON and is not used by AMP's console", + "Description": "Sets the password for the game's in-game RCON. A client that sets the same value can run remote commands with 'rcon '. Leave blank to disable. This RCON is handled by the game itself and is not driven by the AMP console", "Keywords": "rcon,remote,console,command,password", "FieldName": "RconPassword", "InputType": "password", @@ -39,7 +39,7 @@ "DisplayName": "Player Limit", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Server Settings:dns:1", - "Description": "Maximum number of players allowed on the server. The officially supported maximum is 4 - each additional player can severely impact performance. Increase beyond 4 at your own risk", + "Description": "Sets the maximum number of players. The officially supported maximum is 4; higher values can significantly affect performance", "Keywords": "max,players,limit,count,slots,server_max_players_count", "FieldName": "$MaxUsers", "InputType": "number", @@ -54,22 +54,22 @@ "DisplayName": "Networking Mode", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Server Settings:dns:1", - "Description": "How players connect. 'Steam Server Browser' uses Steam's relay/P2P networking - it needs only outbound internet access (no port forwarding) and players join from the in-game Multiplayer > Server Browser. 'LAN / Direct Connect' disables Steam networking - players join with connect \"\" in the game console and the Game Port (6321) must be reachable", + "Description": "Selects how players connect. Steam Server Browser uses Steam relay networking with no port forwarding, and players join from the in-game browser. LAN / Direct Connect disables Steam networking, and players join with connect \"\" on the Game Port", "Keywords": "steam,lan,direct,connect,networking,mode,disable_steam,p2p,relay", "FieldName": "DisableSteam", "InputType": "enum", "ParamFieldName": "DisableSteam", "DefaultValue": "0", "EnumValues": { - "0": "Steam Server Browser (recommended - no port forwarding)", - "1": "LAN / Direct Connect (requires Game Port 6321 open)" + "0": "Steam Server Browser (no port forwarding)", + "1": "LAN / Direct Connect (Game Port 6321)" } }, { "DisplayName": "List In Server Browser", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Server Settings:dns:1", - "Description": "If enabled, the server is publicly listed in the in-game server browser. Disable to keep the server private", + "Description": "If enabled, the server is listed publicly in the in-game server browser", "Keywords": "broadcast,public,private,listed,visible,server_broadcast_enabled", "FieldName": "Broadcast", "InputType": "checkbox", @@ -84,7 +84,7 @@ "DisplayName": "Pause When Empty", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Server Settings:dns:1", - "Description": "If enabled, the server pauses the game simulation while no players are connected. This prevents your base from being attacked while you are away and resumes automatically when someone joins", + "Description": "If enabled, the server pauses the game while no players are connected and resumes when someone joins", "Keywords": "pause,empty,idle,afk,server_pause_game_when_empty", "FieldName": "PauseWhenEmpty", "InputType": "checkbox", @@ -99,30 +99,30 @@ "DisplayName": "Game Mode / Campaign", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Game Settings:videogame_asset:2", - "Description": "The campaign type to host. Story Campaign is the guided co-op story. Open Campaign and Survival both require a Starting Mission to be selected below. Make sure your Difficulty selection matches the chosen mode", + "Description": "Sets the campaign type. Open Campaign and Survival also require a Starting Mission. Set the Difficulty to match the chosen mode", "Keywords": "campaign,mode,story,open,survival,game", "FieldName": "Campaign", "InputType": "enum", "ParamFieldName": "Campaign", "DefaultValue": "mp_story/mp_story", "EnumValues": { - "mp_story/mp_story": "Story Campaign (co-op)", - "open/open": "Open Campaign (choose a Starting Mission)", - "mp_survival/mp_survival": "Survival (choose a Starting Mission)" + "mp_story/mp_story": "Story Campaign", + "open/open": "Open Campaign", + "mp_survival/mp_survival": "Survival" } }, { "DisplayName": "Starting Mission / Biome", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Game Settings:videogame_asset:2", - "Description": "The starting mission/biome. Required for Open Campaign (campaigns/open/...) and Survival (survival/...). Leave as 'None' for the Story Campaign. The prefix must match your Game Mode selection above", + "Description": "Sets the starting mission. Required for Open Campaign and Survival, and left as None for the Story Campaign. The prefix must match the chosen campaign type", "Keywords": "mission,biome,map,starting,start", "FieldName": "Mission", "InputType": "enum", "ParamFieldName": "Mission", "DefaultValue": "", "EnumValues": { - "": "None - for Story Campaign (default)", + "": "None (Story Campaign)", "campaigns/open/headquarters_jungle": "Open Campaign: Jungle", "campaigns/open/headquarters_desert": "Open Campaign: Desert", "campaigns/open/headquarters_acid": "Open Campaign: Acid", @@ -145,7 +145,7 @@ "DisplayName": "Difficulty", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Game Settings:videogame_asset:2", - "Description": "The difficulty level. IMPORTANT: pick the entry that matches your Game Mode - Story uses the 'Story:' options, Open Campaign uses the 'Open Campaign:' options, and Survival uses the 'Survival:' options. A mismatched value may be ignored by the game", + "Description": "Sets the difficulty. Choose the entry that matches the campaign type; a value from a different mode may be ignored by the game", "Keywords": "difficulty,hard,easy,normal,brutal,coop", "FieldName": "Difficulty", "InputType": "enum", @@ -170,7 +170,7 @@ "DisplayName": "Additional Server Settings", "Category": "The Riftbreaker:stadia_controller", "Subcategory": "Advanced:build:3", - "Description": "Extra config lines added verbatim to config.cfg, one per line, e.g. set autosave_timer \"10\". To load an existing save instead of starting a new game, add a line like set mission_save \"SAVE_NAME\" and set Game Mode/Mission/Difficulty appropriately. See the EXOR Studios dedicated server guide for all available parameters", + "Description": "Additional config.cfg lines added as-is, one per line, such as set autosave_timer \"10\". To load an existing save, add set mission_save \"SAVE_NAME\". See the EXOR Studios dedicated server guide for the full parameter list", "Keywords": "additional,custom,advanced,extra,settings,cvars,mission_save", "FieldName": "UserSettings", "InputType": "Textarea", diff --git a/riftbreakerports.json b/riftbreakerports.json index f5083e062..ac55faa51 100644 --- a/riftbreakerports.json +++ b/riftbreakerports.json @@ -4,6 +4,6 @@ "Port": 6321, "Ref": "GamePort", "Name": "Game Port", - "Description": "Port used for direct/LAN game connections (TCP and UDP). Required only for LAN / Direct Connect mode. Steam Server Browser mode uses Steam's relay/P2P networking and needs only outbound internet access (no port forwarding)." + "Description": "Port used for direct/LAN game connections. Not required in Steam Server Browser mode, which uses Steam relay networking" } ] diff --git a/riftbreakertemplatesettings.cfg b/riftbreakertemplatesettings.cfg index c48ec9386..4da3e4578 100644 --- a/riftbreakertemplatesettings.cfg +++ b/riftbreakertemplatesettings.cfg @@ -1,10 +1,5 @@ -// This file is managed by AMP. Configure settings through the AMP web interface. -// The game ignores everything after // on a line, so those lines act as toggles. -// Do not remove the 'set app_mode "server"' line - the server needs it to start -// headless instead of waiting at the menu. -// -// Advanced/extra options can be added via "Additional Server Settings" in the AMP UI. -// See the EXOR Studios dedicated server guide for the full list of parameters. +// This file is controlled by AMP +// Configure any additional settings via the AMP UI set app_mode "server" diff --git a/riftbreakerupdates.json b/riftbreakerupdates.json index 0177fb639..4db45b448 100644 --- a/riftbreakerupdates.json +++ b/riftbreakerupdates.json @@ -12,7 +12,7 @@ "UpdateStageName": "Config Template Download", "UpdateSourcePlatform": "All", "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CostcoFanboy/AMPTemplates/main/riftbreakertemplatesettings.cfg", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/riftbreakertemplatesettings.cfg", "UpdateSourceTarget": "{{$FullRootDir}}", "UpdateSourceArgs": "AMP_config.cfg", "OverwriteExistingFiles": true, @@ -30,7 +30,7 @@ "UpdateStageName": "Winescript Download", "UpdateSourcePlatform": "Linux", "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CostcoFanboy/AMPTemplates/main/riftbreakerwinescript.sh", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/riftbreakerwinescript.sh", "UpdateSourceTarget": "{{$FullInstanceDir}}", "UpdateSourceArgs": "winescript.sh", "OverwriteExistingFiles": true, diff --git a/riftbreakerwinescript.sh b/riftbreakerwinescript.sh index b067d196a..62f98f8a6 100644 --- a/riftbreakerwinescript.sh +++ b/riftbreakerwinescript.sh @@ -1,24 +1,8 @@ #!/bin/bash -# Installs the Windows runtime components required by The Riftbreaker dedicated -# server (a Windows-only application) into the Wine prefix so it can run on Linux. -# The Wine prefix itself is created/updated by the separate "Initialise Wine" update -# stage (wineboot --init --update), which never resets the prefix so saves survive. -# A marker file makes this script idempotent - the (slow) winetricks install runs -# only once per prefix and is skipped on subsequent updates. - SCRIPT_NAME=$(echo \"$0\" | xargs readlink -f) SCRIPTDIR=$(dirname "$SCRIPT_NAME") -export WINEPREFIX="$SCRIPTDIR/riftbreaker/.wine" -export WINEARCH=win64 -export WINEDLLOVERRIDES="mscoree,mshtml=" -export WINEDEBUG=-all - -MARKER="$WINEPREFIX/.rb-runtime-done" -[[ -f "$MARKER" ]] && exit 0 - -# winetricks needs a display, so spin up a temporary virtual framebuffer. exec 6>display.log /usr/bin/Xvfb -displayfd 6 -nolisten tcp -nolisten unix & XVFB_PID=$! @@ -27,26 +11,24 @@ while [[ ! -s display.log ]]; do done read -r DPY_NUM < display.log rm display.log + +export WINEPREFIX="$SCRIPTDIR/riftbreaker/.wine" +export WINEDLLOVERRIDES="mscoree,mshtml=" +export WINEARCH=win64 +export WINEDEBUG=fixme-all export DISPLAY=:$DPY_NUM [[ -f winetricks ]] && rm -f winetricks wget -q https://raw.githubusercontent.com/Winetricks/winetricks/refs/tags/20260125/src/winetricks chmod +x winetricks +PACKAGES="vcrun2022 d3dcompiler_47" echo "" > winescript_log.txt 2>&1 -for PACKAGE in vcrun2022 d3dcompiler_47; do +for PACKAGE in $PACKAGES; do ./winetricks -q $PACKAGE >> winescript_log.txt 2>&1 done rm -rf ~/.cache/winetricks -# Only mark the runtime install complete if the key DLLs are actually present. -# This way a transient winetricks/download failure retries on the next update -# instead of being permanently skipped by the marker check above. -SYS32="$WINEPREFIX/drive_c/windows/system32" -if [[ -f "$SYS32/d3dcompiler_47.dll" && -f "$SYS32/vcruntime140.dll" ]]; then - touch "$MARKER" -fi - exec 6>&- kill $XVFB_PID