diff --git a/MPSGameLift/Documentation/GameLift.md b/MPSGameLift/Documentation/GameLift.md index 146da47bd..fcd77e8b2 100644 --- a/MPSGameLift/Documentation/GameLift.md +++ b/MPSGameLift/Documentation/GameLift.md @@ -12,58 +12,32 @@ This README covers optional setup, testing and running on [Amazon GameLift](http C:\> aws --version aws-cli/2.10.0 Python/3.11.2 Windows/10 exe/AMD64 prompt/off ``` -1. Enable the "AWSGameLift" and "MPSGameLift" gems - - Option 1: Commandline - ```sh - \scripts\o3de.bat enable-gem -pp -gn MPSGameLift - ``` - Option 2: Project Manager - 1. Open Project Manager - 2. Select the "Configure Gems" options for Multiplayer Sample - 3. Enable "AWSGameLift" and "MPSGameLift" gems - - ![Enable GameLift Gems](Media/enable_gamelift_gems.jpg) - 4. Click "Save" - - - --- - **NOTE** - - Due to [bug-15829](https://github.com/o3de/o3de/issues/15829) please also add "AWSGameLift" to project.json's _gem_names_ list. - - --- - - -1. Build the server, game launchers, and asset bundler for MultiplayerSample - - `cmake --build build\windows --target Editor MultiplayerSample.GameLauncher MultiplayerSample.ServerLauncher AssetBundler --config profile -- /m ` - -1. Build all the assets - - `cmake --build build\windows --target MultiplayerSample.Assets --config profile -- /m` - 1. Work in progress (WiP) step: Add your AWS region to Config/default_aws_resource_mappings.json (example: "Region": "us-west-2") a. Currently needed otherwise when the client initializes GameLift there will be an error about not having a region. b. This step will be removed once we properly parse the game-session data which contains the fleet-id, region-id, etc -## Build Server for Windows -1. Build Monolithic Server +1. Use Export Project to Compile Code and Build Assets - a. `cmake -B build\windows_mono -S . -G "Visual Studio 16" -DLY_MONOLITHIC_GAME=1 -DALLOW_SETTINGS_REGISTRY_DEVELOPMENT_OVERRIDES=0` + ```sh + \scripts\o3de.bat export-project -es \MPSGameLift\Scripts\export_gamelift_server_package.py --code --assets -ll INFO + ``` + --- + **Important** - b. `cmake --build build\windows_mono --target MultiplayerSample.GameLauncher MultiplayerSample.ServerLauncher --config profile -- /m /nologo` -1. Bundle Content + The export_gamelift_server_package script only works for projects built using engine source, and won't work with engine as an sdk. - a. Open .\build\windows\bin\profile\AssetBundler.exe + --- + + --- + **Important** - b. Follow steps for "Create a bundle for game assets" and "Create a bundle for engine assets" and "Add bundles to the release game layout" here: https://www.o3de.org/docs/user-guide/packaging/asset-bundler/bundle-assets-for-release/ + The export_gamelift_server_package script only works for projects built using engine source, and won't work with engine as an sdk. -The "default seed lists" choice should choose all but 4 seed lists to make the engine_pc.pak -The other 4 seed lists should all get selected to make the game_pc.pak + --- It's important to make sure that the bootstrap.game.profile.setreg file has been added to one of the seed files. (also add debug if you want to support debug builds) + 1. Create the Launcher Zip file Use the following .bat file or equivalent copy steps to create a directory with the launchers in it: Run from MultiplayerSample project root directory... @@ -90,14 +64,14 @@ It's important to make sure that the bootstrap.game.profile.setreg file has been 1. Test the profile pak server and game locally Run the server in headless mode using `rhi=null` and `NullRenderer` parameters; the server appears as a white screen in headless mode. - `C:\GameLiftPackageWindows\MultiplayerSample.ServerLauncher.exe --rhi=null -NullRenderer -bg_ConnectToAssetProcessor=0 -sys_PakPriority=2 -sv_terminateOnPlayerExit=true --console-command-file=launch_server.cfg` + `C:\GameLiftPackageWindows\MultiplayerSample.ServerLauncher.exe --rhi=null -NullRenderer -bg_ConnectToAssetProcessor=0 -sys_PakPriority=2 --console-command-file=launch_server.cfg` - `C:\GameLiftPackageWindows\MultiplayerSample.GameLauncher.exe -bg_ConnectToAssetProcessor=0 -sys_PakPriority=2 --connect` + `\build\windows\bin\profile\MultiplayerSample.GameLauncher.exe -bg_ConnectToAssetProcessor=0 --connect` --- **NOTE** - Note: launch_server.cfg is required because there's a bug with multiplayer when calling --loadlevel in the command-line. See https://github.com/o3de/o3de/issues/15773. + Launch_server.cfg is required because there's a bug with multiplayer when calling --loadlevel in the command-line. See https://github.com/o3de/o3de/issues/15773. --- @@ -150,9 +124,13 @@ Launch the game client with: ```sh aws gamelift create-player-session --region us-west-2 --game-session-id --player-id Player1 ``` -Note: PlayerId passed into create-player-session shouldn't be the player id passed into these JSON block; keep these unique. +--- +**NOTE** +PlayerId passed into create-player-session shouldn't be the player id passed into these JSON block; keep these unique. Record PlayerSessionId and use this in the game immediately because it expires after 60 seconds. Example: psess-50311090-9283-4fb0-ad1a-94468e60fa16 +--- + Paste in the game session and player session and click Connect. ```json { "GameSessionId": "", "PlayerId": "player_id", "PlayerSessionId": "" } diff --git a/MPSGameLift/Scripts/export_gamelift_server_package.py b/MPSGameLift/Scripts/export_gamelift_server_package.py new file mode 100644 index 000000000..681827767 --- /dev/null +++ b/MPSGameLift/Scripts/export_gamelift_server_package.py @@ -0,0 +1,153 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. +# For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# +""" +Enables the project for AWS Gamelift and creates a Windows server package which can be uploaded to a GameLift. + +To use this script pass it into o3de.bat's export-project command: +\scripts\o3de.bat export-project -es \MPSGameLift\Scripts\export_gamelift_server_package.py -ll INFO +""" + +import os +import argparse + +import o3de.export_project as exp +import o3de.enable_gem as enable_gem + +from o3de.export_project import process_command +from o3de import manifest + +project_json_data = manifest.get_project_json_data(project_path=o3de_context.project_path) +project_name = project_json_data.get('project_name') + +o3de_logger.info(f"Exporting AWS GameLift Server Package for {project_name}") + +# Parse arguments to either build code, assets, or both +parser = argparse.ArgumentParser( + prog='GameLift Server Package', + description='Helps setup the project for AWS Gamelift and creates a Windows server package which can be uploaded to a GameLift.') + +parser.add_argument('--code', action='store_true', help='Build code') +parser.add_argument('--assets', action='store_true', help='Build assets') +parser.add_argument('-g', '--generator', choices=['Visual Studio 16', 'Visual Studio 17'], help='Which compiler do you want to use?') + +args = parser.parse_args(o3de_context.args) + +# Help user choose to build code, assets, or both if they didn't specify via command-line +while not args.code and not args.assets: + user_input = input('No build command specified. Do you want to build code, assets, or both? (c/a/b). Quit(q): ') + if user_input.lower() == 'c': + args.code = True + elif user_input.lower() == 'a': + args.assets = True + elif user_input.lower() == 'b': + args.code = True + args.assets = True + elif user_input.lower() == 'q': + quit() + +# Help user choose their compiler if they didn't specify via command-line +while not args.generator: + user_input = input('Select generator:\n 1. Visual Studio 16\n 2. Visual Studio 17.\n Quit(q)\n') + if user_input == '1': + args.generator = "Visual Studio 16" + if user_input == '2': + args.generator = "Visual Studio 17" + elif user_input.lower() == 'q': + quit() + +build_folder = os.path.join(o3de_context.project_path, "build", "windows") + +# Build code +if (args.code): + # Enable GameLift gems + o3de_logger.info(f"Enabling AWSGameLift and MPSGameLift gem") + if (enable_gem.enable_gem_in_project(gem_name="AWSGameLift", project_path=o3de_context.project_path) != 0): + quit() + + if (enable_gem.enable_gem_in_project(gem_name="MPSGameLift", project_path=o3de_context.project_path) != 0): + quit() + + # Build server launcher + os.makedirs(build_folder, exist_ok=True) + o3de_logger.info(f"Building {project_name}.ServerLauncher") + + if (process_command(["cmake", "-B", build_folder, "-S", o3de_context.project_path, "-G", args.generator])): + quit() + + if (process_command(["cmake", "--build", build_folder, "--target", f"{project_name}.ServerLauncher", "AssetProcessor", "AssetBundler", "AssetBundlerBatch", "--config", "profile", "--", "/m"]) != 0): + quit() + + # Build monolithic server launcher build + monolithic_build_folder = os.path.join(o3de_context.project_path, "build", "windows_mono") + os.makedirs(monolithic_build_folder, exist_ok=True) + if (process_command(["cmake", "-B", monolithic_build_folder, "-S", o3de_context.project_path, "-G", args.generator, "-DLY_MONOLITHIC_GAME=1", "-DALLOW_SETTINGS_REGISTRY_DEVELOPMENT_OVERRIDES=0"])): + quit() + + if (process_command(["cmake", "--build", monolithic_build_folder, "--target", f"{project_name}.ServerLauncher", "--config", "profile", "--", "/m"])): + quit() + +# Build Assets +if (args.assets): + # Process assets + if (process_command(["cmake", "--build", build_folder, "--target", f"{project_name}.Assets", "--config", "profile", "--", "/m"]) != 0): + quit() + + if (process_command(["cmake", "--build", build_folder, "--target", "AssetBundler", "AssetBundlerBatch", "--config", "profile", "--", "/m"]) != 0): + quit() + + # Create a game asset list by using the game seed list + platform = "pc" + asset_bundler_batch = os.path.join(build_folder, "bin", "profile", "AssetBundlerBatch.exe") + asset_list_directory = os.path.join(o3de_context.project_path, "AssetBundling", "AssetLists" ) + seed_list_directory = os.path.join(o3de_context.project_path, "AssetBundling", "SeedLists" ) + game_asset_list_path = os.path.join(asset_list_directory, f"game_{platform}.assetlist") + engine_asset_list_path = os.path.join(asset_list_directory, f"engine_{platform}.assetlist") + + generate_asset_list_command = f"{asset_bundler_batch} assetLists --assetListFile {game_asset_list_path} --platform {platform} --allowOverwrites" + + # Add all the .seed files found inside /AssetBundling/SeedLists + seed_file_extension = ".seed" + + seed_files = [os.path.join(seed_list_directory, f) for f in os.listdir(seed_list_directory) if f.endswith(seed_file_extension)] + + if not seed_files: + o3de_logger.error(f"Building assets failed! Could not find any game seed files inside {seed_list_directory}") + quit() + + for file in seed_files: + generate_asset_list_command += str(f" --seedListFile ") + generate_asset_list_command += str(os.path.join(seed_list_directory, file)) + + if (process_command(generate_asset_list_command.split()) != 0): + quit() + + + if (process_command([asset_bundler_batch, "assetLists", "--assetListFile", game_asset_list_path, "--platform", platform, "--allowOverwrites", + "--seedListFile", os.path.join(seed_list_directory, "BasePopcornFxSeedList.seed"), + "--seedListFile", os.path.join(seed_list_directory, "GameSeedList.seed"), + "--seedListFile", os.path.join(seed_list_directory, "ProfileOnlySeedList.seed"), + "--seedListFile", os.path.join(seed_list_directory, "VFXSeedList.seed")]) != 0): + quit() + + # Create a engine asset list by using the engine seed list + if (process_command([asset_bundler_batch, "assetLists", "--assetListFile", engine_asset_list_path, "--platform", platform, "--allowOverwrites", + "--addDefaultSeedListFiles"]) != 0): + quit() + + # Bundle game asset using game asset list + bundles_directory = os.path.join(o3de_context.project_path, "AssetBundling", "Bundles" ) + if (process_command([asset_bundler_batch, "bundles", "--maxSize", "2048", "--platform", platform, "--allowOverwrites", + "--outputBundlePath", os.path.join(bundles_directory, "game.pak"), + "--assetListFile", game_asset_list_path]) != 0): + quit() + + # Bundle engine asset using engine asset list + if (process_command([asset_bundler_batch, "bundles", "--maxSize", "2048", "--platform", platform, "--allowOverwrites", + "--outputBundlePath", os.path.join(bundles_directory, "engine.pak"), + "--assetListFile", engine_asset_list_path]) != 0): + quit()