ID:32774
 
Keywords: miscellaneous
It might be a bit over-generous to call this one a BYONDscape Classic, but what the heck... here it is anyway!


Ask the Editor!
by Gughunter


This morning, before leaving for work, I opened my email reader to find a message addressed to the BYONDscape account. "Oh goody!" I thought. "Maybe it's a new contribution for BYONDscape! Or a cordial paragraph of constructive criticism!" Then I read the subject line and felt a chill that had nothing to do with the drafty window two feet away. The forlorn plaintiveness of the subject line tugged at my heartstrings: "please help??"

The email was a request for advice on performing not one but a whole sequence of tasks within BYOND. The essentials boiled down to this:

Is it possible to

1) create a turf which, when entered, transports the player to a black screen;

2) allow the player to choose a GameBoy ROM from a list;

3) open a GameBoy emulator;

4) launch the game;

5) return the player to the original turf after the game is finished?


I left the house in a daze. My wiper fluid was creating a vicious circle by freezing on the windshield, I was still only half-awake, and now I faced a BYOND coding conundrum. How to reply to this message? Of course, being a flinty-hearted ogre, my first thought was to reply "Ask on the forums at BYOND.com." Then it occurred to me to twist the dagger further: "Search the forums at BYOND.com, and if you don't find anything relevant, then post a question." But in the end, I realized that BYONDscape was in dire need of updating, and furthermore, this was a question I might actually be able to answer without help from people who know lots of stuff. Out of this furiously bubbling cauldron of emotion, "Ask the Editor!" was born.

The short answer is "Most of this is possible, but not all of it, unless you ask someone smarter than me." This code is the best I could come up with. I didn't have a GameBoy emulator handy, so I decided to try to play some music with WinAmp, because their website says it can be run from the command line, and I tried it, and it works just fine when you run it from the command line. However, despite my best efforts, the code has a flaw. Can you guess what it is? I'll reveal the answer after you've had a moment to speculate.

turf
teleporter
icon = 'teleporter.dmi'

Entered(mob/M)
if(istype(M))
M.last_turf = src
M.loc = null

usr << "Pick an mp3 file, buddy!"

var/F = input(usr) as file

var/commandLine = "c:/Progra~1/winamp/winamp.exe [F]"
shell(commandLine)

usr << "I played it!"

M.loc = M.last_turf

mob
icon = 'tester.dmi'
var/turf/last_turf


I'm actually surprised at how almost-functional this is. I was sure it wouldn't detect when I closed WinAmp, but it does, and returns me properly to the teleporter. Literally the only part that doesn't work is that, though WinAmp runs and it says the song is loaded (many thanks to our guest song of the day, "C:\windows\desktop\enteringmarion-1.mp3"), the song itself doesn't play! Instead the WinAmp display flickers spastically and it says my file is 0:00 minutes long. I have no idea what causes this, but I blame WinAmp, because the alternative of blaming BYOND or my own ignorance is too horrible to contemplate.

Of course, there would be other potential problems if you wanted to distribute this to the general public. For example, WinAmp is on the D drive on my machine at work, so you'd want to provide a way for the user to locate winamp.exe first (and save the path so it doesn't have to be reselected on every run). And it's entirely possible that WinAmp isn't available for Linux, though once you had the select-your-own-player functionality in place, I guess it wouldn't matter what the user chose, as long as the player could accept an mp3 file as a command-line argument.

Anyway, there's a moral to all this: don't ask the Editor. Chances are very good that, despite my kind intentions, I'll only give you a half-assed solution that doesn't quite work. Go to the helpful denizens of the BYOND.com forums instead!


Epilogue

After posting this article last night, I set up a little contest in the BYOND forums, and in no time at all, I received two solutions that both worked fine. It turns out that the reason for my failure was pretty simple. F isn't text, it's a file; so the text value of [F] is the filename without a path! How did I miss such a glaring flaw? Well, when WinAmp opened, it displayed the filename I had given it, even though it hadn't actually opened a file (that would explain the 0:00 length, I guess). So I never even thought to double-check it with a simple debugging output line. Shame on WinAmp, and shame on me too!

The first contest entry came from Nadrew, who pointed out that the path was absent. He created a solution that assumed the relevant files would be in a single directory, which you could then hard-code into the command text. I tried it and it worked, so Nadrew wins 10 BYONDimes! As he pointed out, you could also make multiple directories available to the user with something like this:

var/myDir = input(usr, "Pick a directory") in list("C:/windows/desktop/", "C:/fred/barney/")


Then came Cinnom's contribution, which you can download from this link. This one gives you complete freedom to pick your file from anywhere! Since F is a file, you just use fcopy() to duplicate it in a fixed temporary directory. Then after it's done playing, you delete it with fdel(). Sure, it's a hacky trick and we already had a winner, but since it solves the problem a little more robustly and I'm a sucker for hacky tricks, Cinnom gets 10 BYONDimes too. (Also notice how Cinnom brackets the filename with quotes, to prevent DOS from choking if the filename contains spaces.)

By the way, there's still another potential troublemaker in our code: if the user has one of the high-security modes enabled, and rejects BYOND's request for permission to access the chosen file, the verb crashes and the mob is left in limbo forever. A simple way around this would be to put the file-access code in a separate proc, and call it from the verb; then it would simply return to the verb's code when it crashed.

In closing, let me just point out that even though the Editor eventually came up with an answer this time (thanks to our clever contestants), it still isn't generally a good idea to Ask the Editor.
A classic in my book.

I like how you repeat, "Don't ask the editor." :-)