Monday 13 July 2015

MEMAP-format

This is just a technical specification. If you're expecting war stories, this text might be a bit disappointment.

Specification for the memap-format

Files editor spits out are zip-files with a funny extension designed mostly to screw with prehistoric Windowses. Root of an example zip-file looks like this:

  • Map 0.memap
  • Map 1.memap
  • Map N.memap
  • initial.png
  • G__1312.png
  • G__4332.png
  • asdfgh.png

Where N means arbitrary number, and names of the pngs' aren't strongly defined. Editor creates sequential id-numbers for the inner memap-files, but upon loading they may be called anything. Only *.memap-extension is needed. As for *.pngs, only requirement for them that filename is a legal Clojure keyword

.png-files are tilesets, .memap-files contain the maps. For each .png an expression

(and (= (rem (width *png-image*) 50) 0)
     (= (rem (height *png-image*) 50) 0))

is true. I highly recommend to keep an initial.png - tileset in your file. Editor allows removing it, but skies will open and horrible things will happen if it is removed.

Each .memap-file has a clojure-map full of data. Example of this follows:

  ^{:tyyppi :map,
  :id :G__9092,
  :hit-layer ^{:tyyppi :layer...}
              [[true ...] 
               [true ...]
               ...], :zonetiles {}, 
  :name "Map 228E9"}
  [^{:tyyppi :layer, :name "New layer", :opacity 255, :visible? true}
    [;;Layer begins here
     [{:x 3, :y 1, :tileset :G__8862, :rotation 0} ...]
     ...]]

First we have a map of metadata. :tyyppi (:type in english) can be either :map or :layer. It's used in editor's multimethod-dispatching machinery. :id:s are just to ease seeking a map, and in future I might write an upgradeable format where maps are stored in a map instead of a seq, and :id:s are used keys there. Map's :hit-layer is a layer with all the ordinary metadata, and the interesting data comes next: a 2D vector of booleans. Editor/future game engine will query if player can step on a tile with the following function:

(get-in hit-layer [x y])

:name is the string visible in editor's Maps-listbox. The actual data this metadata describes is a vector of layers. Layer's metadata is in my opinion self-explanatory. All values editor cares of are present in the example above. Valid :opacity values are 0<=:opacity<=255

Layers are again 2D-vectors, where one queries tile located at (x,y) completely the same way as with hit-layer. Instead of booleans real layers consist of tile-structures.

Tile's 4 interesting values are :x, :y, :tileset and :rotation. :tileset is the key editor queries the tileset with, valid values are defined by the names of the png-files in your zip-file. :x and :y define which of the 50px*50px chunks in the aforementioned tileset tile is rendered with. The origin is, similar to most of the 2D-things, in the upper left corner. :rotation's valid values are 0<=:rotation<4. Tile is rendered in the angle of 90&dg;*:rotation.

Map's origin is also in the upper left corner

Upgrade-path

It's possible that this isn't the final format :D. In case I screw with the format of the map I'll change the inner .memap-files' extension to something else, .memapx or something, and write an upgrade procedure. If I add something else (like, for example, script files), I'll just dump them to a specific folder in the root of the .zip-package.

That's it

It's really not a complex format. Files are not exactly small, but structure is loose, with Clojure's reader-facilities made implementation unbelievably easy, and XML would've been twice bigger.

Anyway, are there details I've overlooked?

No comments:

Post a Comment