Sleeping

I would like to implement a sleeping action that causes everything in the world to continue doing things while the player sleeps, and so time moves as normal until the player wakes up 5 to 9 hours later (determined randomly; after all, you can’t control how long you sleep).

The problem is that if you are asleep during midnight, you become trapped in endless sleep and have to stop the game.

[code]“Sleep…but Not at Midnight”

The block sleeping rule is not listed in the check sleeping rulebook.

When play begins:
now the right hand status line is “[time of day]”.

Carry out sleeping (this is the standard sleeping rule):
let n be a random number between 360 and 480;
let x be a random number between -60 and 60;
let n be n plus x;
let t be the time of day;
increase t by n minutes;
say “You fall asleep…”;
while the time of day is not t:
follow the turn sequence rules.

Report sleeping (this is the standard report sleeping rule):
say “…and you wake up feeling refreshed.”

The Bedroom is a room.[/code]

I’m sure someone must have done what I want before, so what’s the solution?

I don’t think is really true; many if not most people can control how long they sleep within an hour or two. And most people sleep a fairly consistent length of time, all else being equal; if every time I went to sleep I didn’t know whether it’d be for nine hours or five…

I think you have generally the right idea here, but the code as you have it:

will go horribly wrong, because the while loop is in the wrong place; it’ll advance the time to the time the player wakes up, then run through most of the rest of the day (waking up 24 hours after the player went to sleep!) You need something more like

let n be a random number between 360 and 480;
   let x be a random number between -60 and 60;
   let n be n plus x;
say "You fall asleep...";
   while n > 0:
      now n is n - 1;
      follow the turn sequence rules.

Some considerations:

  • This will not suppress any messages that are printed by the every turn rules. If you have any of those you’ll need to do something about that (probably with a value like ‘if the player is asleep’) or the player will get barraged with a screenful of every turn messages.
  • If you have a lot of every turn rules, running through this many turns at once has the potential to really slow Inform down. Be careful.
  • If you want to interrupt sleep for whatever reason, add another condition to that ‘while’.

Huh, I’m not really sure I understand why that worked, but it did. Thank you, Maga.

I intend to make an “interrupted” state, so that the player will wake up if anything sets him or her to being interrupted. The only problem I can foresee is having to make a lot of things say “now the player is interrupted”. Here’s the new working example:

[code]“Sleep at Last…or Not”

The block sleeping rule is not listed in the check sleeping rulebook.

A person is either awake or asleep. A person is usually awake.

When play begins:
now the right hand status line is “[time of day]”.

Carry out sleeping (this is the standard sleeping rule):
let n be a random number between 360 and 480;
let x be a random number between -60 and 60;
let n be n plus x;
now the player is asleep;
say “You fall asleep…”;
while n is greater than 0:
if the player is interrupted:
now the player is awake;
stop the action;
otherwise:
now n is n minus 1;
follow the turn sequence rules;
now the player is awake.

Report sleeping (this is the standard report sleeping rule):
if the player is not interrupted:
say “…and you wake up feeling refreshed.”

Instead of doing anything while the player is asleep:
say “You are asleep. You can’t do anything.”

The Bedroom is a room.

A person can be interrupted. A person is usually not interrupted.

Every turn:
now the player is not interrupted.

Every turn:
if a random chance of 1 in 30 succeeds:
now the player is interrupted;
if the player is asleep:
say “Wake up! Wake up!”;
otherwise:
say “Wa…oh, you’re awake.”[/code]

You probably want to change that ‘Every turn’ rule to something like ‘Every turn when the player is asleep’. Having it go off randomly while the player’s awake would be pretty annoying.

(Also, I’m assuming that 1 in 30 chance is just an off-hand example; if you did that, there’d be an 87% chance that the player would wake up in the first hour, rising to a near-certainty after three hours.)

Right, that was just for an example. While I’m here, though, I’ve come to a different problem.

In the same game that I’ve implemented sleeping, I use scenes to govern the general time of day, a la the “Night and Day” example. In that example, it works fine, but even with Maga’s solution to my midnight problem, the current scene gets stuck at midnight. Just add the following code to “Night and Day” and wait fifteen times and you’ll see what I mean.

[code]The time of day is 11:50 PM.

When play begins:
now the left hand status line is “[if Night is happening]Night[otherwise if Dawn is happening]Dawn[otherwise if Day is happening]Day[otherwise if Dusk is happening]Dusk[end if]”;
now the right hand status line is “[time of day]”.

Test glitch with “z / z / z / z / z / z / z / z / z / z / z / z / z”.[/code]

Unless I’m missing something, this looks as though it might potentially represent a bug in I7 with scene firing if scenes are tied to turns since. (Very few games care much about the time of day as I7 represents it, few games are big enough to require the 840 turns it’d normally take for this issue to manifest, and not everybody uses scenes, so it’s the sort of bug that might not have become obvious.)

In the meantime, there are plenty of ways you could replace the ‘when the time since’ formulation; you could have a counter that increments every turn while a scene is running, and change scenes and reset it whenever it reaches a certain value. Or you could tie it to the turn count variable (although that might mess you up if you ever wanted to change the time of day artificially.)

Here’s how to do the turn-counter method:

Scene-count is a number that varies. Scene-count is 0.

Every turn: now scene-count is scene-count + 1.

Night ends when scene-count is 3.

When Night begins:
now scene-count is 0;

and then adjust the code for the other scenes accordingly, removing the original ‘Night ends’ statement.

Once again, works perfectly. Thank you so much for you help!