Class System
ScaffScript provides a class syntax that compiles to GML struct constructors. Classes can also be extended across multiple files using impl.
class Declaration
Section titled “class Declaration”Syntax
Section titled “Syntax”export class <name> { constructor([<args>])
<field> = <value>; <method>() { ... }}Constructor
Section titled “Constructor”The constructor(...) line defines the parameters of the GML constructor function.
Fields / Properties
Section titled “Fields / Properties”Plain assignments, become direct assignments inside the constructor body:
// --- snip --- name = _name; age = _age;// --- snip ---Methods
Section titled “Methods”All three forms of functions compile to <name> = function( ... ) { ... }:
Example
Section titled “Example”// --- snip --- print = function() { show_debug_message($"Name: {name}"); }
show_name(_name?) { show_debug_message(_name ?? name); }
show_age = (age, test = false) => { show_debug_message(age); show_debug_message(test); }// --- snip ---Result
Section titled “Result”// --- snip --- // function expression, unchanged print = function() { show_debug_message($"Name: {name}"); }
// shorthand, converted to function expression show_name(_name?) { show_name = function(_name = undefined) { show_debug_message(_name ?? name); }
// arrow function, converted to function expression show_age = (age, test = false) => { show_age = function(age, test = false) { show_debug_message(age); show_debug_message(test); }// --- snip ---Static Fields / Static Methods
Section titled “Static Fields / Static Methods”Add static keyword before the field / method name.
Example
Section titled “Example”// --- snip --- static created_cnt = 0;
static print = function() { show_debug_message($"Name: {name}"); }
static show_name(_name?) { show_debug_message(_name ?? name); }
static show_age = (age, test = false) => { show_debug_message(age); show_debug_message(test); }// --- snip ---Result
Section titled “Result”// --- snip --- static created_cnt = 0;
static print = function() { show_debug_message($"Name: {name}"); }
static show_name(_name?) { static show_name = function(_name = undefined) { show_debug_message(_name ?? name); }
static show_age = (age, test = false) => { static show_age = function(age, test = false) { show_debug_message(age); show_debug_message(test); }// --- snip ---Full Example
Section titled “Full Example”export class MyClass { constructor(_name, _age = 0, _is_active?)
static created_cnt = 0;
name = _name; age = _age; is_active = _is_active ?? false;
print = function() { show_debug_message($"Name: {name}"); }
static show_name(_name?) { show_debug_message(_name ?? "Unknown"); }
show_age = (_age, _test = false) => { show_debug_message(_age); show_debug_message(_test); }}Final Result
Section titled “Final Result”function MyClass(_name, _age = 0, _is_active = undefined) constructor { static created_cnt = 0;
name = _name; age = _age; is_active = _is_active ?? false;
print = function() { show_debug_message($"Name: {name}"); }
static show_name = function(_name = undefined) { show_debug_message(_name ?? "Unknown"); }
show_age = function(_age, _test = false) { show_debug_message(_age); show_debug_message(_test); }}Extending Existing Classes
Section titled “Extending Existing Classes”Use impl to adds properties or methods to an existing class from a separate file. Useful for splitting large classes, or managing class logic in a more organized way.
Syntax
Section titled “Syntax”impl <ClassName> { <field> = <value>; <method>() { ... }}Example
Section titled “Example”We’ll use this structure for this example:
Directorysrc/
Directorymy-class/
- MyClass.ss
- print.ss
- index.ss
export class MyClass { constructor(_name, _age = 0, _is_active?)
name = _name; age = _age; is_active = _is_active ?? false;}impl MyClass { print_cnt = 0;
print_name() { show_debug_message($"Name: {name}"); print_cnt++; }
print_age() { show_debug_message($"Age: {age}"); print_cnt++; }}Result
Section titled “Result”function MyClass(_name, _age = 0, _is_active = undefined) constructor { name = _name; age = _age; is_active = _is_active ?? false;
print_cnt = 0;
print_name = function() { show_debug_message($"Name: {name}"); print_cnt++; }
print_age = function() { show_debug_message($"Age: {age}"); print_cnt++; }}- The class name must exist and match an
export classin another file in the same scan.- So, you can’t implement a class that’s not defined.
- If no match is found:
- Aborts if
onNotFound: "error"(default). - Skips with a warning if
onNotFound: "ignore".
- Aborts if
- Methods defined inside
implfollows the same conversion rules as regular class fields / methods. - Multiple
implfiles for the same class are all merged in order.
Limitations
Section titled “Limitations”- Fields / methods redeclaration is not supported. You’ll have duplicated fields / methods if you do.
Best Practices
Section titled “Best Practices”Here are some best practices to keep in mind when using classes in ScaffScript.
Use _ Prefix for Constructor Parameters
Section titled “Use _ Prefix for Constructor Parameters”export class MyClass { constructor(name, score)
name = name; // already defined, so it's an undefined variable error score = score; // also an undefined variable error}Using the same name for constructor parameter and field would cause an undefined variable error.
export class MyClass { constructor(player_name, player_score)
name = player_name; score = player_score;}Using different names for constructor parameter and field is better, but it may be verbose and may confuse the readers. But of course, it’s just a matter of preference.
export class MyClass { constructor(_name, _score)
name = _name; score = _score;}Using _ prefix for constructor parameters is a good practice. You won’t have to worry about naming conflicts, and it’s easy to tell which variables are constructor parameters.
Implement Classes in the Same Directory
Section titled “Implement Classes in the Same Directory”Keep impl files in the same directory as the export class file. It makes it easier to understand the class structure at a glance.
Directorysrc/
Directorymy-class/
- MyClass.ss
Directorymy-class-impl/
Directoryfs/
- input.ss
- output.ss
- logic.ss
- print.ss
- index.ss
Directorysrc/
Directorymy-class/
Directorydebug/
- print.ss
Directoryfs/
- input.ss
- output.ss
Directorymain/
- logic.ss
- MyClass.ss
- index.ss