> 4D Blocks

> Version 6

  Block Motion
> Scene Language
  Kinds of Blocks

  General Information
  Geometry Commands
  More Geometry Commands
  Train Commands
  Elevated Train Commands
> Scenery Commands

Scenery Commands

To understand what kinds of things these commands do, please go look at Scenery Examples. Also, please realize that scenery is relatively slow to render. I haven't worked out any optimizations yet, so to tell whether a line of scenery is visible I have to look at every single block in the scene.


If a scene file contains no scenery, a standard mat is automatically added.

So, if a scene file does contain scenery, you'll need to add a standard mat explicitly if you want one. The commands for that are "mat3" and "mat4". Also, the command "oldmat4" will give you the old version of the 4D mat. I thought it had too many lines, but it's worth a look.

If, on the other hand, you don't want a mat or any other scenery, you can use the "nomat" command.

For reference, the center of the standard mat is a unit cell with coordinates in the range 0-1. The mat itself is 5x5 (x5). In 3D the user starts at (0,0,-3) with x+ to the right and z+ forward. In 4D the user starts at (0,0,0,-3) with x+ to the right, z+ outward, and w+ forward. Actually, those are integral cell coordinates. In 3D the user really starts at (0.5,0.5,-2.5).

Scene files normally have to contain at least one block—that's how the program knows whether the world is supposed to be three- or four-dimensional. If you want to have a world that's only scenery, you can use one of the commands "noblock3" and "noblock4" instead.

Custom Scenery

If you want to create your own mats, or draw on the ground in any other way, you can do that with the "groundtexture" command.

texture color projectionmode datum groundtexture

The given texture is projected onto the ground using the given projection mode and datum. Projection modes are explained at the end of More Geometry Commands.

If you want to draw on the sky hemisphere, you can do that with the "monolith" command.

texture color monolith

In this case, the texture is projected outward with the user's viewpoint as the origin. So, for example, a line from (0,0,1) to (0,1,1) will create a vertical line marking north (z+) that extends from ground level to 45 degrees elevation. I haven't made a ringworld monolith yet but that's definitely something one could do.

Artificial Scenery

You can create a coordinate grid on the ground with the "grid3" and "grid4" commands. These take five arguments: the grid color, the radius of the area where the grid should be drawn, a boolean flag for whether the area should be round (true) or square (false), and the base value and interval for the grid lines. For example, if the base is -2 and the interval is 5, there will be grid lines at -2, 3, 8, 13, and so on (and also -7, -12, and so on), matching the outer edge of the standard mat.

You can create a set of compass points with the "compass3" and compass4" commands. These take four arguments: a color function, the radius where the tips lie, the length backward, and the width at the back end. There are currently only two commands that produce color functions: "colorconst", which takes a color argument and produces a constant color, and "colorblend", which takes an array of colors, one per direction in the order x+ x- y+ y- etc., and produces different colors in different directions. There are no compass points in the y directions so you can leave those array entries null.

There's a third command "colordir" that in this context does exactly the same thing as "colorblend". The difference is that as you turn from one compass point to another, "colorblend" changes color smoothly, while "colordir" changes abruptly, blending only at the midpoint. So, you can use "colordir" with the "sky" command below to get slightly different effects.


There are a bunch of commands that create meshes. A mesh is a specialized texture where the vertices all have y=0 and lie at unit distance from the origin. In 3D that doesn't leave many degrees of freedom. The vertices have to lie on a circle, so if you want them to be uniformly spaced, the only question is how many of them there should be. The command "n offset meshring3" creates that mesh. The offset can range from 0 to 1 but should usually be zero.

In 4D there are more possibilities. I'll list the commands, but the easiest way to understand the shapes is to look at the "scenery-mesh" examples. The letters in parentheses are the example numbers.

  • n offset meshring4 (a) - Three orthogonal rings.
  • array meshframe4 - A cubic frame.
  • array meshringframe4 (b) - Three orthogonal rings plus a cubic frame.
  • array meshcube4 (c) - A cubic frame with square grids on the faces.
  • latarray n offset meshsphere4 (d) - A sphere with lines of latitude and longitude.

The "array" argument gives the coordinates of the vertices and/or grid lines before normalization. It's easiest to think about in the "meshcube4" case, where the array values are used to put square grids on the faces of a cube. The first and last values should be -1 and 1 if you want the grids on different faces to join up.

As a detailed example, if the array is the usual one ...

[-1 -0.4142 0 0.4142 1]

then the face with w=1 will have vertices at (x,0,z,1), with x and z values taken from the array. The vertex (1,0,0,1) will project down to a 45-degree point, and the vertex (0.4142,0,0,1) will project down to a 22.5-degree point, which is why that exact value was chosen.

The "latarray" argument is the same kind of thing, but there the values -1 and 1 should be omitted.

The commands "groundcube3" and "groundcube4" (no arguments) create unnormalized cubic meshes that can be used with the "ground" command below.

Natural Scenery

The "ground" command takes a mesh, a color, and a radius as arguments and creates an indicator ring (or whatever the mesh is) that follows you around on the ground.

The "sun" command takes a mesh, a color, and a height as arguments and creates a sun (always at zenith). The height is relative to the unit length of the mesh vertices, so height 1 will give you a giant sun that extends 45 degrees downward from the zenith.

Before I can explain the last two commands, I need to tell you about the height functions that are used to define mountain heights. A height function takes a horizontal direction and returns a height. Here horizontal directions are represented by points on the unit sphere that have y=0.

  • height heightconst - A constant height.
  • n height heightpower - A function that sums the nth powers of the coordinates and multiplies the result by the "height" number. This is what's used to create the standard mountains.
  • pos min n height mountain - If you want to create a single mountain you can use this command. Here "pos" is the horizontal direction to the mountain, "min" is the cosine of the angle between the mountain's center and its edge, "n" gives a power to apply, making the mountain pointier or flatter, and "height" gives the maximum height.
  • [height1 ... heightN] heightmax - When there are several ranges of mountains, or several individual mountains, the net height at the horizon is the maximum of the individual heights. "heightmax" is used to combine height functions in that way.

The "horizon" command takes a mesh, a color, a height function, and a clipping height function as arguments and creates a horizon. The clipping function can usually just be null. If you have one range of mountains behind another, the clipping function for the second range should be the height function of the first. To assist with that, horizon scenery objects are also height functions, so you can pass the first range as an argument to the second, like so.

[-1 -0.4142 0 0.4142 1] meshcube4 "mesh" def

// range 1
[0 0 0 1] 0.5 4 1 mountain
null // no clipping on range 1

// range 2
[0.7071 0 0 0.7071] 0.5 4 1 mountain
3 index // grab the previous horizon for clipping

Finally, the "sky" command takes a mesh, a color function, an array of heights, a sun color, an array of sun color blending values, and a height function as arguments and uses them to create sky-rays extending from the sun to the ground. What do all the arguments do? Well, the height function part is simple enough—it tells where the ground is so that the sky-rays can extend that far and no farther. (In this context you have to say "5 index" to grab the previous horizon.) The mesh and color function are also pretty much what you'd expect. That leaves the sun color blending.

Here's how that works. The height array is twice as long as the blending array. To construct a segment of sky-ray, take two numbers from the height array to get the start and end heights and one number from the blending array to tell how much sun color should be blended in (0 = no blending, 1 = pure sun color). If you want the segments to join up, you'll have lots of duplicate numbers in the height array, but that's not required.

You can include the file "sky3" or "sky4" to add a standard sky to any scene.