Basic Deployment
By using Deploy you can create a deliverable of your game for your current architecture pretty easily. Simply adjust the system definition of your game to include the following fields:
:build-operation "deploy-op"
:build-pathname #+linux "my-game-linux.run"
#+darwin "my-game-macos.o"
#+win32 "my-game-windows"
#+(and bsd (not darwin)) "my-game-bsd.run"
#-(or linux bsd win32) "my-game"
:entry-point "my-game::main"
:defsystem-depends-on (:deploy)You can adapt the build pathnames as you wish, as long as the pathname types stay consistent: .run for Linux, .o for MacOS, and none for Windows (.exe is added by default). You can also adapt the entry point as you choose. Usually it'll be a function similar to this:
(defun main ()
(command-line-toplevel)
(load-keymap :package #.*package*)
(load-settings)
(save-settings)
(launch 'my-game))
You can now invoke (asdf:make :my-game) to build a release of your game. It'll be put into the bin/ subdirectory of your system source directory. You should be able to just ZIP that directory up and give it to people to play.
Pruning Asset Files
By default Trial copies all files in all asset pools it knows of. This may be over-eager, especially if you make use of asset bundles like trial-assets. To clean up some of the mess, you can use define-as-unused. It accepts asset names or wildcard pathnames so you can easily exclude entire directories or file types.
(define-as-unused trial
"*.glsl"
cat)
Using the Release Mechanism
It is often useful to automate the build for multiple operating systems and also automate the submission. For this purpose, the trial-release extension exists This is a system offering automation for pushing releases of your game to a zip, Steam, Itch.io, or other services.
Getting Set Up
First you'll want to create a new ASDF system for your game's release. The ASD file should be in a directory where your releases will be put, so ideally not in the game's source root. The ASD should be something like this:
(asdf:defsystem my-game-release
:components ((:file "release"))
:depends-on (:trial-release)
:perform (asdf:build-op (op c) (uiop:symbol-call :org.shirakumo.fraf.trial.release :make)))
The release file can be something like this:
(org.shirakumo.fraf.trial.release:configure
:itch (:user "my-itch-username")
:steam (:user "my-steam-username")
:system "my-game"
:depots (:content ("pool/")
:windows ("*.dll" "*.exe")
:linux ("*.so" "*.run")
:macos ("*.dylib" "*.o"))
:bundles (:linux (:depots (:linux :content))
:windows (:depots (:windows :content))
:macos (:depots (:macos :content))
:all (:depots (:linux :windows :macos :content)))
:bundle (:targets #(:linux :windows))
:upload (:targets #(:steam :itch)))There are other configuration parameters you can set if necessary to customise the build and release process.
Outside of this, you'll have to have the following binaries set up in your PATH:
sbcl-lin(linux)
The SBCL binary used to build the Linux version. This should be a binary that was compiled on the minimum linux kernel version you want to support. It's also recommended that you modify theLD_LIBRARY_PATHof it to include a directory with all necessary libraries also compiled on the same minimum kernel version.sbcl-win(linux)
The SBCL Windows binary used to build the Windows version. This can be a wrapper using Wine, which works really well to build for Windows under Linux.sbcl-mac(linux)
The SBCL binary used to build the Mac version. This is currently unsupported, but in the future once Darling works better this could be used to deploy to that platform from Linux as well.pass(optional)
Used to retrieve passwords and other secrets for uploads. If not present, will query for a password at the REPL.
Once all of this is ready, you can run a build using (asdf:make :my-game-release) or manually invoking org.shirakumo.fraf.trial.release:make after loading that system.
For the sbcl-* variants, you can use the binaries and scripts from the following repository: https://gitea.tymoon.eu/shinmera/trial-deployment They have been pre-tested.
Build Configuration
You can configure the build with the following options, all under the :build scope:
:featuresA list of symbols to push onto *features* when building.:build-argumentsA list of command line argmuents to pass on when building.:dynamic-space-sizeThe max heap size to use when building.:linuxThe binary used to build for Linux from linux.:windowsThe binary used to build for Windows from linux.:macosThe binary used to build for MacOS form linux.:targetsWhich targets to build by default (can include :linux, :windows, :macos).:pruneSpecify directories or files that should be removed before deploying. Paths are relative to the target directory.:copySpecify additional files that should be copied before deploying. May be a path or a list of source and target. Source paths are relative to the system root, target paths relative to the output directory.
Bundle Configuration
Some upload mechanisms require appropriate bundles to be configured. Bundles will also produce standalone ZIP files that you can distribute manually. To configure bundles, you must first configure depots. A depot is a list of paths in the release that belong to it. Each path in a depot may be either:
A plain path, in which case the singular file is copied.
A directory path, in which case the directory is copied recursively.
A wild path, in which case all matching files are copied.
Once your depots are configured, you can specify the bundles. Each bundle under the :bundles scope should be a plist of the following options:
:depotsThe list of depots to include in the bundle.:file-formatAn optional format string by which to create the file name for the bundle. Is passed the three arguments:The
:systemkey.The bundle's name.
The current version string.
By default the format string is just
~(~a-~a-~a~).
To configure which bundles are actually created when you run a default release build, fill the vector for :bundle :targets.
Upload Configurations
The Trial release mechanism supports a number of upload mechanisms to automatically distribute releases to different platforms. See the sections below on how to configure them. If you would like to automatically push releases, make sure to add the upload mechanism to the :upload :targets array.
Steam
Steam will require some VDF files to configure your build in addition. Please consult the SteamWorks documentation on how to do that. However, be aware that the base file should be called app-build.vdf and should be in the same directory as your my-game-release.asd file, and should have several fields set specially so the Trial release mechanism can operate properly. Here's an example:
"appbuild"{
"appid" "1261430"
"desc" "Kandria developer build"
"buildoutput" "../steam/"
"contentroot" "$CONTENT"
"setlive" "$BRANCH"
"preview" "$PREVIEW"
"local" ""
"depots"{
"1261431" "../windows-depot.vdf"
"1261432" "../linux-depot.vdf"
"1261433" "../macos-depot.vdf"
"1261434" "../content-depot.vdf"
}
}The Trial release build will automatically take this file and replace the $ variables, then copy it to a subdirectory where the upload happens, hence the ../ backrefs in the paths. The depot VDF files do not need any special configuration.
The steamcmd also needs to be available in your PATH.
In the configuration, the following keys are available in the :steam scope:
:branchThe branch to which to push on Steam:previewWhether it should only preview the upload and not actually perform it:userThe user with which you log in to perform the upload:passwordThe password for the user. If NIL will try to get it from pass or query for it.
Itch
To upload to itch, you will need to have the butler program in your PATH. Make sure to run Butler once before to save the login credentials.
In the configuration, the following keys are available in the :itch scope:
:userThe user under which the project is located.:passwordIf given, should be the cached token that Butler stores in a file when you log in. This lets you automate login without your user password.:projectThe name of the project. Defaults to the:systemkey.
GOG
To upload to GOG, you need the GOGGalaxyPipelineBuilder program in your PATH. You can run it first to cache credentials, or pass them in the Trial configuration.
In the configuration, the following keys are available in the :gog scope:
:userThe username to log in with:passwordThe password to log in with:branchThe branch to push the build to. If the branch is password protected, this should be a list of the branch name and its password.
Keygen
To upload to a Keygen instance, you'll need to generate an oAuth application on your instance and also authorise a token using the standard oAuth flow. If you use pass, you should create a pass entry with your tokens and secrets in it. On the Keygen side, create a project and a file under the project for each of the bundles you want to upload. On the release side you'll of course need the corresponding bundles to upload.
In the configuration, the following keys are available in the :keygen scope:
:bundlesA plist of bundles to upload, with the corresponding IDs of the files to upload to.:keyThe oAuth application key.:secretThe oAuth application secret.:tokenThe oAuth token for your authorisation.:token-secretThe oAuth token secret key.:api-baseThe base URL under which to perform keygen API calls. Something like: https://keygen.tymoon.eu/api/:secretsThe password to query for the tokens/secrets. If unspecified defaults to the api-base.
HTTP
This will perform a simple HTTP request to upload bundle payloads.
In the configuration, the following keys are available in the :http scope:
:bundlesA list of bundles to upload.:urlThe URL to send the request to.:methodThe method by which to send the request. Defaults to POST.:file-parameterWhich parameter the payload is sent under.:parametersAdditional content parameters to send.
Rsync
This will use the rsync tool to send the file to a remote server. rsync must be in the PATH and available on the remote server as well.
In the configuration, the following keys are available in the :rsync scope:
:bundlesA list of bundles to upload.:userThe user by which to connect.:portThe port under which to connect.:hostnameThe hostname of the server to connect to.:pathThe path under which to upload the bundle.
SSH
This will use an SSH connection to send the file to a remote server.
In the configuration, the following keys are available in the :ssh scope:
:bundlesA list of bundles to upload.:userThe user by which to connect.:portThe port under which to connect.:passwordThe password for the user. May be a pathname to a key file, a string,:passto query the pass utility, and NIL to use the SSH agent.:hostnameThe hostname of the server to connect to.:pathThe path under which to upload the bundle.
FTP
This will use an FTP connection to send the file to a remote server.
In the configuration, the following keys are available in the :ftp scope:
:bundlesA list of bundles to upload.:userThe user by which to connect.:portThe port under which to connect.:passwordThe password for the user. If unspecified, will use pass or query.:hostnameThe hostname of the server to connect to.:pathThe path under which to upload the bundle.