Skip to content

Using template strings

Vadim ‮oknehcayD edited this page Mar 30, 2020 · 1 revision

General idea

Games commonly need to print formatted text and doing so in a convenient way is important.

Concatenating strings and wrapping non-string values in string() is usually quickly established to not be a good flow, so people make string interpolation scripts (format("health: %/%", 1, 2) -> health: 1/2), but with a bit of preprocessing it is possible to make it even nicer.

Setting up

First, you would to add a string interpolation script to your project.

These can be made arbitrarily complex, but here's a good starter with some optimization:

/// sfmt(format, ...values)
// sfmt("%/% hp", 1, 2) -> "1/2 hp"
gml_pragma("global", "global.sfmt_buf = buffer_create(1024, buffer_grow, 1); global.sfmt_map = ds_map_create();");
var f = argument[0];
var w = global.sfmt_map[?f], i, n;
if (w == undefined) {
    w[0] = "";
    global.sfmt_map[?f] = w;
    i = string_pos("%", f);
    n = 0;
    while (i) {
        w[n++] = string_copy(f, 1, i - 1);
        f = string_delete(f, 1, i);
        i = string_pos("%", f);
    }
    w[n++] = f;
} else n = array_length_1d(w);
//
var b = global.sfmt_buf;
buffer_seek(b, buffer_seek_start, 0);
buffer_write(b, buffer_text, w[0]);
var m = argument_count;
for (i = 1; i < n; i++) {
    if (i < m) {
        f = string(argument[i]);
        if (f != "") buffer_write(b, buffer_text, f);
    }
    f = w[i];
    if (f != "") buffer_write(b, buffer_text, f);
}
buffer_write(b, buffer_u8, 0);
buffer_seek(b, buffer_seek_start, 0);
return buffer_read(b, buffer_string);

Then, you would want to open your Project Properties (from menu or Ctrl+Shift+T), and put your string interpolation script name into "Template string script name" field (under "Syntax extensions").

From this point onward, any newly opened tabs can make use of the syntax.

Syntax

This is simple enough, inside a backtick string you can use ${} to insert expressions,

show_debug_message(`2**4 = ${power(2, 4)}`); // 16

which would expand to

show_debug_message(your_script("2**4 = %", power(2, 4))); // 16

in the saved file;

If your expression is a single word/identifier, you can insert it without having to surround in {}:

show_debug_message(`x=$x, y=$y`);

which would expand to

show_debug_message(your_script("x=%, y=%",x,y));

If you want to insert ${ or $<word> without it being parsed, you can do

show_debug_message(`... ${"$v"} ... ${"${"} ... %`);

which would expand to

show_debug_message(sfmt("... % ... % ... %", "$v", "${","%"));

Better workflow:

Syntax extensions:

  • `vals: $v1 $v2` (template strings)
  • #args (pre-2.3 named arguments)
  • ??= (for pre-GM2022 optional arguments)
  • ?? ?. ?[ (pre-GM2022 null-conditional operators)
  • #lambda (pre-2.3 function literals)
  • => (2.3+ function shorthands)
  • #import (namespaces and aliases)
  • v:Type (local variable types)
  • #mfunc (macros with arguments)
  • #gmcr (coroutines)

Customization:

User-created:

Other:

Clone this wiki locally