Nothing all in one place that I can think of, I'd reccomend using the dataWriter.js module that comes with miniSphere (or writing something similar.)
It has a lot of the boilerplate code for file handling/output you'd otherwise have to write pre-written.
To write a sphere readable map you'd then have to follow the format that's outlined in map.rmp.txt
Firstly there's a header
---- 256 byte header ----
byte signature[4]; // Must be ".rmp"
word version; // Must be 1
byte type; // obsolete
byte num_layers;
byte reserved;
word num_entities;
word startx; // In pixel coordinates, not tile
word starty;
byte startlayer;
byte startdirection; // 0 = north, 1 = northeast, 2 = east, etc. (clockwise)
word num_strings; // 9
word num_zones;
byte reserved[235];
If you use dataWriter.js's Write Struct feature you could do that by setting out something like this though adding a value field in each case (the below is intended for reading not writing so has an id and a type rather than a value and a type):
[{id: 'signature', type: 'fstring', length: 4},
{id: 'version', type: 'uint16le'},
{id: 'type', type: 'uint8'},
{id: 'numLayers', type: 'uint8'},
{id: 'res', type: 'raw', size: 1 }, // reserved
{id: 'numEntities', type: 'uint16le'},
{id: 'startX', type: 'uint16le'},
{id: 'startY', type: 'uint16le'},
{id: 'startLayer', type: 'uint8'},
{id: 'startDir', type: 'uint8'},
{id: 'numStrings', type: 'uint16le'},
{id: 'numZones', type: 'uint16le'},
{id: 'repeating', type: 'bool' },
{id: 'res2', type: 'raw', size: 234 }] // reserved
After that there is string data, these are lstr16le (if using dataWriter.js) note, make sure you set the numStrings value in the header to the number of strings, normally 9:
---- String data ----
Defined strings:
0 - tileset file (obsolete)
1 - music file
2 - script file (obsolete)
3 - entry script
4 - exit script
5 - north script
6 - east script
7 - south script
8 - west script
After the strings the layers appear, each layer begins with a header:
word width;
word height;
word flags; // visible = ~flags & 1, has_parallax = flags & 2
float32 parallax_x;
float32 parallax_y;
float32 scrolling_x;
float32 scrolling_y;
dword num_segments;
byte reflective; // 0 = false, 1 = true
byte reserved[3];
string layer name
Again writeStruct from dataWriter.js could do this for you with something like this (again you'd need to add value fields to this)
[{id:'width', type:'uint16le'},
{id:'height', type:'uint16le'},
{id:'flags', type:'uint16le'},
{id:'parallaxX', type:'float32le'},
{id:'parallaxY', type:'float32le'},
{id:'scrollX', type:'float32le'},
{id:'scrollY', type:'float32le'},
{id:'numSegments', type:'uint32le'},
{id:'reflective', type:'bool'},
{id:'filler', type:'raw', size: 3},
{id:'name', type: 'lstr16le'}]
After the header there is a tile map, this is literally the index value of each tile one after the other all written with the uint16le from dataWriter.js.
Note1: the number of tiles you put a value for must exactly equal the width of the layer times the height of the layer
Note2: the tiles go from top left along each row then back to the start of the next row, there is nothing in the data dividing the rows.
After the tile data ends there is the obstruction segment data, each segment is just 2 coordinates stored as x1,y1,x2,y2; these use a larger number type uint32le from datawriter.js will handle it, 4 per segment. Note that the layer header above specified the number of segments.
After the segments you move on to the next layer with another layer header etc.
Once all the layers are done you'd go onto entity data and then zone data - may be easier to create the map with none of these and add such things layer with CreatePerson - though you could do it here.
Note at the end of the mapfile you should include the entire contents of the tileset file (unless alternatively you put in a tileset filename as one of the strings above - assuming you need to include the tileset file you could do this by opening it as a filestream and just reading the whole file into a variable then writing that variable to the map file you're making.)
Anyway that's the process does it make sense? Anything you'd like me to elaborate further?
Making an in Sphere map generator of some kind that uses the above method is my todo list but it has slide a long way down said list.