> 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

Train Commands

car, lencar

For ease of use, the train system is designed so that a standard one-unit cube or tesseract in default position can be used as a railcar. The car will be scaled down to whatever scale is set by the track and then stretched by an amount that's set by the track but can be overridden for individual cars.

The command "car" takes the shape on the stack and makes it into a railcar. The command "lencar" takes an additional length argument which replaces the default car length for that one car. In particular, "1 lencar" prevents the car length from being adjusted, which is useful if you've built some elaborate shape that shouldn't be stretched.


len front-bevel back-bevel trainpoly - This creates a two-dimensional rectangle of length "len" and height 1 with 45-degree front and back bevels that range from 0 (none) to 1 (full). This is useful for creating nice engine shapes. You have to do a "prism" operation before you can use the shapes, of course. You'll often want to use "1 lencar" on railcars created in this way.


There can be only one track object per scene, but the track can contain disjoint loops. The "newtrack" command creates the track object while the "track" command (below) adds track segments. Track segments are laid out on tiles of size 1, so the scales and widths and so forth will normally be a lot less than 1.

The "newtrack" command has many interesting arguments, all required.

  • The dimension, 3 or 4.
  • The default car length to be applied to all cars.
  • The scale to be applied to all cars.
  • The width of the rails.
  • The size of the margin on each tile where the rails run straight. (This can be zero.)
  • The number of segments that curves are broken into for display purposes.
  • The track color.
  • The track color for switched segments.
  • Whether or not the rails should start out expanded (boolean).
  • The velocity increment.


The track object created by newtrack must be on top of the stack for this command to work.

track-object pos dir1 dir2 instructions track

The "pos" argument is the starting position for this bit of track. The coordinates must be integers, and the y coordinate should be zero unless you're building an elevated track. From the starting position, you move outward in direction "dir1" and build track according to the instructions. No tile is placed at the starting position unless you loop back around to it.

What about that "dir2" argument? In 3D you should always set it to "w+". In 4D it tells which direction is inward and so specifies the rest of your orientation. If you're just getting started, the following values are reasonable. They start you off in the middle of the floor mat, facing in the same direction that you'll be looking when you load the geometry.

3D : [0 0 0]   z+ w+
4D : [0 0 0 0] w+ z-

The instructions are built from the following letter codes. The whole set of instructions must be inside double quotes.

s     -- straight segment
l r -- turn left or right
i o -- turn in or out
u d -- add a ramp up or down (see Elevated Train Commands)
g h -- straight segment with left or right helix (4D only) (*)
t -- turn around (in the left-right direction)
space -- ignored, so you can break up long instructions

So, if you have a track object on the stack already, you can create a simple 3D loop track like so.

[0 0 0] z+ w+ "llslls" track

When you're building track in 4D, it may be helpful to think of the in and out directions as up and down, or as down and up, depending on what you're doing. The track sits flat on the 3D floor so you only need three dimensions to think about how you want to lay it out. Unless it's elevated, of course!

(*) When a train traverses a helical segment, its left, right, in, and out directions get cycled around. To keep things simple that doesn't happen during the track-building step.


There can be any number of train objects per scene, and each train can contain any number of cars. (Although, take it easy at first, performance isn't great.)

The "train" command also has many interesting arguments, starting with these.

  • An array of railcars. (So, yes, you need brackets around them.)
  • The gap between cars.
  • The starting position of the (head of the) train. This is a tile position and must be all integers.

The next two arguments tell which segment of track the train should start on. If you're sitting in the middle of that tile, first look in the direction the segment enters the tile. That's the first argument. Then look in the direction the segment leaves the tile. That's the second argument. In the simple loop example above, the tile at the origin has a straight segment in the z direction, so we could place a train on that tile moving away from us with the arguments "[0 0 0] z- z+".

Of course, we still haven't completely specified the train position, so we need one more argument to tell the distance along the segment.

Finally, there's the "train mode", which normally should be set to "TM_ROTATE". The value "TM_ROUND" makes the cars move around the track without rotating, which is cute for cubes but not much use for anything else. The value "TM_SQUARE" makes the cars move in square paths through the centers of the tiles. This is useful if you want to make large blocks move around without running into anything. The rails are always drawn with curves, however.