Level Design

The first steps to create a basic level are described in the Game Design Tutorial that you should start with. However, not only aesthetical, but also technical issues must be considered when designing a level. They are described herein.

BSP Tree Considerations

For building an A7 BSP Map, the invisible intersecting parts of blocks are clipped off by the build process, and new edges and vertices are automatically placed at the intersections. This makes rendering faster, because the overlapping parts of blocks aren't rendered (in a Simple Map, all blocks in the view frustum are just rendered over each other). The disadvantage is that small angle differences can lead to large vertex position differences. If surfaces touch or intersect at a very small angle, inaccuracies of only 1/100 degree can move the joining edge position by several pixels, which is really visible in the level.

For this reason, don't use extremely narrow, elongated, or acute blocks for a BSP Map . Do not create blocks with edges smaller than 2 quants. Always try to design your map with as less surfaces as possible, and use as thick blocks as possible. Sometimes you can't avoid surfaces touching at small angles - but even then there's a bad way and a good way to do it. For instance, if you have a sloping road over a hill (side view):

Bad BSP design: uses long thin plates, and small angle inaccuracies in the marked joints will be visible as 'gaps' or 'steps' from above.

Good BSP design: 3 blocks with 13 surfaces instead of 5 blocks with 20, and angle inaccuracies, even if they occur, won't be visible.

The BSP tree creation will 'snap' all vertices to integer positions. This can produce problems with T-junctions - a place where two block edges form a 'T' - when the junction vertex is not at an integer position. In this case the vertex displacement to an integer position can leave a visible gap or seam between the junction and the non-displaced crossbar of the 'T'. This is a common problem in BSP tree levels. The map compiler tries to convert as much 3-way T junctions as possible to 4-way 'X' junctions that aren't a problem in that reagrd. But it can't catch all. There are two solutions: a) have no T-junctions, and/or b) have all vertices snapped to the integer grid in your level.

Lighting considerations

Static lights and shadowmaps greatly add to the atmosphere of a level. Although they are available in all Gamestudio editions and are simple to use - you only need to place lights and give them proper ranges and colors - some users manage to create a level with really bad lighting, or with no lighting at all. The three most common beginner's mistakes are:

• Not knowing about static lights and thus not using them.
• Using too bright Sun and Ambient colors in Map Properties that give the level a full-bright look and eliminate all shadows.
• Putting the level together from model entities that are not static and thus don't have any shadow maps. When you want a static model in the level, use File/Import for converting it to level geometry. If you place it as entity instead, it may move, and you can attach actions, but it won't have a shadow map.

Use static lighting carefully and you'll end up with a great looking level. You'll find a description of the light algorithms under Light Engine, and hints how to use dynamic lights for shaders under Shader Guide.

More level design hints

• Construct any map or model in a way that the coordinate grid origin - the point with coordinates 0,0,0 - is always within its boundaries and close to its center. Having the origin far outside your level or entity will not only cause slower rendering. Floating point inaccuracies can even lead to collision problems and wrong texture positions.
• Use the Snap to Grid function whenever possible. Blocks that are aligned to each other, and have perfectly vertical and horizontal edges in all three windows not only look better - they are also better for the BSP tree and compile and render noticeably faster.
• Each level should be surrounded by a sky box. A sky box is just a very large hollowed cube, normally with a sky texture assigned. The level sits inside this box.
• Each level should have a ground plane (which can be the bottom block of the sky box). The ground plane receives the environment light at the ground, and is needed for calculating the brightness of the entities above it.
• Don't create or import blocks with extremely small or narrow surfaces. If no lightmap sample point falls into the surface area, the surface won't be lit properly.
• Use the Detail flag for small blocks that don't obscure visibility or need collision detection.
• For non-visible surfaces - like the bottom side of ground plates or the sides of water blocks - mark the None flag. This can save valuable texture memory that would otherwise be used for black or invisible light maps.