Room Enter
Local_Redditor
29 Sept 2021, 12:42Can I make multiple (universal) copies of 'Script when entering a room'? (So that I can...sort them...again...)
mrangel
29 Sept 2021, 13:09Not easily. But there's nothing to stop you making multiple script attributes, or multiple functions, and having the main roomenter script just run all of them.
But this time, I'm wondering why you would want more than one. A request like this makes me wonder what you're putting in there that's complex enough to need splitting up. In most of the cases that come to mind, there might be a simpler way to do it.
Local_Redditor
30 Sept 2021, 03:47Was just searching for some alternative for universal scripts. I didn't end up needing them in the end.

Dcoder
13 Nov 2021, 10:11Just noticed this thread recently, and it helped me solve a problem with my game -- I wanted to randomly select one of my game's many rooms, and then add to (rather than simply replace) that room's enter
script. The problem was that many of my rooms already had their own customized enter
scripts, while other rooms simply had an empty enter
script. So just replacing the random room's enter
script wouldn't work, as I would lose the original scripting, if any.
MrAngel's comment was enlightening:
But there's nothing to stop you making multiple script attributes, or multiple functions, and having the main roomenter script just run all of them.
The answer, then, was to first copy the room's enter
script attribute to a new (backup) script attribute:
RandomRoom.EnterBackup = RandomRoom.enter
Then I replaced the room's enter
script by setting that attribute to a new script, one that calls a function that I created:
RandomRoom.enter => {
NewFunction
}
The function then runs the backup script attribute, plus whatever additional scripting that I wanted:
do (RandomRoom, "EnterBackup")
// additional scripting follows
So, in effect, the function runs the room's original enter
script, plus my added scripting. The only wrinkle is that the new function has to check to see if the backup script attribute is null
, and then only run it if it isn't null
(otherwise Quest will print an error message if it is null
):
if (RandomRoom.EnterBackup <> null) {
do (RandomRoom, "EnterBackup")
}
Seems simple in hindsight, but I couldn't think of this solution at the time! Thank you again MrAngel!
mrangel
13 Nov 2021, 12:10That seems like quite a complex way to do it.
If there's only one script you're adding to a room in this way, you could just use a flag:
RandomRoom.RunNewFunctionOnEnter = true
And then in your game.roomenter
script, put:
if (GetBoolean (game.pov.parent, "RunNewFunctionOnEnter")) {
NewFunction ()
}
No need to change the enter
script.
If you've got several functions that might be added, you can just add a separate flag for each; and you don't need to check if a EnterBackup
already exists.
If you have multiple scripts that a random room could be set to, but you don't want it to run more than one, it's probably good adding a script attribute. But it seems simpler to just add a new ExtraEnter
script and run it from roomenter
, rather than changing the existing enter
:
if (HasScript (game.pov.parent, "ExtraEnter")) {
do (game.pov.parent, "ExtraEnter")
}
Although I have in the past used a method like this, which allows you to add multiple different scripts to a room, and control which order they run in, by making the room's enter
attribute a list of scripts:
- To add a new function after the existing
enter
script:
enters = NewList ()
switch (TypeOf (RandomRoom, "enter")) {
case ("list") {
enters = RandomRoom.enter
}
case ("script") {
list add (enters, RandomRoom.enter)
}
}
newscript => {
NewFunction ()
}
list add (enters, newscript)
RandomRoom.enter = enters
- To add a new function before the existing
enter
script:
enters = NewList ()
newscript => {
NewFunction ()
}
list add (enters, newscript)
switch (TypeOf (RandomRoom, "enter")) {
case ("list") {
enters = ListCombine (enters, RandomRoom.enter)
}
case ("script") {
list add (enters, RandomRoom.enter)
}
}
RandomRoom.enter = enters
- The
game.roomenter
script to make it work:
if (TypeOf (game.pov.parent, "enter") = "list") {
foreach (script, game.pov.parent.enter) {
game.pov.parent.tempenter = script
do (game.pov.parent, "tempenter")
}
}

Dcoder
14 Nov 2021, 03:51The reason I didn't use roomenter
was because I did not want to add to the turn-by-turn "overhead" of my game. But it would be more straightforward to do it that way.
As for making an attribute a list of scripts, I didn't even know that could be done! I thought that lists had to be either string or object lists. Thanks for sharing something new (at least, to me)!
mrangel
14 Nov 2021, 10:22I do like efficient code; but I think that a singe HasScript
call is simple enough to make little difference (especially compared to some of the code that's already in the core).
If you wanted to use the list method without checking for it every turn, you could have a separate attribute for a list of scripts. Something like:
newscript => {
Whatever()
}
if (HasAttribute (room, "multienter")) {
list add (room.multienter, newscript)
}
else if (HasScript (room, "enter")) {
room.multienter = NewList()
list add (room.multienter, room.enter)
list add (room.multienter, newscript)
room.enter => {
foreach (script, this.multienter) {
invoke (script, QuickParams ("this", this))
}
}
}
else {
room.enter = newscript
}