Est. 1998 Beginner

NQC

Dave Baum's Not Quite C, a small C-like language that compiles to the bytecode of LEGO's own RCX firmware, which made it the first popular way to program LEGO MINDSTORMS robots in text rather than graphical blocks

Created by Dave Baum

Paradigm Procedural, with built-in multitasking (tasks) and, on later targets, event monitoring
Typing Static; every variable is a 16-bit signed integer (pointers to int were added in NQC 3.0)
First Appeared 1998
Latest Version NQC 4.1.0 (September 2025, BrickBot community repository); the last release from the original project was 3.1 r6 (June 2007)

NQC, short for Not Quite C, is a small programming language with C-like syntax for LEGO’s programmable bricks: above all the yellow RCX from the 1998 MINDSTORMS Robotics Invention System, and later the CyberMaster, Scout and Spybotics. Dave Baum wrote it in 1998, within weeks of the RCX reaching shops. Instead of replacing LEGO’s firmware, NQC compiles programs into the bytecode that LEGO’s own firmware already interprets. This made it the easiest route from drag-and-drop RCX Code to typed programs, and for several years it was, by most accounts, the most popular way to program the RCX in text. NQC is a good example of a language shaped by the machine underneath it. Nearly every unusual restriction it has, from functions that cannot return values to a limit of eight subroutines, comes straight from what the RCX bytecode interpreter could do.

History & Origins

A toy that adults took apart

LEGO announced MINDSTORMS in January 1998 and shipped the Robotics Invention System (RIS) in the first week of September 1998. The kit’s programmable brick, the RCX, had a Hitachi H8 microcontroller, three motor outputs, three sensor inputs and an infrared link to a tower on the PC’s serial port. LEGO supplied RCX Code, a graphical language for Windows. Many of the earliest buyers were adults, and they soon wanted something more powerful.

The community opened up the brick quickly. Kekoa Proudfoot, a Stanford graduate student, documented the RCX’s internals, firmware and bytecodes. According to IEEE Spectrum, David Baum, who was then a software engineer at Motorola, worked out the communications protocol for the IR link. Baum then wrote a compiler for a C dialect he called Not Quite C. It turned source text into LEGO bytecodes and downloaded them through the IR tower, without touching the firmware.

The first months

The earliest traces of NQC are on LUGNET, the LEGO fan discussion server, whose lugnet.robotics group opened on 28 September 1998. On 30 September a member wrote that his projects were “using Dave Baum’s NQCC, rather than TLG’s graphical language” (TLG is The LEGO Group). On 6 October he posted a robot-tag program “written in NQC version 0.5b1”, which he downloaded from Baum’s page at enteract.com/~dbaum/lego/nqc/. By mid-October, Mac users were happy to have Baum’s NQC MPW tool, because LEGO’s software did not run on the Mac at all.

Baum later told IEEE Spectrum that for the first few months after he released NQC, he half-expected a letter from LEGO’s lawyers. It never came; instead, he says, he ended up meeting and befriending LEGO designers. The same article reports that, according to a LEGO official quoted at the 2001 Mindfest conference, the company might once have considered legal action against the hackers instead of welcoming them. NQC stayed a free, independent project under the Mozilla Public License. It was never sponsored or endorsed by LEGO.

Debian began packaging NQC 1.0b4 in December 1998. On 19 February 1999 LUGNET created a dedicated discussion group, lugnet.robotics.rcx.nqc, described in its charter as being for “an unofficial language and compiler for programming the LEGO MINDSTORMS RIS”.

Design Philosophy

The NQC Programmer’s Guide is open about what the language is and is not:

Although the preprocessor and control structures of NQC are very similar to C, NQC is not a general purpose language - there are many restrictions that stem from limitations of the LEGO bytecode interpreter.

Three ideas run through the design:

  • Keep LEGO’s firmware. NQC programs run on the standard firmware. As Baum’s FAQ points out, RCX Code, ROBOLAB and NQC programs can then sit on the brick side by side, and the user keeps the firmware’s stability and its on-brick interface, such as the View button. The cost is that NQC “must live within the constraints of the standard firmware”. There is no floating point, for example, because the firmware has none. Alternatives such as legOS and pbForth replaced the firmware to remove those limits.
  • Look like C, so C programmers feel at home. The project’s welcome page puts it simply: for a C programmer who prefers “typing a few lines to drag and drop icon programming”, NQC “may be perfect”.
  • Separate the language from the API. The guide defines NQC as two pieces: the language (syntax, statements, preprocessor) and the API (functions and constants such as OnFwd, SENSOR_1 and OUT_A). The API is a header file built into the compiler, and nqc -api prints it. Supporting a new brick mostly meant writing new API definitions, not changing the language.

Key Features

Program structure

An NQC program is made of global variables and three kinds of code block:

BlockKeywordNotes
TasktaskMaps directly onto a firmware task. main starts when the program runs. The RCX allows 10 tasks, CyberMaster 4, Scout 6 and Spybotics 8
Inline functionvoidExpanded inline at every call site. Takes arguments, but cannot return a value
SubroutinesubOne shared copy of the code, but no arguments, no calls to other subroutines, and at most 8 on the RCX

The guide explains the void keyword as “an artifact of NQC’s heritage”: since functions cannot return data, every function is declared void. Function arguments come in six flavours, int, const int, int &, const int &, int* and const int*, because some firmware operations accept only constants and others only variables.

A taste of NQC

This program drives a two-motor robot forward until its bumper (a touch sensor on input 1) is pressed, then backs up:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
task main()
{
    SetSensor(SENSOR_1, SENSOR_TOUCH);   // touch sensor on input 1

    OnFwd(OUT_A + OUT_C);                // both drive motors forward
    until (SENSOR_1 == 1);               // wait for the bumper

    PlaySound(SOUND_CLICK);
    OnRev(OUT_A + OUT_C);
    Wait(100);                           // time is in 10 ms ticks: 1 second
    Off(OUT_A + OUT_C);
}

until, repeat (n) and start/stop for tasks are NQC additions to C’s familiar if, while, do, for and switch.

Types and storage

Every NQC variable is a 16-bit signed integer. Pointers to integers were added in NQC 3.0. Variables are assigned to the brick’s limited global and local storage locations by the compiler. #pragma reserve keeps the compiler away from particular locations, such as the ones the RCX 2.0 firmware uses for its counters.

Events and resource control

From NQC 2.2 the language added two statements for targets whose firmware supports them (the Scout, RCX 2.0 firmware, Spybotics and Dick Swan’s firmware):

1
2
3
4
5
6
7
8
acquire (ACQUIRE_OUT_A)        // claim motor A
{
    Wait(1000);                // 10 seconds
}
catch
{
    PlaySound(SOUND_UP);       // another task took the motor
}

acquire asks for ownership of outputs or sound, and jumps to catch if a higher-priority task takes them away. monitor runs a block while watching up to 16 configurable events, with separate catch handlers for different events. These statements gave NQC a structured, almost exception-like way to write the reactive, interrupt-driven code that robots need.

The compiler as a toolkit

The nqc command does more than compile. It downloads programs and firmware over the IR tower (including a -firmfast firmware-download mode that, according to the 2.1 release notes, loads firmware about four times as fast as the standard method but needs the IR tower in “near” mode), prints disassembly listings, can merge source with assembly, and selects targets with options such as -TRCX2, -TScout and -Tspy. Its asm statement lets programmers emit raw bytecodes when the API lacks something.

Evolution

NQC’s release notes show a language that grew with LEGO’s product line:

VersionApproximate dateHighlights
0.5b1in use by October 1998Early public build, already in hobbyist use
1.0b4by December 1998First Debian package
2.01999First 2.x release; 2.0.2 packaged for Debian by November 1999
2.1—Scout support, switch, faster firmware download, -T target option
2.2—Preliminary RCX 2.0 API, local variables, monitor/acquire, for, arrays on RCX 2
2.3by October 2001Conditions and expressions merged with C precedence, multiple catch clauses
2.4—Ternary ?:, shift and xor operators, USB IR tower support; old 1.x syntax removed
2.5by 2003Spybotics support, limited goto, Linux USB tower driver
3.0 a1/a2January–February 2004Pointers, built-in Spybotics API, asm syntax change
3.1 r1–r6March 2005 – June 2007Swan firmware, LASM-compatible listings, bug fixes, 64-bit builds
4.0.0–4.1.0April–September 2025BrickBot community releases: TCP support (for the BrickEmu emulator), Cygwin and WebAssembly builds, bundled libraries and docs

Version dates before 2004 come from Debian package uploads and LUGNET posts, so they show when a release was in use, not the day it came out. The 2.1, 2.2 and 2.4 releases cannot be dated from the sources consulted; 2.3 r1 is dated only by its Debian upload in October 2001.

Baum’s own copyright notices run through 2005, and the 3.x Programmer’s Guide is credited to “Dave Baum & John Hansen”. The 3.x releases, starting with the 3.0 betas of January 2004, are published on the SourceForge site of the Bricx Command Center project, and source files carry portions copyrighted by John Hansen in 2005. When LEGO released the NXT brick in 2006, NQC did not follow. Its home page sends NXT users to NXC (Not eXactly C), which it describes as “very similar to NQC so that you don’t have to learn a completely new programming language.”

Current Relevance

The original NQC line stopped at 3.1 r6 in June 2007, and LEGO reportedly discontinued the last RCX-based set, the Robotics Invention System 2.0, around 2006, when the NXT replaced it. That is why NQC is listed here as historical. It is not dead, though. The RCX still has an active retro community, and NQC remains its standard language:

  • Distribution packages. Debian still ships NQC. Its unstable branch moved to 4.1.0 after many years on 3.1 r6.
  • BrickBot/nqc. Since April 2025 this GitHub repository has published new releases. It merges patches that were posted to SourceForge but never applied, fixes for OS X and BSD from John Verne’s 2014 fork, and a WebAssembly target. Version 4.1.0 also brought the old tutorial, FAQ and Baum’s book examples into a documentation site.
  • In the browser. WebPBrick compiles NQC in a web page and talks to a real RCX through the Web Serial and WebUSB APIs. Someone with a 1998 brick and an IR tower can now program it without installing anything.

Why It Matters

NQC was one of the first and most widely used results of the “right to hack” culture that grew up around MINDSTORMS. It showed that a hobbyist could put a real textual language on a commercial toy without permission and without replacing its firmware, simply by targeting the bytecode the vendor had already shipped. LEGO’s decision to tolerate, and later welcome, the hackers rather than pursue legal action left room for that kind of work.

As a language, NQC is a clear case study in designing for a fixed virtual machine. Its quirks are not arbitrary. Each one shows a limitation of the RCX bytecode interpreter, so reading the NQC manual is also a guided tour of what LEGO’s firmware could and could not do. For many students in university robotics courses, and for thousands of hobbyists, it was also a first introduction to concurrent, event-driven embedded programming: several tasks sharing motors, sensors firing events, and code that has to react to the physical world in real time.

Timeline

1998
LEGO ships the MINDSTORMS Robotics Invention System and its RCX brick in September. By the end of the month hobbyists on lugnet.robotics are writing programs in Dave Baum's compiler, and by 6 October a posted program names NQC version 0.5b1
1998
Version 1.0b4 is packaged for Debian on 26 December, under the Mozilla Public License
1999
LUGNET opens a dedicated discussion group, lugnet.robotics.rcx.nqc, on 19 February. NQC 2.0 follows later in the year, with 2.0.2 packaged for Debian in November
1999
Jonathan Knudsen's "The Unofficial Guide to LEGO MINDSTORMS Robots" (O'Reilly, October) includes a chapter on NQC, and Mark Overmars' tutorial "Programming LEGO Robots using NQC" reaches version 3.03 on 2 October
2000
Apress publishes "Dave Baum's Definitive Guide to LEGO MINDSTORMS" and "Extreme MINDSTORMS", which Baum co-wrote with Michael Gasperi, Ralph Hempel and Luis Villa
2004
NQC 3.0 a1 goes into beta on 22 January, adding pointers, the Spybotics API and alternate-firmware download. The 3.x releases are distributed from the BricxCC project site on SourceForge
2005
NQC 3.1 r1 is released on 15 March. It adds support for Dick Swan's replacement RCX firmware and a LASM-compatible listing output
2007
NQC 3.1 r6 is released on 6 June with changes for 64-bit platforms. It is the last release from the original project
2025
The BrickBot/nqc repository on GitHub releases NQC 4.0.0 on 26 April, its first new version (the repository had earlier republished 3.1 r4 and r6), which merges years of outside patches and adds a WebAssembly build. Version 4.1.0 follows in September

Notable Uses & Legacy

Hobbyist RCX robotics

NQC was the main text language of the early MINDSTORMS community, which shared programs on LUGNET from the autumn of 1998. A 1999 LUGNET feature called it "a highly popular third-party tool", and in 2001 IEEE Spectrum reported that tens of thousands of users had downloaded the compiler

University robotics courses

Courses used NQC to teach embedded and robot programming on the RCX. Brown University's 2001 robotics course (CS148), for example, did its programming work in NQC, and its lecture notes compared NQC with the replacement-firmware legOS

RCX Command Center and BricxCC

Mark Overmars' RCX Command Center (RcxCC), and its successor Bricx Command Center (BricxCC), are Windows IDEs that call the NQC compiler to edit programs, download them to the brick and control it

MINDSTORMS books and tutorials

NQC was the language of Dave Baum's own books for Apress and of Mark Overmars' widely copied tutorial. Knudsen's O'Reilly guide also gave it a chapter

WebPBrick

A browser IDE started in 2024 that compiles NQC with a WebAssembly build of the compiler, offers the Blockly-based BlockNQC editor, and downloads programs to a real RCX through LEGO's serial or USB IR tower over the Web Serial and WebUSB APIs

Language Influence

Influenced By

Influenced

NXC

Running Today

Run examples using the official Docker image:

docker pull
Last updated: