Introducing godam
🙏🏼 Big thanks to imjp94 for creating gd-plug and the team at ChickenSoft Games for their tool GodotEnv. Both have been great inspirations for godam.
Introduction
My sister and I rely on having a playable game build updated and available at all times. This includes installing addons in a non-user environment and deploying to itch.io.
Tools like gd-plug and GodotEnv have made addon management easier, but we’ve hit a snag. They don’t yet support installing addons like the Godot editor does it — from zip archives. This is how many Godot assets are packaged, like the popular LimboAI Extension.
Unfortunately, there’s no official Godot command-line tool yet to automate this process for CI/CD pipelines.
This is where godam comes in — a command-line tool designed to install Godot addons just like the editor does, directly from zip archives pulled from the Godot AssetLib.
At the bottom of this post, you’ll find references on how to get started with godam. But first, let’s look at what makes it tick!
Creating command-line tools using clap
godam is implemented using the clap crate. It truly makes the user interface a breeze. For instance, this is my main:
use Parser;
use Cli;
async
Before looking at a user command, let’s look at the Cli
struct and what the godam::run
function does.
// mod statements omitted
use Parser;
use *;
/// godam
///
/// A minimal addon manager for Godot.
pub async
It’s just a simple match, each arm a command that godam supports. The exec
functions contains the logic that is executed when running a command, taking in parameters that are parsed from the user input.
To see the actual magic, we have to look at the Command
struct.
use Subcommand;
By deriving from Subcommand
, these roughly 30 humble lines specify the entire interface:
-
Subcommands are created by adding enum variants:
Command::Init
allows us to rungodam init
-
Subcommands can be configured using the attribute macro
#[command(...)]
:For example, adding an alias allows us to run
godam install
asgodam i
. -
Arguments to subcommands are added using enum variant fields:
godam search limboai
will assign"limboai"
to thename
field -
Help texts can even be provided by adding doc comments to the enum variants:
godam search -h
will display not only the text specified in the doc comment, but also outline the arguments and usage.<NAME>
I cannot praise clap
enough - it is unfathomably ergonomic and takes all the headache out of argument parsing! I’m using a fraction of its capabilities - godam
is a fairly simple application.
For completeness sake, let’s quickly showcase the godam::commands::search::exec
function:
use Error;
use crate::;
pub async
exec
is nothing but a wrapper, calling functions in various service modules contained in godam
,
Firstly, it gets the Godot project version using the godot::project::get_version
function, parsing it from the project.godot
file in the current working directory.
Secondly, it calls the godot::asset_library::get_assets_by_name
function, which makes an API request to the Godot Asset Library, finding assets filtering on the provided asset_name
.
Finally, it prints out each found asset on its own line, using an info!
macro which is just a styled println!
I made using the console
crate.
🙋🏼 And so the story goes for all other commands. The
install
command might need some love further down the line, but let’s forget about that for now…
Getting started with godam
You can find godam in its public repository over at GitHub. Here you can read more about it and how to download it. Most importantly, you can leave feedback and suggestions to help improve it!
For general usage, check out the README.
If you’re looking for pipeline use cases, I’ll include an example itch.io deploy workflow below. The docker image used is based on the barichello/godot-ci image.
name: "build-and-deploy-to-itch"
on:
push:
branches:
- develop
paths-ignore:
- "*.md"
env:
GODOT_VERSION: 4.3
ITCH_USER: your_user
EXPORT_NAME: your_project_name
jobs:
export-web:
name: Web Export
runs-on: ubuntu-latest
container:
image: docker://nilsiker/godam:v0.1.1-godot4.3
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup directories
run: |
mkdir -v -p build/web ~/.local/share/godot/export_templates
mv /root/.local/share/godot/export_templates/${GODOT_VERSION}.stable ~/.local/share/godot/export_templates/${GODOT_VERSION}.stable
- name: Install addons (godam)
run: |
cd project
godam install
- name: Web Build
run: |
cd project
godot --headless -v --export-release "Web" ../build/web/index.html
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: web
path: ./build/web/
- name: Deploy to itch.io
run: |
butler push ./build/web/ ${ITCH_USER}/${EXPORT_NAME}:web
env:
BUTLER_API_KEY: ${{ secrets.ITCHIO_API_KEY }}
What’s next?
Currently godam only supports installing addons following the zip folder structure /addons/name_of_addon/**/*
and /name_of_addon/**/*
. Any other zip structure will throw an error.
Moving forward, it would be nice to handle any Godot AssetLib asset, and extract them tidily into the Godot project structure.
For now, I’m focusing on stabilizing what’s already in place. It’s early days for godam, and I suspect the API will change more often than what is comfortable. For this to turn out well, I need to use the tools more myself.
If I could make a wish, godam would see some user adoption from within the Godot community. Everyone is welcome to pitch in and help improve it.
To make godam the best tool it can be, I need more eyes on it - so let’s make something cool! ☀️
Thanks for reading,
Nilsiker