-
Notifications
You must be signed in to change notification settings - Fork 0
naming_conventions
GML has no namespaces. The config's prefix (default: gm) generates four derived tokens
that are prepended to every generated name to prevent collisions:
| Token | Example (gm) |
Used for |
|---|---|---|
{prefix}_ |
gm_ |
Public functions (endpoint wrappers, cookie API, auth API) |
_{prefix}_ |
_gm_ |
Private helpers (singleton getter, create_request, cookie_capture) |
{Prefix} |
Gm |
Struct constructor names |
{PREFIX}_ |
GM_ |
Macros and constants (reserved for future use) |
With "prefix": "petstore":
- Public:
petstore_get_pet() - Private:
_petstore_get_singleton() - Struct:
PetstoreUser
There are two sources of endpoint names, and which one applies depends on whether the operation
declares an operationId.
The name is the operationId, snake_cased, with the prefix in front. The tag is not involved.
operationId: "getUserById" → gm_get_user_by_id
operationId: "createOrder" → gm_create_order
operationId: "healthCheck" → gm_health_check
So the full public name is {prefix}_{snake(operationId)}.
Only used for an operation with no operationId, which is an error unless
"requireOperationId": false. Here the tag is used: the first entry of operation.tags becomes a
group prefix (or default when there are none), followed by the verb and the literal path segments,
with _by_id appended when the path ends in a parameter.
GET /users/{id} tag: "Users" → gm_users_get_by_id
GET /health (no tag) → gm_default_get_health
These names change whenever the URL is refactored, which is exactly why operationId is required by
default — see CLI Reference.
Author-chosen names are claimed before derived ones, so a path-derived name can never take a name
that an operationId asked for, regardless of where the operations appear in the document.
If two operations still map to the same generated name, numeric suffixes are appended —
gm_get_item, gm_get_item_2 — and the collision is reported as IR_SYM_001, an error by
default. The suffix is positional, so reordering the spec would move it to a different operation;
it exists to keep the emitted file compilable, not as a solution. Fix the operationIds.
The ToSnake() helper:
- Protects known acronyms/exceptions from being split (
OAuth2,OAuth,iOS,eBay,GitHub,iPhone) — these are lowercased as a single token. - Inserts
_at camelCase boundaries (userId→user_id). - Inserts
_at acronym boundaries (XMLParser→xml_parser). - Replaces non-alphanumeric characters with
_. - Collapses consecutive
_, trims leading/trailing_, lowercases.
All parameters are prefixed with _ and converted to snake_case:
"userId" → _user_id
"max-count" → _max_count
"OAuth2Token" → _oauth2_token
_body, _content_type and _callback are reserved for the generator. A spec parameter that
snake_cases onto one of them is suffixed (_body_2), as is a second parameter that collides with an
earlier one after conversion (userId and user_id in the same operation).
A struct member keeps the name the spec used. Only the constructor argument is snake_cased:
function GmUser(_user_id, _display_name) constructor
{
userId = _user_id; // member keeps the spec's casing
displayName = _display_name;
}A member whose name is not a legal bare GML identifier is written through the struct accessor instead. That covers three cases:
self[$ "x-rate-limit"] = _x_rate_limit; // illegal characters
self[$ "delete"] = _delete; // GML reserved word
self[$ "health"] = _health; // GML global built-in variableThe full list is NameUtils.Reserved. It covers GML's keywords (if, var, end, constructor,
delete, self, argument0, …) and its global built-in variables.
The global built-ins matter more than they look. A constructor assigns to self, so a member named
after one resolves to the global instead:
-
read-only globals (
fps,current_time,delta_time, …) are a compile error in the consuming project; -
writable globals (
health,lives,score,room, …) silently write the global, and the struct member is never created.
Instance built-ins are safe and are deliberately not reserved — inside a constructor self is
the struct, so id, x, y, depth, speed, visible, sprite_index, alarm, layer and the
rest become ordinary members. id in particular appears in a large share of real schemas, and
escaping it would make the output much harder to read for no benefit.
schema name: "UserProfile" prefix: gm
→ struct constructor: GmUserProfile
→ validate function: GmUserProfile_validate
A schema declared inline rather than under #/components/schemas is named from its owner — the
operation and the role it plays — PascalCased:
operation "uploadAvatar", request body → GmUploadAvatarBody
Component names are reserved before any of this happens, so an inline schema can never take the name
of a declared component; if the generated name is already spoken for, a counter is appended
(GmUploadAvatarBody2).
Internal variables inside generated functions use double-underscore-wrapped identifiers, so a spec parameter (which is always single-underscore) can never shadow one:
var __base_url__ // server URL for this call
var __url__ // final request URL
var __content_type__ // content-type for this call
var __security__ // auth scheme array for this request
var __where__ // caller location, used in error messagesThe generated helpers read two GameMaker Extension options from the extension named after the struct prefix:
extension_get_option_value("Gm", "server_rest_url") // base URL
extension_get_option_value("Gm", "debug_logging") // boolCreate an extension with the matching name and these option keys, or replace the helper functions with a custom implementation.
If
server_rest_urlis empty, endpoints build a relative URL andhttp_requestrejects it, returning-1with no other diagnostic. Check this option first when every call fails immediately.
GameMaker