On 9/10/2010 12:26 PM, Ralph Versteegen wrote:
On 11 September 2010 03:15, Mike Caron<[email protected]>  wrote:
On 9/10/2010 10:58 AM, Ralph Versteegen wrote:

On 10 September 2010 03:18, James Paige<[email protected]>    wrote:

On Thu, Sep 09, 2010 at 10:18:41PM +1200, Ralph Versteegen wrote:

Well, this email was originally going to be part of the one about SAV,
but then I remembered that NPC instance data has never been read from
.SAV!

I'd like start adding of data to NPC instances, like zone
restrictions. (I'll have to create an NPC instance editor.)
Actually, I already started.  A few months ago I wrote these (below),
but didn't check them in because I was waiting for .SAV to be dropped.
Opps! Sorry Jeremy!
But anyway, I just thought I may as well ask about functions for
reading/writing NPC instance data.

functions:
472,setnpcbit,3,0,0,1         #set NPC instance bit (npcref, bit, value)
473,getnpcbit,2,0,0           #get NPC instance bit (npcref, bit)

constants:
0,NPCbit:ignore walls
1,NPCbit:not obstruction
2,NPCbit:suspend use
3,NPCbit:suspend movement

(Incidentally, those "bits" are not actually stored as bits in the
UDT.) And then other non-flag data like zone restrictions would each
get a pair of getter/setting functions. Would people prefer something
more uniform like alter/read npc (below)? Or the opposite extreme of
individual read/write functions for each bit?

472,read npc instance,3,0,0,1         #set NPC instance data (npcref,
data id, value)
473,write npc instance,2,0,0           #get NPC instance data (npcref,
data id)

0,NPCinst:ignore walls
1,NPCinst:not obstruction
2,NPCinst:suspend use
3,NPCinst:suspend movement
4,NPCinst:zone

I like individual functions for each bit. I may have advocated generic
functions with constants in the past, but I am really starting to hate
the heck out of them. it is all about what I want to be writing as an
end-user in my script:

# this is good
set npc ignore walls(npc, true)

# this is bad
set npc bit(npc, NPCbit:ignore walls, true)

Well, I choose the second approach because I hate having too many
functions (and having to document them :) ), because it makes the
dictionary extremely verbose: consulting a compact table as for
alternpc is much faster (I actually prefer read/alternpc to trying to
remember over 100 menu functions, for example). And our commands are
inconsistent and difficult to remember as a rule -- I can never
remember whether to use "slice parent" or "parent slice" -- so I end
up looking up an awful lot. However a few paragraphs of documentation
for every tiny bit is much more fair for people who aren't familiar
with engine internals in the first place.

However despite all that, I must agree with you: I didn't realise how
overly verbose the setnpcbit approach was.

But while we're on the topic of too many functions which are
impossible to remember, I think I'll sidetrack into adding structures
to HS, which I've been meaning to talk about. Having actually used
Euphoria a whole a couple months back, I take back what I said about
it being a nice language. I think not supporting user defined data
structures in the new HamsterSpeak is out of the question, it's just
unworkable.

And following this train of reasoning, if we have user defined
structures, and function objects, then we may as well add some form of
object orientation, since you're already nearly there.

And if we now present a slice handle, npc reference, menu handle or
whatever else as an object with members and/or methods, we can provide
an alternative way to interact these objects that's less verbose,
highly consistent, easy to remember and compactly documentable:
   menuitem.caption
instead of
   get menu item caption (menuitem)

   heroes[who].stats[stat.hp] += x
instead of
   set hero stat(who, stat:hp, get hero stat(who, stat:hp) + x)
and so on.

The exact details don't matter right now, but this is very similar to
the Magic Variables plan.

I'm having deja vu; this is a lot like the transition between the
mathematical operators being functions and them being actual symbols.
(although, this transition occurred long before I had ever used the OHR)

Hypothetically speaking, how would you implement these structs? Would you go
for a classical model (like how they work in C), or something else?

I was thinking something along the lines of Python or Lua, which
implement objects in very similar ways. I'm not all that familiar with
Lua though.

We can afford to be less flexible than these though. For example,
should you be able to add new members to builtin data types, like
setting npcref.is_hallucinating := true? (Realise that if we do this,
it would be handled entirely by the script interpreter, and in fact I
think it's quite likely we can add builtin types without having to
significantly modify any existing commands beyond what's needed for
dynamic types anyway) I think it looks elegant, but isn't there a rule
of thumb that composition is preferred to inheritance?

It depends on the situation. It boils down to has-a vs is-a, really. Or, on other words, if it looks like a duck, quacks like a duck, and has a feathers property, but was created by CreateChimera(), can we still treat it as a duck?

(Lua, Python and Javascript say yes. C/++, FreeBasic and others say no)

If you're looking for suggestions, I think Lua has the best system.
Basically, every variable that isn't a basic type (integer, string, etc) is
a table (i.e., a set of key->value pairs). If the indicies are numeric, you
call it an array, whereas if the keys are strings, you call it a hash. If
the values are functions, then it must be an object.

Even better, you can set what's called a "metatable", which defines
functions that are called when the table is operated on, which allows you to
simulate properties. The identity of an object is based on its metatable. If
get_metatable(objA) == get_metatable(objB), then they must be instances of
the same class.

I'm hazy on this part of lua, but I think we should make properties as
easy as possible to write. In fact, they're actually the focus of this
suggestion, rather than methods in general.

Just to clarify, a field is a data member on an object. eg, myobj.color. A property is actually a method that disguises itself as a field, but can be read only, or have special validation done, or maybe the property doesn't even have a backing store, but is actually inferred from other things.

In light of this, Lua uses the metatable to distinguish whether it's assigning a field, or calling a method when you do this:

myobj.color = "red";

If color is a property, then it will call the appropriate function with the value "red". If it's a field, then it will store "red" under "color".

(You already know this. I don't know why I felt it necessary to write all the above.)

One of Lua's interesting quirks is that it actually has two ways to invoke
methods on objects. If you use the dot operator (myobj.method()), it's
called normally (eg, just as method()). But, if you use the colon operator
(myobj.method()), it's called by passing the table as the first operator
(eg, method(myobj)).

This scared me a little, but I guess it's good to be explicit about
whether you're calling a method or a function object member with
method-like syntax. I doubt that adding more syntax than necessary to
HS is a good idea, though.

I don't necessarily like it either, but it's an artifact of the way Lua works. Lua doesn't have a magic "this" parameter. A function has to expect it as an explicit parameter. If the function doesn't expect it, then you call it with the dot, and it doesn't get it. If it *does* expect it, call with the color, and it will.

Of course, if you DO use the magic "this", then it's a non-issue.

A whimsical thought: it occurred to me that using : instead of . would
be more idiomatic for HS.

Just a minor problem: All 12 hojillion constants that already use :

As I said, I know the library is already full of stuff that does it the
second way, I just wish now that it wasn't.

But I suppose this is a matter of personal taste, and my opinion on this
is certainly not the final word.

---
James
_______________________________________________
Ohrrpgce mailing list
[email protected]
http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org

_______________________________________________
Ohrrpgce mailing list
[email protected]
http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org

_______________________________________________
Ohrrpgce mailing list
[email protected]
http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org

_______________________________________________
Ohrrpgce mailing list
[email protected]
http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org

_______________________________________________
Ohrrpgce mailing list
[email protected]
http://lists.motherhamster.org/listinfo.cgi/ohrrpgce-motherhamster.org

Reply via email to