IsoGen

Overview

A tool for quickly and easily generating seamless tiles and walls for isometric games.

Making a game is hard and time consuming. And it can be difficult to do at all without a basic art set. The purpose of Isogen is to quickly get you up and running with reasonably good isometric art. You can tune that art over time - or replace it with hand finished art later - but Isogen will get you started with correct isometric graphics quickly.

Isogen takes an XML configuration file and images for input, and generates isometrics graphics - ready to use.

Features

  • Stand alone utility. It ships with the Kyra codebase, but is a separate program.
  • Creates true seamless tiles and walls.
  • Can layer textures, including alpha channels, for variation and effects.
  • Ambient and diffuse lighting.

Building

Isogen needs to link to SDL and load SDL_image at run time, just like the main Kyra code. The build page documents the SDL requirements and how to set it up.

Visual Studio: Simply set isogen to the active project and build. The command line can be set in the Project settings.

Linux, mingw: 'make'

Quick Start

Executing './isogen dungeon.xml' will execute isogen. It is a command line utility, so you will only see a few lines of output. Running isogen will create:

  • dungeon.bmp. The output file that contains all the tiles and walls.
  • dungeon_encoder.xml. An XML file that describes all the images in the output bmp file. If you are using the Kyra sprite engine, this is an input XML file that will generate a .dat file. (krencoder dungeon.dat dungeon_encoder.xml).

Anatomy of a Tile

Defining an isometric tile is tricky. Isogen only creates tiles - it doesn't position or draw them. (Kyra is a full drawing package, although Kyra's isometric math has not yet been fully updated for Isogen). Regardless, it is very important to have a clear understanding of isometric tile geometry.

Isogen is based on the notion at every object it creates fills a cube in 3D space. That's why the floor texture is "on top". A floor is the top of a filled cube, and leaves empty space above it.

The cube is then projected into an isometric projection, and pixels are chosen so that every image touches correctly, but none overlap.

  • The (mathematical) unit cube is shown as black lines.
  • East and North, in isometric space, are marked.
  • In pixel coordinates 0,0 is in the upper left.
  • The isometric width is the width of the isometric cube (projected) in pixels. In this case it is 16 pixels. The isometric width is used to position the tile, even though the "visual" width is 2 pixels smaller.
  • The tile width is 2 pixels less than the isometric with. In this example, 14 pixels.
  • The tile height is 1/2 the isometric with. 8 pixels in this case.
  • The origin of each tile is completely arbitrary. Isogen uses the pixel marked with a blue dot.
  • The next tile East is at x+(isometric width)/2, y-(isometric width)/4
  • The next tile North is at x-(isometric width)/2, y-(isometric width)/4

An Effective Process

Isogen is made to be quick and easy to get started, but grow with your game or application. In general, you'll want to:

  1. Get the size of the art, and get it in the game.
  2. Set up basic lights and texture.
  3. Add more complex overlays and textures.
  4. Hand tweak the resulting art.

The first step should come as you create the game...and hand tweaking once you have taken automation as far as possible!

At the beginning, you want to get a feel for the size of the art. Start with

isogen sprite="myart"

Which will create basic grayscale art. You can then tweak the size with:

isogen sprite="myart" isoWidth="100"

Once you have the size you want, and it is in your app and testable, create a basic XML file. (Described below). Or copy the existing dungeon.xml. You can use this to generate more and varied art for you game.

Textures

The XML reference, below, describes the many ways textures are used in Isogen. However, there are some general rules for textures.

  • Any texture format supported by SDL_image is acceptable. This includes BMP, PNG, TGA, and PCX.
  • Alpha channel is supported for 32 bit images (PNG and TGA if saved as 32 bits). Alpha channel is not support for 24 bit and lower images (BMP and PCX).
  • For overlays that use formats without an alpha channel, pure black is assumed transparent.
  • Many isogen textures should be seamless (tileable) textures. This is very important - discontinuities in the texture images will be very apparent when the images are stitched together. Many textures for 3D graphics are seamless. A very good - and cheap - editor for working with seamless textures is PhotoSeam. (I'm not affiliated - I just think it is good software.)
  • Textures should be approximately the same size, or a little larger, as the output for the best results. For example, if you use an isometric width of 120, a wall will be about 60 pixels wide. Textures are traditionally a power of 2. So an input texture of 64x64 or possibly 128x128 would be a good choice.

XML

The basic structure of an isogen input file is:

<Isogen> The top level tag contains global settings. There is only one.

<Set> Each set defines a group of graphics to be generated from the same images. A set can be walls, floors, etc, all with the same graphics effects and textures. There can be any number of sets (as long as they fit in the generated image.)

<FloorOverlay> Images that overlay the basic floor graphics. Each one is layered in order, and there can be any number of layers.

<WallOverlay> Images that overlay the basic wall graphics. Each one is layered in order, and there can be any number of layers.

<Isogen>

<Isogen> is the top level tag for the document and contains global settings for the generated images. It can contain any number of <Sets>. <Isogen> requires the 'sprite' attribute, and supports many optional attributes.

sprite="spritename"

Required attribute. The output image is "spritename.bmp" and the output XML file is "spritename_encoder.xml". In the output XML file, the 'sprite' will be named "spritename".

isoWidth="120"

The isometric width of the tiles. (See Anatomy of a Tile, above.) Will be rounded to be a multiple of 4.

wallInset="10"

The thickness of walls generated by isogen. Defaults to isoWidth / 12. Lower values are thicker walls, higher values are thinner. If the walls are too thin, they won't connect any more.

width="800"
height="600"

The size of the output image file.

ambient="0.6 0.6 0.6"
diffuse="0.4 0.4 0.4"
lightVector="0 2 -3"

The ambient and diffuse light used. Ambient light has no direction and is everywhere, diffuse light is directional and in the direction of the lightVector. The components of ambient and diffuse are "red green blue" and have a value between 0 and 1. 0 is dark, 1 is full brightness. The components of lightVector are "x y z" and will be normalized when read. Normally the ambient and diffuse components add to 1.0, but they don't have too. (The output is clamped between 0 and 1). The equation of light in isogen is a standard, simple model:

c = ambient.c + diffuse.c * (surfaceNormal * lightVector)

<Set>

A <Set> is a collection of graphics (walls, floors, etc.) with the same effects applied. You can have any number of sets. A <Set> has the following attributes:

useAA="true"

Use anti-aliasing when rendering. This is almost always the look you want, but turning it off will give a sharper appearance.

drawAll="true"

Draws all the single size objects. If true overrides most other "draw" settings. If false, be sure to specify other "draw" attributes.

drawBasic="false"

If true, draws the floor and cube.

drawWall="false"

If true, draws straight walls.

drawJoin="false"

If true, draws joins that connect walls.

drawWallJoin="false"

If true, draws the 2 joins that have a wall face. Useful because only these 2 joins use the overlays.

drawRamp="false"

If true, draws the ramps.The first ramp is East one unit and Up one unit. The 2nd ramp is North one unit and up one unit.

Although good for positioning and correctly establishing the image seams, you will probably want to edit the ramps to either be stairs, have thickness, or both.

drawDouble="true"

Modifies the above options to also draw the "double height" graphics. This allows a sprite that is 2 units high compared to the walls. Setting drawAll="true" and drawDouble="true" gives the following set -

floor="floor.bmp"
wall="wall.bmp"

Specify the floor or wall texture, which should be a seamless texture. (See Textures, above.) These are the base texture. Overlays are applied on top of the floor or wall texture.

action="ICON0"

If you are using Kyra, each set is an Action to the Kyra engine, with a postfix attached. For example, "FOO.JOIN.NWSE". You can specify the name of the action with this tag. Note that all actions have one frame when generated from isogen.

<WallOverlay>
<FloorOverlay>

The overlays add images on top of the basic floor and wall texture. They can produce many effects - some ideas are below. You can add any number of overlays. With overlays, remember that true black will be interpreted as transparent.

name="filename.bmp"

Specify the file name of the overlay. The simplest overlay is very useful, and puts an image on your wall or floor.

alpha="1.0"

Apply an alpha value to the image. 1.0 is opaque and 0.0 is fully transparent. Values in the middle blend the image on the layers below. If a 32 bit texture is used, then the alpha parameter is applied as well as the alpha of each pixel in the texture.

The image on the left has alpha=1.0, or the right, alpha=0.4

emit="false"

If set to true, the overlay emits light. This can be used for glow or neon effects. There is a very subtle "torchlight" effect is the dungeon.xml example shipped with isogen.

A simple glow effect using the mystical glyph of the wizard "M".