Skip to content

getting_started

Francisco Dias edited this page Aug 19, 2026 · 5 revisions

Getting Started

Build

Clone the repo and build the solution.

git clone https://github.com/YoYoGames/GM-OpenAPIGenerator.git
cd GM-OpenAPIGenerator\OpenAPIGenerator
dotnet build -c Release

The binary lands at openapigen\bin\Release\net9.0\openapigen.exe.

First run

Bootstrap a config in a working folder, then point it at your spec:

openapigen.exe --init ./myapi

This creates ./myapi/config.json and ./myapi/openapigen.schema.json. If a config.json is already there, --init refuses rather than overwriting it — pass --force if replacing it is what you meant. Open config.json, set "input" to the path of your OpenAPI spec, and run:

openapigen.exe --config ./myapi/config.json

There is no direct-arguments mode — every run goes through a config file, so it is reproducible and reviewable.

config.json format

{
  "$schema": "./openapigen.schema.json",
  "input": "./openapi.json",
  "root": "./",
  "prefix": "gm",
  "requireOperationId": true,
  "code": {
    "endPoints": { "enabled": true, "outputFile": "./generated_http.gml" },
    "schemas":   { "enabled": true, "outputFile": "./generated_schemas.gml" },
    "helpers":   { "enabled": true, "outputFile": "./generated_helpers.gml" }
  },
  "controller": {
    "createEvent":    { "enabled": true, "outputFile": "./controller_create.gml" },
    "cleanupEvent":   { "enabled": true, "outputFile": "./controller_cleanup.gml" },
    "httpAsyncEvent": { "enabled": true, "outputFile": "./controller_http.gml" }
  },
  "docs": {
    "schemas":   { "enabled": false, "outputFile": "./schemas_codegen.js" },
    "functions": { "enabled": false, "outputFile": "./function_codegen.js" }
  }
}
Key Meaning
input OpenAPI 3.x spec, JSON or YAML, relative to this config
root Base directory every outputFile resolves against
prefix Namespace prefix for generated symbols — see Naming Conventions
requireOperationId Error when an operation has no operationId (default true)
<section>.<output>.enabled Set false to skip generating that file
<section>.<output>.outputFile Destination path, relative to root

Comments (//) and trailing commas are allowed in config.json, though comments are lost when the tool rewrites the file to patch $schema.

Two enabled outputs may not point at the same file — that is an error, because one would silently overwrite the other. An output that resolves outside root is allowed but warns. A ~ is only expanded to your home directory at the start of a path; elsewhere it is an ordinary filename character.

Writing directly into a GameMaker project

Because each output has its own path, you can target the project tree and skip the copy step entirely — set root to your .yyp folder and point each file at its final home:

{
  "input": "./openapi.json",
  "root": "../MyGame",
  "prefix": "gm",
  "code": {
    "endPoints": { "enabled": true, "outputFile": "./scripts/gm_http/gm_http.gml" },
    "schemas":   { "enabled": true, "outputFile": "./scripts/gm_schemas/gm_schemas.gml" },
    "helpers":   { "enabled": true, "outputFile": "./scripts/gm_helpers/gm_helpers.gml" }
  },
  "controller": {
    "createEvent":    { "enabled": true, "outputFile": "./objects/obj_gm_core/Create_0.gml" },
    "cleanupEvent":   { "enabled": true, "outputFile": "./objects/obj_gm_core/CleanUp_0.gml" },
    "httpAsyncEvent": { "enabled": true, "outputFile": "./objects/obj_gm_core/Other_62.gml" }
  }
}

The three controller.* outputs are raw event bodies, so they can be written straight over the event files of an existing object. Other_62.gml is the Async HTTP event.

A GML script asset must live in a folder matching its filename (scripts/gm_http/gm_http.gml), and the script has to be registered in the .yyp once. After that, regeneration just overwrites the file.

Output files

Output Default file Contents
code.schemas generated_schemas.gml Constructors + _validate per schema
code.endPoints generated_http.gml One wrapper function per operation
code.helpers generated_helpers.gml Request struct, auth, cookie jar, URL encoding
controller.createEvent controller_create.gml Controller Create event
controller.cleanupEvent controller_cleanup.gml Controller Clean Up event
controller.httpAsyncEvent controller_http.gml Controller Async HTTP event
docs.schemas schemas_codegen.js Feather doc partials for structs
docs.functions function_codegen.js Feather doc partials for endpoints

Wiring the output into GameMaker

  1. Add the GML files to your project (drag into the Script or Extension asset).

  2. Create a persistent manager object — by convention, obj_gm_core (the prefix matches prefix). Make it persistent so it survives room transitions.

  3. Paste the controller snippets into the object's events:

    File Event
    controller_create.gml Create
    controller_http.gml Async — HTTP
    controller_cleanup.gml Clean Up
  4. Do not place an instance yourself. The singleton helper (_gm_get_singleton()) creates obj_gm_core on first use via instance_create_depth. Placing one in a room as well gives you two controllers, each with its own requests and response_hooks maps, and the Async HTTP event then runs on both.

  5. Call an endpoint:

    gm_my_endpoint(_param1, _param2, function(_status, _data, _request) {
        show_debug_message($"status={_status} data={json_stringify(_data)}");
    });

Setting auth tokens

Before calling secured endpoints, store the credential:

gm_request_auth_set_token("bearer_scheme_name", "your-jwt-here");

The scheme name must match the key in components.securitySchemes of the spec. The generated code injects the token automatically on every request that requires that scheme.

Regenerating

Re-run the tool whenever the spec changes. The output files are fully generated — do not hand-edit them. Keep any custom converters or hooks in separate scripts.

Clone this wiki locally