NPC Following Player

It seems that I’m having trouble making an NPC follow the character. It just won’t run the loop (I-MARVIN), no matter what. I’m not exactly sure why.

For context, here is the code:

<GLOBAL PLUG-POINT <>>
<GLOBAL MARVIN-TIMES-FOLLOW 0>
<GLOBAL LIFE-PAIN 0>

<OBJECT MARVIN
	(IN LOCAL-GLOBALS)
	(DESC "Marvin")
	(LDESC "Marvin, the Paranoid Android, is sulking.")
	(SYNONYM MARVIN MARV ROBOT ANDROID)
	(ADJECTIVE DEPRESSED SAD PARANOID MARVIN SULKING)
	(FLAGS NARTICLEBIT PERSONBIT)
	(ACTION MARVIN-F)>

<ROUTINE MARVIN-F ()
	<COND (<NOT ,PLUG-POINT>
		<I-MARVIN>)>
	<COND (<EQUAL? ,MARVIN ,WINNER>
		<COND (<AND <VERB? ASK-ABOUT TELL-ABOUT>
					<PRSI? ,OBJECT-OF-GAME>>
				<TELL "\"What's the point? Ugh. Life,\" he says,
\"don't talk to me about life!\"">)
			(<VERB? HELLO>
		       <SETG WINNER ,PLAYER>
		       <PERFORM ,V?HELLO ,MARVIN>
		       <SETG WINNER ,MARVIN>
		       <RTRUE>)
			(<AND <VERB? ASK-ABOUT TELL-ABOUT>
					<PRSI? ,LIFE>>
				<COND (<EQUAL? ,LIFE-PAIN 0>
					<TELL "Marvin eyes you morosely, then goes on a
long tangent about life. You listen painfully, and when he is done,
your ears are stinging and your brain feels like it could implode." CR>
					<INCREMENT-SCORE -20>
					<SET LIFE-PAIN <+ ,LIFE-PAIN 1>>)
				(ELSE 
					<TELL "You are NOT doing that again. Not even
funny. You decide to insult Marvin instead, who shrugs at your
comment." CR>)>)>)>>

<ROUTINE I-MARVIN ()
	; "I literally added this in just to test that it will run. It doesn't."
	<TELL "THIS IS A TEST" CR CR CR>
	<COND (<NOT <IN? ,MARVIN ,HERE>>
		;<COND (<NOT <G? ,MARVIN-TIMES-FOLLOW 5>>)>
		<TELL "Marvin follows you.">
		;<SETG MARVIN-TIMES-FOLLOW <+ ,MARVIN-TIMES-FOLLOW 1>>)>
		<MOVE ,MARVIN ,HERE>>

By the way, you have a radio here (this is me working on the unfinished Milliways sequel) and a plant, and once you plug the plant into the radio, you set PLUG-POINT to true, and Marvin begins to follow you.

2 Likes

Does anyone know how to fix it so that Marvin will follow you?

1 Like

I’m far from an expert in ZIL—you probably have more experience than me—but my impression is that the standard way to use an “interrupt” (I-) routine is to queue it.

<ENABLE <QUEUE I-MARVIN -1>>

Now the clocker will call it every turn. Putting it in an object’s ACTION property, to my understanding, will only run it when an action directly involves that object as WINNER, PRSI, or PRSO.

I normally wouldn’t offer ZIL advice without being more sure of it, but it doesn’t seem like anyone better-experienced is volunteering.

3 Likes

Oh, wow, yeah. The documentation is quite limited, so I don’t think it was in there. I’ll try it out on my code to see if it works.

1 Like

It doesn’t seem to work, I’m not sure why.

It’s possible ZILF’s library handles NPC interrupt routines differently from Infocom’s; the latter is what I’m more familiar with.

1 Like

How could I fix that?

It’ll depend how ZILF’s library handles it, which I don’t really have any experience with. That’ll have to wait for someone with more ZILF experience.

1 Like

Where did you add that line to ENABLE the interrupt routine?

2 Likes

Oh, sorry, I already fixed it. It turns out that I hadn’t had an ENABLE/DISABLE function from the start, so I could just use QUEUE/DEQUEUE instead. But on another question, would you have any idea why sometimes when going UP/DOWN & IN/OUT, you are sent to darkness for no reason or into an object which is in that room? I don’t think you’ll know but it was worth trying.

My first guess would be that something is wrong in the room definition and UP is connected to an object that isn’t a room. Remember that rooms only are objects with different set of attributes and properties. When compiled the direction only points to a numbet in the object list. This isn’t specifict to ZIL, it is how the z-machine works.

The second guess is that something is broken in the library code. Infocom often (always?) used an older game as template for a new game and stripped out all game specific code from the older game and modified it for the new. Milliways was so early in development so I guess they could have introduced errors in the movement code.

(If you post some of the code and the definition of a room with an faulty exit it might be easier to pinpoint the problem.)

2 Likes

I have just realized the bigger, really weird part of the problem. The most recent room made ( or something ) is the room that you automatically move to, no idea why. Here are some files:
h2.z5 (54.8 KB)
magrathea.zil (22.6 KB)
mouse.zil (1.3 KB)
You can see what’s happening once you go down into the crater without dying. This is weirder than, I dunno, than I could imagine.

When you go down (or east) from the ledge you do it by a routine, DOWN-TO-CRATER.

<ROUTINE DOWN-TO-CRATER ()
	<TELL "You hop over the teeth and scramble down to the crater floor. ">
	<COND (,PLUG-POINT
		<MOVE ,MARVIN ,WHALE-CRATER>
		<TELL "Marvin climbs down slowly, after you." CR>)>
	<SETG GONE-DOWN T>
	;<FSET ,MARVIN ,ONBIT>
	<STOVE ,WHALE-CRATER>
	<COND (,PLUG-POINT
		<CRLF>)
	(ELSE
		<JIGS-UP "Unfortunately, you don't get to do much after that, because...">)>>

This routine is expected to return the room the exit leads to or <RFALSE> if the player are unable to move in that direction (usually after printing an appropriate message). See for example the GRATING-EXIT from Zork 1:

<ROUTINE GRATING-EXIT ()
	 <COND (,GRATE-REVEALED
		<COND (<FSET? ,GRATE ,OPENBIT>
		       ,GRATING-ROOM)
		      (T
		       <TELL "The grating is closed!" CR>
		       <THIS-IS-IT ,GRATE>
		       <RFALSE>)>)
	       (T <TELL "You can't go that way." CR> <RFALSE>)>>

In this example you move Marvin to the WHALE-CRATER and then prints <CRLF> and then return from the routine with the value from the <CRLF>, which is T (value 1). Object 1 is always the last added.object. To fix this, just add he room after <CRLF>.so the correct object number is returned.

<ROUTINE DOWN-TO-CRATER ()
	<TELL "You hop over the teeth and scramble down to the crater floor. ">
	<COND (,PLUG-POINT
		<MOVE ,MARVIN ,WHALE-CRATER>
		<TELL "Marvin climbs down slowly, after you." CR>)>
	<SETG GONE-DOWN T>
	;<FSET ,MARVIN ,ONBIT>
	<STOVE ,WHALE-CRATER>
	<COND (,PLUG-POINT
		<CRLF>
		,WHALE-CRATER)
	(ELSE
		<JIGS-UP "Unfortunately, you don't get to do much after that, because...">)>>
3 Likes

Oh my god, thank you! I wish there was a thing which allowed you to give awards, like in Reddit. You’d be getting one right now. Where is the solution button?

1 Like