第11行：我们希望玩家能够“将（对象）设置为（数字）”。这包括在扩展的verbset中，所以我们’LL只是添加该选项。我们也得到了一堆其他漂亮的动词。如果文件规模是我们的重大关注，我们可以定义动词‘set’ by hand, but it’s not.
第12行：除了用数字播放器型号，我们可以允许它们为少量使用单词，因此玩家可以键入“set timer to five”.
第13行：我们决定我们不’t need a scoring system for this game. Defining
NO_SCORE drops the verbs and actions for showing the score, as well as the messages telling the player the score has gone up or down etc.
进入点例程, extensions and grammar
定义所有库常量后，它’是时候包括全局。在此之后，我们创建了自己的全局变量。 PunyInform程序可以定义最多约150个全局变量。这可以很有用来跟踪游戏中发生的事情等。我们为此特定变量提供了名称“f_” to mark that it’s a flag –只能具有值true（1）或false（0）的东西。当游戏开始时，玩家还没有为莫里斯夫人提供一顿饭，因此标志从价值为false开始。
punyinform.支持一套“Entry point routines”（看看其中的哪些punyinform.手册和read up on what they do in the 设计师’s Manual). If you want to define any entry point routines, you need to do so before including puny.h. One of these routines is
If at any time we want to end the game, we set
deadflag to a value greater than 0. The value 1 (also referred to as
GS_DEAD) means the player died. The value 2 ( =
GS_WIN) means the player won. Values greater than 2 are used when we want to add our own ways of ending the game. If we use a value greater than 2, we must also add a
DeathMessage routine which checks the value of
deadflag和prints a message.
在第26行，我们包括一个调用的分机“ext_waittime.h”。这允许玩家键入类似的东西“wait for 10 minutes” or “wait until 9 pm”.
动词‘set’可以用两种方式使用：“set (object)” or “将（对象）设置为（数字）”. For our game, it’如果我们放弃表格，更好“set (object)”并添加另一种形式：“将（对象）设置为（数字） minutes”. When we want to remove some part of the grammar for a verb, we need to replace the entire grammar for that verb. This is what we do in line 28-30. Note the keyword
在第32-36行中，我们添加了表达的新方法“switch on (object)” and “switch off (object)”, namely “start (object)” and “stop (object)” respectively.
If the player tries to go north, we supply a routine to decide on the outcome of this action. If they have served Mrs. Morris her meal, we return
Street, which is of course a location. Otherwise, we print a message saying why the player can’去北方并返回真实。
笨蛋is a container which is always open. To give it a paragraph of its own in the room description, we give it the
when_open property. In this routine, we print that there’s a dumbwaiter here, and then we perform the action
##Search with the noun
self. We do this with the angle bracket notation on line 58. This means the game will print whatever it would normally print if the player had typed “搜索笨爪”，意味着它会说什么’s in the dumbwaiter.
Then we have a
before routine, to handle the player putting things in the dumbwaiter. As you already know from previous tutorials, a
before routine can react to the actions the player types. It can also react to actions performed in code, like
. Additionally, some actions issue “fake actions”。假行动是一种行动’T有一个动作例程，没有语法指向它。这些是PunyInform可以发布的虚假行为：
##Insertaction issues a
##Receivefake action to the object the player tries to put something in. While this fake action is happening,
receive_actionhas the value
##PutOnaction issues a
##Receivefake action to the object the player tries to put something on. While this fake action is happening,
receive_actionhas the value
##Takeaction issues a
##LetGofake action to the object the player tries to remove something from.
##ThrowAtaction issues a
##ThrownAtfake action to the object the player tries to throw something at.
##Goactions issues a
##Goingfake action to the location where the player is about to go.
所以即播放器类型“put banana in box”, the banana can react to the
##Insert action, and the box can react to the
##Receive action. In the game we’重新编写，这是我们在玩家试图在笨蛋中放置某些东西时所做的事情：
- 如果名词不是’t the spaghetti, it’s simply denied –我们打印一条消息并返回true。
- 我们检查意大利面的温度，除以六个。 （任何剩余的被扔掉）
- 如果它’s less than 2, it’太冷了。玩家需要更多地加热食物。
- 如果它’s more than 2, it’太热了。播放器被解雇，游戏结束。
- Since at this point it has to be two, we note that the player has indeed served Mrs. Morris a satisfactory meal (by setting
true), and can now go home. We also remove the spaghetti from the game, and print a message.
First, we want to tell the player about the oven in the room description. While there are specific properties like
when_closed, there’s always the more generic
describe, and this seems more suitable here, since not only do we want to say if the oven is open or closed, but also if it’s on or off and what’s inside it.
Then comes the
before routine, which reacts to the
##SwitchOn action. If the oven is already on, we don’T需要反应。行动程序将告诉玩家烤箱已经打开了’就像我们想要的方式一样。因此，我们返回错误。现在，如果烤箱关闭并打开，它可以’T打开。同样的事情如果它’关闭并关闭，但定时器HASN’T已设置。在这些情况下，我们打印一条消息并返回true。
现在它’s time for an
after routine. If
##SwitchOn wasn’t stopped in the
before routine, and the
##SwitchOn action routine didn’看到玩家应该应该的任何原因’被允许切换烤箱，我们将开始烤箱’s daemon using the
A daemon is a routine attached to an object using the
daemon property. It can be started with
StartDaemon(object)and stopped with
StopDaemon(object). By starting a daemon, you indicate that you want it to be run at the end of each turn until you stop it again. It will run regardless if the player is near the object or not. In this case, we use a daemon to heat food. Even if we had other rooms the player could explore, and the player left the kitchen, the oven should keep heating any food that’在它中，只要烤箱’s timer is set for.
Back to the
after routine. In line 106, we react to
##SwitchOff by stopping the oven’s daemon.
Then we react to
##Open. If the player opens the oven when it’S ON，我们关闭烤箱，停止守护进程并打印合适的信息。由于我们也返回true，默认消息赢了’t be printed.
如果玩家检查烤箱，我们会说’s clean and tidy, and then we have them examine the timer using
< The double angle brackets mean “执行此操作，然后返回true”.
如果意大利面位于烤箱中，请通过四个步骤提高意大利面的温度。我们通过调用自定义例程来完成此操作个人财产 of the Spaghetti object, named
change_temperature. We could have named this property pretty much anything we like, but what is does is change the temperature of the spaghetti, so
change_temperature seemed appropriate.
图书馆提供的属性全部共同特性 . You can add a few common properties yourself using the syntax
Property my_property; but the number of common properties is limited, especially when using the z3 format. You can however use any number of individual properties. You do so by just writing the name you want to use in an object declaration, and the value it should have for that object. Individual properties take up a little more space and are a little slower to access than common properties, but for many uses that’s not so important.
Then we decrease the timer setting by 1, using
Timer.setting--; . This is equivalent to writing
Timer.setting = Timer.setting - 1; . There is also
++ to increase a variable by one.
waittime_waitingto false. This is a signal to the ext_waittime extension that if the player is currently waiting because they typed something like “wait until 8:30” or “wait for 20 minutes”，现在应该中止等待– the player wouldn’当食物再次变冷时，不想继续等待。
In line 132, we define a property called
add_to_scope. . The
add_to_scope. property is used to say “每当该对象处于范围（播放器可以参考）时，也会在范围内放置一些其他对象。” It can hold either a list of objects to place in scope, or a routine which places objects in scope using
PlaceInScope(object);. In this case, we just need to place a single object in scope, and there are no ifs or buts about it, so a list is fine. The list can hold up to four objects in a z3 game, or up to 32 objects in a z5 or z8 game.
So, why do we need
add_to_scope. here? Normally, we could attach the timer to the oven by making the timer a child object of the oven (put it “in”烤箱），但这会变得令人困惑，因为烤箱也是一个容器，所以孩子们都认为是inside烤箱。这是一个案例add_to_scope.派上用场。另一个例子可以是电话。当你’再次与电话交谈，那个人应该处于范围，即使他们’没有你在房间里。为实现这种效果，只要呼叫持续，您就可以将该人添加到范围内。
意大利细面条, part one
We have given it an individual property called
temperature. This starts out as 0, meaning room temperature. We have decided that 29 is the maximum temperature, and this is the temperature it gets if we warm it in the microwave oven for a long time. 29 probably corresponds to about 200° C.
然后是’s another individual property called
change_temperature和it holds a routine which does this. The routine is meant to be called with one argument (
deg), and it tries to change the temperature that much, while making sure the temperature stays in the range 0 to 29 inclusive.
And we have another individual property called
print_temperature, holding a routine which does just this. It uses a
switch statement which is a convenient way of doing different things depending on the value of an expression. You could achieve exactly the same effect with a series of
else statements, but this may be more readable.
Keep in mind that Inform only has integer arithmetics, so
self.temperature / 6 will be rounded down to the neareast integer. If you wanted to know the remainder of the division, you would use
%, as in
self.temperature % 6 .
意大利细面条 has an
invent property. This is used to affect how the object is printed when PunyInform lists objects, like when taking inventory, when looking inside something else (“search oven”), or when printing the objects in a room. The
invent routine is called twice:
inventis called with
inventory_stage放 to 1. This happens just as the object name is about to be printed. If the
inventroutine returns true, nothing further is printed (and
inventisn’t called again).
inventis called with
inventory_stage放 to 2 when the object name has been printed but additional information like ” (providing light)” hasn’t. If the
inventroutine returns true, nothing further is printed.
对于意大利面，我们用这可以说意大利面是多么温暖，除非我们可以’T触摸意大利面，只有在它时发生的’s in the oven.
ObjectIsUntouchable(object, dont_print) is a routine provided by PunyInform to decide if an object can’因为那里而被球员感动’在途中是一个障碍。如果我们不’t give a value for the
dont_print parameter, or we give it the value
false, a message will be printed if the player can’触摸对象。我们不’t want that here, so we give it the value
description property. Since we want to print some words descibing the temperature of the spaghetti both in the
description routines, it makes sense to put the code to print those words in a routine of its own. Hence the
这是烤箱的计时器。它’s not in located in a room, but is dragged into scope by the oven. The timer has an individual property
放ting which holds the number of minutes it has left to go.
description property tells the player the current setting of the timer.
We use the
before routine for multiple purposes:
- 如果玩家试图打开定时器而不是烤箱，我们将动作重定向到烤箱。我们在烤箱对象中有一堆代码来处理交换机，所有这些都将应用，就像播放器所键入的那样“switch on the oven”。请注意，我们使用双角括号语法来执行操作，这意味着我们之后还返回真实，从而阻止了对计时器的交换机动作的默认响应。
- We allow the player to set the timer to a number (of minutes). When a grammar line allows the player to type a number as part of the input, that number is kept in
The final object in the game is the Street location. As soon as we get out here, a
##Look action will automatically be performed. We use the
after routine to react to this by ending the game and printing a message.
Initialise routine, we need to set the time of day, since this is a game that shows the time on the statusline. We set it by calling
SetTime(time, step); .
time is the number of minutes past midnight, so 20 * 60 means 8:00 PM.
step is the relation between minutes and moves. A value of 1 means that one move takes one minute. A value of 5 would mean that one move takes five minutes. A value of -5 would mean that five moves take one minute.