---
Copyright © 2024-2025 Kyle Gagner
---

# Open-Vario

Open-Vario is an open source design for toy train track and accessories. Intercompatible track is manufactured in wood and plastic by many brands, but there is no industry standard design specification for this toy system, sometimes called the vario system. Open-Vario's OpenSCAD files specify dimensions, implement design, and are ready to use for 3D printing and other applications. The parametric library of track is complemented with a system of toy blocks to support hills and elevated track, and a system for trains. The blocks' interlocking features, inspired by prefabricated concrete blocks, allow for more sturdy construction. For makers, the train system is easily extended with your car body designs using your preferred design tools.
Open-Vario is in active development. No part of the design is finalized at this time. If you have ideas, requests, or bug reports for Open-Vario, send an E-mail to <kyle@gagner.us>.

## Getting Started

### Start Printing

See [Thingiverse release](#202512-thingiverse) with pre-rendered STL files. Most pieces are printed in their orientation in the stl file. Track has nice tactility in a wood-filled PLA filament. Blocks are attractively finished in matte PLA.

#### Printing Hills

Parabolic track transitions between track grades, such as level grade to an upward hill grade. Helical track curves left or right while at hill grade. These pieces must be re-oriented manually and will require support material. Support removal may be difficult and require the use of danngerous tools with sharp edges.

#### Printing Trains

Train pieces are single pieces or print-in-place, with no supports. The pre-rendered STLs are likely to work for you, however you may refer to [Start Customizing Parts](#start-customizing-parts) if you must adjust clearances. All train parts are generatedby _custom-train.scad_. Train assemblies have small parts. Dry lubricants may be hazardous.

* Plain PLA is recommended. It is smooth, rigid, and sufficiently strong. Wood fiber filled filaments and matte filaments should not be used for these parts, due to higher friction rolling contact surfaces and compromised strength. Some filaments, such as PETG, may be too flexible for snap-together parts.
* Bearing surfaces for wheels must be lubricated with graphite. Coloring with a pencil works well but is tedious. Graphite powder may be difficult to use, but can be applied faster.
* Print one set of 4 wheels &mdash; _train-set-of-wheels.stl_.
* Print one truck for a fixed car &mdash; _train-truck-for-fixed-car.stl_.
* Print one fixed flatcar body &mdash; _train-fixed-flatcar-body.stl_.
* If you have graphite powder, snap on the wheels and work some graphite into each axle.
* If you do not have graphite powder, color the axles thoroughly with a pencil then snap on the wheels.
* Vigorously roll the truck back and forth on your palm to break in the wheel / axle bearing surfaces.
* Try rolling the truck on track. If the wheels are too tight and won't roll, you will need to customize their clearance adjustment. If the wheels are too sloppy and camber excessively, you will need to customize them in this case as well. The parameter _vario\_truck\_pin\_clearance\_adjustment_ should be increased for tight wheels and decreased for sloppy wheels.
* Work the couplers back and forth more gently than the wheels. If pivoting takes excessive force, or the pivot is so sloppy that the coupler drags down on the track, you will need to adjust the truck's _vario\_coupler\_arm\_clearance\_adjustment_.
* Print a fixed flatcar body and pin for fixed car. Push the recessed feature on the body down onto the interlocking feature of the truck. If it does not fit, you will need to increase the truck's _vario\_truck\_plate\_clearance\_adjustment_.
* To pin your fixed truck to the body removably, print one fixed body pin &mdash; _train-pin-for-fixed-car.stl_. Fit the body and car together and push the pin through the bottom of the truck until it snaps into the body and is flush with the bottom of the truck. If the body is loose on the truck, decrease _vario\_truck\_plate\_clearance\_adjustment_.
* Alternately, you may also glue the truck and body together, with no need for a pin.
* To print an articulating car print two sets of 4 wheels, one set of trucks for articulating cars, one set of pivots, and an articulating flatcar body &mdash; _train-set-of-trucks-for-articulating-car.stl_, _train-set-of-pivots-for-articulating-car.stl_, _train-articulating-flatcar-body.stl_.
* The pivots for articulating cars snap onto pins in the bottom of the train body such that the pivot's own pin is centered on the body. Snap the pivoting pins down into each truck.

### Start Making Train Bodies

Open-Vario comes with exclusions which may be subtracted from the bottom of your own train car designs to attach to trucks. Use a single _train-fixed-train-body-exclusion.stl_ or a pair of _train-articulating-train-body-exclusion.stl_. See _train-fixed-flatcar-body.stl_ and _train-articulating-train-body-exclusion.stl_ as examples. If your design software does not have constructive solid geometry / boolean operations, you can likely use your 3D slicer's software to do the subtraction.

### Start Customizing Parts

* Download the latest [development snapshot of OpenSCAD](https://openscad.org/downloads.html#snapshots). Download links are also available in _OpenSCAD-downloads.yml_.
* See [GitLab release](#202512-gitlab) to get a copy of Open-Vario's source code.
* The scripts _custom-straight-track.scad_ and other _custom-*.scad_ files are designed for [OpenSCAD's customizer](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Customizer).

### Start Rendering Batches

* Follow setup for customizing parts above.
* Install [Python](https://www.python.org/).
* Save your customizer parameter sets, stored in the customizer script's corresponding _.json_ file.
* Run the build script:
  ```
  python build-customizer-presets.py
  ```
* If OpenSCAD is standalone, rather than installed, also use the `--openscad <path>` flag, to specify the path to OpenSCAD.
* For more options, use the `-h` flag to view help.

### Start Learning Dimensions

* See [GitLab release](#202512-gitlab) to get a copy of Open-Vario's source code.
* See [Thingiverse release](#202512) for a copy of _draft.pdf_. Or: OpenSCAD can render and [export](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Export) the draft to PDF &mdash; a background of 2.5mm grid is recommended.
* The top of _open-vario.scad_ contains dimensions specifications as commented global variables. A visual aid for interpreting the specification is provided in _draft.scad_ / _draft.pdf_.

### Start Extending Open-Vario

* Follow setup for customizing parts above.
* See [Usage](#usage) below.

## Releases

### 2025.12 Thingiverse

Coming soon.

### 2025.12 GitLab

* Browse: <https://gitlab.com/Kyle-Gagner/open-vario/-/tree/release/2025.12?ref_type=heads>
* Zip file: <https://gitlab.com/Kyle-Gagner/open-vario/-/archive/release/2025.12/open-vario-release-2025.12.zip>
* [Git](https://git-scm.com/downloads) clone:
  ```
  git clone https://gitlab.com/Kyle-Gagner/open-vario.git
  git checkout release/2025.12
  ```

### 2025.04 Thingiverse

Enjoy 150 pre-rendered track pieces on Thingiverse! Not all are play tested, so feedback is welcome. Leave a comment or post a make with your thoughts!

<https://www.thingiverse.com/thing:7016070>

### 2025.04 GitLab

* Browse: <https://gitlab.com/Kyle-Gagner/open-vario/-/tree/release/2025.04?ref_type=heads>
* Zip file: <https://gitlab.com/Kyle-Gagner/open-vario/-/archive/release/2025.04/open-vario-release-2025.04.zip>
* [Git](https://git-scm.com/downloads) clone:
  ```
  git clone https://gitlab.com/Kyle-Gagner/open-vario.git
  git checkout release/2025.04
  ```

### 2025.01

Gitlab: <https://gitlab.com/Kyle-Gagner/open-vario/-/tree/release/2025.01?ref_type=heads>

Thingiverse: <https://www.thingiverse.com/thing:6895688>

## Usage

### OpenSCAD Library

All global variables and primitive parts are in _open-vario.scad_. To use Open-Vario as an OpenSCAD library, put `include <open-vario/open-vario.scad>` at the top of your script. To use complex parts, you may also include _tactile-track.scad_ and/or _junction-track.scad_. You may include _quality.scad_ to use the same quality defaults used in the customizer scripts. See [Installation](#installation) below to install Open-Vario into your OpenSCAD installation, or to add it as a Git submodule in your own repository. See [API Docs](#api-docs) below for library usage.

### Installation

* If using as a library, install in an OpenSCAD library path:
  * Refer to: [Open-SCAD User Manual/Libraries](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Libraries#Library_locations)
  * Place the scad scripts in an _open-vario/_ subdirectory of your library location.
* If creating your own repository, consider adding Open-Vario as a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules).

## API Docs

The primitive modules in _open-vario.scad_, complex parts in _junction-track.scad_, and blocks in _vario-blocks.scad_ are parameterized with common parameters and special variables.

### Common Parameters

Common parameters have the same purpose in multiple modules

| Parameter | Purpose | Recommendation |
| :--- | :--- | :--- |
| count | number of parallel tracks | 1 or 2 |
| z1, z2 | Z-axis extent of connector pegs | defaults except special cases |
| fraction | length of a track piece as a fraction of vario_basic_length | 1/4, 1/3, 1/2, 2/3, 3/4, 1 |
| length | override fraction with a specified length | as required, limited uses |
| number | curve radius is `vario_basic_radius + vario_track_spacing*(number + (count - 1)/2)` | 0 through 3 |
| radius | override number with a specified radius | as required, limited uses |
| angle | angle of a curve | 15, 30, 45, 60 |
| shift | for sigmoid track, the horizontal (X-axis) distance between centers at either end of the track as multiples of vario_track_spacing | -2 through 2 in steps of 1/2 |
| conn_* | connector polarities at track ends | &gt;0 (peg), =0 (none), &lt;0 (hole) |
| extend | create track primitives with slightly extended ends | `true` for negative track profiles when constructing with combined primitives |
| symmetric | for select track pieces specifies whether the part is symmetric | `true` or `false` |
| grade, grade1, grade2 | hill grade | 0, 0.25
| tangent | lengthens track piece by `sqrt(1 + tangent^2)` | 0, 0.25 for hill grades; 0, tan(30), tan(45) for angles in the horizontal plane |
| tactile | enables tactile elements | use for straight greater than 1/4 length in multiples of 1/12th; use for all parabolic track |

### Additional Common Parameters for Blocks

| Parameter | Purpose | Recommendation |
| :--- | :--- | :--- |
| rows, cols | depth and width in block units | 2 through 8 |
| slabs | height in block units | 1, 2, 4, 6 |
| top | top index pattern | "grid", "flat" |
| bottom | bottom index pattern | "checkers", "grid" |
| reduction | amount of taper | -2 through 2 |

### Additional Common Parameters for Trains

| Parameter | Purpose | Recommendation |
| :--- | :--- | :--- |
| wheelbase | distance between front and back axles on truck | default 25 for articulated trucks, 40 for fixed trucks |
| units | length of flatcars in block units | 4 for fixed flatcars, 8 for articulated flatcars |
| diameter | wheel diameter | default 20 |
| part | name of part for module which produces multiple shapes | see [Train Modules](#train-modules) |
| coupler_south, coupler_north | booleans to enable or disable couplers on each end of the trucks | trucks have 180 degree rotational symmetry; if you want just one coupler it does not matter which you disable |
| assembly_sample | shows an assembly for visualization purposes, not for printing |


### Profile Special Variables

These special variables shape the profile of track and are `undef` by default. Setting these special variables overrides default behaviors. Road on a top or bottom surface always overrides rails on the same surface.

| Special Variable | Purpose | Overrides |
| :--- | :--- | :--- |
| $vario_profile_chamfer_rail | set `false` to produce a profile with no chamfers on the edges of its rails and/or road surfaces |
| $vario_profile_taper_rail | set `false` to produce a profile with no taper to the edges of its rails and/or road surfaces |
| $vario_profile_positive | set `true` to produce a profile with no rails or road surface | $vario_profile_\*[rails\|rail\|road\] |
| $vario_profile_negative | set `true` to produce a negative profile consisting only of rails and/or road cutouts | |
| $vario_profile_rails | set `false` to produce a profile with no rails | |
| $vario_profile_\[top\|bottom\]_rails | sets top or bottom surface rails | $vario_profile_rails |
| $vario_profile_\[top\|bottom\]_\[left\|right\]_rail | sets specific rails | $vario_profile_rails, $vario_profile_\[top\|bottom\]_rails |
| $vario_profile_roads | set `true` to produce a profile with roads | |
| $vario_profile_\[top\|bottom\]_road | sets top or bottom surface road | $vario_profile_roads, $vario_profile_\[top\|bottom\]_road |
| $vario_profile_chamfers | set `false` to produce a profile with no track edge chamfers |
| $vario_profile_\[top\|bottom\]_chamfers | sets top or bottom edge chamfers | $vario_profile_chamfers |
$vario_profile_\[top\|bottom\]_\[left\|right\]_chamfer | sets specific chamfers | $vario_profile_chamfers, $vario_profile_\[top\|bottom\]_chamfers |
| $vario_profile_full_width | set `true` to make track in _vario_track_spacing_ width rather than _vario_track_width_ |

### Plan and Profile Modules

Nearly all shapes in Open-Vario are combined extrusions from these fundamental modules:

| Module | Purpose |
| :--- | :--- |
| vario_rail_negative, vario_road_negative | for construction of track profiles |
| vario_chamfer_negative | for construction of track profiles |
| vario_connector_positive_plan | for extrusion into a track peg end |
| vario_connector_negative_plan | for extrusion into a hole (peg receptacle) track end negative |
| vario_track_profile | for extrusion into a track |

### Connector Solid Modules

| Module | Purpose |
| :--- | :--- |
| vario_connector_positive | to be unioned to a track end for a peg |
| vario_connector_negative | to be subtracted from a track end for a hole |
| vario_connector | to be unioned and subtracted to/from a track end, for parameterized connections in a track module |

To use vario_connector, union the track end with negative `false` and difference from the track end with negative `true`. By passing the polarity through in each case, the module will automatically handle unioning the peg, subtracting the hole, or neither unioning nor subtracting, as appropriate for the polarity.

### Core Track Modules

| Module | Remarks |
| :--- | :--- |
| vario_straight_track | straight track |
| vario_curve_track | positive angles curve to the right |
| vario_sigmoid_track | positive shifts move to the right |
| vario_parabola_track | primitive for hill track features |

### Block Modules

| Module | Remarks |
| :--- | :--- |
| vario_block_regular | regular block, with support for endstops with optional connectors |
| vario_block_sloped | sloped top block, mostly used to support track with an optional connector |
| vario_block_tapered_2 | block with two tapered sides |
| vario_block_tapered_4 | block with four tapered sides |

### Train Variables

| Variable | Purpose |
| :--- | :--- | :--- |
| vario_truck_plate_clearance_adjustment | increase if fixed bodies will not fit on the truck's interlocking features; decrease if the fixed bodies are loose on the truck |
| vario_coupler_arm_clearance_adjustment | increase if the coupler arm is tight in its socket; decrease if it is loose, coupler drags on the track, or coupler pulls out of its socket |
| vario_truck_pin_clearance_adjustment | increase if wheels are tight and fail to roll; decrease if the wheels are loose and camber excessively |

### Train Modules

| Module | Remarks |
| :--- | :--- |
| vario_truck_wheel | a wheel |
| vario_truck | a truck with print-in-place couplers, an interlocking feature on the top, and axle pins for each of 4 wheels |
| vario_train_flatcar_articulated | a flatcar for attachment to articulated trucks; stacks blocks |
| vario_train_flatcar_fixed | a flatcar for attachment to fixed trucks; stacks blocks |
| vario_truck_pivot | a pivoting pin for articulated trucks and an exclusion which may be subtracted from the bottom of a train car to accomodate the pin |
| vario_truck_fixture | an attachment pin for fixed trucks and an exclusion which may be subtracted from the bottom of a train car to accomodate the pin and interlocking features on the truck |

### Complex Track Modules

Complex track pieces are combined from primitives. Complex track itself is not intended to be combined in assembling yet further derived track &mdash; these are merely parametric track pieces. Modules are found in _junction-track.scad_.

### Freeform Track Modules

| Module | Remarks |
| :--- | :--- |
| vario_freeform_track | track of arbitrary shape, defined using control points for a Catmull-Rom spline |
| vario_helical_track | and upward curving hill; the track is chiral so you may wish to make it in positive and negative angle pairs for both orientations |

# Licensing

The MIT license is permissive, easy to use, and easy to understand. However, Thingiverse does not offer the option of MIT licensing. For that reason, this work is dual licensed under the MIT license and the BSD-2-Clause license. That is, you may exercise your preference between the two.