# Debugging Tools and Techniques for ArmorPaint Development: A Complete Guide

> Master ArmorPaint development with our guide to debugging tools. Explore command-line builds, GPU diagnostics, console logging, and native debugger support for efficient troubleshooting.

- Repository: [Armory 3D/armorpaint](https://github.com/armory3d/armorpaint)
- Tags: how-to-guide
- Published: 2026-09-13

---

**ArmorPaint provides a comprehensive debugging ecosystem including `--debug` command-line builds that generate symbol-rich binaries, an in-app Debug tab for real-time GPU diagnostics, console logging utilities, and support for external native debuggers like GDB, LLDB, and Visual Studio.**

ArmorPaint is a 3D painting tool built by the **armory3d/armorpaint** repository with a hybrid JavaScript build system and C rendering engine. Understanding the debugging tools and techniques for ArmorPaint development is essential for contributors working across both the scripting layer and native graphics code.

## Enabling Debug Builds from the Command Line

The build pipeline in [`base/tools/make.js`](https://github.com/armory3d/armorpaint/blob/main/base/tools/make.js) orchestrates Debug configuration through the `--debug` flag. When invoked, the script sets `goptions.debug` to true at line 970, triggering compiler flags that generate binaries with full debug symbols.

Additionally, the runtime in [`paint/project.js`](https://github.com/armory3d/armorpaint/blob/main/paint/project.js) parses command-line arguments at line 5, storing the debug state in `flags.embed`. This allows the application to detect if it was launched with `--debug` or `--embed` flags.

To build and run in Debug mode:

```bash

# Generate Debug binaries with symbols

node base/tools/make.js --debug

# Launch with debug runtime checks

./build/Debug/ArmorPaint --debug

```

The resulting executable retains symbol tables required for breakpoint debugging and enables additional runtime assertions throughout the codebase.

## Runtime Debugging Features

Once running a Debug build, ArmorPaint exposes several diagnostic interfaces compiled conditionally via the `is_debug` macro.

### The Debug UI Tab ([`tab_debug.c`](https://github.com/armory3d/armorpaint/blob/main/tab_debug.c))

The dedicated Debug tab, implemented in [`paint/sources/ui/tab_debug.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/ui/tab_debug.c), provides visual inspection of render targets and performance counters. This UI component only registers when `is_debug` is defined during compilation.

In [`paint/sources/ui/ui_base.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/ui/ui_base.c) at line 351, conditional blocks push draw callbacks into the UI array when debugging is active:

```c
#ifdef is_debug
    // Add a draw callback that visualises the current render target
    any_array_push(a0, _draw_callback_create(tab_debug_draw));
#endif

```

This allows developers to overlay texture previews and diagnostic geometry directly in the viewport without affecting Release builds.

### In-App Console Logging ([`console.c`](https://github.com/armory3d/armorpaint/blob/main/console.c))

The central logging API in [`paint/sources/console.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/console.c) routes diagnostic messages to the internal console pane. The functions `console_log`, `console_error`, `console_info`, and `console_toast` provide runtime feedback without external tooling.

Example usage from native code:

```c
console_log("Loaded texture %s", texture_name);
console_error("Failed to load mesh");

```

These calls appear in the Console tab ([`tab_console.c`](https://github.com/armory3d/armorpaint/blob/main/tab_console.c)), creating a unified logging surface for both JavaScript build messages and C runtime events.

## External Debugger Integration

Because Debug builds emit full symbol information, ArmorPaint supports attaching industry-standard native debuggers. The build system generates platform-specific project files that you can open directly in your IDE.

On Linux, navigate to the output directory and launch GDB:

```bash
cd build/Debug
gdb ./ArmorPaint
(gdb) run

# Set breakpoints, inspect variables, step through rendering code

```

For Windows development, running [`make.js`](https://github.com/armory3d/armorpaint/blob/main/make.js) with `--debug` emits `.vcxproj` files compatible with Visual Studio. The generated `ArmorPaint.sln` includes proper Debug configurations with working directory settings and symbol paths pre-configured. On macOS, the script produces `.xcodeproj` files for LLDB debugging within Xcode.

## Performance Profiling and Hot Reloading

Beyond static debugging, ArmorPaint includes dynamic analysis tools for GPU optimization and script iteration.

### Frame Performance Monitoring ([`main.c`](https://github.com/armory3d/armorpaint/blob/main/main.c))

The Debug tab captures real-time metrics through the notification system defined in [`paint/sources/main.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/main.c) at line 391. Using `sys_notify_on_next_frame` callbacks, the engine records frame times, draw-call counts, and GPU memory allocation statistics.

This instrumentation helps identify bottlenecks in the rendering pipeline by correlating CPU-side code execution with GPU frame metrics displayed in the Debug UI.

### Script Console for Rapid Iteration ([`tab_console.c`](https://github.com/armory3d/armorpaint/blob/main/tab_console.c))

The console supports hot-reloading via `text_to_text_node_run`, allowing developers to execute JavaScript commands at runtime by typing into the Console tab. Errors return immediately to the console pane, creating a fast feedback loop for testing build logic or automation scripts without restarting the application.

## Summary

- **Debug builds** are enabled via `--debug` in [`make.js`](https://github.com/armory3d/armorpaint/blob/main/make.js), generating symbol-rich binaries in `build/Debug/` with the `_DEBUG` and `is_debug` definitions.
- **In-app diagnostics** include the Debug tab ([`tab_debug.c`](https://github.com/armory3d/armorpaint/blob/main/tab_debug.c)) for render target inspection and the Console ([`console.c`](https://github.com/armory3d/armorpaint/blob/main/console.c)) for logging via `console_log()` and related functions.
- **Conditional compilation** wraps debug-only code in `#ifdef is_debug` blocks, ensuring zero overhead in Release binaries.
- **External tooling** integrates with GDB, LLDB, Visual Studio, and Xcode through automatically generated project files.
- **Performance profiling** leverages frame callbacks in [`main.c`](https://github.com/armory3d/armorpaint/blob/main/main.c) to display real-time GPU statistics.

## Frequently Asked Questions

### How do I compile ArmorPaint in Debug mode?

Run the build script with the `--debug` flag: `node base/tools/make.js --debug`. This sets `goptions.debug` in the build configuration, passes `-g` to the compiler, and defines `is_debug` for conditional compilation.

### Where are debug symbols stored in ArmorPaint builds?

Debug symbols are embedded directly into the executables located in `build/Debug/`. The [`make.js`](https://github.com/armory3d/armorpaint/blob/main/make.js) script configures the compiler to generate these symbols automatically when the Debug flag is present.

### Can I use Visual Studio to debug ArmorPaint?

Yes. The build system generates `.vcxproj` and `.sln` files when you run the Debug configuration. Open `ArmorPaint.sln` in Visual Studio, set breakpoints in the C source files, and press F5 to launch the debugger with full symbol support.

### How do I view render targets and GPU performance in real-time?

Open the Debug tab in the UI, which is available only in Debug builds. This panel, driven by [`tab_debug.c`](https://github.com/armory3d/armorpaint/blob/main/tab_debug.c) and updated via callbacks in [`main.c`](https://github.com/armory3d/armorpaint/blob/main/main.c), displays live render target previews, frame times, and memory statistics without requiring external profiling tools.