Tables


Introduction

This tutorial will show you how to create a simple defense tracker in the IRE MUD, Aetolia. It is assumed you have installed Mudlet and have a working familiarity in its environment. I’ll explain how Lua uses tables and how you can use tables to create a system. This tutorial should not be taken as the ‘best method’ for constructing a defense tracking system; it’s intended to teach the application and use of tables.

Some theory

There are a few concepts important to understand before working with tables.

Collection types

Arrays are data structures that represent a list of elements. arrays can be accessed though a index eg. arrayName[1] for the first element or arrayName[2] for the second element

Tables are associative arrays wich is an array that can be indexed not only with numbers, but also with strings or any other value of the lua language, except nil. Moreover, tables have no fixed size; you can add as many elements as you want to a table dynamically.Tables are created by means of a constructor expression, which in its simplest form is written as {}.

1
2
3
4
5
6
7
8
9
-- Let's declare a table
a = {
    "apple",
    1,
    x = {
        name = "bosworth",
        breed = "mutt"
    }
}

Now let’s explore the index values of the table

a[1] -> "apple"       a[2] -> 1
a[3] ->  nil          a[x] -> nil
a["x"] -> {name = "bosworth", breed = "mutt"}

Notice a[3] and a[x] evaluate as nil. Like global variables, table fields evaluate as nil if they are not initialized. Likewise nil can be assigned to a table field to delete it.

Records are represented with the use of a field name as an index. Lua supports this representation by providing a.x as another method to express a["x"]. Let’s take a closer look:

x = {name = "bosworth", breed = "mutt"}
x.name -> "bosworth"     x["name"] -> "bosworth

Be careful not to confuse a.x with a[x]. The former is a["x"] which is a table indexed by the string "x". The latter is a table indexed by the variable x and not yet initialized.

Iteration

Iteration is a process in which a set of instructions are repeated in a sequence for a specified number of times or until a condition is met. In the example below the iterative for function is used to define elements of a table.

1
2
3
4
a = {}
for i = 1, 10 do   --this will run from a[1] to a[10]
    a[i] = i * 2
end

When iterating over the elements of an array, the first non-initialized index will result in nil; this can be a value used to represet the end of the array. Using the previous example, the elements of the array could be printed as followed:

1
2
3
4
--print values for a. 
for i, _ in ipairs(a) do
    print(a[i])
end

Lua provides the ipairs function to allow iteration over the elements of an array, following the convention that the array ends at its first nil element.

Now that these concepts have been explained, let’s open up mudlet and begin building a defense tracking system.

Building a defense tracker in Mudlet

As we work through this tutorial we will be using a mudlet function to run lua code from the command line in mudlet to evaluate the tables we will be working with

Run-Lua-Code

Before diving in, first ensure your directory in mudlet contains an alias group named run-lua-code. This is an important alias for checking the current state of a table. If it does not exist then create an alias using the following example. Please note the pattern entry in the comments.

1
2
3
4
5
6
7
8
9
-- pattern: lua (.*)
-- script:
local f,e = loadstring("return "..matches[2])
if not f then
	f,e = assert(loadstring(matches[2]))
end

local r = f()
if r ~= nil then display(r) end

If you already have this, great! We’ll be using it.

GMCP tables

In Aetolia some character data can be found in a table the game creates serverside called gmcp. To view your own gmcp table, send the command lua display(gmcp). This table is very large and may take up the entireity of your current page length.

For our purposes, we will be looking at gmcp.Char.Defences.List table. Below is a snippit of what this table might look like:

 {
    {
      name = "blindness",
      desc = "Being blind will prevent various visual-based attacks."
    },
    {
      name = "deafness",
      desc = "Being deaf prevents various sound-based attacks from affecting you."
    },
    {
      name = "mindseye",
      desc = ""
    }, 
 }

The first step will be taking this table and creating a new one with only the name elements. Create a new script with the follwing function:

1
2
3
4
5
6
7
8
--Stringification--
function stringifyDefences()
	stringifyTable = {}
	for k, _ in pairs(gmcp.Char.Defences.List) do
		stringifyTable[k] = gmcp.Char.Defences.List[k].name
	end
	return stringifyTable
end

Take note, this script returns a new table that consists only of the name elements from the gmcp table we were working with. From our snippit example, the table returned would look like this:

{
    "blindness",
    "deafness",
    "mindseye",
}

The next step is to determine when this information will be assigned and where the table information will be stored.

Defense System Tables

This defence system will compare ones current state of defences to that of a list of desired defences to be always maintained. In order to do this a few tables need to be defined. In mudlet, create a new script labeled Defence Tables and then add the following tables:

”’ sep = – Your separator configuration for aetolia defence = { [“core”] = { [“general”] = { [“mindseye”] = “touch allsight”, [“deafness”] = “outc ototoxin”..sep..“eat ototoxin”, [“blindness”] = “outc amaurosis” .. sep .. “eat amaurosis”, [“levitation”] = “sip levitation”, [“speed”] = “sip speed”, }, [“carnifex”] = { [“soul_shroud” ] = “soul shroud”, } } } “’

This table is assigning