Skip to content

The Data System

Ruin0x11 edited this page Apr 7, 2020 · 4 revisions

The data table is a global available in all mod environments. It stores the definitions of nearly everything in the game.

Usage

Open the REPL and enter this code:

data["base.chara"]["elona.putit"]

A table will be printed to the REPL. This is the definition for this character. The first index is for the data type, the second is for the ID. This corresponds to the _type and _id fields of each entry. The usage of each data type is specific to the code that operates on them; this merely provides a way to store many data entries that all contain the same fields.

A very useful feature is the iter() method for the table returned by the first index. It returns a luafun iterator over the data entries of a certain type. Try running the following code:

data["base.chara"]:iter():length()

This prints out the total number of data entries of base.chara. A common use of this function is to retrieve the list of all IDs of known data entries, like so:

data["base.chara"]:iter():extract("_id")

This returns an iterator returning each entry's ID. To make this into a list-like table, call :to_list() on the resulting iterator:

data["base.chara"]:iter():extract("_id"):to_list()

For more information about iterators, see luafun's documentation.

Adding new data

Here is how to add new entries in the data table from within mods.

data:add {
  _type = "base.chara",
  _id = "my_character",

   -- <other fields>
}

data:add() is a method which receives a single table argument. This table must contain at least the following fields:

  • _type: The type of thing you want to add. There are numerous types of things available, each with different required or optional parameters. How to discover information about what types of things are available is detailed below.
  • _id: A unique identifier to assign to this entry. It must be unique against all entries created in the same mod with the same _type. When the entry is actually added this field will be prefixed with the name of the mod and a dot, so if the table you pass contains _id = "my_item" then the actual _id of the created entry will become mod_name.my_item.

The other fields that must be added depend on the _type of the entry. To make it easier to enter them all, you can use the editor extension to automatically insert a template with the required fields filled out. The palette command for this in VS Code is OpenNefia: Insert template.

Adding new data types

Less commonly needed is the ability to create new data types. For example, Elona+ features an evolution system. A mod implementing this system might want to allow other modders to add new evolutions at a later time. To do this, create a new type to hold the evolution data. Then, other modders can use data:add() to add new evolution types.

The method to add a new type is data:add_type(). Here is an example of its usage:

data:add_type {
   -- Name of the type. In this example, the name gets changed into `<mod_id>.chip`.
   name = "chip",

   -- These are the publicly available fields for this type. This is what controls the code that
   -- gets inserted when you want to insert a template, so be descriptive enough for other
   -- modders to understand how to use them.
   fields = {
      {
         name = "y_offset",
         default = 0, -- If unspecified with data:add(), this is the default value set.
         type = "number" -- Type of this field. If omitted, it is inferred from `default` if it is non-nil.
         template = true, -- If true, this value must be set and will be placed in the template uncommented.
         doc = "Y offset of the sprite in pixels." -- Documentation for this field. It will be inserted as a comment in the template.
      },
      -- <more fields...>
   }
}

The idea is that you should be able to use the defaults provided when creating a new entry from a template without any errors, so be sure to test out adding new entries from the template this provides.

Next Steps

Proceed to The Event System.