Friday, May 29, 2009

Commands

A "Command" in Metaplace is like an instruction or action from the user. Clicking on the ground in a Metaplace world sends a Command ("walk_to"), pressing a key sends a Command ("inventory open") and clicking a button in a pop-up window sends a Command ("purchase confirm"). These are all examples of "user-defined" Commands, where each of these, "walk_to", "inventory", "purchase" would have to be defined in a script attached to the user's "object" in the world.

There are also "system" Commands, which for the most part, can be thought of as "meta" commands -- "meta" means "above" or "beyond", and is typically used in the sense of something thinking or acting "outside of the box" or interacting with its own reality (in Dungeons & Dragons, the term "meta-knowledge" is often used to refer to knowledge the player's character has that it shouldn't, but does because the player has it, such as the fact that that dragon is immune to fire, even though the character should know nothing about dragons). The system Commands, then, usually don't deal with the world content itself - walking around, opening inventory or confirming events - but modify things external to the gameplay, such as add new graphics to the world or restarting the server. These commands are built-in, not written by users, and are distinguished by their leading slash, such as "/create_sprite" or "/restart_server", and are generally not (knowingly) sent by the user, but rather are sent, for the most part, by the world-building tools.


The idea that Commands are instructions from the user, then, means that, in theory, they're not something that non-users should need to send. This is emphasized by the fact that Commands are defined in scripts attached to the user template, and can't exist in the script attached to this monster or that rock. Monsters and rocks don't give Commands, only users!

Since the Metaplace client is the user's interface into a Metaplace world, it seems to make sense that the client is the only thing that would need to send a Command (on behalf of the user's actions of clicking and typing. However, during alpha and beta testing, some scripters found that there were some cases where calling these same Commands from withing a script seemed reasonable: if the player walks up to an NPC shopkeeper and says that he or she would like to buy or sell some goods, it was nice for the "shopkeeper" script to automatically pop up the user's inventory for him or her. Since we already had a Command set up for this (for when the user pressed "i" on their client), we could use a built-in function called DoCommand(), which would tell the system to execute the Command just as if the user had asked to.

The DoCommand() was also able to issue system commands. This meant that we could have code that could automatically create sprites, or remove them; that could re-configure object templates; or that could enhance the build environment with extra tools.

Unfortunately, we lost access to DoCommand(). The reasoning makes sense: with more modules available on the Marketplace and more users arriving all the time, it's just a matter of time before malicious code comes along.


Malicious modules are going to happen. I think it must fall under some sort of law of averages or something, but eventually there will be someone that comes along and writes a Metaplace script that does something different (or in addition) to what it claims. I, myself, think along these lines, perhaps because my line of work involves security, or perhaps because I have a "hacker" mindset at times, and admittedly like to "cheat" at times. But the majority of malicious code that can exist can, at most, just affect the world's operation, removing monsters, clearing highscores, or providing superuser rights. I say "just", even though these can be devastating to a world, because I don't think these compare to the damage that could be caused if someone had access to system Commands in a world. Even with peer review, a rating system, and distrust of closed-source modules, there are still ways to sneak in some nasty code (a future post).

While script access to the slash commands through DoCommand() provided the ability to make all sorts of interesting modules, I can definitely understand why it had to be removed. It's one thing to delete all of the trees you painstaking placed in your forest realm, but it's another if I remove the template completely, or export your code without your permission, or include even more modules... it doesn't take long to come up with some evil.

And access to the user Commands from script has also been removed. I believe the motivation behind this is because there now exist modules that interact with the user in a "meta" fashion -- things such as in-game purchases using the metacoins, or accepting friend requests, or meeping another Metaplace user -- are now possible. These aren't actions that are world-specific, such as popping up the inventory or buying a sword, but affect your global Metaplace self. And if a malicious script could automatically buy 1000 balloons for someone, or friend every user, or flood-meep everyone, without the user's permission... well, again, it'd be one thing if it was something just in-world (it made you automatically sell all of your equipment to the shopkeeper), but it's something completely different to affect the user at that extra-world level.


So I understand why DoCommand() was removed. But are there legitimate uses for it?

Luckily, there's an easy solution for the user Commands: turn them all into Triggers (so scripts can easily call them), and have the Command that is called by the user (via the client) also call the Trigger. The numerous DoCommand()s I had in my UO scripts were all changed over to this method in less than five minutes.

And what about system Commands? Well, there's now a DoSlashCommand() function, but it's restricted to "privileged" scripts, which means specially-marked Metaplace-written scripts. What about the rest of us? I have three main reasons to have scriptable access to system Commands -- slash-only Commands, batch Commands, and in-world tools.


Slash-only Commands means Commands that don't have a world-builder equivalent. While many/most of the system commands can be activated by some part of the build tools, there are some that cannot (and worse, some that used to be under the old, beloved, "JS tools" from the alpha days). Things such as parallax and data templates (future blog posts) can only be done using slash commands (not precisely true -- some of the parallax and data templates stuff can be done from scripting as well, but not from the build tools). The command-line interface to Metaplace isn't friendly, so being able to script these operations instead of typing them by hand would be handy, especially if you need to do large batches...

Entering batches of Commands isn't really possible with the command-line, because it only takes one line at a time, and means that you'd have to cut-and-paste each line in. Slow, error-prone... not fun. The creation of my UO test worlds is done through a lot of automation, and involves a lot of system commands that upload sprites, configure them, set up tiles, place objects... this is hundreds of commands that can no longer be done from a script. Another example is the avatar system...

The character customization system (future blog post) is not very user-friendly at all. Not only does it require a lot of slash-commands to be entered manually through the command-line, but even the scripting portion, and the data template portion, can be error-prone and difficult. Having an in-world tool, an avatar wizard, could help people create their avatar module by letting them provide the easy stuff (images and animations), and having the wizard automate all of the error-prone work.


So how do we trade off script security and scripting flexibility? Is there a solution? I think there is, and I think it's relatively easy: allow local scripts to use DoSlashCommand(). This means that imported modules don't have access to it, so the only malicious code is something the world owner adds. It allows users to write a script to do slash-only and batch Commands. The only thing that it wouldn't fix is buying an in-world wizard for things like the avatar builder. Something like that would have to be cut-and-pasted into a local script and run from there, which wouldn't be a good practice to get into, but at least it's a workaround.

I don't know if this is being considered as a solution, or if another one is coming. We're told that DoCommand() was "deprecated", but that usually implies that one method is being phased out because a new method is being brought in. I'm still waiting for the new method!

What motivates me?

I've been programming computers for almost thirty years. After doing so for so long, I felt that I could pretty much program anything. Sure, domain-specific things like medical imaging or physics simulation might require me to go learn more than my high-school knowledge of sciences, but other than that (and NP-complete problems), I can code pretty much anything.

This makes me curious when I see an impressive piece of software, either something that's running very efficiently, or something large scale. As I use such software, my mind tends to drift to thoughts of how I would write it.

The most prevalent case of this was while playing Ultima Online. It would usually start with a bug in the game -- some item not working correctly, or even a loophole or exploit -- and I would think about how that portion of the game must have been scripted to allow the bug; I would be debugging the problem without the code itself.

This thinking leads to thoughts about the general algorithms behind the game, about how combat must work, or how crafting works, or how it makes no sense at all that the 8x8 macroing method should work. And eventually, while thinking about how all of these subsystems of such a large-scale system must work, I got thinking about the underlying structure of the game engine.


This led me to think, "could I write a general-purpose massively-multiplayer engine"? Of course, I expected the answer to be "yes", since I can program anything, remember? Thus the MMORF project was born. The primary goal was to see if I could write all of the subsystems of a generalized game engine, and the secondary goal was actually using that engine to make a game, the test-case being whether I could implement Ultima Online in what I wrote.

I wrote a dozen or so posts on the blog, started working out some design, but over a year and a half, it was progressing slowly, and eventually, I discovered Metaplace. Interest in the platform took my available time for such pursuits, especially once I got into the alpha-test program.

It was a nice surprise, then, that once I got into alpha, I discovered that the backend of Metaplace was VERY similar to how I would have written MMORF; I'd say that my vision for MMORF and the Metaplace design are about 90% related. That other 10% would make for an interesting future post...

With an engine already made, very close to what I had envisioned, my goal has now changed to seeing whether or not my vision would have worked: could I have written an Ultima Online clone with what I had thought up? And that still remains my primary goal with Metaplace, answering the question of whether UO could be implemented on the Metaplace platform. My notes so far on this can be found on my user page on the Metaplace wiki.


So, this is why I'm part of Metaplace. Of course, in the last year-and-a-half that I've been an alpha- and beta-tester, I've done a lot more than work on a UO clone (which should be obvious, considering how far I haven't gotten). I sit in the global chat as often as I can, helping out old and new testers alike, as I like to think that I'm one of the most knowledgeable users out there, and have always enjoyed teaching and sharing knowledge. I try to make demo worlds to show off new features, such as the effects system. I get convinced to write little code snippets for people, when it's either quick-and-simple, or a problem that challenges me. I get side-tracked with thoughts of "I wonder if I can get Metaplace to do this", and then attempt to prove that it can, whether or not it was ever designed to. And every so often, I even publish a module for others to use, actually finishing something! Oh, and I suppose I've "finished" two worlds: a game, Sniper, and a chatroom, educhat.


I still think, every so often, about the MMORF project, and how successful I would have been. While I'm testing the design of it by testing Metaplace, it still doesn't answer the question of whether I could have done it. And some day, after Metaplace has released, the global chat has become too unwieldy to reside in, and the Metaplace Marketplace becomes so large that every possible module is available, I shall go back and see.

But until then, I'll continue working away at Ultima Online...

Thursday, May 28, 2009

Content

So what will this blog contain? A range of things: ideas for Metaplace worlds that I may or may not ever have time to try; ideas for plugins (modules) to write for Metaplace users; limitations and bugs that I find, including workarounds; critical commentary (read: complaints) about the functionality or direction of the service; and even some code snippets for cool things that can be done in Metascript.

I hope this last bit doesn't scare anyone off; ideally, non-programmers can gain some benefit from posts that talk about scripting, to give them an idea of what's possible in Metaplace (and drive them to ask someone to script it for them), or to perhaps take on the challenge of learning how to do a little scripting themselves.

Introduction

Now that the NDA for beta-testing Metaplace has been lifted, a bunch of users have started blogs about it, and I figured I might as well jump on the bandwagon.

I started alpha testing Metaplace back in December 2007, and I think the only day that I haven't logged into a Metaplace world is the day I was in San Diego at the Metaplace office, meeting the team.

If you don't know what Metaplace is, go check it out. As of this post, it's in Open Beta, so anyone can give it a try - signup is quick and painless. Metaplace, as a whole, is geared to pretty much anyone, whether you're just looking for some games to play (though it's still Beta, so the selection isn't huge, compared to sites like Kongregate and the like), looking to build your small corner of the internet, or you're a game or content developer looking for a flexible platform to work on.

If you do decide to give it a try, I can be found in the "metaplace" global chat channel during the (North American) day every weekday (work time), and off-and-on during evenings and weekends (family time). I'm happy to try to answer questions and to help with problems, or just to chat. We're friendly in that channel, so come say hi!