-
Notifications
You must be signed in to change notification settings - Fork 0
Relique Developer Architecture
Technical documentation for Relique (Item Blueprint Editor) development.
- Overview
- Project Structure
- Component Architecture
- Key Services
- MVVM Layer
- Item Property System (2DA Cascade)
- File Format: UTI
- Startup Lifecycle
- Integration Points
- Testing
- Settings & Persistence
Relique edits UTI (Item Blueprint) files for Neverwinter Nights.
Status: Alpha (active development)
Namespace: ItemEditor (historical — product renamed to Relique)
Dependencies: Radoub.Formats, Radoub.UI, Radoub.Dictionary
Relique/
├── CHANGELOG.md
├── CLAUDE.md (tool-specific guidance)
├── version.json (NBGV: 0.7.0-alpha)
├── Relique/
│ ├── Program.cs
│ ├── App.axaml(.cs)
│ ├── Services/
│ │ ├── CommandLineService.cs
│ │ ├── SettingsService.cs
│ │ ├── BaseItemTypeService.cs
│ │ ├── BaseItemCategoryService.cs
│ │ ├── ItemPropertyService.cs
│ │ ├── ItemNamingService.cs
│ │ └── ItemStatisticsService.cs
│ ├── ViewModels/
│ │ ├── ItemViewModel.cs
│ │ ├── VariableViewModel.cs
│ │ └── BoolToErrorBrushConverter.cs
│ ├── Views/
│ │ ├── MainWindow.axaml(.cs)
│ │ └── NewItemWizardWindow.axaml(.cs)
│ └── Assets/
└── Relique.Tests/
├── CommandLineServiceTests.cs
├── SettingsServiceTests.cs
├── Services/
│ ├── BaseItemCategoryServiceTests.cs
│ ├── ItemNamingServiceTests.cs
│ ├── ItemPropertyServiceTests.cs
│ ├── ItemPropertyOperationTests.cs
│ └── ItemStatisticsServiceTests.cs
└── ViewModels/
├── ItemViewModelTests.cs
├── ItemViewModelConditionalTests.cs
├── ItemEditingRoundTripTests.cs
└── VariableViewModelTests.cs
flowchart TD
subgraph Views
MW[MainWindow]
WIZ[NewItemWizardWindow]
end
subgraph ViewModels
IVM[ItemViewModel]
VVM[VariableViewModel]
end
subgraph Services
CMD[CommandLineService]
SET[SettingsService]
BIT[BaseItemTypeService]
BIC[BaseItemCategoryService]
IPS[ItemPropertyService]
INS[ItemNamingService]
ISS[ItemStatisticsService]
end
subgraph SharedLibs["Shared Libraries"]
RF[Radoub.Formats]
RU[Radoub.UI]
RD[Radoub.Dictionary]
end
MW --> IVM
WIZ --> BIT
WIZ --> BIC
WIZ --> INS
IVM --> RF
IPS --> RF
BIT --> RF
MW --> RU
MW --> RD
SET --> RU
Parse CLI arguments: --file, --safemode, --new, --help, -m (module context).
Dependencies: CommandLineParser (Radoub.UI)
Singleton inheriting BaseToolSettingsService. Stores settings in ~/Radoub/ItemEditor/ReliqueSettings.json.
Key settings: BrowserPanelWidth, OpenInEditorAfterCreate
Loads base item types from baseitems.2da via IGameDataService. Provides dropdown list with TLK-resolved descriptions. Hardcoded fallback if game data unavailable.
Categorizes base items by EquipableSlots bitmask into groups: Weapons, Armor, Jewelry, etc. Used by New Item Wizard for filtered type selection. Identifies custom content items.
Walks the 2DA cascade chain to resolve property types, subtypes, cost values, and parameter values. Powers the cascading dropdown UI for property editing.
itempropdef.2da → iprp_[subtype].2da → iprp_costtable.2da → iprp_[param].2da
Generates and validates NWN identifiers:
-
Tag: max 32 chars,
[a-zA-Z0-9_], typically UPPERCASE -
ResRef: max 16 chars,
[a-z0-9_], lowercase
Handles filename conflict resolution via ResolveResRefConflict().
Auto-generates formatted statistics description from an item's property list. One line per property with TLK-resolved names.
Wraps UtiFile. Exposes all editable fields via INotifyPropertyChanged: Name, Description, Tag, ResRef, BaseItem, Cost, StackSize, Charges, flags (Plot, Stolen, Cursed, Identified), model parts, colors, local variables, scripts.
Property changes update the underlying UTI directly.
Wraps a single local variable (Int/Float/String) with validation. Converts via FromVariable() / ToVariable().
| View | Purpose |
|---|---|
| MainWindow | Primary editor: menu bar, status bar, browser panel, editing sections (Basic, Properties, Appearance, Variables) |
| NewItemWizardWindow | Guided creation: Step 1 (base type) → Step 2 (name/tag/ResRef) → Step 3 (palette category) → Step 4 (finish) |
flowchart LR
PD[itempropdef.2da] -->|SubTypeResRef| ST["iprp_[subtype].2da"]
PD -->|CostTableResRef| CT[iprp_costtable.2da]
CT -->|"table name"| CV["iprp_[cost].2da"]
PD -->|Param1ResRef| PT[iprp_paramtable.2da]
PT -->|"table name"| PV["iprp_[param].2da"]
ItemPropertyService walks this chain to:
- List available property types from
itempropdef.2da - Load subtypes, cost values, param values on demand
- Provide cascading dropdowns in the UI
- Validate property combinations before save
GFF-based binary format parsed by Radoub.Formats/Uti/.
| Section | Key Fields |
|---|---|
| Identity |
LocName, Tag (32 chars), TemplateResRef (16 chars), Description
|
| Base Properties |
BaseItem (baseitems.2da index), Cost, AddCost, Weight, StackSize, Charges
|
| Flags |
Plot, Stolen, Cursed, Identified, Droppable, Pickpocketable
|
| Properties |
PropertiesList — enchantments via 2DA cascade |
| Appearance |
ModelPart1/2/3, ArmorPart_*, Cloth/Leather/MetalColor
|
| Variables | Local variables (Int/Float/String) |
| Scripts |
OnActivate, OnAcquire, OnUnacquire, OnEquip, OnUnequip
|
sequenceDiagram
participant P as Program.cs
participant A as App.axaml.cs
participant MW as MainWindow
P->>P: Parse CLI args
P->>P: Init UnifiedLogger
P->>A: Build Avalonia app
A->>A: Register tool path
A->>A: Apply theme/font
A->>MW: Create MainWindow
MW->>MW: Constructor (light init)
MW->>MW: Loaded (restore window state)
MW->>MW: Opened (async: GameData, palettes, startup file)
| Tool | Integration |
|---|---|
| Trebuchet | Registers Relique for discovery and file launch via --file
|
| Fence | Context menu "Edit Item" → launches Relique with --file
|
| Quartermaster | Context menu "Edit Item" → launches Relique with --file
|
| Category | Focus | Key Files |
|---|---|---|
| Service tests | Business logic isolation | ItemPropertyServiceTests, ItemNamingServiceTests, ItemStatisticsServiceTests, BaseItemCategoryServiceTests |
| ViewModel tests | Data binding, property changes | ItemViewModelTests, VariableViewModelTests |
| Conditional logic | Field visibility by base item type | ItemViewModelConditionalTests |
| Round-trip | File save → load cycle integrity | ItemEditingRoundTripTests |
| CLI | Command-line parsing, --new wizard | NewItemCommandLineTests, CommandLineServiceTests |
dotnet test Relique/Relique.TestsTool settings: ~/Radoub/ItemEditor/ReliqueSettings.json
Shared settings (RadoubSettings): CurrentModulePath, ReliquePath, game paths, TLK, theme/font
DocumentState (Radoub.UI): Centralized dirty tracking, title bar updates with [*] marker.
Page freshness: 2026-03-19
Getting Started
User Guide
Features
Help
- Manifest - Journal Editor
- Quartermaster - Creature/Inventory Editor
- Relique - Item Editor
- Reliquary - Placeable Editor (Alpha)
- Fence - Merchant/Store Editor
- Trebuchet - Radoub Launcher
- Marlinspike - Search and Replace
- Spell Check - Dictionary-based spell checking
- Token System - Dialog tokens and custom colors
Parley Internals
Manifest Internals
Quartermaster Internals
Relique Internals
Reliquary Internals
Fence Internals
Marlinspike (Search Engine)
Trebuchet Internals
Radoub.UI
Library
Low-Level Formats
High-Level Parsers
- JRL Format (.jrl)
- UTI Format (.uti) - Item blueprints
- UTC Format (.utc) - Creature blueprints
- UTM Format (.utm) - Store blueprints
- UTP Format (.utp) - Placeable blueprints
- UTD Format (.utd) - Door blueprints
- ARE Format (.are) - Area properties
- BIC Format (.bic) - Player characters
Original BioWare Aurora Engine file format specifications.
Core Formats
- GFF Format - Generic File Format
- KEY/BIF Format - Resource archives
- ERF Format - Encapsulated resources
- TLK Format - Talk tables
- 2DA Format - Data tables
- Localized Strings
- Common GFF Structs
Object Blueprints
- Creature Format (.utc)
- Item Format (.uti)
- Store Format (.utm)
- Door/Placeable (.utd/.utp)
- Encounter Format (.ute)
- Sound Object (.uts)
- Trigger Format (.utt)
- Waypoint Format (.utw)
Module/Area Files
- Conversation Format (.dlg)
- Journal Format (.jrl)
- Area File Format (.are/.git/.gic)
- Module Info (.ifo)
- Faction Format (.fac)
- Palette/ITP Format (.itp)
- SSF Format - Sound sets
Reference
Page freshness: 2026-05-24