Help with alternative command scopes on nested objects.

I have a command, corpus, that I want to work only within the object "overworld," and all of its child, grand child, great grand child, etc. nested objects. I've tried following the "alternative scope" tutorial, but have currently been completely unsuccessful in my attempts to make what they say should work work.

You need to be a little more specific. In what way doesn't it work? Is it failing to match objects that should be in scope, or matching objects that you've removed from scope? Can you show us the code that isn't working?

One thing to note is that the scope only determines which objects are considered natural targets for a command. When the player types the alias of an object, first their input will be compared to the list of objects in scope, and if it doesn't match any of those it will be compared to the list of all objects the player can see. So if the player enters an object that isn't in scope, the command still needs to check and come up with its own error message.

It's more like.... I want the player to only be able to access the objects that they can see with this command, but I only want them to be able to use the command within a certain set of rooms... So that's probably my issue then. I want a command to work in some rooms, but not in others.

That's not a scope issue.

Controlling where a command can be used is pretty rudimentary. If a command is moved into a room, it can only be used within that room. Elsewhere it will get the generic response as if the game doesn't know what it means.

A common way to enable or disable commands is to put commands in a box somewhere when they should be disabled. For example, on the roomenter script (on the game's "Scripts" tab, it is run whenever the player enters a new room) you could so something like:

if (Contains (overworld, game.pov)) {
  MoveObjectHere (corpus)

this moves the command into the current room whenever the player visits a new room within the overworld.

However, this doesn't provide a good user interface. It can be confusing for a player if the game says that it doesn't understand a command if the command works elsewhere. In most cases, it's probably better to modify the command itself. Something like:

if (Contains (overworld, game.pov)) {
  // the rest of the stuff your command does
else {
  msg ("You can only do that in the overworld.")

In this case I've used game.pov to refer to the player, which is a good habit to get into.

(moving the command around is better in some circumstances; such as when you want to override one of the built-in commands in a certain location. If you do that, you can use MoveObjectHere on a command to make it work as long as the player stays in the same room, RemoveObject to make it work everywhere, or AddToInventory to disable a command - somewhat counterintuitive, but those functions work a bit differently when they're applied to commands)

Thank you, you've been most helpful.
for game.pov, why is it a good habit to get into using that instead of, say, player? Is that just in case I change the game.pov to another object that isn't the player?

game.pov is always the current player object; that's how all the core functions do it.

There are only two situations where using game.pov is essential:

  • If you allow the player to choose between multiple characters, or to take over NPCs at some point, then game.pov is always the one they're currently controlling.
  • If you're posting code for other people to use – whether on the forums or as part of a library. Because you don't know if the person using it has changed the name of the player object, or allows the player to switch characters.

Even if you don't need it right now, it's still better to use it. Because if you make another game some time in the future that lets the player switch characters, you couldn't reuse code from older projects without going through and changing every reference to player. And if you're used to using game.pov by default, you're not going to slip and type player without thinking.

Log in to post a reply.