Skip to main content

CLI and REPL

crashlink is invoked as crashlink <file>, either directly or via python -m crashlink. With no subcommand it opens file and drops you into the interactive REPL. Everything else, one-shot subcommands, top-level flags, and REPL commands, is covered below.

Top-level flags

These apply to the base invocation, crashlink <file> [flags]:

  • -N / --no-constants: skip constant resolution on deserialisation. Useful for malformed or unusually large files.
  • -a / --assemble: treat file as crashlink assembly and assemble it to bytecode instead of opening it.
  • -o / --output: output path for --assemble or --patch.
  • -p / --patch: apply a patch module (a file of patch definitions) to file.
  • -c / --command: run a single REPL command on startup instead of dropping into the interactive prompt (-c '' opens the REPL as usual).
  • -t / --traceback: print full Python tracebacks on error instead of a short message.
  • -d / --debug: enable extra debug output.
  • -D / --no-debug: force debug output off, overriding anything that turned it on implicitly.
  • -C / --dehlc: extract debug info from a compiled HL/C binary (needs PDB on PE, DWARF on ELF).
  • --help-all: print the top-level help plus every subcommand's own -h output in one go.

One-shot subcommands

For anything that doesn't need a live session, there are subcommands that run once and exit. Each has its own -h:

SubcommandDoes
funcsList functions in a bytecode file
disasmDisassemble a function
decompileDecompile a function or class to pseudo-Haxe (decompiler is incomplete, usually functional)
infoSummary info: version, counts, etc.
searchSearch strings by substring
dbInspect a .cldb debug-info database (db info, db check, db renames, db comments)
hlcTranspile bytecode to C, optionally build it (--build)
mcpRun crashlink as an MCP server
guiLaunch the graphical bytecode inspector
$ crashlink funcs game.hl # list functions
$ crashlink disasm game.hl 42 # disassemble f@42
$ crashlink decompile game.hl 42 # decompile f@42 to pseudo-Haxe
$ crashlink info game.hl # summary info (version, counts, etc.)
$ crashlink search game.hl "password" # search strings by substring
$ crashlink db info game.cldb # inspect a .cldb debug-info database
$ crashlink hlc game.hl --build # transpile to C and compile it
$ crashlink mcp # run as an MCP server

The REPL

Running crashlink game.hl with no subcommand loads the file and starts an interactive prompt. Bytecode objects are addressed by index throughout: f@<findex> for functions and natives, t@<tIndex> for types, g@<gIndex> for globals, s@<index> for strings. Command history persists across sessions in ~/.crashlink_history (up/down arrows to browse it), and Tab completes command names. help lists every command with its aliases; help <command> shows a command's usage string and full description.

Command reference

This isn't exhaustive (there are 60+ commands; run help in a live session for the full current list), but it covers what you'll reach for most:

CommandAliasesDoes
funcs [std]fnsList functions; pass std to include stdlib
fn <idx>fDisassemble a function to opcodes
cfg <idx>Render a control flow graph and open it in the default image viewer
ir <idx>Print a function's IR in object notation
decomp <idx>decompile, dec, pseudo, dDecompile a function to pseudo-Haxe
decompfile <file>dfDecompile every function in a debug source file, grouped by class
stub <file>stubfileEmit a compilable stub of a file (signatures kept, bodies stubbed)
autostub <folder>Stub every file in the debug database to a folder
findfunc <query>ffSearch functions by name substring, or list functions in a source file
fnn <name>Print a function by exact name
patch <idx>editPatch a function's raw opcodes
save <path>Write the modified bytecode out to path
xref <kind> <index> [aux]Cross-references: func, type, field, global, string, or enum
locals <findex>List a function's IR locals with their rename keys
rename <findex> <reg> <def_op|_> <name>Rename an IR local
unrename <findex> <reg> <def_op|_>Clear a local rename
addcomment <findex> <op_idx> <text>Attach a comment to a statement
rmcomment <findex> <op_idx>Remove a comment from a statement
entryPrint the bytecode's entrypoint
typesList all types
objsList all Obj types
obj <tIndex>objectOverview of a class's fields, protos, and bindings
type <tIndex>tDetailed info on a type by index
virt <idx>Print a Virtual type by index
enum <idx>Print an enum type by index
tn <name>Find a type by name
global <gIndex>gShow a global's initialised values
stringsstrsList all strings
floatsList all floats
nativelibslibsList native dynlibs used by the bytecode
infile <file>Find all functions from a given source file
debugfilesList all debug files
source <...>Debug-file/line lookup, in either direction
op <opcode>Print documentation for an opcode
hlc <output path>Transpile the loaded bytecode to C
class <tIndex>cls, cDecompile an entire class by type index
apidocs <path>Generate API documentation for the bytecode's classes
mkdocs <path> [name]mkdocGenerate a MkDocs + Material site for the bytecode's API
shader [name]shadersRecover hxsl shaders embedded in the bytecode
runRun the bytecode in crashlink's integrated interpreter
pyreplDrop into a Python REPL with direct access to the Bytecode object
copy <command> [args...]cpRun a command and copy its plain-text output to the clipboard
checkRun basic sanity checks on the loaded bytecode
sha256Print the SHA-256 of the loaded bytecode image
pluginsList discovered plugin optimizers and whether they apply
offset <hex>Print the bytecode section at a given file offset
history [count]histShow recently run REPL commands
clearClear the terminal
wikiOpen the HashLink bytecode wiki page in your browser
exitExit the REPL

A worked session

$ crashlink game.hl
crashlink> funcs
f@22 static Clazz.main () -> Void (from Clazz.hx)
f@23 Clazz.method (Clazz) -> I32 (from Clazz.hx)
crashlink> findfunc method
f@23 Clazz.method (Clazz) -> I32 (from Clazz.hx)
crashlink> fn 23
f@23 Clazz.method (Clazz) -> I32 (from Clazz.hx)
Reg types:
0. Clazz
1. I32

Ops:
0. Ret {'ret': 1} return
crashlink> decomp 23
function method(this: Clazz): Int {
return 0;
}
crashlink> cfg 23
crashlink> xref func 23
f@22 static Clazz.main () -> Void (from Clazz.hx)
crashlink> rename 23 0 _ localName
crashlink> save game_patched.hl
crashlink> exit

cfg renders the graph with Graphviz and opens it in your system image viewer, so there's no meaningful text output to show. See Getting Started for installing Graphviz if that command errors out.