Chapter 15: Programming The First Room
We will now continue the script programming by building upon the first room.
By default, SCI Studio uses the naming system rmXXX for rooms, so the first
room is naturally rm001. You could name them anything you like, but this naming
system works the best. Sierra used it as well.
Getting Started
In the Game Explorer, there's a list of the game's resources.
 |
Click on the script folder and the list of scripts in your
game will appear on the right, along with a preview of the first script. |
 |
Scroll down the list until you read the "rm001"
script. Double click on it, and the script editor will open up. |
Programming The Script
Start by scrolling down to the rm001 instance. It is the first
instance in the script. This too, can be named anything you wish, but it only
makes sense to name it the same name as the script.
 |
The properties specify the characteristics of your room.
- picture indicates the number of the picture to use for it's
background. The scriptNumber
keyword is specified, so it will use the picture with the same number
as the script. This being script.001, it will use pic.001.
- The north, east, south and west properties
specify the room numbers that surround the room. If ego walks off the
right side of the screen, for example, it will go to the room specified
by the east property. If east was 10, for example, it would switch to
rm010 (script.010). If their value is zero, then it won't switch to
any room.
|
Positioning Ego
In each room, you'll want the ego to be at a certain position on the screen.
To handle this, there is a switch statement at the top of the room instance's
init() method. This can be used to check the room that the ego has come from.
For example, if the ego came from the west room, you'll want to position in
on the left side of the screen. You can put in cases for any or all of the four
surrounding rooms. At the end of it is the default case, so if the room the
ego has come from doesn't match any of the cases, the default is executed. When
starting the game, the default case will be executed since the ego hasn't been
in any other rooms. This being the case, it is where you will set up the coordinates
for the ego when the game is started.
 |
Scroll down to the send to gEgo. This code tells the interpreter to position
ego at 150 pixels from the left and 130 pixels from the top. It then tells
the interpreter to set the ego's loop to loop #1, which is ego facing
left.
You can change these values. Just remember that the X coordinate must
be from 0 to 319, the Y must be from 0 to 189, and the loop must be from
0 to 3.
|
 |
Click the "Compile and Run" button and you will see the actor
is now part of your game!
|
Your game will now look something like this:

How Rooms Work
Each room consists of two main instances: a public Rm instance and a
local Script instance.
When the game changes to a new room, it calls the Rm instance's init() method.
In this case, it's rm001's init() method. This method is executed only once,
and used to set things up. The init() method sets up the room's script as the
RoomScript instance. As soon as the Rm's init() method is done, your room becomes
controlled by the RoomScript instance. The rm001 is just used for initialization.
Using The RoomScript Instance
The RoomScript instance is used to handle and perform all the
room's events. There are three methods which you can have in it: the doit()
method, the handleEvent() method, and the changeState()
method. Some rooms may not need any of these, while some others may use all
of them.
The RoomScript Methods |
|
If your RoomScript has a doit method, it's code will be executed
repeatedly, once per interpreter cycle. How many times per second
it is called depends on the speed the game is set to.
Example:
(method
(doit)
(super:doit())
Display(
"Hello
World"
dsCOORD 0 0
dsCOLOUR Random(0
15)
dsBACKGROUND clBLACK
)
) |
 |
Inserting the code
|
The
brackets and indents clarify where blocks begin and
where blocks end. The RoomScript instance starts with
a "(" and ends with a ")". Everything
in those brackets is part of the RoomScript.
In the current RoomScript instance, there are two
elements, the properties block and the handleEvent
method. They start with their first "(" and
end with their last ")"
|
Inserting
the doit() method, or any other element into the block
is simple. You can put it anywhere in the block you
like. I just goes between where the block's body begins
and where it ends, and before or after any existing
elements in the block.
Look at the diagram on the left for a visual example.
Now, insert the doit() example into your RoomScript
instance and run your game. You will see the text "Hello
World" flashing in random colours in the top
left corner. You can put anything in the doit method
that you want to be executed constantly.
|
|
If no doit method is in your RoomScript instance, the super
class' doit method is executed. When defining your own doit
method, you'll
still want the super's doit method to be executed, so you
must insert the line (super:doit())
at the beginning of it. This ensures that your doit
method will perform everything it's supposed to. In this
case the super is Script, so (Script:doit()) is
the method actually executed.
|
|
The handleEvent method is the most important method for rooms.
It handles the input from the user, including the text that they
enter in the "Enter Input" dialog. This is where you check
what they input and perform the the tasks complementary to it.
Example:
(method (handleEvent
pEvent)
(super:handleEvent(pEvent))
(if(Said('look'))
Print("You
are in an empty room")
)(else
(if(Said('take/key'))
Print("O.K.")
(send
gEgo:get(INV_KEY))
)
)
) |
Like the doit method, you must insert the line (super:handleEvent(pEvent))
at the beginning of it. This ensures that your handleEvent
method will perform everything it's supposed to.
This checks if the user enters "look". If they do,
it prints "You are in an empty room". Otherwise, if
they enter "take key", it prints "O.K." and
adds the key to the ego's inventory. Said statements will be fully
explained in the next chapter, and the inventory in the chapter
following that.
|
|
The changeState method is similar to the doit method, but it is
only executed if your set it up to be. This can be used in any room,
but it primarily used on the title screen.
For example, you can use this to draw a view, then move it for
3 seconds, then play a sound for 5 seconds, then draw a different
view, then animate it for 8 seconds, then wait for 10 seconds, then
go to another screen, etc. You can use this for absolutely anything
you want.
Each RoomScript instance has state and cycles properties.
- The state property indicates which state case should
be executed.
- The cycles property specifies how many interpreter cycles
to wait before executing the next state. If cycles is not set
in your changeState, it stops (see case 4 in the example).
The actual time in seconds of the cycles varies depending on the
game speed. With the game speed set to 1, 60 cycles equals about
one second. However, if the speed was set to 2 for example, 30 cycles
would be about one second. The default speed gives about 10 cycles
per second. You should never set the game speed to 0 when doing
timed animation, as it will remove the cycle delay, which will give
unpredictable speeds from computer to computer.
Example:
(method
(changeState newState)
= state newState
(switch(state)
(case 0
Display(
"State
0: waiting 20 cycles..."
dsCOORD
0 0 dsCOLOUR clWHITE dsBACKGROUND
clBLACK
)
= cycles
20
)
(case 1
Display(
"State
1: waiting 50 cycles..."
dsCOORD
0 0 dsCOLOUR clWHITE dsBACKGROUND
clBLACK
)
= cycles
50
)
(case 2
Display(
"State
2: waiting 10 cycles..."
dsCOORD
0 0 dsCOLOUR clWHITE dsBACKGROUND
clBLACK
)
= cycles
10
)
(case 3
Display(
"State
3: waiting 40 cycles..."
dsCOORD
0 0 dsCOLOUR clWHITE dsBACKGROUND
clBLACK
)
= cycles
40
)
(case 4
Display(
"State
4: this is the last cycle."
dsCOORD
0 0 dsCOLOUR clWHITE dsBACKGROUND
clBLACK
)
)
)
)
|
Paste the example into your RoomScript instance and see it for
yourself. Then, change some values to get familiar with it.
The start property, by default, 0, specifies the first state
to execute. The start state is executed as soon as the RoomScript
is initialized.
As stated, if the cycles property is not set in the changeState
method, it stops. However, you can call any state you want with
the (RoomScript:cue(aState))
method and the changeState will begin executing again.
 |
Note that your can use the "seconds"
property instead of the cycles property. However, for animation,
you should generally use the "cycles" property since
they player could have the game set to any speed. |
|
|
That concludes the RoomScript instance. In the next chapter, you will learn
all about handling the user's "Said" input.