why am I getting this error?
Nemec
21 Apr 2022, 02:04Error running script: Error compiling expression 'exit.visible': RootExpressionElement: Cannot convert type 'Object' to expression result of 'Boolean'
I do not have an exit.variable in my code. In fact I never referenced any variable called "visible". Why am I be getting this error?
mrangel
21 Apr 2022, 09:54There are two places in the core code the expression exit.visible
appears.
First is in the function ScopeExitsForRoom
, which looks like this:
<function name="ScopeExitsForRoom" type="objectlist" parameters="room">
<![CDATA[
result = NewObjectList()
foreach (exit, AllExits()) {
if (exit.parent = room) {
if (exit.visible) {
if (GetBoolean(room, "darklevel")) {
if (GetBoolean(exit, "lightsource")) {
list add(result, exit)
}
}
else {
list add(result, exit)
}
}
}
}
return (result)
]]>
</function>
Now, in this case the variable exit
is being extracted from the built-in function AllExits()
, so it can only be an exit. And all exits inherit the type defaultexit
, which forces them to have a visible
attribute. So if the error is coming from here, it means that either you have modified defaultexit
and omitted the visible
attribute; or you have created an exit whose visible
attribute is set to an actual object.
Both of these seem unlikely, so let's look at the other possibility.
The built-in go
command starts with:
<command name="go" pattern="[go]" unresolved="[UnresolvedLocation]">
if (exit.visible) {
if (exit.locked) {
msg (exit.lockmessage)
}
else if (exit.runscript) {
if (HasScript(exit, "script")) {
do (exit, "script")
}
}
else if (exit.lookonly) {
msg ("[UnresolvedLocation]")
}
else {
if (HasString(exit, "message")) {
if (not exit.message = "") {
if (game.clearscreenonroomenter) {
game.currentexitmessage = exit.message
}
else {
msg(exit.message)
}
}
}
game.pov.parent = exit.to
}
}
else {
msg ("[UnresolvedLocation]")
}
</command>
Hmm… the parser's scope functions should ensure that this only gets an exit as well. Or are you invoking the go
script manually? I would wonder if you were passing an object to go.script
using some of your own code; but that still shouldn't cause that error, as defaultobject
also has a boolean visible
attribute. Are you manually invoking go.script
and passing it a command or a turnscript in place of an exit for some reason?
So… further questions:
- Have you modified
defaultexit
? - Does the error appear as soon as the game starts, at some specific interval, or when the player uses the
go
command? - Have you manually called
go.script
anywhere in your code? If so, what exit are you passing it?
With a weird case like this, it would probably be better if you could just show us a copy of the game (or a sample game that demonstrates the same error). This is the kind of issue where explaining what to look for can be tough, but it should stand out to a more experienced user.
Nemec
21 Apr 2022, 13:10So if the error is coming from here, it means that either you have modified defaultexit and omitted the visible attribute; or you have created an exit whose visible attribute is set to an actual object.
Both of these seem unlikely, so let's look at the other possibility.
Oops
<type name="defaultexit">
<access_requirement type="string"></access_requirement>
<action_description type="string"></action_description>
<display_when_out_of_combat type="string"></display_when_out_of_combat>
<display_during_close_combat type="string"> </display_during_close_combat>
<can_push_to type="boolean">true</can_push_to>
<can_fall_down type="boolean">false</can_fall_down>
</type>
I am hoping to have exits that don't require me to keep manually updating each one individually as I develop my game. Is there a way to add what I have above to "defaultexit" without removing what is already in it?
mrangel
21 Apr 2022, 14:45The usual way to do stuff like that is for the code that uses those attributes to check if they exist, and if not use a default value.
I've also seen people redefine the type direction
, which by default is inherited by all directional exits, but doesn't contain any attributes you would need to preserve.]
If you really want to modify defaultexit
itself, to ensure that your attributes appear on all exits, you would need to include some of the default attributes.
I assume you've seen the default definition?
<type name="defaultexit">
<displayverbs type="simplestringlist">[GoTo]</displayverbs>
<visible type="boolean">true</visible>
<scenery type="boolean">false</scenery>
<locked type="boolean">false</locked>
<lockmessage>[LockedExit]</lockmessage>
<lookonly type="boolean">false</lookonly>
<runscript type="boolean">false</runscript>
<lightstrength type="string"></lightstrength>
<grid_length type="int">1</grid_length>
<grid_render type="boolean">false</grid_render>
<grid_offset_x type="int">0</grid_offset_x>
<grid_offset_y type="int">0</grid_offset_y>
</type>
Core scope functions use the attributes visible
and scenery
, so you will need to include those unless you are rewriting the scope functions too. (They also use lightsource
and lightstrength
, but those are checked using the GetBoolean
and GetString
functions, so omitting them doesn't cause an error)
So you'd end up with something like:
<type name="defaultexit">
<visible type="boolean">true</visible>
<scenery type="boolean">false</scenery>
<access_requirement type="string"></access_requirement>
<action_description type="string"></action_description>
<display_when_out_of_combat type="string"></display_when_out_of_combat>
<display_during_close_combat type="string"> </display_during_close_combat>
<can_push_to type="boolean">true</can_push_to>
<can_fall_down type="boolean">false</can_fall_down>
</type>
The grid_
attributes are used by the grid/map system, so should be included as well if you want to use the map at all.
The remaining attributes (locked
, lookonly
, runscript
, and to
) are referenced by the default go
command; so if you've written your own go
you can probably omit them.
Nemec
22 Apr 2022, 19:17Everything related to this issue seems to be fixed now! Thanks for all the help mrangel!