System Requirements

Installation

Download the current release from the client portal at portal.whitehorn.ltd. Compiler updates, runtime-library updates, and new editions of this guide are all published there.

Two ways to install, depending on your platform:

Path Platforms Download
Installer Windows 10 and 11, x64 triton-rpg-win64.msi
Universal zip Linux, macOS, or Windows triton-rpg-universal.zip

Triton RPG requires Java 17 or later on the machine that runs it. If you don't already have a JDK or JRE installed, download and install one from Adoptium before proceeding.

Windows (installer)

The recommended way to install Triton RPG on Windows is with our installer. First, run triton-rpg-win64.msi and follow the install wizard: accept the licence, choose which components you want and where they go, confirm, and finish. rpgc and rpg-lsp are on your PATH when it's done, and the jars they run are already in the install location's lib folder - all ready to use immediately.

Four components are offered, all selected by default. Clear the checkbox of any you don't want; use Browse on the component tree to change the install location.

Component What it installs
Compiler rpgc, the language server, and the Triton RPG runtime library. This is the product itself, so it cannot be deselected.
Visual Studio Code Extension The extension file, registered with VS Code for you if code is on your PATH.
Documentation This guide, as a PDF, in the install location's doc folder.
Start Menu Group A Triton RPG group containing Triton Compiler - a command prompt with rpgc already on its PATH - plus a shortcut to the guide, if you chose to install it.

Clearing Visual Studio Code Extension skips both the extension file and the registration. If you keep it but code isn't on your PATH, the install still succeeds and the extension file is left at <install location>\editor\triton-rpg.vsix for you to install yourself (see below).

Universal zip (Linux, macOS, or Windows)

Triton RPG is also shipped as a universal ZIP file containing everything for every platform. Unzip triton-rpg-universal.zip and it unpacks a triton-rpg folder laid out like the Windows install:

triton-rpg/
  bin/
    rpgc          the compiler          (Linux, macOS)
    rpgc.cmd      the compiler          (Windows)
    rpg-lsp       the language server   (Linux, macOS)
    rpg-lsp.cmd   the language server   (Windows)
  lib/
    rpgc.jar        the compiler, as a jar
    rpg-lsp.jar     the language server, as a jar
    triton-rpg.jar  the runtime library
  editor/
    triton-rpg.vsix the VS Code extension

Move the triton-rpg folder wherever you keep tools, then add its bin directory to your PATH. Keep the folder intact - the launchers in bin find their jars at ../lib, so moving files out of the tree individually will break them.

export PATH="$PATH:/opt/triton-rpg/bin"     # Linux, macOS

You can also run any jar directly if you prefer - java -jar /opt/triton-rpg/lib/rpgc.jar - and the options are identical either way.

triton-rpg.jar is the runtime library, and must be on the classpath of every compiled program at run time. The examples throughout this guide assume it is beside your output directory; adjust the path to wherever your copy lives.

Editor integration (optional)

The Triton RPG extension brings the compiler's diagnostics, hover, go-to-definition, find-references, rename and completion into VS Code. Install it from the file that came with your copy:

code --install-extension /opt/triton-rpg/editor/triton-rpg.vsix     # Linux, macOS
code --install-extension "%LOCALAPPDATA%\Programs\Triton RPG\editor\triton-rpg.vsix"

This works offline, and works the same way in VS Code forks that provide a code command - VSCodium, Cursor, Windsurf, Insiders. See Editor Integration for what it provides.

The extension is not published to the Visual Studio Marketplace, so it does not update itself. New versions come from the portal with the rest of Triton RPG; install the new .vsix the same way to upgrade.

# Verify the installation
rpgc --version   # prints the compiler version, e.g. "rpgc 2026.09.3"
rpgc --help

Licensing

Triton RPG requires a valid license file to operate. To obtain your license:

  1. Run rpgc --machine-key. It prints a machine key in the form TRP-XXXX-XXXX-XXXX, identifying this specific machine - it works with no license installed, or with an expired or corrupt one.
  2. Submit that key at portal.whitehorn.ltd, or send it to your account representative.
  3. Download the .lic file the portal issues you.
  4. Place it where rpgc will find it. rpgc checks, in order: the --license <path> flag, the RPGC_LICENSE environment variable, then the default ~/.rpgc/license.lic.

One license covers the whole product. The language server uses the same file and the same three locations - see Editor Integration, which notes one wrinkle: an editor launched from a desktop icon rather than a shell usually cannot see RPGC_LICENSE.

rpgc --machine-key
# Machine Key: TRP-XXXX-XXXX-XXXX

cp TRP-XXXX-XXXX-XXXX.lic ~/.rpgc/license.lic

Run --machine-key on the machine that will actually run the compiler - a key taken from a different machine (your laptop, say, instead of the build agent) produces a license that won't validate there. The key is derived locally from the host's own characteristics, with no network connection; the same machine always produces the same key, though a substantial hardware change can alter it and require a re-issued license.

If a license is missing, expired, corrupt, or issued for a different machine or product, rpgc reports it and exits without writing any .class files. Every such error echoes the machine key back so you never need a second command to find out what to send:

[ERROR] License has expired. Please renew at https://whitehorn.ltd

       Machine Key: TRP-XXXX-XXXX-XXXX

       To obtain a license, provide this Machine Key to your
       account representative or visit https://portal.whitehorn.ltd

Your First Compile

Create a file called hello.rpgle:

**FREE
DCL-S greeting CHAR(50);
greeting = 'Hello from rpgc!';
DSPLY greeting;
*INLR = *ON;
RETURN;

Compile and run:

rpgc hello.rpgle
java -cp out:triton-rpg.jar HELLO

You should see:

DSPLY  Hello from rpgc!

A Program with a Display File

For interactive programs, you need a DDS display file and the --dds-path flag. Given a display file qddssrc/myscreen.dspf and a program myapp.rpgle that declares DCL-F MYSCREEN WORKSTN, compile with:

rpgc --dds-path qddssrc myapp.rpgle

Run with the terminal screen handler (the default - renders the 5250 screen in your terminal):

java -cp out:triton-rpg.jar:jline-3.25.1.jar MYAPP

Or, for the Swing GUI screen handler, compile with --screen:

rpgc --dds-path qddssrc --screen ltd.whitehorn.rpg.handler.GuiScreenHandler myapp.rpgle
java -cp out:triton-rpg.jar:jline-3.25.1.jar MYAPP

A Program with Embedded SQL

Programs that use EXEC SQL need a JDBC connection at runtime. If the program also uses ExtName('TABLENAME') to describe data structures from the database catalog, the compiler needs a connection at compile time too:

# Compile with catalog resolution (for ExtName). The catalog credentials are
# read from environment variables (never passed on the command line, where they
# would be visible in the process table); the names default to JDBC_USER /
# JDBC_PASSWORD.
JDBC_USER=MYUSER JDBC_PASSWORD=MYPASS \
rpgc --verify-jdbc-url jdbc:as400://myhost/MYLIB \
     --verify-library MYLIB \
     --jdbc-driver-path jt400.jar \
     myapp.sqlrpgle

# Run with JDBC connection
JDBC_URL="jdbc:as400://myhost/MYLIB" \
JDBC_USER=MYUSER \
JDBC_PASSWORD=MYPASS \
java -cp out:triton-rpg.jar:jt400.jar MYAPP

Multi-Program Applications

Real-world RPG applications typically have multiple programs and service modules. Compile each separately, then place all .class files on the same classpath at runtime:

# Compile the service module (--lib = no main())
rpgc --lib --include-path . empdet.sqlrpgle

# Compile the main programs
rpgc --include-path . --dds-path qddssrc --bnddir APP=out depts.sqlrpgle
rpgc --include-path . --dds-path qddssrc --bnddir APP=out employees.sqlrpgle

# Run
java -cp out:triton-rpg.jar:jt400.jar DEPTS

The --bnddir APP=out flag tells the compiler that the binding directory APP (referenced by BNDDIR('APP') in the source) maps to the out/ directory, where it can find --lib-compiled service modules and resolve their exported procedures.

TRN4001 - If a source file declares BNDDIR('NAME') but no corresponding --bnddir NAME=<path> is provided on the command line, the compile fails and no class file is written. A binding directory that cannot be found stops the program being created. To fix this, compile the service module with --lib first, then pass --bnddir NAME=<dir> pointing to the directory containing the compiled .class file.