On this page

sys

Functions and messages for using system resources, controlling the engine, error handling and debugging.

Functions

sys.save(filename: string, table: Record<string | number, unknown>)

The table can later be loaded by sys.load. Use sys.get_save_file to obtain a valid location for the file. Internally, this function uses a workspace buffer sized output file sized 512kb. This size reflects the output file size which must not exceed this limit. Additionally, the total number of rows that any one table may contain is limited to 65536 (i.e. a 16 bit range). When tables are used to represent arrays, the values of keys are permitted to fall within a 32 bit range, supporting sparse arrays, however the limit on the total number of rows remains in effect. This function will raise a Lua error if an error occurs while saving the table.

// Save data:
const my_table = [];
my_table.push("my_value");
const my_file_path = sys.get_save_file("my_game", "my_file");
sys.save(my_file_path, my_table);

Parameters

  • filename: string — file to write to
  • table: Record<string | number, unknown> — lua table to save

sys.load(filename: string): Record<string | number, unknown>

If the file exists, it must have been created by sys.save to be loaded. This function will raise a Lua error if an error occurs while loading the file.

// Load data that was previously saved, e.g. an earlier game session:
const my_file_path = sys.get_save_file("my_game", "my_file");
const my_table = sys.load(my_file_path);
if (!next(my_table)) {
  // empty table
}

Parameters

  • filename: string — file to read from

Returns

  • loaded: Record<string | number, unknown> — lua table, which is empty if the file could not be found

sys.exists(path: string): boolean

Check if a path exists Good for checking if a file exists before loading a large file

// Load data but return nil if path didn't exist
if (!sys.exists(path)) {
  return undefined;
}
return sys.load(path); // returns {} if it failed

Parameters

  • path: string — path to check

Returns

  • result: booleantrue if the path exists, false otherwise

sys.get_host_path(filename: string): string

Create a path to the host device for unit testing Useful for saving logs etc during development

// Save data on the host
const host_path = sys.get_host_path("logs/test.txt");
sys.save(host_path, mytable);

// Load data from the host
const host_path = sys.get_host_path("logs/test.txt");
const table = sys.load(host_path);

Parameters

  • filename: string — file to read from

Returns

  • host_path: string — the path prefixed with the proper host mount

sys.get_save_file(application_id: string, file_name: string): string

The save-file path is operating system specific and is typically located under the user's home directory. This function will raise a Lua error if unable to get the save file path.

// Find a path where we can store data:
const my_file_path = sys.get_save_file("my_game", "my_file");
// macOS: /Users/foobar/Library/Application Support/my_game/my_file
print(my_file_path); //> /Users/foobar/Library/Application Support/my_game/my_file

// Windows: C:\Users\foobar\AppData\Roaming\my_game\my_file
print(my_file_path); //> C:\Users\foobar\AppData\Roaming\my_game\my_file

// Linux: $XDG_DATA_HOME/my_game/my_file or /home/foobar/.my_game/my_file
// Linux: Defaults to /home/foobar/.local/share/my_game/my_file if neither exist.
print(my_file_path); //> /home/foobar/.local/share/my_game/my_file

// Android package name: com.foobar.packagename
print(my_file_path); //> /data/data/0/com.foobar.packagename/files/my_file

// iOS: my_game.app
print(my_file_path); //> /var/mobile/Containers/Data/Application/123456AB-78CD-90DE-12345678ABCD/my_game/my_file

// HTML5 path inside the IndexedDB: /data/.my_game/my_file or /.my_game/my_file
print(my_file_path); //> /data/.my_game/my_file

Parameters

  • application_id: string — user defined id of the application, which helps define the location of the save-file
  • file_name: string — file-name to get path for

Returns

  • path: string — path to save-file

sys.get_application_path(): string

The path from which the application is run. This function will raise a Lua error if unable to get the application support path.

// Find a path where we can store data (the example path is on the macOS platform):
// macOS: /Applications/my_game.app
const application_path = sys.get_application_path();
print(application_path); //> /Applications/my_game.app

// Windows: C:\Program Files\my_game\my_game.exe
print(application_path); //> C:\Program Files\my_game

// Linux: /home/foobar/my_game/my_game
print(application_path); //> /home/foobar/my_game

// Android package name: com.foobar.my_game
print(application_path); //> /data/user/0/com.foobar.my_game

// iOS: my_game.app
print(application_path); //> /var/containers/Bundle/Applications/123456AB-78CD-90DE-12345678ABCD/my_game.app

// HTML5: http://www.foobar.com/my_game/
print(application_path); //> http://www.foobar.com/my_game

Returns

  • path: string — path to application executable

sys.get_config_string(key: string, default_value?: string): string

Get string config value from the game.project configuration file with optional default value

// Get user config value
const text = sys.get_config_string("my_game.text", "default text");

// Start the engine with a bootstrap config override and add a custom config value
// $ dmengine --config=bootstrap.main_collection=/mytest.collectionc --config=mygame.testmode=1

// Read the custom config value from the command line
const testmode = sys.get_config_int("mygame.testmode");

Parameters

  • key: string — key to get value for. The syntax is SECTION.KEY
  • default_value?: string — (optional) default value to return if the value does not exist

Returns

  • value: string — config value as a string. default_value if the config key does not exist. nil if no default value was supplied.

sys.get_config_int(key: string, default_value?: number): number

Get integer config value from the game.project configuration file with optional default value

// Get user config value
const speed = sys.get_config_int("my_game.speed", 20); // with default value

const testmode = sys.get_config_int("my_game.testmode"); // without default value
if (testmode !== undefined) {
  // do stuff
}

Parameters

  • key: string — key to get value for. The syntax is SECTION.KEY
  • default_value?: number — (optional) default value to return if the value does not exist

Returns

  • value: number — config value as an integer. default_value if the config key does not exist. 0 if no default value was supplied.

sys.get_config_number(key: string, default_value?: number): number

Get number config value from the game.project configuration file with optional default value

// Get user config value
const speed = sys.get_config_number("my_game.speed", 20.0);

Parameters

  • key: string — key to get value for. The syntax is SECTION.KEY
  • default_value?: number — (optional) default value to return if the value does not exist

Returns

  • value: number — config value as an number. default_value if the config key does not exist. 0 if no default value was supplied.

sys.get_config_boolean(key: string, default_value?: boolean): boolean

Get boolean config value from the game.project configuration file with optional default value

// Get user config value
const vsync = sys.get_config_boolean("display.vsync", false);

Parameters

  • key: string — key to get value for. The syntax is SECTION.KEY
  • default_value?: boolean — (optional) default value to return if the value does not exist

Returns

  • value: boolean — config value as a boolean. default_value if the config key does not exist. false if no default value was supplied.

sys.open_url(url: string, attributes?: Record<string | number, unknown>): boolean

Open URL in default application, typically a browser

// Open an URL:
const success = sys.open_url("http://www.defold.com", { target: "_blank" });
if (!success) {
  // could not open the url...
}

Parameters

  • url: string — url to open
  • attributes?: Record<string | number, unknown> — table with attributes target
  • string : Optional. Specifies the target attribute or the name of the window. The following values are supported:
  • _self - (default value) URL replaces the current page.
  • _blank - URL is loaded into a new window, or tab.
  • _parent - URL is loaded into the parent frame.
  • _top - URL replaces any framesets that may be loaded.
  • name - The name of the window (Note: the name does not specify the title of the new window).

Returns

  • success: boolean — a boolean indicating if the url could be opened or not

sys.load_resource(filename: string): string | nil, string | nil

Loads a custom resource. Specify the full filename of the resource that you want to load. When loaded, the file data is returned as a string. If loading fails, the function returns nil plus the error message. In order for the engine to include custom resources in the build process, you need to specify them in the "custom_resources" key in your "game.project" settings file. You can specify single resource files or directories. If a directory is included in the resource list, all files and directories in that directory is recursively included: For example "main/data/,assets/level_data.json".

// Load level data into a string
const [data, error] = sys.load_resource("/assets/level_data.json");
// Decode json string to a table
if (data) {
  const data_table = json.decode(data);
  pprint(data_table);
} else {
  print(error);
}

Parameters

  • filename: string — resource to load, full path

Returns

  • data: string | nil — loaded data, or nil if the resource could not be loaded
  • error: string | nil — the error message, or nil if no error occurred

sys.get_sys_info(options?: Record<string | number, unknown>): Record<string | number, unknown>

Returns a table with system information.

// How to get system information:
const info = sys.get_sys_info();
if (info.system_name === "HTML5") {
  // We are running in a browser.
}

Parameters

  • options?: Record<string | number, unknown> — optional options table
  • ignore_secure boolean this flag ignores values might be secured by OS e.g. device_ident

Returns

  • sys_info: Record<string | number, unknown> — table with system information in the following fields:

device_model string Only available on iOS and Android. manufacturer string Only available on iOS and Android. system_name string The system name: "Darwin", "Linux", "Windows", "HTML5", "Android" or "iPhone OS" system_version string The system OS version. api_version string The API version on the system. language string Two character ISO-639 format, i.e. "en". device_language string Two character ISO-639 format (i.e. "sr") and, if applicable, followed by a dash (-) and an ISO 15924 script code (i.e. "sr-Cyrl" or "sr-Latn"). Reflects the device preferred language. territory string Two character ISO-3166 format, i.e. "US". gmt_offset number The current offset from GMT (Greenwich Mean Time), in minutes. device_ident string This value secured by OS. "identifierForVendor" on iOS. "android_id" on Android. On Android, you need to add READ_PHONE_STATE permission to be able to get this data. We don't use this permission in Defold. user_agent string The HTTP user agent, i.e. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8"

sys.get_engine_info(): Record<string | number, unknown>

Returns a table with engine information.

// How to retrieve engine information:
// Update version text label so our testers know what version we're running
const engine_info = sys.get_engine_info();
const version_str = `Defold ${engine_info.version}\n${engine_info.version_sha1}`;
gui.set_text(gui.get_node("version"), version_str);

Returns

  • engine_info: Record<string | number, unknown> — table with engine information in the following fields:

version string The current Defold engine version, i.e. "1.2.96" version_sha1 string The SHA1 for the current engine build, i.e. "0060183cce2e29dbd09c85ece83cbb72068ee050" is_debug boolean If the engine is a debug or release version

sys.get_application_info(app_string: string): Record<string | number, unknown>

Returns a table with application information for the requested app. On iOS, the app_string is an url scheme for the app that is queried. Your game needs to list the schemes that are queried in an LSApplicationQueriesSchemes array in a custom "Info.plist". On Android, the app_string is the package identifier for the app.

// Check if twitter is installed:
const sysinfo = sys.get_sys_info();
let twitter = {};

if (sysinfo.system_name === "Android") {
  twitter = sys.get_application_info("com.twitter.android");
} else if (sysinfo.system_name === "iPhone OS") {
  twitter = sys.get_application_info("twitter:");
}

if (twitter.installed) {
  // twitter is installed!
}

// Info.plist for the iOS app needs to list the schemes that are queried:
// ...
// <key>LSApplicationQueriesSchemes</key>
//  <array>
//    <string>twitter</string>
//  </array>
// ...

Parameters

  • app_string: string — platform specific string with application package or query, see above for details.

Returns

  • app_info: Record<string | number, unknown> — table with application information in the following fields:

installed boolean true if the application is installed, false otherwise.

sys.get_ifaddrs(): Record<string | number, unknown>

Returns an array of tables with information on network interfaces.

// How to get the IP address of interface "en0":
const ifaddrs = sys.get_ifaddrs();
for (const iface of ifaddrs) {
  if (iface.name === "en0") {
    const ip = iface.address;
  }
}

Returns

  • ifaddrs: Record<string | number, unknown> — an array of tables. Each table entry contain the following fields:

name string Interface name address string IP address. might be nil if not available. mac string Hardware MAC address. might be nil if not available. up boolean true if the interface is up (available to transmit and receive data), false otherwise. running boolean true if the interface is running, false otherwise.

sys.set_error_handler(error_handler: function(source, message, traceback))

Set the Lua error handler function. The error handler is a function which is called whenever a lua runtime error occurs.

// Install error handler that just prints the errors
function my_error_handler(source, message, traceback) {
  print(source); //> lua
  print(message); //> main/my.script:10: attempt to perform arithmetic on a string value
  print(traceback); //> stack traceback:
  //>         main/test.script:10: in function 'boom'
  //>         main/test.script:15: in function <main/my.script:13>
}

function boom() {
  return 10 + "string";
}

export default defineScript({
  init() {
    sys.set_error_handler(my_error_handler);
    boom();
  },
});

Parameters

  • error_handler: function(source, message, traceback) — the function to be called on error

source string The runtime context of the error. Currently, this is always "lua". message string The source file, line number and error message. traceback string The stack traceback.

sys.set_connectivity_host(host: string)

Sets the host that is used to check for network connectivity against.

sys.set_connectivity_host("www.google.com");

Parameters

  • host: string — hostname to check against

sys.get_connectivity(): Opaque<"constant">

Returns the current network connectivity status on mobile platforms. On desktop, this function always return sys.NETWORK_CONNECTED.

// Check if we are connected through a cellular connection
if (sys.NETWORK_CONNECTED_CELLULAR === sys.get_connectivity()) {
  print("Connected via cellular, avoid downloading big files!");
}

Returns

  • status: Opaque<"constant"> — network connectivity status:

  • sys.NETWORK_DISCONNECTED (no network connection is found)

  • sys.NETWORK_CONNECTED_CELLULAR (connected through mobile cellular)

  • sys.NETWORK_CONNECTED (otherwise, Wifi)

sys.exit(code: number)

Terminates the game application and reports the specified code to the OS.

// This example demonstrates how to exit the application when some kind of quit
// message is received (maybe from gui or similar):
export default defineScript({
  on_message(self, message_id, message, sender) {
    if (message_id === hash("quit")) {
      sys.exit(0);
    }
  },
});

Parameters

  • code: number — exit code to report to the OS, 0 means clean exit

sys.reboot(arg1?: string, arg2?: string, arg3?: string, arg4?: string, arg5?: string, arg6?: string)

Reboots the game engine with a specified set of arguments. Arguments will be translated into command line arguments. Calling reboot function is equivalent to starting the engine with the same arguments. On startup the engine reads configuration from "game.project" in the project root.

// How to reboot engine with a specific bootstrap collection.
const arg1 = "--config=bootstrap.main_collection=/my.collectionc";
const arg2 = "build/game.projectc";
sys.reboot(arg1, arg2);

Parameters

  • arg1?: string — argument 1
  • arg2?: string — argument 2
  • arg3?: string — argument 3
  • arg4?: string — argument 4
  • arg5?: string — argument 5
  • arg6?: string — argument 6

sys.set_vsync_swap_interval(swap_interval: number)

Set the vsync swap interval. The interval with which to swap the front and back buffers in sync with vertical blanks (v-blank), the hardware event where the screen image is updated with data from the front buffer. A value of 1 swaps the buffers at every v-blank, a value of 2 swaps the buffers every other v-blank and so on. A value of 0 disables waiting for v-blank before swapping the buffers. Default value is 1. When setting the swap interval to 0 and having vsync disabled in "game.project", the engine will try to respect the set frame cap value from "game.project" in software instead. This setting may be overridden by driver settings.

// Setting the swap intervall to swap every v-blank
sys.set_vsync_swap_interval(1);

Parameters

  • swap_interval: number — target swap interval.

sys.set_update_frequency(frequency: number)

Set game update-frequency (frame cap). This option is equivalent to display.update_frequency in the "game.project" settings but set in run-time. If Vsync checked in "game.project", the rate will be clamped to a swap interval that matches any detected main monitor refresh rate. If Vsync is unchecked the engine will try to respect the rate in software using timers. There is no guarantee that the frame cap will be achieved depending on platform specifics and hardware settings.

// Setting the update frequency to 60 frames per second
sys.set_update_frequency(60);

Parameters

  • frequency: number — target frequency. 60 for 60 fps

sys.serialize(table: Record<string | number, unknown>): string

The buffer can later deserialized by sys.deserialize. This function has all the same limitations as sys.save. This function will raise a Lua error if an error occurs while serializing the table.

// Serialize table:
const my_table = [];
my_table.push("my_value");
const buffer = sys.serialize(my_table);

Parameters

  • table: Record<string | number, unknown> — lua table to serialize

Returns

  • buffer: string — serialized data buffer

sys.deserialize(buffer: string): Record<string | number, unknown>

This function will raise a Lua error if an error occurs while deserializing the buffer.

// Deserialize a table that was previously serialized:
const buffer = sys.serialize(my_table);
const table = sys.deserialize(buffer);

Parameters

  • buffer: string — buffer to deserialize from

Returns

  • table: Record<string | number, unknown> — lua table with deserialized data

sys.load_buffer(path: string): Opaque<"buffer">

The sys.load_buffer function will first try to load the resource from any of the mounted resource locations and return the data if any matching entries found. If not, the path will be tried as is from the primary disk on the device. In order for the engine to include custom resources in the build process, you need to specify them in the "custom_resources" key in your "game.project" settings file. You can specify single resource files or directories. If a directory is included in the resource list, all files and directories in that directory is recursively included: For example "main/data/,assets/level_data.json".

// Load binary data from a custom project resource:
const my_buffer = sys.load_buffer("/assets/my_level_data.bin");
const data_str = buffer.get_bytes(my_buffer, "data");
const has_my_header = data_str.slice(0, 6) === "D3F0LD";

// Load binary data from non-custom resource files on disk:
const asset_1 = sys.load_buffer("folder_next_to_binary/my_level_asset.txt");
const asset_2 = sys.load_buffer("/my/absolute/path");

Parameters

  • path: string — the path to load the buffer from

Returns

  • buffer: Opaque<"buffer"> — the buffer with data

sys.load_buffer_async(path: string, status_callback: function(self, request_id, result)): number

The sys.load_buffer function will first try to load the resource from any of the mounted resource locations and return the data if any matching entries found. If not, the path will be tried as is from the primary disk on the device. In order for the engine to include custom resources in the build process, you need to specify them in the "custom_resources" key in your "game.project" settings file. You can specify single resource files or directories. If a directory is included in the resource list, all files and directories in that directory is recursively included: For example "main/data/,assets/level_data.json". Note that issuing multiple requests of the same resource will yield individual buffers per request. There is no implic caching of the buffers based on request path.

// Load binary data from a custom project resource and update a texture resource:
function my_callback(self, request_id, result) {
  if (result.status === resource.REQUEST_STATUS_FINISHED) {
    resource.set_texture("/my_texture", {}, result.buf); // texture args
  }
}

const my_request = sys.load_buffer_async("/assets/my_level_data.bin", my_callback);

// Load binary data from non-custom resource files on disk:
function my_callback(self, request_id, result) {
  if (result.status !== sys.REQUEST_STATUS_FINISHED) {
    // uh oh! File could not be found, do something graceful
  } else if (request_id === self.first_asset) {
    // result.buffer contains data from my_level_asset.bin
  } else if (request_id === self.second_asset) {
    // result.buffer contains data from 'my_level.bin'
  }
}

export default defineScript({
  init(self) {
    self.first_asset = hash("folder_next_to_binary/my_level_asset.bin");
    self.second_asset = hash("/some_absolute_path/my_level.bin");
    self.first_request = sys.load_buffer_async(self.first_asset, my_callback);
    self.second_request = sys.load_buffer_async(self.second_asset, my_callback);
  },
});

Parameters

  • path: string — the path to load the buffer from
  • status_callback: function(self, request_id, result) — A status callback that will be invoked when a request has been handled, or an error occured. The result is a table containing:

status number The status of the request, supported values are:

  • resource.REQUEST_STATUS_FINISHED

  • resource.REQUEST_STATUS_ERROR_IO_ERROR

  • resource.REQUEST_STATUS_ERROR_NOT_FOUND

buffer buffer If the request was successfull, this will contain the request payload in a buffer object, and nil otherwise. Make sure to check the status before doing anything with the buffer value!

Returns

  • handle: number — a handle to the request

sys.set_engine_throttle(enable: boolean, cooldown: number)

Enables engine throttling.

// Disable throttling
sys.set_engine_throttle(false);

// Enable throttling
sys.set_engine_throttle(true, 1.5);

Parameters

  • enable: boolean — true if throttling should be enabled
  • cooldown: number — the time period to do update + render for (seconds)

sys.set_render_enable(enable: boolean)

Disables rendering

// Disable rendering
sys.set_render_enable(false);

Parameters

  • enable: boolean — true if throttling should be enabled

Constants

sys.NETWORK_DISCONNECTED

no network connection found

sys.NETWORK_CONNECTED_CELLULAR

network connected through mobile cellular

sys.NETWORK_CONNECTED

network connected through other, non cellular, connection

sys.REQUEST_STATUS_FINISHED

an asyncronous request has finished successfully

sys.REQUEST_STATUS_ERROR_IO_ERROR

an asyncronous request is unable to read the resource

sys.REQUEST_STATUS_ERROR_NOT_FOUND

an asyncronous request is unable to locate the resource