Verb Problems

I’m having a bit of trouble with actions. I hate to ask another question so soon, but this should hold me over for awhile. I’m making a SleepOn action. I created the definition, the phrase, and modified thing. The game runs, but it just says it doesn’t understand the command.

All this code does absolutely nothing, lol. Did I spell something wrong, or get an error in the structure?

[code]DefineTAction(SleepOn);

VerbRule(SleepOn)
‘sleep on’ singleDobj
: SleepOnAction
verbPhrase = ‘sleep/sleepin (on)’
;

modify Thing
dobjFor(SleepOn)
{
verify()
{

        if(gActor.sleepBar >= 100)
        {
        
              if(gActor.aName() == 'you' || gActor.aName() == 'You')
            {
              
                illogical('<<gActor.name>> do{es}n\'t need rest.');
            
            }else{
               
                illogical('<<gActor.aName>> do{es}n\'t need rest.');
                
            }
         // end if sleepBar >= 100
        }
       // End Verify SleepOn 
    }
   // End dobjFor SleepOn 
 }

// End Modify Thing
;
[/code]

For the start it should be ‘sleep’ ‘on’ singleDobj and not ‘sleep on’ singleDobj, every word must be treated as a separate token, otherwise it won’t match in parser.

You should define the verb rule with ‘sleep’ ‘on’ (two tokens), not ‘sleep on’ (a single token containing whitespace).

As an aside, note that you may be able to get rid of the gActor().aName == ‘you’ condition using for both cases the syntax: illogical(’{The actor/he} do{es}n’t need rest.’);

Thanks Micheal. I coded a mammoth of structured sloppy butch code, so I’m not sure if doing that would be feesible. I would have to change a lot :frowning: I should have changed my isHe variable in my player actor, but instead created a gender variable. I also let the players choose a name for name variable I defined… Sorry for being sloppy.

I’m working on a daemon for my sleep, but it’s not working. Can you check this and tell me how I can turn it around?

I modified Thing

modify Thing
     dobjFor(SleepOn)
     {
       verify() 
       {
            
            if(gActor.sleepBar >= 100)
            {
            
                  if(gActor.aName() == 'you' || gActor.aName() == 'You')
                {
                  
                    illogical('<<gActor.name>> doesn\'t need rest.');
                
                }else{
                   
                    illogical('<<gActor.aName>> doesn\'t need rest.');
                    
                }
             // end if sleepBar >= 100
            }
           // End Verify SleepOn 
        }
       
       // End dobjFor SleepOn 
        
        
       action()
        {
     
            // make character asleep
            // make sleep posture
            // effect stats
            if(gDobj.sleepable)
            {
                // character gets good rest
                gActor.asleep = true;
                gActor.makePosture(sleepingPosture); 
                 if(gActor.aName.toLower == 'you')
                    {
                    
                        "<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
                        // have sleep bar go up by 3 every second (takes roughly 30 seconds)
                           daemonID = new RealTimeDaemon(gActor, &gActor.sleep_handler(), 30000);
                           sleepOver = nil;
                        
                        do{
                        
                            if(gActor.sleepBar == gActor.maxSleep || !gActor.asleep)
                            {
                                //  Wake up the characters
                            
                                // end the sleep daemon
                                daemonID = nil;
                                daemonID.removeEvent();
                                // finished sleeping
                                
                            }
                        
                        }while(daemonID)
                        // have hp gp up by 
                    
                    }else{
                    
                        "<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
                    
                    }
               
            }else if(gDobj.name.toLower == 'floor')
            {
                // character gets slower rest
                
            }else{
                // can't sleep on item
            
                    if(gActor.aName.toLower == 'you')
                    {
                    
                        "<<me.name>> doesn't want to sleep on that.";
                    
                    }else{
                    
                    "<<gDobj.aName>> doesn't want to sleep on that.";
                    
                    }
            }
            
 
      // end sleep on execAction           
    } 
        
        
     }
// End Modify Thing
;

This line throws an error saying I’m not pointing to a function.

  daemonID = new RealTimeDaemon(gActor, &gActor.sleep_handler(), 30000);

The function is in my player actor.

sleep_handler()
    {
        
    }

Not filled out yet though.

Indeed, I think you should write

daemonID = new RealTimeDaemon(gActor, &sleep_handler, 30000)

instead of

daemonID = new RealTimeDaemon(gActor, &gActor.sleep_handler(), 30000)

Great, almost working, but there is an error in my code structure. It will only work if I remove this whole chunk.

 do{
                        
                            
                            if(gActor.sleepBar == gActor.maxSleep || !gActor.asleep)
                            {
                                //  Wake up the characters
                            
                                // end the sleep daemon
                                daemonID = nil;
                                daemonID.removeEvent();
                                // finished sleeping
                                
                            }
                        
                        }while (daemonID)

It seems to be the loop itself, and not the content in the loop, as it still wont run with the center code removed.

Thanks for all the help guys :slight_smile:

Wait, sorry for double posting. I removed the loop because I want to make the daemon more realtime, with a wake command. My sleep_handler function doesn’t get called though.

Modified thing

action()
        {
        
           
            // make character asleep
            // make sleep posture
            // effect stats
            if(gDobj.sleepable)
            {
                // character gets good rest
                gActor.asleep = true;
                gActor.makePosture(sleepingPosture);
                sleepID = new RealTimeDaemon(gActor, &sleep_handler, 30000);
                 if(gActor.aName.toLower == 'you')
                    {
                    
                        "<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
                        // have sleep bar go up by 3 every second (takes roughly 30 seconds)
                        
                    }else{
                    
                        "<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
                    
                    }
               
            }else if(gDobj.name.toLower == 'floor')
            {
                // character gets slower rest
                
            }else{
                // can't sleep on item
            
                    if(gActor.aName.toLower == 'you')
                    {
                    
                        "<<me.name>> doesn't want to sleep on that.";
                    
                    }else{
                    
                    "<<gDobj.aName>> doesn't want to sleep on that.";
                    
                    }
            }
            
 
      // end sleep on execAction           
    } 

sleep handler on actor character

sleep_handler()
    {
        "sleeping";
           
    }

I should see “sleeping” every 3 seconds?

Does the daemon callback function have to be on the same object the action is on?

Ug, no go. I’ll post full code.

  heroesBed: Immovable, Sleepable
    vocabWords = 'bed cot matress'
    name = 'bed'
    location = startRoom
    sleepable = true
    desc = "<<if !me.nameEndS>><<me.name>>'s<<else>><<me.name>>'<<end>> bed looks pretty cozy. The large matress
        is covered by a fluffy blue blanket."    
    
;

class Sleepable : Thing
    isSleepable = true
     // sleep handler
    
    sleep_handler()
    {
        "sleeping";
           
    }
     dobjFor(SleepOn)
     {
       verify() 
       {
            
            if(gActor.sleepBar >= 100)
            {
            
                  if(gActor.aName() == 'you' || gActor.aName() == 'You')
                {
                  
                    illogical('<<gActor.name>> doesn\'t need rest.');
                
                }else{
                   
                    illogical('<<gActor.aName>> doesn\'t need rest.');
                    
                }
             // end if sleepBar >= 100
            }
           // End Verify SleepOn 
        }
       
       // End dobjFor SleepOn 
        
        
       action()
        {
        
           
            // make character asleep
            // make sleep posture
            // effect stats
            if(gDobj.isSleepable)
            {
                // character gets good rest
                gActor.asleep = true;
                gActor.makePosture(sleepingPosture);
                daemonID = new RealTimeDaemon(self, &sleep_handler, 30000);
                 if(gActor.aName.toLower == 'you')
                    {
                    
                        "<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
                        // have sleep bar go up by 3 every second (takes roughly 30 seconds)
                        
                    }else{
                    
                        "<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
                    
                    }
               
            }else if(gDobj.name.toLower == 'floor')
            {
                // character gets slower rest
                
            }else{
                // can't sleep on item
            
                    if(gActor.aName.toLower == 'you')
                    {
                    
                        "<<me.name>> doesn't want to sleep on that.";
                    
                    }else{
                    
                    "<<gDobj.aName>> doesn't want to sleep on that.";
                    
                    }
            }
            
 
      // end sleep on execAction           
    } 
        
        
     }
    
;

///
//Postures
////

sleepingPosture: Posture
   tryMakingPosture(loc) { return tryImplicitAction(LyeOn, loc); }
   setActorToPosture(actor, loc) { nestedActorAction(actor, LyeOn, loc); }
   msgVerbIPresent = 'sleep{s} on'
   msgVerbIPast = 'slept on'
   msgVerbTPresent = 'sleeps{s}'
   msgVerbTPast = 'slept'
   participle = 'sleeping'
;

////
//Actions and Verbs
////

modify SleepAction
    execAction()
    {
       
        // The sleep action will increase health a little slower than the sleep on action
        "Try sleeping on something.";
        
    }
;


DefineTAction(SleepOn);

VerbRule(SleepOn)
    'sleep' 'on' singleDobj
    : SleepOnAction
   verbPhrase = 'sleep/sleeping (on)'
;

I tried the last version of your code by copying it nearly as-is (just replacing the condition gActor.sleepBar >= 100 with nil) in a starter game, and it worked. But I see the daemon message every 30 seconds, not every 3 seconds, because the third argument to RealTimeDaemon is 30 000. Could the longer duration be why it appeared not to work?

You should also declare daemonID somewhere, but ideally not on class, but somewhere global, on player character or such to have only one instance and before creating a new daemon check that it is not running already. Or you risk more daemons at once or losing inaccessible daemon when garbage collector runs.

Oh my, didn’t see the type error for milliseconds. I also set the daemon to me.sleepDaemon, so it can be accessed from there.

Thanks guys.

I’m having some new troubles. I’m trying make the Sleepable class a little more advanced by adding isHard. The problem is is I need to access gDobj in the sleep_handler function. I tried passing it as an argument two different ways. One way game me a formal argument error, and the other is just saying that my set daemon function expects a comma after arguments (as if the parser can’t differentiate between an argument being passed to the handler and the arguments in the demon calling function.)

class Sleepable : Thing
    isSleepable = true
    isHard = nil
    hardWord = ''
     // sleep handler
    sleep_handler(bed)
    {
          
            if(gActor.sleepBar <= 100)
            {
               
                 gActor.sleepBar +=  10;
                
            }
        
          if(!bed.isHard)
            {
                if(gActor.sleepBar > 100)
                {
            
                        gActor.sleepBar = 100;
                        // wake the gActor
                        // set posture to laying
                        // cancel sleep daemon
                    
                        gActor.asleep = true;
                        gActor.makePosture(lying);
                        me.sleepDaemon.removeEvent;
                        
                    "<<one of>><<gActor.name>> wakes, after a good rest. <<me.return_pronoun('he/she', me.gender ,'u')>>
                      feels much better now.<<or>>After a good rest, <<me.name>> feels much better.";
                }   
                // !isHard in sleep handler
           }else{
                    // isHard in sleep handler
                    if(gActor.sleepBar >= 60)
                    {
            
                        gActor.sleepBar = 60;
                        // wake the gActor
                        // set posture to laying
                        // cancel sleep daemon
                    
                        gActor.asleep = true;
                        gActor.makePosture(lying);
                        me.sleepDaemon.removeEvent;
                        
                    "<<one of>><<gActor.name>> wakes resltessly, feeling under rested. <<me.return_pronoun('he/she', me.gender ,'u')>>
                      After waking <<gActor.name>> wakes, still feeling tired.";
                }  
                    
                    // end isHard in sleep handler
            }
        
        "Zzz";
        "/t <em>sleep +10</em>";
           
    }
     dobjFor(SleepOn)
     {
       verify() 
       {
            
            if(gActor.sleepBar >= 100)
            {
            
                  if(gActor.aName() == 'you' || gActor.aName() == 'You')
                {
                  
                    illogical('<<gActor.name>> doesn\'t need rest.');
                
                }else{
                   
                    illogical('<<gActor.aName>> doesn\'t need rest.');
                    
                }
             // end if sleepBar >= 100
            }
           // End Verify SleepOn 
        }
       
       // End dobjFor SleepOn 
        
        
       action()
        {
        
        
            
            if(gDobj.isSleepable)
            {
                
                if(!gDobj.isHard)
                {       
                    // character gets good rest
                    gActor.asleep = true;
                    gActor.makePosture(sleepingPosture);
                    me.sleepDaemon = new RealTimeDaemon(self, &sleep_handler(gDobj), 3000);
                     if(gActor.aName.toLower == 'you')
                        {
                        
                            "<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
                            // have sleep bar go up by 3 every second (takes roughly 30 seconds)
                            
                        }else{
                        
                            "<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
                        
                        }
                    // End if Sleepable not hard
                }else{
                        // Character gets bad rest
                    gActor.asleep = true;
                    gActor.makePosture(sleepingPosture);
                    me.sleepDaemon = new RealTimeDaemon(self, &sleep_handler(gDobj), 10000);
                     if(gActor.aName.toLower == 'you')
                        {
                        
                            "<<me.name>> plunks down on the <<gDobj.hardWord>> <<gDobj.name>> and falls asleep.";
                            // have sleep bar go up by 3 every second (takes roughly 30 seconds)
                            
                        }else{
                        
                            "<<gDobj.aName>> lays on the <<gDobj.hardWord>> <<gDobj.name>> and sleeps.";
                        
                        }
                    
                    // end if Sleeple is hard
                }
            }else if(gDobj.name.toLower == 'floor')
            {
                // character gets slower rest
                
            }else{
                // can't sleep on item
            
                    if(gActor.aName.toLower == 'you')
                    {
                    
                        "<<me.name>> doesn't want to sleep on that.";
                    
                    }else{
                    
                    "<<gDobj.aName>> doesn't want to sleep on that.";
                    
                    }
            }
            
 
      // end sleep on execAction           
    } 
        
        
     }
    
;

There is no way to pass an argument in new RealTimeDaemon(self, &sleep_handler, 3000) statement, because you are not calling the handler here. You are calling RealTimeDaemon constructor and passing a reference to sleep_handler function. Sleep_handler is so called “callback function” which is called by the daemon on an occasion and not by you. And the daemon is not willing to pass any arguments.

But you can overcome this limitation in other way. For example similar as you set gActor.asleep = true; create an additional property on actor and try to gActor.sleepingOn = gDobj or me.sleepingOn = gDobj. Then you can read these properties from the callback.

Also you shouldn’t depend on gActor in the callback. gActor is a macro expanding to actor of currently processed action and it is not necessary defined once the action processing ends or even can change on subsequent commands from the player as the RealTimeDaemon wakes up on some real time occasions. When you are in action() phase copy gActor value somewhere and use this copy from callback.

I solved by referencing self, because the sleep_handler is on the Sleepable class. Is this a bad idea?

If it works then it’s probably fine. I’m just not sure whatever there are more actors that could sleep in your game or just the player and if so whatever more then one actor can sleep at any given time. Class properties are copied for every object of that class, so every Sleepable object has the property isHard, which is what you want, but it would be more logical to locate daemon property to player object.

Also I’ve noticed you are referring gDobj in action() of Sleepable: if(gDobj.isSleepable) and if(!gDobj.isHard) which is unnecessary, you are on Sleepable object so you don’t need isSleepable test and you can shorten second test to only if(!isHard). Also gActor.aName.toLower == ‘you’ could be shortened to gActor == me, if(gDobj.name.toLower == ‘floor’) to if(gDobj.ofKind(Floor)).

Okay, I fixed some of the errors you suggested. I’m interested in having multiple characters be able to sleep, even if in a different game. I’ve got sleep_handler on Sleepable, and store the sleepDaemon on the player. Tell me if this looks alright so far, or am I in the right ball park?

class Sleepable : Thing
    isSleepable = true
    isHard = nil
    hardWord = ''
     // sleep handler
    sleep_handler()
    {
          
            if(gActor.sleepBar <= 100)
            {
               
                 gActor.sleepBar +=  10;
                
            }
        
           if(gActor == me)
            {
            
                "Zzz \n";
                "\t <em>sleep +10</em>\n";
            
            }else{
            
                if(gActor.reportSleep)
                {
                
                    "Zzz \n";
                    "\t <em>sleep +10</em>\n";
                
                }
            
            }
        
            gActor.wakeIssued = true;
        
          if(!self.isHard)
            {
                if(gActor.sleepBar > 100)
                {
            
                        gActor.sleepBar = 100;
                        // wake the gActor
                        // set posture to laying
                        // cancel sleep daemon
                    
                        gActor.asleep = nil;
                        gActor.makePosture(lying);
                        gActor.sleepDaemon.removeEvent;
                       
                        
                    "\b<<one of>><<gActor.name>> wakes, after a good rest. <<me.return_pronoun('he/she', me.gender ,'u')>>
                      feels much better now.<<or>>After a good rest, <<me.name>> feels much better.<<end>>";
                }   
                // !isHard in sleep handler
           }else{
                    // isHard in sleep handler
                    if(gActor.sleepBar >= 60)
                    {
            
                        gActor.sleepBar = 60;
                        // wake the gActor
                        // set posture to laying
                        // cancel sleep daemon
                    
                        gActor.asleep = nil;
                        gActor.makePosture(lying);
                        gActor.sleepDaemon.removeEvent;
                        
                    "\b<<one of>><<gActor.name>> wakes resltessly, feeling under rested. <<me.return_pronoun('he/she', me.gender ,'u')>>
                      After waking <<gActor.name>> wakes, still feeling tired.<<end>>";
                }  
                    
                    // end isHard in sleep handler
            }
        // end sleep handler   
    }
     dobjFor(SleepOn)
     {
       verify() 
       {
            
            if(gActor.sleepBar >= 100)
            {
            
                  if(gActor == me)
                {
                  
                    illogical('<<gActor.name>> doesn\'t need rest.');
                
                }else{
                   
                    illogical('<<gActor.aName>> doesn\'t need rest.');
                    
                }
             // end if sleepBar >= 100
            }
           // End Verify SleepOn 
        }
       
       // End dobjFor SleepOn 
        
        
       action()
        {
        
        
            
            if(gDobj.isSleepable)
            {
                
                if(!gDobj.isHard)
                {       
                    // character gets good rest
                    gActor.asleep = true;
                    gActor.makePosture(sleepingPosture);
                    gActor.sleepDaemon = new RealTimeDaemon(self, &sleep_handler, 3000);
                     if(gActor == me)
                        {
                        
                            "<<me.name>> plunks down on the <<gDobj.name>> and falls asleep.";
                            // have sleep bar go up by 3 every second (takes roughly 30 seconds)
                            
                        }else{
                        
                            "<<gDobj.aName>> lays on the <<gDobj.name>> and sleeps.";
                        
                        }
                    // End if Sleepable not hard
                }else{
                        // Character gets bad rest
                    gActor.asleep = true;
                    gActor.makePosture(sleepingPosture);
                    gActor.sleepDaemon = new RealTimeDaemon(self, &sleep_handler, 10000);
                     if(gActor == me)
                        {
                        
                            "<<me.name>> plunks down on the <<gDobj.hardWord>> <<gDobj.name>> and falls asleep.";
                            // have sleep bar go up by 3 every second (takes roughly 30 seconds)
                            
                        }else{
                        
                            "<<gDobj.aName>> lays on the <<gDobj.hardWord>> <<gDobj.name>> and sleeps.";
                        
                        }
                    
                    // end if Sleeple is hard
                }
            }else if(gDobj.ofKind(Floor))
            {
                // character gets slower rest
                
            }else{
                // can't sleep on item
            
                    if(gActor == me)
                    {
                    
                        "<<me.name>> doesn't want to sleep on that.";
                    
                    }else{
                    
                    "<<gDobj.aName>> doesn't want to sleep on that.";
                    
                    }
            }
            
 
      // end sleep on execAction           
    } 
        
        // end dobjFor SleepOne
     }
 
    
;