Skip to content

Commit

Permalink
Add map exporter tool
Browse files Browse the repository at this point in the history
  • Loading branch information
sork committed Apr 10, 2012
1 parent 8d9856e commit fc9f6c6
Show file tree
Hide file tree
Showing 9 changed files with 3,354,491 additions and 2 deletions.
2 changes: 1 addition & 1 deletion client/maps/world_client.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/maps/world_client.json

Large diffs are not rendered by default.

92 changes: 92 additions & 0 deletions tools/maps/README.md
@@ -0,0 +1,92 @@
BrowserQuest map exporter
=========================

***Disclaimer: due to popular demand we are open sourcing this tool, but please be aware that it was never meant to be publicly released. Therefore the code is messy/non-optimized and the exporting process can be very slow with large map files.***


Editing the map
---------------

Install the Tiled editor: http://www.mapeditor.org/

Open the `tmx/map.tmx` file in Tiled and start editing.

Note: there currently is no documentation on how to edit BrowserQuest-specific objects/layers in Tiled. Please refer to `tmx/map.tmx` as an example if you want to create your own map.


Using the exporter
------------------

This tool is to be used from the command line after the TMX file has been saved from the Tiled editor.

Note: This tool was written with OSX in mind. If you are using a different OS (eg. Windows), additional/different steps might be required.

**Prerequisites:**

- You need python and nodejs installed.
- Install pip: http://www.pip-installer.org/en/latest/installing.html
- Install lxml: `pip install lxml` (preferably within a virtualenv)
- Optional: Install Growl + growlnotify if you are on OSX.

**Usage:**

1. `cd tools/maps/`

2.
- Converting the client map: `./export.py client`
- Converting the server map: `./export.py server`

You must run both commands in order to export the client and server map files. There is no one-step export command for both map types yet.

**Warning:** depending on the `.tmx` filesize, the exporting process can take up to several minutes.


Things to know
--------------

The client map export will create two almost identical files: `world_client.js` and `world_client.json`
These are both required because, depending on the browser, the game will load the map either by using a web worker (loading `world_client.js`), or via Ajax (loading `world_client.json`).

The client map file contains data about terrain tile layers, collision cells, doors, music areas, etc.
The server map file contains data about static entity spawning points, spawning areas, collision cells, etc.


**How the exporting process works:**

1. The Tiled map TMX file is converted to a temporary JSON file by `tmx2json.py`.
2. This file is be processed by `processmap.js` and returned as an object. This object will have different properties depending on whether we are exporting the client or the server map.
3. The processed map object is saved as the final world map JSON file(s) in the appropriate directories.
4. The temporary file from step 1. is deleted.


**Known bugs:**

* There currently needs to be an empty layer at the bottom of the Tiled layer stack or else the first terrain layer will be missing.
(ie. if you remove the "don't remove this layer" layer from the `map.tmx` file, the 'sand' tiles will be missing on the beach.)


Contributing / Ideas for improvement
------------------------------------

Here are a few ideas for anyone who might want to help make this tool better:

- Remove hard-coded filenames from export.py (eg. `map.tmx`, `world_client.json`) in order to allow easier switching to different map files.

- Fix known bugs (see section above)

- Write documentation on how to use the exporter on Windows.

- Write documentation about map editing in the Tiled editor (ie. editing BrowserQuest-specific properties of doors, chests, spawning areas, etc.)

- Write documentation about the BrowserQuest map JSON format, both for client and server map types.

- Get rid of the `tmx2json.py` step which can currently take up to several minutes. Note: There is a JSON exporter built in Tiled since version 0.8.0 which could be useful. We didn't use it because our tool was written before the 0.8.0 release.

- A complete rewrite of this tool using a custom Tiled plugin would surely be a better approach than the current one. Being able to export directly from Tiled would be much easier to use. Also, the export process is currently too slow.


**Additional resources:**

- Tiled editor wiki: https://github.com/bjorn/tiled/wiki
- TMX map format documentation: https://github.com/bjorn/tiled/wiki/TMX-Map-Format

25 changes: 25 additions & 0 deletions tools/maps/export.py
@@ -0,0 +1,25 @@
#!/usr/bin/env python
import commands
import sys

SRC_FILE = 'tmx/map.tmx'

TEMP_FILE = SRC_FILE+'.json'

mode = sys.argv[1] if len(sys.argv) > 1 else 'client'
if mode == 'client':
DEST_FILE = '../../client/maps/world_client' # This will save two files (See exportmap.js)
else:
DEST_FILE = '../../server/maps/world_server.json'

# Convert the Tiled TMX file to a temporary JSON file
print commands.getoutput('./tmx2json.py '+SRC_FILE+' '+TEMP_FILE)

# Map exporting
print commands.getoutput('./exportmap.js '+TEMP_FILE+' '+DEST_FILE+' '+mode)

# Remove temporary JSON file
print commands.getoutput('rm '+TEMP_FILE)

# Send a Growl notification when the export process is complete
print commands.getoutput('growlnotify --appIcon Tiled -name "Map export complete" -m "'+DEST_FILE+' was saved"')
62 changes: 62 additions & 0 deletions tools/maps/exportmap.js
@@ -0,0 +1,62 @@
#!/usr/bin/env node

var util = require('util'),
Log = require('log'),
path = require("path"),
fs = require("fs"),
processMap = require('./processmap'),
log = new Log(Log.DEBUG);

var source = process.argv[2],
destination = process.argv[3],
mode = process.argv[4];

if(!source || !destination) {
util.puts("Usage : ./exportmap.js map_file json_file [mode]");
util.puts("Optional parameter : mode. Values: \"server\" (default) or \"client\".");
process.exit(0);
}

function main() {
getTiledJSONmap(source, function(json) {
var options = { mode: mode || "server" },
map = processMap(json, options);

var jsonMap = JSON.stringify(map); // Save the processed map object as JSON data

if(mode === "client") {
// map in a .json file for ajax loading
fs.writeFile(destination+".json", jsonMap, function(err, file) {
log.info("Finished processing map file: "+ destination + ".json was saved.");
});

// map in a .js file for web worker loading
jsonMap = "var mapData = "+JSON.stringify(map);
fs.writeFile(destination+".js", jsonMap, function(err, file) {
log.info("Finished processing map file: "+ destination + ".js was saved.");
});
} else {
fs.writeFile(destination, jsonMap, function(err, file) {
log.info("Finished processing map file: "+ destination + " was saved.");
});
}
});
}

// Loads the temporary JSON Tiled map converted by tmx2json.py
function getTiledJSONmap(filename, callback) {
var self = this;

path.exists(filename, function(exists) {
if(!exists) {
log.error(filename + " doesn't exist.")
return;
}

fs.readFile(source, function(err, file) {
callback(JSON.parse(file.toString()));
});
});
}

main();

0 comments on commit fc9f6c6

Please sign in to comment.