Converting from Quest 5 - ThePix/QuestJS GitHub Wiki

As of QuestJS 1.2, conversion software is included. This is in the folder "convert" and comprises a web page, plus a JavaScript file.

However, please understand that this is no magic bullet. You will still need to go though every script and check it yourself. It may improve over time, but probably not to a huge degree and it will never be perfect. How it fares on your game will depend on many scripts you have, how complex they are and what features of the Quest language you use.

How To Use

Fire up the convertor

Assuming you have QuestJS already on your computer, double click converter/index.html. You should see a web page with two big text areas and some blue text. Quest 5 goes in the top, QuestJS comes out the bottom.

Create a blank game

You will also need a blank game, so make a copy of the "game" folder. You can call it what you like, but I will assume it is called "game-conv" for these instructions. You can rename later.

Access the Quest 5 code

Now open up your Quest 5 game so you can see the code. There are various ways to do this. In Windows, and I guess other systems, right click the file to get additional options on how to load it, and select a text editor. Alternatively, open up a text editor, such as Notepad, and open the file there. Or open it up in the desktop editor and go to code view.

If your game is online, you will, of course, need to download it first.

Hopefully you can now see the code for your game. It should start like this (the numbers might be different)

<!--Saved by Quest 5.8.6809.15141-->
<asl version="580">

Conversion

Select the whole thing - use [ctrl]-A to select all - and copy-and-paste the entire contents into the top text box on the converter web page.

You can now click on each of the buttons to extract the respective QuestJS code. For example, click "Settings" to get the code to go into the settings.js file. The blue text will tell you what to do with the code.

Test and tweak

Open up your game, and see what happens. You will need to append "?conv" to the URL to see your converted game.

    index.html?conv

If you are really lucky, it will open up fine, but chances are you will have some tweaking to do. Press F12 to open the console, and see where is choked. Do one issue at a time and start at the top of the errors in the developer console; when corrected, reload the page, and see where it gets to.

Hints

This page will be helpful in highlighting possible issues converting to QuestJS. The page on debugging may also be useful.

The convertor will flag all scripts as requiring checking. I suggest you remove the line when you have checked it is okay.

Names

Quest 5 allows users to give objects and attributes of objects names that include spaces. QuestJS does not. I would suggest you do a Search and Replace of each object name and attribute name affected, and that is probably best done before the conversion. I would replace the spaces with underscores.

The `w' object

All objects in QuestJS have to be part of the w object, which means that when you access them in code, the name needs to be prefixed "w.". Variables that contain QuestJS objects do not. In the code below, "hat" is an actualobject, so is referenced using w.hat, while "obj" is a variable that contains the hat object, and so does not require "w."

const obj = w.hat

Testing equality

In particular, look out for testing equality. Quest 5 uses a single equals sign, QuestJS uses three. The convertor will correct that in some places but not others (in fact it will only catch it if it is inside an if and is the first clause), so you could see something like this:

const CloakHere = function() {
    // CONVERTER: Check this code!!!
  return (cloak.loc = player.loc || cloak.loc = player)
}

Parents

It will also have issues with places. In Quest 5, the object's "parent" is the object. In QuestJS, its "loc" is the name of the object, not the object itself.

With all that in mind, our code becomes.

const CloakHere = function() {
  return (cloak.loc === player.loc || cloak.loc === player.name)
}

Special Issues With Commands

An issue with commands is that the Quest 5 script will usually be sent a variable called "object", but sometimes not - when there is more than one, or you want the text not the object. If you just have the one object, the easiest way is to just add const object = objects[0][0] to the top of the script, and the convert will do that for you.

This example has two objects, so we need to do more.

commands.unshift(new Cmd('HangOn', {
  // CONVERTER: Check this!!!
  regex:/(?:hang (.+) on (.+))$/,
  objects:[
    {scope:parser.isHere},
  ],
  script:function(objects) {
    // CONVERTER: Check this code!!!
    const object = objects[0][0]
    if (!object1.loc === player) {
      msg ("You aren't carrying " + object1.pronouns.objective + ".")
    }
    else if (!object2 === hook) {
      msg ("You can't hang stuff on " + lang.getName(object2,{}) + ".")
    }
    else {
      object1.loc = object2
      msg ("You hang the " + lang.getName(object1,{}) + " on the " + lang.getName(object2,{}) + ".")
    }
  },
}))

First, check the regular expression. In this case it is fine, but it may not for you. Then we need a second entry in the objects array, and one of them has to be held.

Then we need to change the script. The easiest way is to create the variables.

We also have some further general issues. Quest 5 is happy with if (not X = Y) but QuestJS wants if (X !== Y), plus we have the isue with "loc" being a string, not an object.

commands.unshift(new Cmd('HangOn', {
  regex:/(?:hang (.+) on (.+))$/,
  objects:[
    {scope:parser.isHeld},
    {scope:parser.isHere},
  ],
  script:function(objects) {
    const object1 = objects[0][0]
    const object2 = objects[1][0]
    if (object1.loc !== player.name) {
      msg ("You aren't carrying " + object1.pronouns.objective + ".")
    }
    else if (!object2 === hook) {
      msg ("You can't hang stuff on " + lang.getName(object2,{}) + ".")
    }
    else {
      object1.loc = object2.name
      msg ("You hang the " + lang.getName(object1,{}) + " on the " + lang.getName(object2,{}) + ".")
    }
  },
}))