Release v1.63.0 - Room scripts Part 2

Merry Christmas to you all!
While I haven’t been able to be around to reply to forum posts, messages, and bug reports, I have at least been tinkering.

Now I can introduce the second Room scripts release, making the feature a bit more useful. Yes, there are still a lot more needed, like custom commands, simplified development and deployment, and better version handling. We will get there eventually.

But let’s have a look at what we currently got!

(The mucklet-script respository has been updated with documentation on all new script features)

Features

Inactive exits

It is now possible to inactivate an exit. While inactive, it will be hidden from view, and it will not be possible to use it.

You can set an exit as inactive by typing:

set exit secret passage : inactive = yes

While characters may not use an inactive exit, room script can intercept an attempt to use an active exit, and instead send them through the inactive exit. This allows us to create exits that takes us to different rooms based on the logic in the script.

Room script improvements

New script examples
Three new script examples have been added to the mucklet-script repository:

Name Description
lock_inside.ts A script that locks a door preventing others from using an exit in the room running the lock_outside.ts script.
lock_outside.ts A script that prevents characters from using an exit locked by the script running the lock_inside.ts script.
secret_exit.ts A script that reveals a secret passage when the password “tapeworm” is spoken.

Script target version
Room scripts created for older API versions will now continue to run.

Note
Compiling (updating) scripts targeting older versions is still not possible. The script needs to be updated to target the newest version. Support for compiling older scripts will be added in another release.

Script debug logging
Room scripts may now use the built-in methods console.log, console.debug, console.info, console.warn, and console.error to log messages.
The different log levels will show up with different colors in the script log:

roomscript test


Thanks to @farcaller for the feedback!

List room characters
With Room.charIterator we can iterate over room characters:

// Iterate over characters in the room
for (let it = Room.charIterator(); it.isValid(); it.next()) {
	let char: Room.Char = it.getChar()
	Room.describe(char.name + " - " + char.species)
}

Get room character
With Room.getChar we can get info about a character in the room:

// Get a single character by ID
let char: Room.Char = Room.getChar("c0n144ot874c2tqpubpg")

List room exits
With Room.exitIterator we can iterate over room exits:

// Iterate over exits in the room
for (let it = Room.exitIterator(); it.isValid(); it.next()) {
	let exit: Room.Exit = it.getExit()
	Room.describe(exit.name)
}

Get exit by key and ID
With Room.getExit and Room.getExitById we can get info about an exit:

let exitByKey: Room.Exit = Room.getExit("out")
let exitById: Room.Exit = Room.getExitById("calchtm9gbrqf705k200")

Get exit order
With Room.getExitOrder we can get an array of IDs of visible exits in their display order:

let order: ID[] = Room.getExitOrder()

Set exit
With Room.setExit we can set the properties of an exit:

// Change the name of an exit
Room.setExit(exitId, new Map<string, boolean>().set("name", "Floor 3"))

onCharEvent
The exported function onCharEvent is called when a character enters a room, leaves a room, or changes any of its properties while inside the room. It requires that Room.listenCharEvent has been called earlier, usually in the onActivate function:

export function onActivate(): void {
    Room.listenCharEvent()
}

export function onCharEvent(
    addr: string, charId: string,
    after: string|null,
    before: string|null,
): void {
    // Handle the event
}

onExitUse
The exported function onExitUse is called when a character attempts to use an exit. It requires that Room.listenExit has been called earlier:

export function onActivate(): void {
    // Intercept the use of all room exits
    Room.listenExit()
}

export function onExitUse(
    addr: string,
    exitIntercept: ExitIntercept,
): void {
    if (exitIntercept.charId == "c0n144ot874c2tqpubpg") {
        // Only Accipiter can use the exits
        exitIntercept.useExit()
    } else {
        exitIntercept.cancel("The door won't open for you.")
    }
}

API endpoints to manage room scripts
It is now possible to manage room scripts without having a controlled character in the room. The API can be used to:

  • list room scripts
  • create a new room script
  • update an existing room script
  • delete a room script
// Javascript examples using the web client
const api = app.getModule('api');
await api.call(`core.room.${roomId}.scripts`, 'create', {
    key: 'hello',
    source: `export function onActivate(): void { Room.describe("Hello, world!") }`,
    active: true,
});
await api.call(`core.roomscript.${scriptId}`, 'set', { active: false });
await api.call(`core.roomscript.${scriptId}`, 'delete');

Cancel scheduled script posts
When using Script.post with a delay, a schedule ID is returned. This ID can be stored and later used to cancel the post using Script.cancelPost.
See the secret exit example for example usage.

Improvements

Partial script access for non-supporters

Non-supporters may now list, view, rename, delete and activate/deactivate room scripts in rooms they own.
Discussed in GitHub issue #328 - Partial script access to non-supporters

Log script parse errors

When parsing an existing script caused an error, the error is now logged to the script log. It was previously just logged as an error on the server.

Decrease move flood cost

The flood cost for a move action has been reduced to 2.5 seconds from the previous 5 second cost, to decrease the chance of normal world exploration triggering the flood guard.
It was reported as an issue by @Kelmi in this thread.

Fixes

Handle script describe in notification
When a webpush or local notification was created as a result of a room script’s describe, the message contained “???” in place of the missing character’s name.
Instead, notifications are no longer triggered by room scripts.

Script error on deactivating a script
When deactivating a script, the error “disposed” were logged to the script. This has been fixed.

Npm notice on script build
When building a roomscript, npm notices could show up in errors. This has been fixed.
Thanks to @GreenReaper for reporting it in this thread!

Missing error handling on area image upload
When uploading an area image, any error would end up in the console as an “Uncaught (in promise)” exception. This has been fixed, and errors are now displayed in a dialog.
Thanks to @GreenReaper for reporting it in this GitHub issue!

Script store data corruption
When storing data in a room script using Script.setString or Script.setBuffer, the data could end up corrupted before being properly stored. This has been fixed.
Thanks again to @GreenReaper for reporting it and providing the means to replicate it in this thread!

8 Likes