HTN Planner is a C++ hierarchical task network planner for game AI. Domains are written in a small declarative language and translated ahead of time into native C. The runtime executes the generated planner directly and does not parse domain source during gameplay.
HTN Planner is under active development. Published releases are tested, while the public API, domain language and generated-code ABI continue to evolve.
Before upgrading, review the release notes for compatibility changes and migration instructions. Some updates require regenerating domains and rebuilding the integration.
Feedback, bug reports and integration experiences are welcome.
The repository includes:
- The generated planner runtime and its C ABI.
- A C++ integration layer with planner hooks and planning units.
HTNTranslator, which validates domains and emits C source.- A visual SDL and ImGui demo with generated execution debugging.
- An editor, language server, hot reload example, tests and benchmarks.
- A packageable Windows x64 SDK with CMake integration.
Version 2.1.0 adds runtime list expressions, explicit diagnostics for non-boolean callterm conditions, and smaller generated C through shared implementations, reachability analysis and optional instrumentation. The C runtime ABI is unchanged from 2.0.4. Regenerate and recompile domains to use the new features and reductions; rebuild clients using the C++ compiler APIs. See the 2.1.0 release notes. Upgrades from older releases must also follow the 2.0.4 migration guide and, for 2.0.2 or earlier, the 2.0.3 migration guide.
(:domain GuardNPC top_level_domain
(:method (run) top_level_method
(patrol
(and
(guard_on_duty)
)
(
(!move_to "checkpoint")
(!scan_area)
)
)
)
)A successful decomposition returns a plan containing the primitive tasks
!move_to and !scan_area. The engine assigns meaning to those tasks and decides
when they start, complete or fail.
See Planner use cases for NPC behavior, active-plan validation, squad coordination and AI Director integration flows. The client owns action execution, scheduling and cancellation.
- Windows x64.
- Visual Studio 2022 with the Desktop development with C++ workload.
- MSVC v143 and a Windows SDK.
- C++20 for clients and C11 for generated domain source.
- CMake 3.25 or newer when consuming the packaged SDK through CMake.
Premake, SDL, Dear ImGui, GoogleTest and the remaining development dependencies are included in the repository.
Generate the Visual Studio solution from the repository root:
GenerateProjectFiles.batBuild HTN.sln for x64. Use Debug to include generated decomposition capture and
the visual debugger. Use Release for an optimized runtime build without debugger
instrumentation.
Run:
bin/<configuration>-windows-x86_64/HTNDemo/HTNDemo.exe
The generated-only HTNDemo provides three views:
- Domain Runner selects a compiled domain, top-level method, backtracking mode and world state. It displays the resulting primitive plan.
- Generated event debugger displays the executed hierarchy, backtracking choices, source locations, constants and bound variables in instrumented builds.
- NPC Simulation runs a generated planner as part of a small agent simulation.
The demo loads world-state data for inspection, but its domain definitions are already compiled into native generated planners.
flowchart LR
Source[".domain source"] --> Lexer["Compiler lexer and tokens"]
Lexer --> AST["Compiler AST"]
AST --> Validation["Validation and linking"]
Validation --> IR["Compiler IR"]
IR --> Generator["C code generator"]
Generator --> Native["Native generated planner"]
HTNCompilerDomainLexercreates tokens and source ranges.HTNCompilerDomainSyntaxParsercreates the compiler-owned AST.- Validation and linking resolve declarations, includes, overrides and references.
HTNCompilerIRBuilderlowers the linked domain into compiler IR.HTNCCodeGeneratoremits C source and static metadata.- The client build compiles that C source into the game or a domain module.
The AST and IR are build-time representations. Generated runtime execution does not retain or depend on them. See Compiler pipeline and IR boundary.
Build HTNTranslator, then validate a domain without producing output:
HTNTranslator.exe --check path\to\npc.domainGenerate C for an exported entry point:
HTNTranslator.exe path\to\npc.domain CreateNpcHTN generatedThe generated source exports:
extern "C" const HTNGeneratedPlannerDefinition* CreateNpcHTN_GetDefinition(void);Useful translation options are:
--backtracking-policy=fixed-with-overflow|fixed-capacity
--backtracking-capacity=<positive integer>
--runtime-backtracking-support=disabled|enabled
Compile generated C with the same configuration definitions and ABI as the runtime. Regenerate domain source whenever the generated planner ABI changes.
The simplest integration uses HTNIntegration, which supplies HTNPlannerHook,
HTNPlanningUnit and HTNDatabaseHook:
#include "HTNIntegration.h"
extern "C" const HTNGeneratedPlannerDefinition* CreateNpcHTN_GetDefinition(void);
HTNDatabaseHook Database;
HTNCallTermRegistry CallTerms;
HTNPlannerHook Planner(Database.GetWorldState(), CallTerms);
if (!Planner.SetGeneratedPlannerDefinition(CreateNpcHTN_GetDefinition()))
return false;
HTNPlanningUnit Unit(Database, Planner, HtnSymbol::sGetSymbol("run"));
Unit.GetExecutionContext().MissingCallTermPolicy = HTNMissingCallTermPolicy::FailSilently;
const HTNDecompositionStatus Status = Unit.DecomposeTopLevelMethod();The example explicitly chooses silent failure for missing callterms. To report them
through your own diagnostics, configure Report and a callback as described in
Missing callterm policy.
After a successful decomposition, use ResolveCurrentPrimitiveTask() and
GetCurrentPrimitiveTask() to inspect the next action. Call
CompleteCurrentPrimitiveTask() after the engine finishes that action. The engine
owns action dispatch, replanning policy, scheduling and world-state updates.
Call terms connect domain expressions to engine functions through
HTNCallTermRegistry and HTNCallTermBindingContext. The packaged
IntegrationConsumer and CoreConsumer examples demonstrate the optional integration
layer and the lower-level runtime API respectively.
Instrumented builds can capture generated execution without changing planner logic:
#ifdef HTN_DEBUG_DECOMPOSITION
HTNGeneratedDebugger Debugger;
Debugger.SetEnabled(true);
Unit.SetGeneratedDebugger(&Debugger);
#endifThe debugger records methods, branches, conditions, axioms, tasks, results, source ranges and scoped values. Its data model is independent of ImGui; an engine can render the captured nodes in its own editor. HTNDemo includes an ImGui reference view.
The application owns the debugger object. Instrumented generated domains and their host runtime must use matching ABI definitions. See Generated execution debugger.
To build and validate all supported SDK variants:
BuildAndValidateSDK.batThis command:
- Generates
HTNSDK.sln. - Builds the eight CRT, configuration and instrumentation variants.
- Creates a versioned directory and ZIP under
dist. - Extracts the package outside the source tree.
- Builds and runs its core, integration and dynamic-domain consumers.
To generate only the SDK solution:
GenerateSDKProjectFiles.batThe package exports CMake targets for HTNFramework, HTNIntegration,
HTNRuntimeBridge and HTNTranslator. Choose an SDK variant that matches the engine's
CRT and instrumentation settings. See SDK variants and
SDK distribution.
| Path | Purpose |
|---|---|
HTNFramework |
Core data types, world state, compiler frontend, IR, code generator and generated runtime. |
HTNIntegration |
Optional C++ engine integration and active-plan handling. |
HTNRuntimeBridge |
Optional bridge for dynamically loaded generated domain modules. |
HTNTranslator |
Command-line domain validator and C source generator. |
HTNDemo |
SDL and ImGui generated planner demo. |
HTNHotReloadDemo |
Example generated-domain DLL compilation and hot reload flow. |
HTNEditor |
Domain authoring tool. |
HTNLanguageServer |
Diagnostics and language tooling backend. |
HTNVSCode |
VS Code extension client. |
HTNTest |
Runtime, compiler, integration and regression tests. |
HTNBenchmark |
Generated planner benchmarks. |
Domains |
Example domains, includes and inheritance hierarchies. |
WorldStates |
Example world-state inputs used by demos and tests. |
SDK |
Packaging, CMake configuration and external consumer validation. |
docs |
Architecture, debugger, SDK distribution and release documentation. |
Build HTNTest and run its executable from the HTNTest directory so relative test
assets resolve correctly:
..\bin\Release-windows-x86_64\HTNTest\HTNTest.exeThe test suite covers compiler diagnostics, AST and IR behavior, generated planning, backtracking, includes, overrides, call terms, lists, ABI validation, dynamic modules, concurrency and the public integration API.
See CI validation for the repository build matrix.
Start with the domain language guide: a complete example followed by syntax, facts, methods, axioms, assignment, operators, callterms, lists, includes, backtracking and deferred decomposition.
The documentation index links the compiler architecture, generated debugger, SDK distribution and release guides. See CONTRIBUTING.md for development workflow and CHANGELOG.md for release history.
The generated planner, compiler pipeline and public release are developed and maintained by Jose Antonio Escribano. The shared 2023 foundation retained in the core, parsing, world-state and integration layers was co-authored with Sandra Alvarez (HTN planner repository).
See CONTRIBUTORS.md and NOTICE.md for contributor credits and formal copyright attribution.
Applicable notices are included when producing an SDK package.
- Exploring HTN Planners through Example
- The AI of Horizon Zero Dawn
- Hierarchical AI for Multiplayer Bots in Killzone 3
Licensed under the MIT License. See copyright and attribution and third-party notices before redistributing binaries or SDK packages.
Use (= ?value expression) to declare and initialize a fresh local variable.
The compiler rejects destinations already declared or used in the same path.
== remains equality comparison; implicit (?value (call ...)) binding is rejected.
See assignment syntax and migration.