Skip to content

patricktcoakley/fgvm

Repository files navigation

fgvm

fgvm, a friendly Godot version manager.

Important

This project was previously known as gdvm, but as of 2.0 has now been renamed to fgvm. Most users won't be significantly impacted, but some changes were breaking and will require users to switch over to fgvm; please see this section for information on how to migrate.

Introduction

fgvm is a friendly Godot version manager that lets users install and manage multiple versions of Godot with ease. It uses a hybrid CLI/TUI design, meaning that in certain places where it makes sense it will prompt you to let you select what you're looking for instead of having to pass in confusing arguments, as well as support for passing it unstructured queries to help find the appropriate version based on your input, like 4 dev or latest. It's released as a self-contained native executable for Windows, macOS, and Linux that can be run without installing the .NET runtime, either by putting it somewhere on your PATH or, preferably, using a package manager.

Features

  • Version Management: Easily manage multiple Godot installations side-by-side, allowing you to try out the latest versions or keep older versions for compatibility testing, including Godot 1.0 to the latest development builds, including both standard and .NET builds.
  • Export Template Management: Install, list, and remove Godot export templates for locally installed Godot versions.
  • Hybrid CLI/TUI Interface: Simple command-line interface with interactive TUI prompts for easy navigation and selection when you don't specify arguments.
  • Flexible Query System: Powerful query system for finding and installing versions using keywords like latest, 4 mono, 3.3 rc, etc.
  • Project Aware: Lock a project to a specific Godot version using a .fgvm-version file in the project directory. fgvm local can automatically detect a compatible version from project.godot or let you manually choose one, and will prompt to install missing versions when needed. fgvm godot uses .fgvm-version when present, otherwise falls back to the global default, and can launch the current project directly from the terminal.
  • Smart Argument Handling: Detection of arguments passed to Godot that contextually switch to an attached mode when necessary to display terminal output.
  • CI-Ready: Suitable for remote installations, CI/CD pipelines, WSL, and containerized environments with its single self-contained native executable.

Installation

Note

On Windows, fgvm creates an optional Godot.url shortcut to the selected version for GUI launch compatibility. You can still install, remove, set, and launch versions with fgvm godot if that shortcut cannot be created.

In addition, PowerShell, the default shell for Windows, doesn't support the emojis out of the box. To fix this, you simply need to update the $PROFILE/profile.ps1:

'[console]::InputEncoding = [console]::OutputEncoding = [System.Text.UTF8Encoding]::new()' | Add-Content -Path $PROFILE

Also, if you are using cmd, you can also try the beta unicode support by going to Region in the control panel, going to Administrative, clicking Change system locale, and checking the Beta: Use Unicode UTF-8 for worldwide language support checkbox. You will have to restart your computer, but it should enable emoji support there as well.

Package Managers

The recommended way to install fgvm is through a package manager, which will make it easier to keep up to date and manage your installations:

Homebrew (macOS/Linux)

If you're on macOS or Linux, you can install fgvm using Homebrew by running the following commands:

brew tap patricktcoakley/formulae
brew trust patricktcoakley/formulae
brew install fgvm

Homebrew 5 requires third-party taps to be explicitly trusted before their formulae can be installed; brew trust marks the tap as trusted so brew install fgvm succeeds. See the brew trust documentation for more details.

Note that you may periodically need to run brew update if any changes are applied to the formula.

Alternatively, macOS and Linux users can use the install script. On macOS, this avoids the browser-added quarantine attribute that can cause Gatekeeper warnings for the non-notarized binaries.

mise

mise can install fgvm directly from the GitHub release artifacts using its GitHub backend on Windows x64, macOS, and Linux:

mise use -g github:patricktcoakley/fgvm
fgvm --version

Install mise first using the mise installation docs; Windows users can use Scoop or winget there.

For now, use the full github:patricktcoakley/fgvm tool name. The shorter mise use -g fgvm form will only work after fgvm is added to mise's registry.

Scoop (Windows)

If you're on Windows, you can install fgvm using Scoop by running the following commands:

scoop bucket add patricktcoakley https://github.com/patricktcoakley/scoop-bucket
scoop install patricktcoakley/fgvm

Install Scripts

If you do not want to use a package manager, the install scripts download the latest release, verify its SHA-256 checksum, install fgvm, and update your user environment. FGVM_HOME controls fgvm's runtime home and defaults to ~/fgvm. FGVM_INSTALL_DIR controls where the fgvm binary is installed and defaults to $FGVM_HOME/bin. The installer adds both FGVM_INSTALL_DIR and $FGVM_HOME/bin to PATH so the fgvm binary and the godot shim work. If you override either variable, the installer persists it in your shell profile or Windows user environment unless you skip environment changes.

macOS and Linux:

curl -fsSL https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.sh | sh

Windows PowerShell:

irm https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.ps1 | iex

Re-run either install script to upgrade an existing install. The installer downloads the latest release again, verifies its checksum, and replaces the fgvm binary in FGVM_INSTALL_DIR; it does not remove your FGVM_HOME installations, registry, or project version files.

If you prefer to inspect the installer before running it, download it first:

macOS and Linux:

curl -fsSLO https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.sh
less installer.sh
sh installer.sh

Windows PowerShell:

irm https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.ps1 -OutFile installer.ps1
notepad .\installer.ps1
.\installer.ps1

To install a specific version, run the downloaded script with --version VERSION on macOS/Linux or -Version VERSION on Windows. Version overrides support v2.2.0 or later only because older release artifacts use a different layout:

sh installer.sh --version v2.2.0
.\installer.ps1 -Version v2.2.0

Use --no-modify-path on macOS/Linux or -NoModifyPath on Windows to skip PATH and environment-variable changes:

sh installer.sh --version v2.2.0 --no-modify-path
.\installer.ps1 -Version v2.2.0 -NoModifyPath

To use a different fgvm home, set FGVM_HOME when using the one-line installer:

curl -fsSL https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.sh | FGVM_HOME="$HOME/dev/fgvm" sh
$env:FGVM_HOME = "$HOME\dev\fgvm"; irm https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.ps1 | iex

To install the fgvm binary somewhere outside $FGVM_HOME/bin, set FGVM_INSTALL_DIR:

curl -fsSL https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.sh | FGVM_INSTALL_DIR="$HOME/.local/bin" sh
$env:FGVM_INSTALL_DIR = "$HOME\.local\bin"; irm https://raw.githubusercontent.com/patricktcoakley/fgvm/main/installer.ps1 | iex

Or pass the install directory to the downloaded script:

sh installer.sh --fgvm-home "$HOME/dev/fgvm" --install-dir "$HOME/.local/bin"
.\installer.ps1 -FgvmHome "$HOME\dev\fgvm" -InstallDir "$HOME\.local\bin"

Pre-built Binaries

If you prefer to install manually, download the archive for your platform from the latest release:

Platform Architecture Archive
Windows x64 fgvm-win-x64.zip
macOS Intel x64 fgvm-osx-x64.tar.gz
macOS Apple Silicon ARM64 fgvm-osx-arm64.tar.gz
Linux x64 fgvm-linux-x64.tar.gz
Linux ARM64 fgvm-linux-arm64.tar.gz

Each archive has a matching .sha256 file on the release. Windows uses ZIP files; macOS and Linux use tarballs. Extract the executable into a directory on your PATH; on macOS and Linux, chmod +x fgvm is only needed if your filesystem or extraction tool strips executable permissions.

The Linux binaries require glibc and do not support musl-based distributions such as Alpine Linux.

macOS manual command-line download

The macOS binaries require macOS 12 or later and are not currently notarized. Downloads made through a browser may be quarantined by Gatekeeper. Downloading with curl does not apply the browser quarantine attribute, so you can verify and run the release directly:

# Apple Silicon
curl -fLO https://github.com/patricktcoakley/fgvm/releases/latest/download/fgvm-osx-arm64.tar.gz -fLO https://github.com/patricktcoakley/fgvm/releases/latest/download/fgvm-osx-arm64.tar.gz.sha256 && shasum -a 256 -c fgvm-osx-arm64.tar.gz.sha256

# Intel
curl -fLO https://github.com/patricktcoakley/fgvm/releases/latest/download/fgvm-osx-x64.tar.gz -fLO https://github.com/patricktcoakley/fgvm/releases/latest/download/fgvm-osx-x64.tar.gz.sha256 && shasum -a 256 -c fgvm-osx-x64.tar.gz.sha256

tar -xzf fgvm-osx-arm64.tar.gz # Use fgvm-osx-x64.tar.gz on Intel.
./fgvm --version

After confirming it runs, move fgvm into a directory on your PATH, such as ~/fgvm/bin.

Downloading with GitHub CLI

The GitHub CLI can download both the archive and its checksum from the latest release:

archive=fgvm-osx-arm64.tar.gz # Replace with the archive for your platform.
gh release download --repo patricktcoakley/fgvm \
  --pattern "$archive" \
  --pattern "$archive.sha256"

Verify the downloaded archive before extracting it:

# macOS
shasum -a 256 -c "$archive.sha256"

# Linux
sha256sum -c "$archive.sha256"

Extract macOS and Linux archives with tar:

tar -xzf "$archive"
./fgvm --version

On Windows, verify the expected hash from fgvm-win-x64.zip.sha256 against the downloaded archive:

$expected = (Get-Content .\fgvm-win-x64.zip.sha256).Split()[0]
$actual = (Get-FileHash .\fgvm-win-x64.zip -Algorithm SHA256).Hash
if ($actual -ne $expected) { throw "Checksum verification failed." }

Build From Source

See Build for instructions on how to build fgvm from source.

Usage

Getting Started

Install the latest stable standard build, set it as the global default, and launch Godot:

fgvm install latest --default
fgvm godot

fgvm downloads and installs Godot into folders inside of ~/fgvm/ for macOS and Linux, and $env:USERPROFILE\fgvm\ for Windows. You can customize this location using the FGVM_HOME environment variable (see Environment Variables). New installations are stored under installations/<VERSION>-<TYPE>-<RUNTIME>/<TARGET>/, and fgvm tracks them in installations.json. For example, a 4.3 stable .NET install on Linux x64 is tracked as installations/4.3-stable-mono/linux.x86_64/.

To install export templates alongside the editor, add --with-templates:

fgvm install 4.4.1 --with-templates

By default, fgvm records the selected version in installations.json. It also creates a stable PATH shim at bin/godot on macOS/Linux or bin/godot.cmd on Windows, and best-effort creates a root symlink named Godot on Linux, Godot.app on macOS, or a Godot.url shortcut on Windows for GUI launch compatibility. You can run fgvm godot -i to pick another installation to launch, or use fgvm set to pick the version you want to launch by default.

Godot installation availability is separate from fgvm's own release matrix. fgvm selects Godot artifacts for the detected operating system and CPU architecture, so older Godot releases may not be available on newer targets, particularly macOS ARM64. Downloading an artifact for a different target is not currently supported.

Commands

All of this is also available in the --help section of the app:

fgvm --help

but here is a detailed summary of the available commands:

Note: Many commands support short-form aliases for faster usage (e.g., fgvm i for fgvm install, fgvm g for fgvm godot).

  • fgvm list or fgvm l [--json] will list locally installed Godot versions. Use --json to output in JSON format.
  • fgvm install or fgvm i [<...strings>] [-D|--default] [--with-templates] will prompt the user to install a version if no arguments are supplied, or will try to find the closest matching version based on the query, defaulting to "stable" if no other release type is supplied. It will automatically set the installed version as the default if it's the first installation. Use --default (or -D) to explicitly set the installed version as the default regardless of whether other versions are already installed. Use --with-templates to install the matching official export template package after editor installation succeeds. If template installation fails, fgvm keeps the editor installation and prints a warning.
    • Queries:
      • latest or latest standard will install the latest stable, and latest mono will install the latest .NET stable.
      • 4 mono will grab the latest stable 4.x .NET release, 3.3 rc will grab the latest rc of 3.3 standard, 1 would take the last stable version 1, and so on.
    • Examples:
      • fgvm install 4.3 - Install 4.3 stable
      • fgvm install 4.3 mono - Install 4.3 stable mono
      • fgvm i latest --default - Install latest stable standard and set as default
      • fgvm install 4.4.1 --with-templates - Install 4.4.1 stable standard and its export templates
  • fgvm godot or fgvm g [-i|--interactive] [-a|--attached] [-P|--project] [--query <string>] [--args <string>] runs the appropriate Godot version, or resolves the optional query against installed versions and launches that match. With the --interactive or -i flag, it will prompt the user to launch an installed version, even if a query is supplied. When run in a project directory with a .fgvm-version file, it will use that project-specific version. If no .fgvm-version file exists, it will use the global default version. The command will automatically detect and launch the project if a project.godot file is found.
    • Once a version is installed, it will launch the editor with the project directly from the terminal.
    • Use --query to launch a specific installed version, such as fgvm godot --query "4.6 mono" or the exact installed version fgvm godot --query "4.6.2-stable-standard".
    • Optionally, pass in arguments to the Godot executable directly using --args followed by a separate value, such as fgvm godot --query "4.6 mono" --args "--headless" or fgvm godot --args "--version". Multiple arguments should be passed as a quoted string, such as --args "--headless -v". Do not use --args="..."; that form is rejected by the CLI parser.
    • Use --project or -P with explicit arguments to add the detected project path, such as fgvm godot -P --args "--dump-extension-api --quit".
    • Use the --attached or -a flag to force Godot connected to the terminal for output; by default, Godot runs in detached mode and will launch in a separate instance. Using an argument detection system, certain arguments (like --version, --help, --headless) automatically trigger this mode since they would otherwise be useless without printing to standard out.
    • The command will only read existing .fgvm-version files for version selection, and does not create or modify version files. Use fgvm local to manage .fgvm-version files.
  • fgvm set [<...strings>] prompts the user to set an installed version of Godot if no arguments are supplied, or will try to find the closest matching version based on the query, including release type (stable) and version (4, 4.4), or an exact match (4.4.1-stable-mono).
  • fgvm local [<...strings>] sets the Godot version for the current project by creating or updating a .fgvm-version file in the current directory. If no .fgvm-version file exists and no arguments are provided, it will automatically detect the project version from project.godot and install the most recent compatible version if not already installed.
    • If a list of arguments are provided, it will find the best matching version based on the query (including runtime preferences like mono or standard) and install it if necessary.
  • fgvm which [<...strings>] displays the executable path for the effective Godot installation in the current directory: .fgvm-version first, then the global default. If query arguments are supplied, it resolves them against installed versions instead. The command prints only the executable path on success and exits non-zero when no version can be resolved.
  • fgvm remove or fgvm r [<...strings>] prompts the user to select multiple installations to delete, or optionally takes a query to filter down to specific versions to delete. If there is only one match, it will delete it directly. If there are multiple matches, it will prompt the user to select which ones to delete.
    • For example, if you wanted to list all of the 4.y.z versions to remove, you could just do fgvm r 4 to list all of the 4 major releases. However, if you remove a specific version, like 4.4.1-stable-mono, it will just delete that version directly. Deleting the currently set version will unset it and you will need to set a new one.
  • fgvm logs [--json] [-l|--level <string>] [-m|--message <string>] displays all of the logs, or optionally takes a level or message filter. Use --json to output in JSON format.
  • fgvm search or fgvm s [<...strings>] [-j|--json] [-F|--no-cache] takes an optional query to search available Godot versions. Use --json or -j to output in JSON format, and --no-cache or -F to force a remote refresh instead of using the local release cache.
    • Queries:
      • 4 would filter all 4.x releases, including "stable", "dev", etc.
      • 4.2-rc would only list the 4.2 rc releases, but 4.2 rc would list all 4.2.x releases with the rc release type, including 4.2.2-rc3
  • fgvm template or fgvm t manages Godot export templates.
    • fgvm template install or fgvm template i [<...strings>] [--force] installs the official export template package for an installed Godot version. With no query, fgvm prompts from local Godot installations. With a query, it resolves against local Godot installations only, such as fgvm template install 4.4.1 or fgvm template install 4.4.1 mono.
    • fgvm template list or fgvm template l [-j|--json] lists installed export template directories.
    • fgvm template remove or fgvm template r [<...strings>] removes installed export template directories. With no query, fgvm prompts from installed export templates. With a query, it removes the exact match directly or prompts when multiple installed templates match.
    • Template commands manage full official TPZ packages. They do not install or remove individual export target files inside a package.

Export Templates

Godot export templates are installed separately from fgvm-managed editor binaries. fgvm uses the same standard export template root that the Godot editor uses:

Platform Default export template root
Windows %APPDATA%\Godot\export_templates
macOS ~/Library/Application Support/Godot/export_templates
Linux/BSD ${XDG_DATA_HOME:-~/.local/share}/godot/export_templates

Installed template directories use Godot's template version format, such as 4.4.1.stable or 4.4.1.stable.mono.

Use install --with-templates when you want editor and template installation in one command:

fgvm install 4.4.1 --with-templates

Use template install when the editor is already installed:

fgvm template install 4.4.1
fgvm template list --json
fgvm template remove 4.4.1

Template installation queries intentionally resolve against local Godot editor installations. This prevents installing export templates for a version you are not managing locally with fgvm.

Project Version Management

fgvm supports project-specific version management through .fgvm-version files. Here's how it works:

Setting up a project version:

# Navigate to your project directory
cd my-godot-project

# Option 1: Auto-detect version from project.godot
fgvm local                    # Detects version from project.godot, creates .fgvm-version

# Option 2: Explicitly set a version
fgvm local 4.3 mono          # Creates .fgvm-version with 4.3-stable-mono

Using project versions:

# In a project directory with .fgvm-version file
fgvm godot                    # Uses version from .fgvm-version
# Or use short form
fgvm g                        # Same as above

# In a project directory without .fgvm-version file
fgvm godot                    # Uses global default version

# In any directory
fgvm godot -i                 # Interactive selection from installed versions
fgvm g -i                     # Same as above

Workflow:

  1. fgvm local - Creates/updates .fgvm-version file for project-specific version management
  2. fgvm godot (or fgvm g) - Respects .fgvm-version file if present, otherwise uses global default
  3. fgvm set - Sets the global default version used when no .fgvm-version exists

Environment Variables

  • FGVM_HOME: Customize the installation directory for fgvm. By default, fgvm uses ~/fgvm/ (macOS/Linux) or $env:USERPROFILE\fgvm\ (Windows). Setting this variable allows you to use a different location:

    macOS/Linux:

    # Temporary (current session only)
    export FGVM_HOME=/custom/path/fgvm
    fgvm list  # Will use /custom/path/fgvm/ directly
    
    # Persistent (add to ~/.bashrc, ~/.zshrc, or ~/.profile)
    echo 'export FGVM_HOME=/custom/path/fgvm' >> ~/.bashrc

    Windows:

    # Temporary (current session only)
    $env:FGVM_HOME = "C:\custom\path\fgvm"
    fgvm list  # Will use C:\custom\path\fgvm\ directly
    
    # Persistent (for current user)
    [System.Environment]::SetEnvironmentVariable('FGVM_HOME', 'C:\custom\path\fgvm', 'User')

    This is particularly useful for testing, CI/CD environments, or keeping your Godot installations on a separate storage device for backup purposes.

Development

Build

Building the project requires the .NET 10 SDK. Publishing the Native AOT executable also requires the native compiler toolchain for the target platform: Visual Studio with the Desktop development with C++ workload on Windows, Xcode Command Line Tools on macOS, or Clang and the required development libraries on Linux. See the .NET Native AOT prerequisites for platform-specific setup.

Run dotnet run --project Fgvm.Cli -- <command> [args] during development, or publish a self-contained release binary for a specific runtime identifier:

git clone https://github.com/patricktcoakley/fgvm.git
cd fgvm
dotnet restore
dotnet publish Fgvm.Cli/Fgvm.Cli.csproj -c Release -r <RID>

Use one of the release RIDs: win-x64, osx-x64, osx-arm64, linux-x64, or linux-arm64. The executable is written to Fgvm.Cli/bin/Release/net10.0/<RID>/publish/.

This repo also includes an optional mise setup for installing the expected .NET SDK and running common development tasks:

mise install
mise run restore
mise run build
mise run test

Test

The mise tasks are the recommended way to run tests because they install the expected tool versions and prepare the integration and end-to-end fixtures:

mise install
mise run test
mise run test:e2e

The more specific tasks are also available:

mise run test:unit
mise run test:integration
mise run test:e2e:detailed

Without mise, install the .NET 10 SDK and PowerShell 7, make sure dotnet and pwsh are on your PATH, and run the equivalent preparation and test commands directly:

dotnet restore

dotnet test --configuration Release Fgvm.Tests/Fgvm.Tests.csproj

dotnet run Fgvm.Tests.Integration/Fixtures/PublishCli.cs
dotnet test --configuration Release Fgvm.Tests.Integration/Fgvm.Tests.Integration.csproj

dotnet run e2e/fixtures/BuildFixtures.cs
dotnet run Fgvm.Tests.Integration/Fixtures/PublishCli.cs --output e2e/.cli
pwsh -NoLogo -NoProfile -File e2e/run.ps1 -Parallel

Contributing

This project uses Conventional Commits for commit messages and Versionize for automated versioning and changelog generation.

When making changes:

  1. Use conventional commit format: type(scope): description.
  2. Supported types: feat, fix, docs, refactor, perf, test, chore, ci, build.
  3. The changelog is automatically generated from these commits.

Example:

git commit -m "feat(environment): Added support for OpenBSD."

Also please make sure to run mise run format before committing to ensure code style consistency.

See: https://github.com/patricktcoakley/fgvm

Roadmap

Planned Features For The Current Version

  • Add releases for Windows on ARM64
  • Create a GitHub Action to simplify using fgvm in CI

Migrating from the original gdvm

If you were using this project in the past then you'll know it used to be called gdvm. Prior to this project's creation and after, there have been several other projects with similar goals using the same name.

In an effort to differentiate this project I decided to change the name to stand out, and am also using it as an opportunity to implement some breaking changes due to some recent updates in the libraries I am using to write this tool.

What this means for you:

  • gdvm and fgvm are mostly the same workflow but there were minor changes to the commands that are breaking, so consult the updated documentation if you get stuck
  • If you are using a package manager (the recommended way to install), you will have to remove the gdvm package and install fgvm
    • Homebrew users: brew update && brew uninstall gdvm && brew install fgvm
    • Scoop users: scoop update && scoop uninstall gdvm && scoop install fgvm
  • If you want to keep your current installations, you can copy the existing gdvm directory to fgvm, which will preserve everything. Here are some one-liners that copy them over and delete the gdvm folder:
    • macOS & Linux users: mkdir -p ~/fgvm && cp -r ~/gdvm/* ~/fgvm/ && rm -rf ~/gdvm
    • Windows users: mkdir -Force $env:USERPROFILE\fgvm ; cp -r $env:USERPROFILE\gdvm\* $env:USERPROFILE\fgvm\ ; rm -r -Force $env:USERPROFILE\gdvm
    • The old updater scripts have been replaced by the simpler install scripts, which install the standalone fgvm binary into ~/fgvm/bin.

About

A friendly Godot version manager.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors