Skip to content

user_cli_docs

DiasFranciscoA edited this page Feb 24, 2026 · 7 revisions

extgen - User CLI Documentation

extgen is a schema-driven code generator for GameMaker native extensions. It generates language bindings, platform glue code, and CMake build systems for all supported GameMaker targets from a single IDL input.

This document explains how to use extgen, how to configure it, and what each option does.


Table of Contents

  1. Overview

  2. Installation & Invocation

  3. Project Initialization

  4. Configuration File Overview

  5. Profiles

  6. GameMaker Generation

  7. Targets (Platforms)

  8. Build System Configuration

  9. Extras (Documentation)

  10. Path Resolution Rules

  11. Common Workflows

  12. Minimal Examples


1. Overview

extgen takes a GMIDL schema (.gmidl, .json, etc.) and produces:

  • C++ native bindings
  • GML bindings
  • Platform glue code (Android, iOS, consoles, etc.)
  • A complete CMake project
  • Optional documentation

Everything is controlled through a JSON configuration file validated by a generated JSON Schema.

If the schema validates, extgen will run.


๐Ÿš€ 2. Installation & Invocation

Basic usage

extgen --config path/to/config.json

Initialize a new project

extgen --init path/to/folder

This creates:

  • config.json
  • extgen.schema.json

The config file automatically references the schema for editor validation and auto-completion.


๐Ÿ 3. Project Initialization (--init)

When you run:

extgen --init ./my-extension

extgen will:

  1. ๐Ÿงพ Generate a JSON Schema describing all supported options
  2. ๐Ÿ“„ Create a minimal config.json
  3. ๐Ÿ”— Automatically set the $schema property

You can immediately open config.json in any schema-aware editor (VS Code recommended).


๐Ÿ—‚๏ธ 4. Configuration File Overview

A simplified configuration file looks like this:

{
  "$schema": "./extgen.schema.json",
  "input": "./api.gmidl",
  "root": "./",
  "profile": "Full",
  "gamemaker": { ... },
  "targets": { ... },
  "build": { ... },
  "extras": { ... }
}

Top-level fields

Field Description
$schema Path to the JSON schema (auto-managed)
input Path to the GMIDL input file
root Root output directory
profile Controls what extgen emits
gamemaker GameMaker artifacts configuration
targets Platform targets
build CMake & build settings
extras Optional generators (docs, etc.)

๐ŸŽ›๏ธ 5. Profiles

The profile field controls what categories of output are generated.

"profile": "Full"

Available profiles

Profile Meaning
Full Emit bindings + native code + build system
BindingsOnly Emit GML / language bindings only
BuildOnly Emit only CMake & build files

This allows workflows like:

  • ๐Ÿ” Updating bindings without touching native code
  • ๐Ÿ—๏ธ Regenerating build files only

6. GameMaker Generation (gamemaker)

Controls all GameMaker-related outputs. This is split into four independent generators:

  • wrappers โ†’ generated GML API wrappers (what your game calls)
  • runtime โ†’ runtime support (GMExtensionCore support code)
  • yy โ†’ .yy generation or patching (function declarations + extension metadata integration)
  • injectors โ†’ optional integration helpers (project/asset injection outputs)

Example:

"gamemaker": {
  "wrappers": {
    "enabled": true,
    "outputFile": "extension.gml"
  },
  "runtime": {
    "enabled": true,
    "outputFile": "ext_runtime.gml"
  },
  "yy": {
    "enabled": true,
    "outputFile": "./declarations.yy",
    "mode": "patch",
    "extensionName": "OperaAds",
    "extensionFileName": "OperaAds.yy",
    "patchFrameworks": true
  },
  "injectors": {
    "enabled": false,
    "outputFolder": "./injectors"
  }
}

wrappers

Generated GML wrapper API (the functions your GML code calls).

Field Description
enabled Enable wrapper generation
outputFile Output .gml file path

Important

extgen does not create GameMaker IDE assets. wrappers.outputFile should point to an existing .gml script asset in your extension (or a path you manage as part of your build/export flow).


runtime

Emits the runtime support code required by generated wrappers (GMExtensionCore support functions).

Field Description
enabled Enable runtime emission
outputFile Output .gml file path

Note

This is the support layer used by the generated bindings (often referred to as the official GMExtensionCore).


yy

Controls generation/patching of .yy content related to your extensionโ€™s function declarations and metadata.

Field Description
enabled Enable .yy generation/patching
outputFile Output path for the generated .yy (or patch output)
mode (required) "plain" or "patch"
extensionName Optional extension display name (used by patch mode)
extensionFileName Optional extension .yy filename (used by patch mode)
patchFrameworks When patching, also patch iOS/tvOS frameworks/link settings where applicable

yy.mode

  • plain Produces a standalone .yy snippet/output which you can append/merge manually.

  • patch Produces an updated extension .yy by patching the target file (recommended for automation).

Important

If you use patch mode, you should treat the extension .yy as build-managed output. This keeps function declarations in sync with GMIDL without manual edits.


injectors

Optional output for integration helpers.

Field Description
enabled Enable injector output generation
outputFolder Folder to write injector scripts/files

Important

This should be enabled if your extension needs to target GMRT.


๐ŸŒ 7. Targets (Platforms)

All native output is target-driven. Each enabled target activates platform-specific emitters and build presets.

Common target fields

Field Description
enabled Enable this platform
outputFolder Where the final binary is copied

Desktop Targets

Windows / macOS / Linux

"windows": {
  "enabled": true,
  "outputFolder": "../"
}

These targets:

  • Require C++
  • Emit shared libraries
  • Generate CMake presets automatically

Android

"android": {
  "enabled": true,
  "mode": "jni",
  "outputFolder": "../AndroidSource"
}

Modes

Mode Description
java Java bridge (source only)
kotlin Kotlin bridge (source only)
jni Pure JNI (C++ native bindings)

Note

  • jni mode requires C++ bindings
  • java and kotlin modes generate source only (no native build presets)

Apple Mobile (iOS / tvOS)

"ios": {
  "enabled": true,
  "mode": "native",
  "sourceFolder": "./ios",
  "sourceFilename": "{0}_ios",
  "outputFolder": "../iOSSourceFromMac"
}

Modes

Mode Description
objc Objective-C bridge
swift Swift bridge
native Obj-C wrapper over C++ native core

Note

native mode requires C++ bindings.


๐ŸŽฎ Consoles

Supported consoles:

  • Xbox
  • PlayStation 4
  • PlayStation 5
  • Nintendo Switch

Example:

"ps5": {
  "enabled": true,
  "outputFolder": "../"
}

Nintendo Switch special case

"switch": {
  "enabled": true,
  "userProps": "path/to/user.props",
  "outputFolder": "../"
}

Important

  • userProps is required
  • extgen does not ship any SDK files
  • You must provide your own .props from the Nintendo SDK

๐Ÿ—๏ธ 8. Build System Configuration (build)

Controls CMake generation.

"build": {
  "emitCmake": true,
  "cmake": {
    "cppStandard": 20,
    "cppExtensions": false,
    "strictWarnings": true,
    "useThirdParty": true,
    "emitPresets": true
  }
}

Options

Field Description
emitCmake Generate CMakeLists.txt
cppStandard C++ standard (e.g. 17, 20)
cppExtensions Allow compiler extensions
strictWarnings Enable strict compiler warnings
useThirdParty Include third_party directory
emitPresets Generate CMakePresets.json

๐Ÿ“š 9. Extras

Documentation

"extras": {
  "docs": {
    "enabled": true,
    "outputFolder": "./docs",
    "outputFileName": "documentation.json",
    "overwrite": true
  }
}

Generates intermediate documentation data that can be consumed by other tools to produce final user-facing documentation.


๐Ÿ“ 10. Path Resolution Rules

All paths:

  • May be relative or absolute
  • root is resolved relative to the config file
  • All other paths are resolved relative to root
  • Support environment variables
  • Support ~ on Unix systems

๐Ÿ”„ 11. Common Workflows

Full extension generation

extgen --config config.json

Update bindings only

"profile": "BindingsOnly"

Regenerate CMake only

"profile": "BuildOnly"

โœจ 12. Minimal Example

{
  "input": "./api.gmidl",
  "root": "./",
  "profile": "Full",
  "gml": { "enabled": true },
  "targets": {
    "windows": { "enabled": true },
    "android": { "enabled": true, "mode": "jni" }
  },
  "build": { "emitCmake": true }
}

๐Ÿง  Final Notes

  • extgen is target-driven, not language-driven
  • C++ is emitted automatically only when required
  • The JSON Schema is the source of truth
  • If the schema validates, extgen will run โœ…

Clone this wiki locally