Skip to content

GML specific metadata

Vadym Diachenko edited this page May 21, 2023 · 5 revisions

Naming and export

@:doc <type|field>

Marks a type/field as intended for access from generated code.

When marking a type, members are marked automatically (unless they have @:noDoc)

When targeting an extension, this makes sure that the field will be shown in auto-completion and generally good to access.

@:noDoc <type|field>

Opposite of @:doc - marks a type/field to not be marked even if it would be otherwise (e.g. a field in a @:doc type).

@:native("name") <type|field>

Overrides the name for a field in generated code.

When used on a type, also overrides the package.

@:expose("name") <type|static field>

Makes the type/field accessible under specified name.

This allows fields to override access path of their parent class (much like in Haxe-JS).

@:docName("name") <type>

Customizes the name of the type that will appear in documentation (e.g. TypeName in func(v:TypeName)➜TypeName).

@:remove <type|field>

Omits a type or a field implementation from output.

@:snakeCase <type>

Forces a type and its members to be in snake_case naming convention, so MyClass.myField becomes my_class_my_field or my_class.my_field.

Use of @:native and @:expose takes precedence over this mechanism.

@:gml.regionName("name") <type>

Changes the label on #region name (GMS2) or //{ name (GMS1) when enabled via -D debug or -D sf-hint-folds.

Primarily handy for -D sfgml-split, but can also be used to include a small comment for the type.

Structure

Per README, default code generation will depend on what GameMaker version you're targeting;

  • "struct" generation (in GMS2.3 or newer) uses constructor functions and maintains an API akin to what you'll see when targeting JS,
     var me = new pkg_Person("Vadym");
     trace(me.name);
     me.greet();
  • "linear"/flat generation represents types using arrays (which are the only managed type in older GM versions) and has non-static functions take this as first argument,
    var me = pkg_Person_create("Vadym");
    trace(me[0/* name */]);
    pkg_Person_greet(me);
  • Extern types default to linear generation since majority of GM API is written in this way.
  • Compiler directives control default behaviour for non-extern types.

@:gml.keep.new <class>

When not using structs, separates function new implementation from the constructor-function even if not necessary (class has no children).

@:gml.linear <type>

In ≥2.3, forces a type to be array-based without using -D sfgml_linear.

This can also be handy for "flat" externs since me.greet("hi!") will be compiled to MyType_greet(me, "hi!").

@:gml.struct <type>

In ≥2.3, forces a type to be struct-based even if you are using -D sfgml_linear.

@:gml.dot_static <type>

In ≥2.3, forces a type to use Type.field for statics even if -D sfgml_dot_static is false.

@:gml.flat_static <type>

In ≥2.3, forces a type to use Type_field for statics even if -D sfgml_dot_static is true.

@:gml.flat_new <type>

Uses flat constructor invocation (pkg_Type_create() or renamed) instead of new pkg_Type() in a struct-based extern type.

@:gml.struct_new <type>

Uses struct constructor invocation (new pkg_Type()) in an otherwise linear extern type.

@:dsMap <typedef>

Indicates that an anonymous structure described by a typedef is a ds_map and should be accessed as obj[?"key"] instead of obj.key.