Objects & Commands (split from "Court of Games"
Freak
07 Jul 2006, 16:36Overcat wrote:Basic technical competence is a useful gauge: when large numbers of games made with a system have the same problems, it's a sign that either 1) the system is not capable of creating technically adequate games or 2) it requires a good deal of effort just to get the normal stuff working. Neither is too attractive for a user when there are alternatives where 3) basic technical competence is automatic.
An excellent argument for more built-in commands, which has been a point of small contention. Couple that with a sound manual and the games will improve.
On the other hand, the easier a system is to use, the larger a group of people will use it. The intellectual scope of the users broadens to include, well, less technically-minded individuals. And that's saying it nice. Nothing wrong with that. But this is where the Court of Games could step in as a regulatory screen.
I think part of the problem is that Quest makes it very easy to do things wrong. For example, if you add a new verb in an Inform game, you'll get sensible behavior for some fallthrough cases. In Quest, it seems to require a fair amount of effort to handle those ordinary cases, if it's even possible.
More specifically, Inform will give a game-level response if you try an action which it could understand, but was not specifically overriden ("COOK THE ROCK", when the rock is held), and will give a system-level error if you try an action it couldn't understand ("COOK THE ROCK", when the rock is in another room, or "COOK THE ZRBLM").
Is there a way in Quest to determine whether the command can be understood, which does not require manually handling each object?
So something like:
for each object x
if x is present and text maches x.vocabulary
say "You can't cook the ", x, ".";
say "I can't understand what you want to cook."
would be fine; it would be possible to write that part of the code before creating any object and not have to revise it afterwards.
Overcat
07 Jul 2006, 16:44Is there a way in Quest to determine whether the command can be understood, which does not require manually handling each object?
Absolutely. This very easily done in a command definition block. Check if the object is present. If not, output A. If so, is the object cook-able? If not, output B, else output C and perform the object's COOK action.
Freak
07 Jul 2006, 17:42Overcat
07 Jul 2006, 18:011) Check if the object referred to is in the current room/inventory, based on its vocabulary (ie, names/aliases)
2) If the object is in the current room/inventory, check if it can be cooked
3) If the object is not in the current inventory, print "I can't understand what you want to cook."
4) If the object can be cooked, print "You cook it."
5) If the object cannot be cooked, print "You cannot cook this object."
Or you could have a quick go at it, tr0n.
paul_one
07 Jul 2006, 18:41Do you mean it doesn't match?
I take it x.vocabulary is actually verbs/actions which can be taken on that object?
And how does that work exactly - because there could be multiple actions that could be done on that on object.
erm right, this bit would launch off the "cook" command;
command <cook #object#> {
}
Now, inside the {}'s would go the code which would be kicked off if "cook the rock" was typed in. (I'm gonna take it that "the" is ignored, as overcat has previously said in another topic).
if here <#object#> then {
if action <#object#;cook> then doaction <#object#;cook> else msg <You can't cook the #object#!>
}
else msg "I can't understand what you want to cook."
Freak
07 Jul 2006, 19:04(Those games I've played in Quest have struck me as being low in technical quality, the manual is not written in a very inviting style, and those ASL files I've looked at seem not to share the features which made clean handling in Inform / TADS possible. That's not very encouraging towards putting in the effort to learn the language.)
'xvocabulary' was intended to be a list of all single words that can refer to 'x'.
Overcat
07 Jul 2006, 19:19 command <cook #@object#> {
if here <#object#> then {
if action <#object#; cook> then {
if not property <#object#; cooked> then {
doaction <#object#; cook>
property <#object#; cooked>
}
else {
msg <That is already cooked.>
}
}
else {
msg <You can't cook that.>
}
}
else {
msg <That object is not here to cook.>
}
}
The problem is that the last message, 'msg <That object is not here to cook.>' will never show, since if the object is not present then Quest will display a standard error message, never running through the code in this command. To remedy, we can change the very first line from 'command <cook #@object#> {' to 'command <cook #object#> {', omitting the @. This causes the code within the command to execute, regardless if the object is present or not (because it is searching for text, I presume, not an object). Including the @ makes Quest search explicitly for an object that is present. If it doesn't find one, the code in the command does not execute. If we omit the @, however, we render the alt property of the object defunct.
I have coded my way around this by re-inventing the wheel, so to speak. I never use the @ in commands: instead I search for objects within the locale (inventory and current room) that match the text input, by alt or otherwise. The alt property cannot be read as a string, so I slapped on another 'alts' property to each object that contains alternate names/synonyms.
Pseudo-code:
For each object in locale {
If instr(#(quest.thing):alts#; #text#) > 0) then {
found object
add to found_objects array
disambiguate if array size > 1
}
return object
}
paul_one
07 Jul 2006, 19:26TADS/inform use a verb-pronoun-noun-whatever language structure system, which is built-in.
Ques see's it as "oh that's a line -does it match any command line which the programmer has entered?
If it does, than it goes off and executes the code.
If not, then it doesn't match any line and it gives out a "I do not recognise that command" line - which you can change.
Also, why go through all the objects in a room and compare them to the text?
Can you not just refer to any part of the text entered as an object straight off?
So entering "key" would automatically link back to "old key" instead of having to go through each object trying to find "key".
Overcat
07 Jul 2006, 19:45If we omit the @, however, we render the alt property of the object defunct.
I still want to use alt functionality. That's why I loop through all of the objects to find any with alts matching the inputted text. And I omit the @ because I want to be able to print different messages other than the standard for different objects/commands.
steve the gaming guy
07 Jul 2006, 19:46Tr0n wrote:...So entering "key" would automatically link back to "old key" instead of having to go through each object trying to find "key".
Amen
paul_one
07 Jul 2006, 23:53I may try and check this out in a spare few mins tomorrow.
I thought it searched the game for that object - BUT, the solution would be to simply move the @ - not remove it.
Move the @ from command <cook #@object#> to if here <#@object#> etc.
It's a little more typing I guess, but one letter saves so much time looping through all the objects.
Also, all of object properties are strings AFAIK.. I'll check this out, but I find it confusing that it doesn't come out.
Does the alt tag use ;'s as seperators?
Overcat, I wasn't refering to you with the looping through all objects, I was refering to Freak.. I understand if the alt tag doesn't work.
I didn't include a check for "cookability", as the fact it has a "cook" action is enough IMO.. I also didn't like to check for any 'cooked', as that should be on a per-object basis under the 'cook' action..
Although I'd do it slightly seperately, and have a 2-teir system. Having a default "cookable" property, "cooked" property (as you've shown above) and a default cook action - inside an else statement. The then would be launched it the object had a cook action - in which the default wouldn't get executed.. Which allows me to go idly by adding objects with a plain property - or fill out an explosion technique of a fork in a microwave (or something).
Overcat
08 Jul 2006, 01:58#@object# has always worked for me...
I may try and check this out in a spare few mins tomorrow.
In what sense does it work for you and not me again? My problem was that it doesn't fire the rest of the code in the command if it cannot find #@object#. Oh yeah. Your solution works if the object is referred to by its alias/name.
Wait a sec. Lemme' test that.
Holy.
command <wield #object#> {
if here <#@object#> then {
msg < Object is here.>
}
}
This only works if the alias AND the object name are identical to the input string #object#...odd. In other words, if I type 'wield apple', both the actual object name and the alias have to be 'apple'. If one or the other is 'apple2', the object is not found. Huh.
In any case, objects can't be accessed via their alt properties with this method either. For instance, if I give the apple the alt 'fruit', and then type 'wield fruit', the object is not found.
Does the alt tag use ;'s as seperators?
Yeah.
command <alt #@object#> {
msg < Alt = #(object):alt#>
string <objectalt; #(object):alt#>
msg < Alt = #objectalt#>
}
The above produces
Alt = !
Alt =
I didn't include a check for "cookability", as the fact it has a "cook" action is enough IMO
Yes, the fact that it has a cook action is good enough.
I also didn't like to check for any 'cooked', as that should be on a per-object basis under the 'cook' action.
Yes, I thought this too, but for ease of example it was put in one block of code.
Although I'd do it slightly seperately, and have a 2-teir system. Having a default "cookable" property, "cooked" property (as you've shown above) and a default cook action - inside an else statement. The then would be launched it the object had a cook action - in which the default wouldn't get executed.. Which allows me to go idly by adding objects with a plain property - or fill out an explosion technique of a fork in a microwave (or something).
Yep. Generally setting up type's is the way to go!
paul_one
08 Jul 2006, 09:59#@object# only works in objects in the current room...
I've uploaded a demo to;
http://www.compwhizz.freeserve.co.uk/asldemos/alias.asl
There's 2 objects;
one and five.
One is alias'd to two. And alt'd to three & four.
Five is alias'd to six. And alt'd to seven & eight.
(one is in the room - five is not)
You can execute look #object# and it'll run just fine, it'll output in the following order:
#object#
#@object#
$getobjectname(#object#;game)$
$objectproperty(#object#;alt)$
Funny thing is, the #@object# doesn't get the real object name - while the $getobjectname()$ function does..
Even though, in the Quest help file, it describes the function as superceeded by #@object# (which should both resolve alt's/alias' -> real names OR real name -> alias) .
Also the way Quest totally flakes out of the command when #@object# isn't in the current room is a bit flaky..
I'm looking up the info on #@object# at the mo.
Also, the alias and name don't have to be the same here - although you can't resolve the alias -> real name (type 'look two'), real name -> alias DOES work (type 'look one').
And also;
$getobjectname(#object#;game)$ returns a ! if #object# is the object name... This is surely wrong!
How do you know if the object actually exists or the user has typed something totally screwy like "look wibblywob" ?
... Oh, and one last thing - if the alt tag uses ;'s, then it's understandable that it is kinda screwy as properties are seperated by ;'s.
I would have prefered ,'s or |'s to seperate the alt's myself.
.... Oh-oh-oh, and I don't really like types, but understand that they can be useful in a runtime situation (assigning different stuff to objects on-the-fly during game, instead of having to give each property/whatever).
Could be quite useful in multi-player games, where you just create a few types (clans/monsters/etc) and you can mix&match different objects on the fly inside the game.
.. Right, done.
Overcat
08 Jul 2006, 11:19A Simple start room. Plain white walls, and no doors.
You have a feeling you will never see anything other than these 6 white sides to this cubist's heaven!
> look one
one
two
!
!
> look two
two
one
!
> look five
five
six
!
!
> look six
six
five
!
> look seven
seven
five
!
> look nine
nine
!
!
Huh.
I never thought of using $getobjectname$. Will have to fool around with this.
.... Oh-oh-oh, and I don't really like types, but understand that they can be useful in a runtime situation
These are just classes. And they allow inheritance. "Object-Oriented Design (OOD) is a design method in which a system is modeled as a collection of cooperating objects and individual objects are treated as instances of a class within a class hierarchy." - Wiki. Types are simply classes. I guess it's all in the way you like to code.
paul_one
08 Jul 2006, 12:26I haven't really been able to find a use for types in Quest yet.. As I say, I don't really like them - i think they over-generalise the use of propeties/actions, in which case I'd have a default action and just one a property as a flag... Although, as I said before, I suppose it'd be good to create objects during run-time to follow certain other types of objects etc.
Yeah, now if you type 'grab one', 'grab two', 'grab five' and 'grab six' you'll see that five and six crap out because the object isn't in the current room - one doesn't work (because it's trying to find Alias' - and two properly works (except I used $objectalias()$ which doesn't work - it should be $displayname()$ .. I've updated the file correctly).
Freak
08 Jul 2006, 13:10Tr0n wrote:quest deals with command structure totally differently from other sytems if I'm reading things like this right.
TADS/inform use a verb-pronoun-noun-whatever language structure system, which is built-in.
Ques see's it as "oh that's a line -does it match any command line which the programmer has entered?
If it does, than it goes off and executes the code.
If not, then it doesn't match any line and it gives out a "I do not recognise that command" line - which you can change.
Well, ADRIFT uses a similar "does it match any command line?" process.
The parser is built into TADS2, but it's part of the library, and fully replacable, in TADS 3 / Inform 6 / Inform 7.
Overcat
08 Jul 2006, 13:53I didn't think Quest supported inheritance?
Inheritance, as a concept, it certainly does.
Inheritance — a mechanism for creating subclasses, inheritance provides a way to define a (sub)class as a specialization or subtype or extension of a more general class: Dog is a subclass of Canidae, and Collie is a subclass of the (sub)class Dog. A subclass inherits all the members of its superclass(es), but it can extend their behaviour and add new members. Inheritance is the "is-a" relationship: a Dog is a Canidae. This is in contrast to composition, the "has-a" relationship: a Dog has a mother (another Dog) and has a father, etc. -Wiki
You don't create the subclass from the class (the object from the type), but it inherits all of the properties and actions of a type when you declare it belongs to that type in the definition block.
The fundamental concepts of OOP, besides inheritance (again Wiki):
Class — the unit of definition of data and behavior (functionality) for some kind-of-thing. For example, the 'class of Dogs' might be a set which includes the various breeds of dogs. A class is the basis of modularity and structure in an object-oriented computer program. A class should typically be recognizable to a non-programmer familiar with the problem domain, and the code for a class should be (relatively) self-contained and independent (as should the code for any good non-OOP function). With such modularity, the structure of a program will correspond to the aspects of the problem that the program is intended to solve. This simplifies the mapping to and from the problem and program.
These are asl Types.
Object — an instance of a class, an object (for example, "Lassie" the Dog) is the run-time manifestation (instantiation) of a particular exemplar of a class. (For the class of dogs which contains breed types, an acceptable exemplar would only be the subclass 'collie'; "Lassie" would then be an object in that subclass.) Each object has its own data, though the code within a class (or a subclass or an object) may be shared for economy.
Any object that has at least one Type.
Method (also known as message) — how code can use an object of some class. A method is a form of subroutine operating on a single object. Methods may be divided into queries returning the current state and commands changing it: a Dog could have a query Age to say how old it is, and command chase (Rabbit target) to start it chasing a rabbit. A method may also do both, but some authorities (e.g. Bertrand Meyer) recommend they be kept separate. Sometimes access to the data of an object is restricted to the methods of its class.
These are asl Actions.
Multiple inheritance – a Dog is both a Pet and a Canidae – is not always supported, as it can be hard both to implement and to use well.
Any object that has more than one Type.
Encapsulation — ensuring that code outside a class sees only functional details of that class, but not implementation details. The latter are liable to change, and could allow a user to put an object in an inappropriate state. Encapsulation is achieved by specifying which classes may use the members of an object. The result is that each object exposes to any class a certain interface — those members accessible to that class. For example, an interface can ensure that puppies can only be added to an object of the class Dog by code in that class. Members are often specified as public, protected and private, determining whether they are available to all classes, sub-classes or only the defining class. Some languages go further: Java uses the protected keyword to restrict access also to classes in the same package, C# and VB.NET reserve some members to classes in the same assembly using keywords internal (C#) or Friend (VB.NET), and Eiffel allows one to specify which classes may access any member.
Don't think this is supported, in principle.
Abstraction — the ability of a program to ignore the details of an object's (sub)class and work at a more generic level when appropriate; For example, "Lassie" the Dog may be treated as a Dog much of the time, but when appropriate she is abstracted to the level of Canidae (superclass of Dog) or Carnivora (superclass of Canidae), and so on.
We can do this.
Polymorphism — polymorphism is behavior that varies depending on the class in which the behavior is invoked, that is, two or more classes can react differently to the same message. For example, if Dog is commanded to speak this may elicit a Bark; if Pig is commanded to speak this may elicit an Oink.
We can do this also.
An object-based language is a language that has most of the properties of an object-oriented language, but may lack some. For example Visual Basic lacks inheritance, while a Prototype-based programming language relies on prototypes instead of classes to create objects.
Quest is an object-based language.
In OOP, "Each object is capable of receiving messages, processing data, and sending messages to other objects. Each object can be viewed as an independent little machine or actor with a distinct role or responsibility." - Wiki
In an earlier post on object interaction, I was trying to achieve this by 'emitting actions' from one object to another. This is really a messaging/information processing system, where each object is an independent little machine, responding to and manipulating information.
paul_one
08 Jul 2006, 23:24
I know what OOP is.
I program (normally) in C++.
I thought type-inheritance was where you could have one type 'inheriting' the actions/properties (methods/properties/the-other-third-thing which might only be in VB but is like methods) of another type - but then further defines that type... Just like it says in your quote.
Ie, you have a generic "techer" type, and then a "headmaster" type - inheriting that of the normal teacher and then further defining extra properties.
Quest doesn't allow types to be made from previous types.
Encapsulation in Quest isn't supported - no.
There is no 'private' area to hide things in. Quest makes everything globally accessible.
How did you turn my question about Quest's support for inheritance and the fact I don't find use for them into explaining classes/methods/properties/that-other-one-I-can't-remember?
Overcat
09 Jul 2006, 12:32I thought type-inheritance was where you could have one type 'inheriting' the actions/properties (methods/properties/the-other-third-thing which might only be in VB but is like methods) of another type - but then further defines that type... Just like it says in your quote.
I have been doing this. Perhaps I should check if it's working. A backpack is a Container type and a Wearable type; a Container type is a MassObject type; a Wearable type is an ItemObject type; an ItemObject type is a MassObject type.
MaDbRiT
09 Jul 2006, 13:01Quest doesn't allow types to be made from previous types.
Unless I'm completely missing what you mean, I'd have to say that's wrong!
My typelib uses types that are derived from other types and inherit actions / properties etc. All the clothing types for instance are derived from the basic TLTclothing type.
Al
paul_one
09 Jul 2006, 18:06Last time I remember, Quest didn't support inheritance!

Overcat
09 Jul 2006, 18:13Arbutus
10 Jul 2006, 00:52Types: Specify here any types you want to inherit. We've discussed inheriting types in objects, but you can also inherit types into other types. For example, we might make a "poison" type, which would inherit everything from "edible" but provide its own "eat" action which would kill the player or decrease the player's health.
I've used inherited sub-types and they work fine.