Skip to content

generated_output

Francisco Dias edited this page Aug 18, 2026 · 6 revisions

Generated Output

The tool produces up to eight files, each enabled and located independently in config.json. All files carry a // auto-generated, DO NOT EDIT header.


generated_schemas.gml

One GML constructor function per OpenAPI #/components/schemas object, plus a paired _validate() function.

/**
 * @func GmApplicationConfiguration(_name, _type, _parent, _id = undefined, _description = undefined)
 * @param {String} _name The application-configuration specific unique ID.
 * @param {String} _type The fully-qualified Java type of ApplicationConfiguration.
 * @param {Struct.GmApplication} _parent
 * @param {String} [_id] The database assigned ID for the application configuration.
 * @param {String} [_description]
 */
function GmApplicationConfiguration(_name, _type, _parent, _id = undefined, _description = undefined) constructor
{
    name = _name;
    type = _type;
    parent = _parent;
    id = _id;
    description = _description;
}

Note that the member keeps the name the spec used (parent, and userId for a spec field userId), while the constructor argument is snake_cased with a leading underscore (_parent, _user_id). See Naming Conventions.

Each schema also gets a standalone validator:

function GmApplicationConfiguration_validate(__inst__, __where__ = _GMFUNCTION_)
{
    __where__ = $"{__where__} :: GmApplicationConfiguration_validate";

    if (!is_struct(__inst__)) throw $"{__where__} :: expected Struct.GmApplicationConfiguration";

    if (!is_string(__inst__[$ "name"])) throw $"{__where__} :: 'name' expected String";
    if (!is_string(__inst__[$ "type"])) throw $"{__where__} :: 'type' expected String";
    GmApplication_validate(__inst__[$ "parent"], $"{__where__} :: 'parent'");
    if (!is_undefined(__inst__[$ "id"]))
    {
        if (!is_string(__inst__[$ "id"])) throw $"{__where__} :: 'id' expected String";
    }
}

Required fields are always checked; optional ones only when defined. A nested schema is validated by calling its own validator, with the field name folded into the location string so a failure deep in a tree still says which field it was:

… :: GmCreateLargeObjectRequest_validate :: 'read' :: GmSubjectRequest_validate :: expected Struct.GmSubjectRequest

Validators throw a plain string, not an exception struct. In a catch block use is_struct(_e) ? _e.message : string(_e) — reading _e.message directly will itself fail.

Schema mapping rules:

OpenAPI type GML type
string String
integer (int32 / int64) Real
number (float / double) Real
boolean Bool
string with format: binary / byte Id.Buffer
array of T Array<T>
object with named properties named struct constructor
object free-form / inline Struct (any-map)
string with enum String, with a switch over the literals in the validator

oneOf / anyOf are validated but not emitted as distinct GML union types: the validator tries each option and counts the successes (oneOf requires exactly one, anyOf at least one). allOf is not flattened — the constituent schemas are validated in turn, but no merged constructor is generated for the composition.


generated_http.gml

One public function per OpenAPI operation.

/**
 * @func gm_get_application(_name_or_id, _callback = undefined)
 * Gets the metadata for a single application.
 * @param {String} _name_or_id
 * @param {Function} [_callback] Callback with signature (status, data, request).
 */
function gm_get_application(_name_or_id, _callback = undefined)
{
    var __base_url__ = _gm_options_get_rest_url();

    // argument validation
    var __where__ = _GMFUNCTION_;

    if (!is_string(_name_or_id)) throw $"{__where__} :: 'nameOrId' expected String";
    if (!is_undefined(_callback))
    {
        if (!is_callable(_callback)) throw $"{__where__} :: '_callback' expected Function";
    }

    // build url path
    var __url__ = $"{__base_url__}/application/{_gm_url_encode(_name_or_id)}";

    var __security__ = [ "auth_bearer", "session_secret" ];

    return _gm_create_request(__url__, undefined, "GET", undefined, undefined, undefined, __security__, undefined, _callback, _GMFUNCTION_);
}

Parameter ordering: required parameters come first, then optional ones (defaulting to undefined unless the spec provides a default value), then _body, then _content_type if the body allows several media types, then _callback.

Parameter locations:

Location Handling
path URL-encoded and interpolated into the URL string
query Collected into a params struct; undefined entries are skipped
header Collected into a headers struct, written into the request header map in GmRequest.send()
cookie Not a function argument — the cookie jar handles these; see Authentication & Cookies

Request body: When an endpoint has a body, a _body parameter is added. If the spec allows multiple content-types, a _content_type parameter is also added (defaulting to the first supported type).

Callback signature:

function(_status, _data, _request)
// _status  {Real}                  HTTP status code
// _data    {Struct|Any}            Parsed JSON response (json_parse attempted; raw string on failure)
// _request {Struct.GmRequest}      The request object (supports .retry())

generated_helpers.gml

Internal plumbing used by the generated endpoint functions. Contains:

Singleton getter

function _gm_get_singleton(__where__) { ... }

Creates obj_gm_core on first call via instance_create_depth(0, 0, 0, obj_gm_core). All state (tokens, jar, requests, hooks) lives on this instance. You do not need to place one in a room — see Getting Started.

Auth token store

gm_request_auth_set_token(_token_id, _token)    // store (public — call this from game code)
_gm_request_auth_get_token(_token_id)           // retrieve (private — used internally)

Body converter registry

gm_request_body_set_converter(_content_type, _function)   // register (public)
_gm_request_body_get_converter(_content_type)             // retrieve (private — used internally)

Response hook registry

gm_request_response_set_hook(_code, _hook)      // register (public — call this from game code)
_gm_request_response_get_hook(_code)            // retrieve (private — used internally)

Cookie jar public API

gm_cookie_set(_name, _value)    // manual write
gm_cookie_get(_name)            // manual read
gm_cookie_delete(_name)         // remove one
gm_cookie_clear()               // wipe jar

URL encoding

_gm_url_encode(_value)          // percent-encodes a value for a path segment or query string

GmRequest struct

The internal request wrapper. Created by _gm_create_request() and stored in the singleton's requests ds_map until the Async HTTP event resolves it.

function GmRequest(_url, _params, _method, _headers, _body, _content_type, _security, _cookies, _callback, __where__) constructor

// Public API:
request.send()           // fire (or re-fire) the HTTP request → returns request id
request.retry()          // alias for send()
request.get_callback()   // return the stored callback function
request.attempts         // integer, increments on each send/retry

_gm_create_request() takes the same ten arguments and returns request.send() directly, which is what every generated endpoint returns.


controller_create.gml (paste into Create event)

Initialises the singleton's state:

type_converters = {};
type_converters[$ "*/*"] = function(__body__) { return __body__; };
type_converters[$ "application/json"] = function(__body__) { return json_stringify(__body__, false, ...); };
type_converters[$ "application/x-www-form-urlencoded"] = function(__body__) { return __body__; };
type_converters[$ "text/plain"] = function(__body__) { return string(__body__); };
type_converters[$ "multipart/form-data"] = function(__body__, __header__) { ... };

auth_tokens    = {};                 // scheme name → token string
cookie_jar     = {};                 // cookie name → value
requests       = ds_map_create();    // request id → GmRequest
response_hooks = ds_map_create();    // HTTP status code → hook function

The application/json converter uses a replacer to strip undefined struct fields before stringifying, so optional unset parameters are omitted from the JSON payload.

The multipart/form-data converter iterates struct fields and builds a MIME multipart body, setting the Content-Type boundary automatically. A field is treated as binary when it is a live buffer (is_handle(v) && buffer_exists(v)); everything else is written as a text part.

Two known limitations of the multipart converter. Binary fields are base64-encoded with Content-Transfer-Encoding: base64 rather than written as raw bytes, which many servers ignore. And a struct-valued field is interpolated with GML's debug formatting rather than serialised as JSON. Both are open items.


controller_http.gml (paste into Async HTTP event)

var __async_id__ = async_load[? "id"];
var __request__ = requests[? __async_id__];

if (is_undefined(__request__)) {
	exit;
}

var __status__ = async_load[? "status"];

// status 1 means "in progress" — wait for the terminal event.
if (__status__ == 1) exit;

if (_gm_options_is_debug()) {
	// async_load is a ds_map, which json_stringify cannot serialise.
	show_debug_message("HTTP: " + json_encode(async_load));
}

var __code__ = async_load[? "http_status"];
var __data__ = async_load[? "result"];

// response_headers is a ds_map, not a struct.
var __headers__ = async_load[? "response_headers"];

if (!is_undefined(__headers__) && ds_exists(__headers__, ds_type_map)) {
	var __set_cookie__ = string_trim(__headers__[? "Set-Cookie"] ?? "");
	if (string_length(__set_cookie__) > 0) {
		_gm_cookie_capture(__set_cookie__);
	}
}

try {
	__data__ = json_parse(__data__);
}
catch (__ex__) { /* body is not JSON; hand it back untouched */ };

var __hook__ = response_hooks[? __code__];
if (is_callable(__hook__) && __hook__(__code__, __data__, __request__) == true) {
	ds_map_delete(requests, __async_id__);
	exit;
}

var __callback__ = __request__.get_callback();
if (is_callable(__callback__)) {
	__callback__(__code__, __data__, __request__);
}

ds_map_delete(requests, __async_id__);

controller_cleanup.gml (paste into Clean Up event)

ds_map_destroy(requests);
ds_map_destroy(response_hooks);

schemas_codegen.js and function_codegen.js

gm-ext-format documentation stubs consumed by the gm-ext updateDocs pipeline. Enable them with docs.schemas and docs.functions in config.json — they are off by default.

schemas_codegen.js uses @struct_partial / @struct_end blocks and documents the struct's members:

/**
 * @struct_partial GmAdvancedInventoryItemQuantityAdjustment
 * @member {String} userId The User whose inventory to modify.
 * @member {Real} quantityDelta The delta to be applied to the inventory item quantity
 * @member {Real} [priority] The priority slot for the item.
 * @struct_end
 */

function_codegen.js uses @func_partial / @func_end blocks with @event callback members for the callback signature, and documents the endpoint's arguments with @param.

Do not hand-edit these files — regenerate them whenever the spec changes.


Response hooks

Hooks intercept responses before the per-request callback fires. Return true to consume the event and suppress the callback:

// Automatically refresh token on 401 and retry
gm_request_response_set_hook(401, function(_code, _data, _request) {
    _refresh_my_token();
    _request.retry();
    return true;   // suppress original callback
});

Custom body converters

Register a converter for a content-type not covered by the defaults:

gm_request_body_set_converter("application/xml", function(_body, _header) {
    // return a string or a buffer
    return my_xml_encode(_body);
});

The converter receives the body value and the ds_map header so it can set (or override) Content-Type — for example the built-in multipart/form-data converter appends the boundary to the header value.

Clone this wiki locally