A look at TADS

Post a reply


This question is a means of preventing automated form submissions by spambots.
Smilies
:smile: :sad: :eek: :shock: :cool: :-x :razz: :oops: :evil: :twisted: :wink: :idea: :arrow: :neutral: :mrgreen:

BBCode is ON
[img] is ON
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: A look at TADS

by pinback » Tue Dec 13, 2016 8:17 pm

RealNC wrote:Just add a new Trip action, and in your class for switch-like objects, implement a Trip handler, and map Throw to Trip with:

Code: Select all

dobjFor(Throw) asDobjFor(Trip)
This is essentially what I said. So I take it back, I am a TADS expert.

by RealNC » Tue Dec 13, 2016 6:32 pm

Do not do anything to Throw. Don't modify it, nor add an XThrow.

Just add a new Trip action, and in your class for switch-like objects, implement a Trip handler, and map Throw to Trip with:

Code: Select all

dobjFor(Throw) asDobjFor(Trip)
Do not modify default actions without a good reason. And the reason you gave is not good :-P

by pinback » Tue Dec 13, 2016 5:24 pm

I don't know TADS.

Could you just override the switch's "throw" action to redirect to "turn on"?

(Also nobody will ever type "throw bathroom switch", and if they did, and the response was "you can't throw that, it's attached to the wall!" then they would surely understand.)

by Tdarcos » Tue Dec 13, 2016 4:33 pm

RealNC wrote:I don't see a handler for Trip in your code.
I did have it in the listing I posted:

Code: Select all

VerbRule(Trip)
    'trip' singleDobj
    : XThrowAction
    verbPhrase = 'throw/trip item'
; 
This is intended to make TRIP KITCHEN BREAKER and THROW KITCHEN BREAKER accomplish the same thing.
RealNC wrote:Also, your throw action cannot possibly work. It clashes badly with the default throw action. Your new Throw is "XThrow", but in your object, instead of handling XThrow, you handle Throw... So when the command is THROW X, which throw action does that refer to? Throw or XThrow? I don't know. So don't do that.
When you use the same verb sequence in another definition it uses the later one. I just couldn't figure out how exactly to override the original THROW verb handler.
RealNC wrote:If you want to modify the default Throw action, you can modify its VerbRule. Leave the vocabulary empty to inherit the default one (which is "('throw' | 'toss') dobjList", defined in adv3/en_us/en_us.t):

Code: Select all

modify VerbRule(Throw)
    /* vocabulary empty on purpose */
    :
    execAction()
    {
        // ...
        // your own code here.
        // ...

       // Call overridden method.
       inherited();
    }
;
Why on earth do you want to modify Throw though?
"THROW BATHROOM BREAKER" or"THROW BATHROOM SWITCH" or "TRIP BATHROOM BREAKER" or "TURN ON BATHROOM BREAKER" or "TRIP AIR CONDITIONER", "TURN OFF AIR CONDITIONER" etc. to indicate the person wants to change the position of the fuse box breaker switch from on to off or vice versa. This would be separate from THROW COFFEE POT AT REFRIGERATOR (which is a different and valid action elsewhere in the game).

by RealNC » Tue Dec 13, 2016 6:17 am

Also, you should probably switch to adv3Lite. The default library (adv3) is extremely simulationist and very complex.

by RealNC » Tue Dec 13, 2016 6:14 am

I don't see a handler for Trip in your code.

Also, your throw action cannot possibly work. It clashes badly with the default throw action. Your new Throw is "XThrow", but in your object, instead of handling XThrow, you handle Throw... So when the command is THROW X, which throw action does that refer to? Throw or XThrow? I don't know. So don't do that.

If you want to modify the default Throw action, you can modify its VerbRule. Leave the vocabulary empty to inherit the default one (which is "('throw' | 'toss') dobjList", defined in adv3/en_us/en_us.t):

Code: Select all

modify VerbRule(Throw)
    /* vocabulary empty on purpose */
    :
    execAction()
    {
        // ...
        // your own code here.
        // ...

       // Call overridden method.
       inherited();
    }
;
Why on earth do you want to modify Throw though?

by Tdarcos » Mon Dec 12, 2016 11:42 am

Ice Cream Jonsey wrote:
pinback wrote:
Post a code snippet that isn't working that you think should be working. I have never used TADS, and I guarantee you I will be able to point out what you're doing wrong, and where the manual explains what you're doing wrong, within 15 minutes.
If Pinner can't, I will put a $100 donation to the Blue Cross / Blue Shield in your name, Paul. That's how confident I am.
You've spent so much time complaining about me and Billy Mays that you lose. Pinback has been here, saw all the other messages, so I have to presume he saw this one, and made no response. So much for his promise of half Domino's Pizza's response time.

Can we look at this as an example that maybe all of us make mistakes and forget things?
RealNC wrote:Yes, you are correct. It's broken. It doesn't work as intended. Nobody noticed this before, weird.

Well, either that, or you didn't really RTFM.
I did read the manuals. I took a piece of code that does work for a different verb and made the modifications for the new verb and it does not work. It's clearly obvious I'm doing something wrong and I do not know what it is.

I will now reiterate what I said before. I have said repeatedly that I know I'm doing something wrong. And I don't know what it is. What I am saying is that this system frustrates me because I have to fight it every step of the way to get anything accomplished. It should not be this difficult and it should not be this restrictive.

Maybe someone can explain why it is necessary to forbid a defined object from implementing a processor for a particular verb if it is the direct or indirect object of that verb. I know the process should work because it does work for PLUG IN TV / PLUG TV IN and PLUG TV INTO SOCKET as well as where CABLE BOX is substituted for TV.

So when I tried to implement TRIP KITCHEN (with or without the word BREAKER) it's clear I'm doing something wrong because instead of executing the stub code that outputs my message (which would allow me to later fill in with the actual code to implement the action) it returns "You can't do that." which means that somewhere along the way it either is not seeing the methods I put in, it is not invoking them, or there is something else involved that I'm not seeing that also needs to be done.

Since it works in one context in theory it should work for the same context if implemented the same way but it doesn't. So either There's something I'm not seeing or I'm not doing the same thing.

I think what I will do is, since I'm banned from posting everywhere but here and the Troll room for the remainder of the time, to set up some scaffold code for fictitious words that are not implemented by copying ones straight out of either the library or some TADS3 games and see if I am doing them correctly. Then if XA KITCHEN , XA TV or XE TV, XE BREAKER works, then I know I was implementing THROW KITCHEN WRONG. But if that also fails then I'll know I don't understand the system.

Either that or maybe I'll just see what verbs TADS has built-in support for that Hugo doesn't and rewrite either the system libraries or Roodylib to add them.

I'm just really not seeing a whole lot of benefit to TADS over Hugo at this point and I thought it might be worth trying but every time I turn around it's like I have to fight the TADS system to accomplish what I want to do.

I'm starting to understand what Jonsey was complaining about.

by Tdarcos » Sun Dec 11, 2016 10:51 am

Sorry, forgot

Code: Select all

class breaker: Fixture
    is_breaker = 1
    location = fusebox
    tripped = nil               // user has not tripped this
    on = 1                      // thisd breaker is not off
    target = nil                // room or device it controls

    dobjFor(Throw)
    {
        verify() { }
        action() { "Throw - D Action"; }
    }
   
    iobjFor(Throw)
    {
        verify() { }
        action() { "Throw - I Action"; }
    }
   
   
;    

by Tdarcos » Sun Dec 11, 2016 10:47 am

pinback wrote:Post a code snippet that isn't working that you think should be working. I have never used TADS, and I guarantee you I will be able to point out what you're doing wrong, and where the manual explains what you're doing wrong, within 15 minutes.
Not everything is in the same place in the manuals and some things are not completely clear. It's funny, when I downloaded the PDF reference manual for the MySQL datanase, and opened it, I almost swallowed my tongue to see it is a whopping 5,000+ pages. I thought that was overkill. Now I realize some things can require a lot more documentation to be comprehensive.

Here's the snippet.

Code: Select all

VerbRule(XThrow)
    'throw' singleDobj
    : XThrowAction
    verbPhrase = 'throw item'
;

VerbRule(Trip)
    'trip' singleDobj
    : XThrowAction
    verbPhrase = 'throw/trip item'
;


DefineTAction(XThrow)
    execAction()
    {
        "Xthrow exc action";
    }
;

fusebox: Fixture 'fuse meter breaker fusebox meterbox breakerbox box' 'breaker box'
    "It's a standard electrical breaker box."
    location = Meter_Room
;    
+breaker_kitchen: breaker  'breaker kitchen' 'kitchen breaker'
    target = Kitchen
        dobjFor(Throw)
    {
        verify() { }
        action() { "Throw - D Action"; }
    }
   
    iobjFor(Throw)
    {
        verify() { }
        action() { "Throw - I Action"; }
    }
   
   
;


That should at least allow me to see that if I TRIP BREAKER KITCHEN (in the room where Kitchen breaker is defined) it should show me a message. I have to call it XThrow because THROW was defined and I'm redefining it and I'm not quite sure how to replace the original definitions.

by Flack » Fri Dec 09, 2016 7:03 am

Can we get an object or class added to TADS for signs that follow the player around?

by Ice Cream Jonsey » Thu Dec 08, 2016 10:08 pm

pinback wrote:
Tdarcos wrote:
RealNC wrote:RTFM.
I have. I did. And it doesn't fucking work! I put in a dummy routine on an object for a particular verb, so the action() initiator will show a message if that is executed and when I try something like "trip ac" (throw the breaker for the air conditioner in the meter room) I still get the "you can't do that" message. Apparently I'm doing something wrong and from what the books say and other objects where it does work, I'm doing something wrong and I can't figure out what it is. And it's frustrating.
Post a code snippet that isn't working that you think should be working. I have never used TADS, and I guarantee you I will be able to point out what you're doing wrong, and where the manual explains what you're doing wrong, within 15 minutes.
If Pinner can't, I will put a $100 donation to the Blue Cross / Blue Shield in your name, Paul. That's how confident I am.

by pinback » Wed Dec 07, 2016 7:35 am

Tdarcos wrote:
RealNC wrote:RTFM.
I have. I did. And it doesn't fucking work! I put in a dummy routine on an object for a particular verb, so the action() initiator will show a message if that is executed and when I try something like "trip ac" (throw the breaker for the air conditioner in the meter room) I still get the "you can't do that" message. Apparently I'm doing something wrong and from what the books say and other objects where it does work, I'm doing something wrong and I can't figure out what it is. And it's frustrating.
Post a code snippet that isn't working that you think should be working. I have never used TADS, and I guarantee you I will be able to point out what you're doing wrong, and where the manual explains what you're doing wrong, within 15 minutes.

by RealNC » Wed Dec 07, 2016 12:05 am

Yes, you are correct. It's broken. It doesn't work as intended. Nobody noticed this before, weird.

Well, either that, or you didn't really RTFM.

by Tdarcos » Tue Dec 06, 2016 4:55 am

RealNC wrote:RTFM.
I have. I did. And it doesn't fucking work! I put in a dummy routine on an object for a particular verb, so the action() initiator will show a message if that is executed and when I try something like "trip ac" (throw the breaker for the air conditioner in the meter room) I still get the "you can't do that" message. Apparently I'm doing something wrong and from what the books say and other objects where it does work, I'm doing something wrong and I can't figure out what it is. And it's frustrating.

by RealNC » Sun Dec 04, 2016 7:54 pm

RTFM.

by Roody_Yogurt » Sun Dec 04, 2016 7:46 pm

TADS needs you, Commander!

by Tdarcos » Sun Dec 04, 2016 7:37 pm

I'll have to look at Adv3lite later, it's something like several hundred files and 3 megabytes in size.

But I'm getting to the point that I am getting disgusted with TADS because of the shitty restrictions it imposes on writing a game.

If someone types in UNPLUG TOILET and the implementer included a dobjFor(Unplug) method in the toilet object, then run the fucking method! If I put a handler in an object presumably I want to handle that verb used on that object, and goddammit let me do so!

Apparently I can't do this for some classes, it does not allow me to just handle the verb for that item, instead of just presuming that if I have a non-nil verb dobjFor/iobjFor method and a check(), verify() or action() then let me do whatever I specified.

The more I see of TADS the more I realize how better Hugo is for implementing a story. This system has a really good IDE but the goddamn compiler and libraries make you have to fight them to accomplish anything. All I want to do is use some commands on some objects, let the RTL handle the simple things, but goddammit when I want to be able to do something just let me!

Why is it that if I define a handler for a particular verb in the object the system refuses to accept it? I sometimes have to jump through hoops to get the system to allow me to get my story to work. I shouldn't have to keep writing overrides for the verbs I want to use, if I put a routine in the object for that verb, the verb's processor should just let the object do it.

by RealNC » Sat Dec 03, 2016 12:11 am

TADS is vastly different to Hugo. Most things don't just convert over from Hugo, and if you try to use TADS that way, you will most likely end up doing it wrong.

Also, it might be a good idea to not use adv3 (the standard library), which is huge and has a very complex class hierarchy. You might want to try "adv3lite" instead:

http://users.ox.ac.uk/~manc0049/TADSGuide/adv3Lite.htm

by Tdarcos » Fri Dec 02, 2016 11:11 pm

RealNC wrote:I would recommend one of the books (or several of them) from here:

http://www.tads.org/t3doc/doc/index.htm
That's the TADS bookshelf and it comes included in the download with the SDK and are accessible via the HELP menu in the IDE ("TADS Workbench"). In fact, I use these documents in the library all the time to figure out how to do things or how to convert the specifications and code from Hugo to TADS.

In fact, the IDE that TADS 3 provides is something I wish I had had when I was using Hugo, it would have made it much easier to program in. I was seriously thinking of doing one and if I had this was the sort of thing I would have wanted to have.

It's slick, polished and very useful. Especially the location-sensitive error messages. Click on the compile error in the log window and in almost every case it will go to the exact line where the error is located. The only time it can't is when two places create an identical reference that apparently can't be diagnosed until "linkage" time as opposed to compile time. Nonetheless it's a huge improvement in productivity and to do better you'd have to go to something representing overkill, like if they developed a plugin for Eclipse to edit TADS code, where it not only brought up your files and libraries, but partially processed the code so if you wanted to find where an object or verb was defined it would be in the object explorer.
For PLUG, you need to learn about direct and indirect objects in a command (when you plug something into something, you have two objects in play, the direct one (dobj) and the indirect one (iobj), and you need to know where to write the action handler depending on whether the object is the direct or indirect one (PLUG TV INTO WALL vs PLUG WALL INTO TV.)
Yeah, I know, the dobjFor(Verb) and iobjFor(Verb) methods attached to the object named as the direct object, depending on whether there is an indirect object, to handle the command defined as the identifier "verb". But I was doing something wrong because I could not get it to work.

Now this did:

Code: Select all

+ TV:  RestrictedSurface, PlugAttachable  'tv television set' 'television set'
    "34 Inch LCD HD-TV mounted on the wall. "
  
;   

++ cablebox: Thing, Attachable, PlugAttachable 'cable box' 'cable box'
    "Cable box connected to the TV"
    attachedObjects = [TV]    
    dobjFor(Take) { check() { failCheck('You can\'t take the \\self.name\\. 
        It is connected to the TV, and you lack the tools to disconnect it.'); }}    
;    
(In the above example \ replaces the symbols "<" and ">" because this BBS software doesn't like it when they show up in code examples. "Self.name" becomes "Self" if I leave the double greater than and less than symbols.)

When someone tries to TAKE the CABLE BOX they get that message instead of the standard one.
Also, you should read more about the Tads language, especially about the "modify" and "replace" keywords. You should never replace system files in Tads. If you want to modify or add something to them, you use "modify" or "replace".
Right, as I said, changing a system file is "ugly" and like violence, it should only be invoked as a last resort. When the language has the capacity to override things then, it is not their only resort and eliminates the need to do that.

Sounds like Modify and Replace are probably what I might use if I can't figure out how to do what I want to do.

I will note here that I decided to port Tripkey over to TADS in order to get my feet wet in a system where I knew what the program I was porting already did. I did not want to try this with something brand new. I made that mistake once with Open Office when I took a gig writing a manual for a software program and they wanted the document in DOC format, which Open Office supports (as opposed to a conversion from Word Perfect 8, which is what I've been using for about 20 years. I have never used Microsoft Word, so I'm not used to its idiosyncrasies and bugs, which Open Office tries to emulate.)

Whatever behavior TADS has WRT Tripkey, I'll know if it matches what happens in Hugo or if it acts in a different way. And thus I will learn how it works.

by Roody_Yogurt » Fri Dec 02, 2016 6:35 pm

That directory you mentioned is a mix of TADS 2 and TADS 3 games. Besides explicitly-marked TADS 3 games like EricGift.zip, Return to Ditch Day, and Fate.zip, I believe It (it_src.zip) also was TADS 3. There may be some others buried in there, too.

Top