[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Enigma-devel] Lua API

From: Ronald Lamprecht
Subject: Re: [Enigma-devel] Lua API
Date: Mon, 22 Oct 2007 00:48:00 +0200
User-agent: Thunderbird (Windows/20070728)


Andreas Lochmann wrote:
well, everybody should have read and thought about the new API till now,
so, let's start feedback. :-)

[C1 - Object Based Syntax]

When I use
 x, y = GetXY(myactor)
what do I get? The integer or float coordinates of the actor?

Actually this not a question of the API. In both cases, old and new, the actor position is artificially confined to an integer. This limits levels to grid based logic. It is a basic concept of Enigma that users expect puzzles on grid basis but can rely on common subgrid physics controlled by the engine. Only the C++ engine is speed optimized enough to be able to handle actor movements. Direct level interactions with these parts is complex and critical in concerns of application stability.

Consecutive naming of objects (building object groups)

  wo[pos] = {"st_chess", color = 0, name="Atrax#"}

For each call of the line above the new object will be named with a unique number appended after the "#" giving "Atrax#1", "Atrax#2", "Atrax#3", ...
What happens if I set "Atrax#2" directly and then create "Atrax#"?

And, if I create "Atrax#1" and "Atrax#2", then delete "Atrax#1" and
create "Atrax#" again, which will be the new name?

Can I access a group like a lua-table, like in:
 for j, v in pairs(no["Atrax#"]) do

"Atrax#" uses *unique* numbers appended to the name. If "Atrax#2" already exists this number/name will not be reused. If "Atrax#1" gets deleted and further "Atrax#" objects will be created the name of "Atrax#1" will be reassigned to the first new object.

You can simply loop over a group by means of a numeric "for" loop:

for i = 1, #my_group do
   obj = my_group[i]

This is possible due to the fact that the group members are always guaranteed to be stored at indices 1 to #my_group.

Lua tables generally represent dictionaries with arbitrary keys. This caused the need for generic loop support functions "pairs()" and "ipairs()". Unfortunately they are only implemented for table values.

You may call it an implementation flaw as a typeless language like Lua should support at least ipairs() for any type that provides the required length operator (#) and index operators ([]). But fortunately it is an easy task to write an own "gpairs" Lua function that is based on the numeric for-loop approach and that allows to iterate over groups like:

for i, obj in gpairs(my_group) do

But I think it would be preferable to introduce the following simple syntax in the new API:

for obj in my_group do

This will have to be done in the C++ part of the API.

Thanks for this valuable hint :-)

Killing an object:

  wo[pos] = {"it_nil"}
Is killing a floor tile possible?

Yes. But it will be auto-replaced by a default floor of the type defined in the world initialization. We do not want to have a "hole" in our world :-)


  my_bolder:message("direction", WEST)
Would it be
 my_trigger:message("callback", myfunction)
 my_trigger:message("callback", "myfunction") ?

Neither, as "callback" is not an existing message name. Currently no message takes a string as value argument.

But if we would add a message that takes a string as value Lua would require to quote function and method arguments. You have to use one of the following expressions:

my_trigger:message("new_message", "a_string")

Classification of objects:
. obj:is("st_chess")
. obj:is("st")
. obj:is("st_chess_black")
How does this work? Is it pattern matching, such that
are true as well?

Sorry - it is no pattern matching as this would add a lot of constraints on the naming part.

This feature will be based on a reflexive C++ object interface as it is known in modern languages like Java. The C++ object classes will be able to provide information about the hierarchy and their attributes. We need this basic support either for future persistent storage of a running game.

[C4 - Multitarget and Multiaction ]
Different targets can take different actions:

my_switch = {"st_switch", target={my_door, my_laser, "my_function"},
    action={"open_close", "on_off", "callback"}}
Is the following possible:
 my_switch = {"st_switch", target={no["door#"], no["laser#"]},
   action = {"open_close", "on_off"}}


Is it neccessary to switch from "openclose" to "open_close" etc?

It is not necessary to switch. All namings of classes, attributes, messages and functions in the draft are preliminary and subject of common aggreement.

For all messages that toggle objects between two states like onoff, openclose,... we will introduce an additional common messages "toggle". This allows sending this most common message to groups mixed up of different objects.

Every callback takes the arguments (state_value, sender) where
"state_value" is an integer value that represents the internal state
of the sender object. For switch like objects the state will be 0 for
"off" and 1 for "on". Other objects like fourswitch etc. will count the
their states from 0, 1, 2,...
Is it possible to combine this with Booleans, or will there
be global constants like STATE_OFF, STATE_ON, STATE_WEST etc.?

None of the state values like "on", "open", "west", ... has a boolean character. They will be intergers. But we will standardize all OFF's to the same value.

Will there be a correspondence between the fourswitch-state and
the directions-constants?

Yes. Even though this is a difficult task as the old API uses a handful of incompatible encodings for directions.

Is it possible to access this internal state directly?

Read access only. Messages will be necessary to change the state of an object.

[C5 - Renaming]

- Short 2 or 3 letter names for the namespace and the special objects
- System attribute and message names have to be valid Lua names not
  starting with underscore
- User attributes start with an underscore
- System attribute and method names are disjoint
What happens when I use a user attribute without underscore, or
a system attribute of a newer Enigma version with an older version?

All attributes will strictly be checked for existance and type. Any error will be reported by proper messages.

- Object Classnames should use a common scheme of underscore/hyphen
  usage: Either underscore only, or first hyphen and all other
  underscore,... (st_chess_black, st-chess_black, ...)
This might be the most difficult point, though neccessary.

It is just possible due to the fact that the old API is based on small set of essential functions. This makes it possible to map old to new names on a table basis.

[C11 - Checkerboard Floor   (coded) ]

Every floor takes an attribute "checkerboard". If set to interger value
0 the floor will only be placed on grids with x+y being even, if set
to 1 the floor will be placed only on grids with x+y being uneven.

ti["x"] = ti({"fl_rough_red", checkerboard=0}) +
         {"fl_rough_blue", checkerboard=1}

generates an arbitrary shaped checkboardfloor on areas with tile "x"
on the world map.
Is it possible to add further algorithms in future?
C.f. the algorithms used in libsoko.

I received a similar proposal in a private email. Yes - we will add a general floor attribute that takes a callback function name. Before a floor will be set this function will be called to acklowledge or reject the floor set operation. Details will be published as soon as I have checked all sideeffects.

Thanks for the feedback



reply via email to

[Prev in Thread] Current Thread [Next in Thread]