Log In  

I recently tried to implement an enum structure in Lua, which turned out to be very useful. So I thought I might share it here :)

Find the latest version here (it's part of a Pico-8 library) https://github.com/sulai/Lib-Pico8/blob/master/lang.lua

Then enum(...) function generates an enum structure from a list of names.

The generated structure is useful when it comes to readability and object orientation.

As a use case for Pico-8, you can comfortably generate named objects that map to sprite ids. So if you want to associate names to your sprites like "sword", "shield", etc to show that to the user, this is a nice way to do it.

Example usage in a RPG:

tiles = enum( {"grass" ,"water", "rock"} )     -- landscape sprites start at 1
items = enum( {"sword" ,"shield", "bow"}, 16 ) -- item sprites start at 16
colors = enum( {"black", "blue", ... }, 0 )    -- map color palette.
actions = enum( {"look", "take", ... } )       -- just an enum.

You can now use the enums to make your code more readable:

if action==actions.take then
    mset(x,y,tiles.grass.id)
    pset(x,y,colors.green.id)
end
  • You can resolve to its name like tiles.water.name.
  • You can resolve by its id, eg: tiles[3].name
  • you can iterate over all enum entries like: for item in items.all() do print(item.name) end
  • You can offset the ids by using tiles=enum(names, 10). Useful if your sprites start at index 10.
  • You can also map arbitrary ids to objects like furniture=enum({[15]="table", [20]="chair"}).
  • You can use the generated objects as a starting point for more complex objects like furniture.table.heavy=true,
    or attach functionality like:
actions.look.execute = function(item)
    print("Looks like a usual "..item.name)
end
actions.take.execute = function(item)
    if not item.heavy then
        add(inventory, item)
    end
end
function onactionuse(action, item)
    action.execute(item)
end

Keep in mind that the usage of enums consumes more tokens than using magic numbers. You trade tokens for readability and elegant code.

P#43901 2017-09-03 18:33 ( Edited 2017-09-03 22:33)

1

This is neat, but as you say you will end up token-optimizing everything in the end. The neat code is simply too expensive :(

As a side note, remember that you can (in lua) change this piece of code:

if offset==nil then offset=1 end

to this:

offset=offset or 1
P#43909 2017-09-04 06:17 ( Edited 2017-09-04 10:17)

Thanks for your comment jeb :) Yes, the token limit works against readability, which is sad.

Nice trick, will use it! :)

P#43910 2017-09-04 06:23 ( Edited 2017-09-04 10:23)

I really like it, thanks for sharing! :)

P#75839 2020-05-05 11:19
2

My version - doesn't support a start value, but it should be as short as possible

function enum(str)
  for a,b in pairs (split(str)) do
    _𝘦𝘯𝘷[b]=a
  end  
end

enum("playing,gameover,die,win")
print(playing)
print(gameover)
print(die)
print(win)

not "_env" must be in "lower case" - activate in the editor the "lower-case-mode" with strg+p!

P#98170 2021-10-03 19:45

You can pretend that enum is a type with this lua shortcut:

potions = enum{ "red", "blue", "yellow" }
P#98199 2021-10-04 16:38

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-18 08:14:27 | 0.007s | Q:15