for each exit in room <#quest.currentroom#> {
'do something
}define exit <North>
end defineproperty <room.north; SomeProperty>
action <room.north; SomeAction>
type <room.north; SomeType>I was assuming that exits would be implemented like this:
Hmmm... Do you really want to iterate over an exit when you're doing a "for each object in..." loop?
for each object in game {
if type <#quest.thing#; Actor> then {
'logic
}
}So I get the feeling that treating exits as objects is to allow them to have a generic action ("destruct", or "unlock").
.. But would you really want people to type "punch north", "unlock east" etc?
west {
if here <BigRock> then {
msg <There's a big rock in the way!>
}
else {
goto <NextRoom>
}
}Overcat wrote:Hmmm... Do you really want to iterate over an exit when you're doing a "for each object in..." loop?
The best solution (for me) would be a 'for each object of type <type> in <room>/game'. We can achieve the same effect ourselves with:
[quote]So I get the feeling that treating exits as objects is to allow them to have a generic action ("destruct", or "unlock").
[quote].. But would you really want people to type "punch north", "unlock east" etc?
I can understand, however, how one would perceive an exit as a property of a location, rather than as an object. We have 360 degrees of infinitely precise freedom in reality, whereas in games we've digitized motion: directions are in discrete chunks. (And so are the locations.) Whether or not each of those directions is linked to an object (like a door) is, in my opinion, irrelevant as to whether the direction should be treated as an object in and of itself. Moving somewhere, anywhere, involves a description of some sort, even if it just be 'east' or 'west'. I think an exit object might allow better programmatic control over the description and effects of movement.
As an example, consider NPC automation:
west {
if here <BigRock> then {
msg <There's a big rock in the way!>
}
else {
goto <NextRoom>
}
}
How the heck is an NPC supposed to interact with that? The exit script is referencing the object, so the NPC has no way of knowing the big rock is linked with going west. Further, how do I tell who attempted to use the exit? (Which might be important.)
If the exit is an object with properties and actions, I can make the NPC interact with the object. The NPC can scrutinize the exit to see if they should even attempt to go that way. They can also discover something about the exit that they couldn't possibly know before attempting to use it, and then respond to that discovery. Additionally, all the logic for the behaviour of an exit object can stay with the exit, no matter if the player or an NPC attempts to use it.
def obj <west>
action <move> if here <stone> then _
msg <no way> _
else _
goto <next room>
end defAs a final argument, why forbid an exit the inherent benefit of being an object? Is anything gained by limiting an exit as a single property or script of a location? I don't see it. (Not to say there's nothing to see - just that I can't see it yet.) You can always treat an object like a property, but you can't treat a property like an object (not easily, and not efficiently, anyway). All that said, I'm still open to any further arguments as to why exits shouldn't be objects.
What I mean is - if you want to remove all the objects from a room, someone blindly going "for each object in <room> -> move it to <room3>" or some such coding muck up (kick north -> you kick north far-far away).
This means you have to code AROUND exits being objects - rather then what is actually a pretty straight forward object interaction mechanism.
Which as I explained, exits are not objects.
A "door" is an object in the way of an object, so is a board, so is a teleporter (the fact you need to supply energy to "open" the exit doesn't mean it IS an exit).
... The exit is only something in two states.. Either it IS an exit, or it isn't. An "exit" can't be locked, or interacted with in any real way.
On the other hand, a door, wooden boards, bricks and morter. These can all be interacted with - or interact with the room - to change the exit from one state to the other.
[quote]This is easily avoided...then they can't.)
You've just added complexity with no benefit (ie functionality) for what reason?
I can imagine that you'd want a walk and a run action on the exit, so you have two different ways of going through it (and possibly more).
BUT, you can code all of that through a procedure/function which your exit can call in ASL-400 (the proc/func would refer to the room/objects passed to it similar to the #quest.self# or #quest.thing# variables that aren't too well documented).
[quote]I can understand...effects of movement.
def obj <west>
action <move> if here <stone> then _
msg <no way> _
else _
goto <next room>
end def
.... aaaaaand in what way can the NPC scrutinize this?
.... You'd give it a SPECIAL action right? - like "NPC" - and have it return either the room or "FALSE" so that it can move into that room or see the exit cannot be traversed yet? (it's the first idea which seems pretty simple and logical to me)
All that would be left out is the player typing "w" or "go west" - which would return "I cannot go there" instead of the nicer "there appears to be a rock in the way". Which you can have as the normal "default" exit script (ie west msg <There's a big rock in the way>).
The NPC would get to the room, use the properties to check all the exits (or go through the "for each exit in") to pick an available room.
You close asking for any benefits of correcting exit usage in ASL-400
Just because something is represented in the game as an object doesn't mean it's necessarily an object in the room. It's a common technique to have an object used solely for structuring data.
I think it's pretty straight forward to "code AROUND" them. It's not like you're circumnavigating the globe any time you want to avoid a certain kind of object.
I understand that in real life exits are not objects! But in a coded representation of the real world, any concept can be programmatically structured - in this case, an exit can be an object. There seems to be a disconnect between what I mean by 'object' and what you mean by 'object'. When I say 'object' I am speaking in a programming sense. I can abstract exits into a class (in ASL's case, a type), and then create instances of that class. I can use the properties and actions defined by the exit type to mutate the instances into all the different kinds of exits I can think of - including exits that are just that: exits with no other noun than the direction (east, west, etc.)
As a parallel, I have an 'event' type in a library file that I use to define event objects. Events are no more objects in the real world than are exits, but I still create them as programming objects. Rather than coding all the different kinds of events that are possible wherever I need them, I create a single type and manipulate properties/actions to achieve the effects I want.
[quote]What you've now introduced above is:
*) Overriding player movement
*) Special treatment of the <exit> object type in ALL commands
*) Special treatment of the <exit> object type for ALL object interactions - not just the ones the player wants to interact with but whatever you want to do automatically to objects too.
*) Special naming convention which voids the benefit of the "for each exit in <room>" loop.
Exits can have all sorts of description involved with them. A thin tree trunk over a fast-flowing river; a rope spanning a crevice; an open window; a magical portal; the mouth of a giant worm. It makes more sense (to me) to have an exit object with properties/actions that determine what is reported to the player when they travel (or attempt to travel) in a certain direction.
It boils down to how you view the construction of the world behind the scenes.
Overcat, could you produce hypothetical code of a small game that would illustrate the usefulness of exit objects?
Also, is it possible to have some sort of intermediate, that has simple connections for the bulk of the connections, but allows using exit objects when needed?
Note: I am trying to stop myself using caps to exaggerate words as it makes me sound smarmy and aggressive.
Mockery is very welcome.
Yes I agree, I think you're combining an exit and object (rope, hole, tree, etc) in order for interact.
Sorry for the length of this (again) but am liking the argument.
Exit objects are not in the same scope as regular objects. You don't need to worry about excluding them from "for each" loops or player commands...
command <someVerb #@object#> {
if action <#object#; someVerb> then {
doaction <#object#; someVerb>
}
else {
msg <You cannot someVerb #(object):prefix# #@object#.>
}
}define type <punchable>
action <BeforePunch> {
doaction <$thisobject$; OnPunch>
}
action <OnPunch> {
'code default functionality here
doaction <$thisobject$; AfterPunch>
}
action <AfterPunch> {
}
end define
define object <NPC_RonBurgundy> {
type <punchable>
end define
define game <SomeGame>
...
verb <punch: BeforePunch> msg <You cannot punch #(quest.lastobject):prefix# #quest.lastobject#.>
...
end definedefine object <NPC_JuliaRoberts> {
type <punchable>
action <BeforePunch> {
if (#player:gender# <> female) then {
msg <You wouldn't hit a lady.>
}
else {
doaction <$thisobject$; OnPunch>
}
}
end define
define object <NPC_HomerSimpson>
type <punchable>
action <AfterPunch> {
msg <Homer: "Doh!">
}
end definedefine type <item>
take
type <punchable>
action <OnPunch> {
'other effects
doaction <$thisobject$; AfterPunch>
}
end define
define object <apple> {
type <item>
end definedefine object <screw> {
type <unscrewable>
action <BeforeTurn> {
doaction <$thisobject$; BeforeUnscrew>
}
end defineThere's no "define exit" block in this version although I may well add that in Quest 4.2. This would add the possibility of specifying alt-names for exits and that sort of thing.
That gets rid of the whole exits-as-objects issue for me and simple allows you to add object functionality to the exit.
For 4.1 I still don't know how to add properties and actions to the exit object during design-time. (Can do so at run-time).
Ugly workaround would be to create a type for each exit and then apply the type to the exit at run-time. You could even loop through all exit objects in your startscript, and apply the type within the loop, perhaps.
Since you can't apply properties and actions to exits in v4.0 anyway I don't think is a big issue for v4.1, is it? I can't think that adding properties and actions to an exit would be that common.
Overcat - I think he means, instead of having one type - have many.
So type <one> would contain everything for exit <one>.
Type <two> would contain exit <two>.
.. etc..
startscript {
for each exit in game {
type <#quest.thing#; #quest.thing#>
}
}