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?

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.

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)).

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

Reply via email to