Final Fantasy Hacktics

General => Archives => Tethical => Topic started by: Kivutar on May 12, 2011, 10:17:56 am

Title: How to create a custom map
Post by: Kivutar on May 12, 2011, 10:17:56 am
This guide demonstrate how to create a custom map for tethical from scratch. Step by step.

Step 1: Modeling a flat map using Blender





Step 2: Giving a shape to your map





Step 3: Apply a texture to your map





Step 4: Export your map to Panda3D format





Step 5: Adding your map server side

A map file on server side is a simple JSON file describing the map data:

{
    "name":  "custom001",
    "x":     9,
    "y":     9,
    "z":     5,
    "scale": [ 1.5, 1.5, 1.285714286 ],
    "offset": [ -4.5, -4.5, 0.0 ],
    "model": "custom001",
    "music": "10",
    "backgroundcolor1": [ 0.34, 0.24, 0.156, 1.0 ],
    "backgroundcolor2": [ 0.89, 0.734, 0.53, 1.0 ],
    "lights": [
        { "color": [ 0.8, 0.8, 0.8, 1.0 ] },
        { "color": [ 0.5, 0.5, 0.5, 1.0 ], "direction": [ 0.0, 45.0, -45.0 ] }
    ],
    "chartiles": {
        "1": [
               { "x": 2, "y": 0, "z": 0, "direction": 2 },
               { "x": 3, "y": 0, "z": 0, "direction": 2 },
               { "x": 4, "y": 0, "z": 0, "direction": 2 },
               { "x": 5, "y": 0, "z": 0, "direction": 2 }
             ],
        "2": [
               { "x": 2, "y": 8, "z": 2, "direction": 4 },
               { "x": 3, "y": 8, "z": 0, "direction": 4 },
               { "x": 4, "y": 8, "z": 0, "direction": 4 },
               { "x": 5, "y": 8, "z": 0, "direction": 4 }
             ]
    },
    "tiles": [
        { "x": 0, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 3, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 4, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 5, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 0, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
       
        { "x": 0, "y": 1, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 1, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 1, "z": 1, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "convex_sw" },
        { "x": 3, "y": 1, "z": 1, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "slant_s" },
        { "x": 4, "y": 1, "z": 1, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "convex_se" },
        { "x": 5, "y": 1, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 1, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 1, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 1, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
       
        { "x": 0, "y": 2, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 2, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 2, "z": 1, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "slant_w" },
        { "x": 3, "y": 2, "z": 2, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 4, "y": 2, "z": 1, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "slant_e" },
        { "x": 5, "y": 2, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 2, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 2, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 2, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
       
        { "x": 0, "y": 3, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 3, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 3, "z": 1, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "convex_nw" },
        { "x": 3, "y": 3, "z": 1, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "slant_n" },
        { "x": 4, "y": 3, "z": 1, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "convex_ne" },
        { "x": 5, "y": 3, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 3, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 3, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 3, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
       
        { "x": 0, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 3, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 4, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 5, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 4, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
       
        { "x": 0, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 3, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 4, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 5, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 5, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
       
        { "x": 0, "y": 6, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 6, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 6, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 3, "y": 6, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 4, "y": 6, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 5, "y": 6, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 6, "z": 4, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 6, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 6, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
       
        { "x": 0, "y": 7, "z": 2, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 7, "z": 2, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 7, "z": 2, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 3, "y": 7, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 4, "y": 7, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 5, "y": 7, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 7, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 7, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 7, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
       
        { "x": 0, "y": 8, "z": 2, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 1, "y": 8, "z": 2, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 2, "y": 8, "z": 2, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 3, "y": 8, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 4, "y": 8, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 5, "y": 8, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 6, "y": 8, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 7, "y": 8, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" },
        { "x": 8, "y": 8, "z": 0, "walkable": true, "selectable": true, "depth": 0.0, "scale": 1.0, "slope": "flat" }

    ]
}


name = the name of your map
x, y, z = dimentions of the map, ours is 9x9, the z is the height*4+1. I think i'm going to remove these properties since the server can compute them itself using the tile data. But for now, you need to set them.
scale = controls the scale of your map model, don't touch this, there is a scale for original maps, and a scale for custom maps.
offset = place the center of the map on the (0,0) tile, on custom maps, it is [ x/2, y/2, 0.0 ], as our map is 9x9, we end with [ -4.5, -4.5, 0.0 ]
model = the filename of your .egg client side
music = the filename of your .ogg client side. Maybe I'm going to remove this too, as music should be chosen by the party creator
backgroundcolor1, backgroundcolor1 = the gradient of the background. this is RGBA, so [1,1,1,1] is white, and [0,0,0,1] is black
lights = a list of lights, if no direction specified it is an ambiant light, if a direction is specified, it is a direction light. Direction coordinates are HPR (see this (http://www.panda3d.org/forums/viewtopic.php?p=59988&sid=f736ea0f2318d814549a77e81755602e#59988) for more info)

chartiles = the team placements. "1" and "2" are the team ID. This is not very smart, I think I'm going to change it too. direction goes from 1 to 4 and is the initial direction of the character.

tiles = the big part:
Our map is 9x9, so x goes from 0 to 8, and y too.
Remember that a wooden box is 4 z.
walkable is self explanatory
selectable is not used yet
depth is usefull for water, try to set it to 2.0
scale is the z scale of a slope, default to 1.0, but can be 2.0
slope is the shape of your tile, here are the available slopes:


Save your .json file under the server/maps directory.

When you launch your developement server, the server finds the map in the maps folder and add it to the list of available map.
Congratulations, your map is complete!