Whether you're a casual collector who just wants RomVault to recognise your files, or a preservation veteran managing hundreds of thousands of ROMs across structured archives, this tool was built for you. Point it at a folder, hit Start, and get clean, consistent Logiqx XML datfiles — no scripting, no manual XML editing, no guesswork.
Bulk-generates datfiles compatible with RomVault, ClrMamePro, and RomCenter. Supports both Mixed (Archive as File) and Zipped collection types across four structure options that mirror RomVault's own native output styles. An incremental update engine lets you rehash only what has changed, so revisiting a large collection doesn't mean starting from scratch. CRC32 and SHA1 are always included; MD5, SHA-256, and BLAKE3 are optional. ZStandard-compressed ZIPs are fully supported.
Datfile Creator Studio is a native C# / Avalonia desktop application — a ground-up rewrite of the original Python/Tkinter Datfile Creator Suite, with a modern Fluent interface, an auto-sliding activity-log drawer, true multithreaded hashing, and a single self-contained executable that needs no runtime installed. Its output is byte-for-byte identical to the original suite (see Parity).
| Tool | What it does |
|---|---|
| Folder Structure Analyzer | Inspects your collection folders and recommends the right structure option before you run |
| Long Path Length Repair | Identifies and allows you to interactively repair files and folders whose full path length approaches or exceeds the Windows 260-character MAX_PATH limit; can be launched standalone or directly from the Folder Structure Analyzer with scan results pre-loaded |
| Bulk Datfile Header Updater | Find and replace header fields (author, version, URL, etc.) across an entire folder of datfiles at once |
| Game and ROM Counter | Tallies total games, ROMs, and collection size across any set of datfiles |
| Validate Datfiles | Validates every <rom> entry and checks required attributes are present and correctly formatted |
| Merge Datfiles | Merges per-subfolder datfiles upward into a single dat at the first-level subfolder of a category root |
| Recursive Archive Extractor | Extracts ZIP, 7Z, and RAR archives recursively through nested folder trees |
| ZIP Store Packer | Repacks files into uncompressed ZIP_STORED archives — fast and RomVault-friendly |
| Remove ReadOnly Attribute | Strips read-only flags and NTFS alternate data streams from files and folders in bulk |
If this tool saves you time, consider supporting the work:
- Requirements
- Install
- Build from Source
- Quick Start
- Interface Overview
- Dat Types
- Generation Modes
- Structure Options
- Format: Modern vs Legacy
- Hash Options
- Multithreading
- Network Cap
- Extension Filters
- ZStandard Support
- Parent Name and Output Folder Structure
- Dat Preview Window
- Activity Log Drawer
- Incremental Update — Skip Already-Hashed Files
- Folder Structure Analyzer
- Tools Menu
- Settings and Config File
- Advanced: Datfile Landscape Analysis
- Advanced: DAT Format Reference
- Known Limitations
- Parity
- License
To run: nothing. The release builds are fully self-contained — no .NET runtime, no Python, no pip packages. Everything the app needs (ZStandard decompression, BLAKE3, NIC-speed detection) is built in.
The only external dependency is optional and used by a single tool: the Recursive Archive Extractor shells out to 7-Zip-ZStandard (7z.exe) for ZIP/7Z/RAR extraction. You only need it if you use that tool.
To build from source: the .NET 10 SDK.
- Download the latest
DatfileCreatorStudio-win-x64.zipfrom the Releases page. - Extract it anywhere.
- Run
DatfileCreatorStudio.exe.
- Download
DatfileCreatorStudio-linux-x64.tar.gzfrom the Releases page. - Extract it:
tar -xzf DatfileCreatorStudio-linux-x64.tar.gz chmod +x DatfileCreatorStudio/DatfileCreatorStudioand run it.
The app is fully portable — every setting lives in a single DatfileCreatorStudio.config file written next to the executable. No registry keys, no %APPDATA%, no temp files.
git clone https://github.com/Eggmansworld/DatfileCreatorStudio.git
cd DatfileCreatorStudio
dotnet run --project src/DatfileCreatorStudio
To produce a self-contained single-file build:
pwsh ./publish-win.ps1 # -> dist/win-x64/DatfileCreatorStudio.exe
./publish-linux.sh # -> dist/linux-x64/DatfileCreatorStudio
The solution is split into DatfileCreator.Core (the engine and all tool logic, no UI dependencies) and DatfileCreatorStudio (the Avalonia app).
- Set your Input top-level folder — the folder that contains the game folders you want to dat.
- Set your Output folder — where the datfiles will be written (mirrors input folder structure).
- Fill in the fields in the header section to suit your dat(s).
- Choose Dat Type: Mixed or Zipped.
- Choose Generation: 1 dat per root folder (most common).
- Choose Structure: Archives as Games is the right choice for the majority of collections.
- Choose Format: Modern.
- Click Start.
The activity log drawer slides up automatically when the run begins, showing live status, a progress bar, elapsed time, and colour-coded activity. Preview Dats lights up when the run completes.
Not sure which structure to use? Use Tools → Analyze Folder Structure before your first run.
| Field | Purpose |
|---|---|
| Input top-level folder | The folder whose immediate subfolders become individual dat jobs |
| Output folder (dat root) | Root of the output structure. Datfiles are written into subfolders that mirror the input |
| Parent name (optional prefix) | Prepended to every dat name: Parent - TopLevel - Subfolder |
All path fields support drag-and-drop. The path to 7z.exe (used only by the Recursive Archive Extractor) is set inside that tool's own window.
These map directly to the <header> block in the output datfile. All fields are optional. Blank fields write empty tags, which is valid and expected in Logiqx XML.
| Field | Header tag | Notes |
|---|---|---|
| Description | <description> |
Free text. Typically matches the collection name |
| Category | <category> |
e.g. PC, Arcade, Commodore |
| Version | <version> |
Release version or date stamp |
| Date | <date> |
Defaults to today's date at runtime |
| Author | <author> |
Your name or handle |
| URL | <url> |
Project or source URL |
| Homepage | <homepage> |
Homepage URL |
| Comment | <comment> |
Free text notes |
The <name> tag is populated automatically from the dat filename stem. Every dat also receives <romvault/> as the last header tag — this is the base RomVault recognition token, and expands to <romvault forcepacking="fileonly"/> when Mixed mode is active.
The UI greys out options that do not apply to the current combination of Dat Type and Generation mode — this prevents invalid combinations without hiding the controls. Every option has a short tooltip describing what it does.
The file itself is the ROM entry. The zip, 7z, or any other archive file is hashed as a single opaque file — its contents are not inspected.
Use this when RomVault is managing archives as atomic units — each archive is one logical game entry in your collection, and RomVault will not look inside it.
<game name="Lemmings (1991) (Psygnosis) [360K]">
<description>Lemmings (1991) (Psygnosis) [360K]</description>
<rom name="Lemmings (1991) (Psygnosis) [360K].zip"
size="1423168" crc="a3f82b1c" sha1="d4e9c02a7f1b3e5d8c6a0f4b2e7d1a9c3f5b8e2d"/>
</game>The header always contains <romvault forcepacking="fileonly"/>, which instructs RomVault to treat every matched file as a file-only entry regardless of extension.
When to use Mixed:
- PC floppy/CD image collections where each game is a discrete archive
- Any collection where the archive boundary is the logical game boundary
- Collections managed as scene-style releases where the zip is the delivery unit
- Dats created in Mixed (Archive as File) mode (aka "fileonly") have a fileonly header tag added to indicate to RomVault that it is dealing with a fileonly dat and to display it as such.
- The dat's
<rom>entries need to be wrapped in a<game>block, which is named after its parent folder name. This<game>block must exist to support the ability for a user to switch the Dat Rule on the folder from fileonly to a compression format if they decide they want to compress the folder. Without the<game>block, RomVault will throw errors forever and require the user to kill the process. - Adding the
<game>block creates a new internal "set" folder for the fileonly roms to reside in, but this throws out the alignment of the dat folder vs. the file folder. Pre-existing roms will end up with a Cyan status because of the insertion of this folder. If you try to scan and rebuild, you'll end up with an extra root folder in your folder path, which is very likely undesirable. - To fix this, set a DAT Rule on the parent folder of "Single Archive", and "Do not use subdirs for sets" to remove the internal
<game>block and have the folder behave like a fileonly dat again.
➡️ This anomaly occurs because of how RomVault is coded, not how the datfile is designed. Until RomVault can learn how to handle its users changing the Dat Rule settings on fileonly folders, this workaround must exist.
Additional factoid: if you load a datfile and get an "Incompatible Compare Type" error when trying to apply the compression setting to a folder, load the datfile into a text editor and check if the <rom> contents have a <game> block wrapped around the files. If not, one must be added.
The contents of each zip archive are hashed. Each zip becomes a game entry, and each file inside the zip becomes a <rom> entry within that game.
Use this when RomVault is expected to open, verify, and manage individual files within archives — the standard mode for ROM sets from No-Intro, Redump, TOSEC, and similar databases.
<game name="Lemmings (1991) (Psygnosis) [360K]">
<description>Lemmings (1991) (Psygnosis) [360K]</description>
<rom name="Disk 1.ima" size="368640" crc="3a9f12b4" sha1="e2c8a4f1b9d3e7c5a2f8b4d0e6c2a8f4b6d2e8c4"/>
<rom name="Disk 2.ima" size="368640" crc="7b2e45c1" sha1="f3d9b5e2c1a4f8b6d2e0c6a3f9b5e1c7a3f9b5e1"/>
</game>Internally zipped subfolders are always preserved in the rom name:
<rom name="original/Lemmings (1991) (Psygnosis) [360K] (Disk B).ima" size="368640" crc="9c4a21d7" sha1="..."/>Empty folders inside a zip produce a zero-byte rom entry with canonical empty hashes, matching RomVault's behaviour:
<rom name="path/to/emptydir/" size="0" crc="00000000"
sha1="da39a3ee5e6b4b0d3255bfef95601890afd80709"
sha256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
md5="d41d8cd98f00b204e9800998ecf8427e"/>The entire input folder is captured in one datfile, including every subfolder at every depth. The dat is named after the input folder alone (the optional Parent Name field is ignored in this mode) and is written directly into the output folder with no mirrored subfolder.
Use this mode for a one-off scan of a single directory — for example, to generate one datfile to add to an existing collection, or to manually replace a single dat.
Each immediate subfolder of the input root becomes one datfile. All content within that subfolder — regardless of depth — is rolled into the single dat.
Given this input:
E:\Floppy\Access Software\
Amazon (1992)\
amazon.zip
Docs\
amazon_manual.zip
Crime Wave (1990)\
crime_wave.zip
The tool produces:
Output\Access Software\
Parent - Floppy - Amazon (1992) (2026-04-24_RomVault).xml
Parent - Floppy - Crime Wave (1990) (2026-04-24_RomVault).xml
The content of Docs\ within Amazon (1992)\ is captured inside the Amazon dat — how it appears depends on the chosen Structure option. Use this mode when each top-level subfolder represents a single logical unit (one game title, one publisher, one platform).
Every folder at every depth that contains relevant content gets its own datfile. The output folder structure mirrors the input exactly. This is the style of granularity used by the TOSEC collection. Each dat contains only the content sitting directly in that specific folder — no recursive capture.
Use this mode for large heterogeneous collections where subfolders are logically independent (different platforms, publishers, or release types sharing a common input root).
Structure controls how the internal hierarchy of a datfile is expressed. It applies to the two recursive (tree) modes — 1 Dat per Top-Level Folder and 1 Dat per Root Folder — where a single dat captures nested content. In 1 dat per root folder & all subfolders, every dat is flat by definition, so the Structure radios are disabled.
The four structures replicate the output options from RomVault's dir2datUI tool. Use the Preview window to compare them side-by-side against your actual data before committing to a structure. Not sure where to start? Use Tools → Analyze Folder Structure first.
All four examples below use this input:
Access Software PC Floppy Disk Image Collection\
Crime Wave (1990)\ ← folder with direct archives
Crime Wave (1990) (Disk A).zip
Crime Wave (1990) (Disk B).zip
original\ ← physical subfolder inside game folder
Crime Wave (1990) (v1.0).zip
Docs\ ← container folder, no direct archives
Amazon Docs\
Amazon - Manual.zip
Crime Wave Docs\
Crime Wave - Manual.zip
Archives become <game> entries. Physical filesystem folders become <dir> entries. Files inside archives that live in internal subfolders have their path preserved in the rom name attribute.
This is the default and most widely used structure. It matches the output format of No-Intro, Redump, TOSEC, and the majority of community-distributed dat files.
<game name="Crime Wave (1990) (Disk A)">
<description>Crime Wave (1990) (Disk A)</description>
<rom name="Crime Wave (1990) (Disk A).ima" size="368640" crc="3a9f12b4" sha1="..."/>
</game>
<dir name="original">
<game name="Crime Wave (1990) (v1.0)">
<description>Crime Wave (1990) (v1.0)</description>
<rom name="Crime Wave (1990) (v1.0).ima" .../>
</game>
</dir>Use when: Your collection uses standard zip-per-game organisation, with physical subfolders representing logical groupings.
This structure represents 68.8% of all datfiles in a survey of 10,497 dats across two large RomVault-managed collections (see Advanced: Datfile Landscape Analysis).
The first level of physical subfolders inside the dat root are always rendered as <game> entries, regardless of whether they contain archives directly or act as containers. Deeper physical subfolders become <dir> entries.
<game name="Crime Wave (1990)">
<description>Crime Wave (1990)</description>
<rom name="Crime Wave (1990) (Disk A).ima" .../>
<rom name="original/Crime Wave (1990) (v1.0).ima" .../>
</game>Use when: Each first-level subfolder represents a complete game or release, and you want the folder itself — not its individual archives — to be the primary named entry in RomVault's database. Useful for multi-disc or multi-format releases.
First-level subfolders become <game> entries. All deeper physical subfolders are merged flat into that game entry. Each merged subfolder gets an empty directory marker rom (size="0" crc="00000000") followed by its files listed with path-prefixed rom names.
<game name="Crime Wave (1990)">
<description>Crime Wave (1990)</description>
<rom name="Crime Wave (1990) (Disk A).ima" .../>
<rom name="original/" size="0" crc="00000000"/>
<rom name="original/Crime Wave (1990) (v1.0).ima" .../>
</game>Use when: Collections have deep and variable subfolder hierarchies, and you want a single flat game entry to capture everything within a top-level folder including folder structure metadata. Well-suited to tape archives, rhythm game collections, and any collection where internal directory layout is part of the preservation data.
In the survey, 2.0% of dats used this structure — primarily complex arcade collections and large preservation projects with nesting depths between 4 and 9 levels.
Every folder at every depth becomes a <dir> tag. No <game> tags are used anywhere. Archives become <dir> entries containing their rom entries.
Use when: Maximum structural compatibility is needed, or when your collection management tool treats all folder levels equivalently. Least common in practice.
| Setting | <game> / <machine> |
<dir> |
<description> |
|---|---|---|---|
| Modern | ✅ Used for archive entries | ✅ Used for folders | Optional (checkbox) |
| Legacy | ❌ | All entries use <dir> |
Not emitted |
Modern is the correct choice for RomVault. The Legacy format (all <dir> tags, no <game>) is ClrMamePro's native format and is retained for compatibility with older toolchains.
When Modern is selected, an additional option appears: Use <machine> instead of <game>. This is the element name used by EmuMovies and some MAME-derived dat files. Unless you are producing dats specifically for an EmuMovies-style or MAME workflow, leave this set to <game>.
CRC32 and SHA1 are always computed. Both are mandatory in Logiqx XML and are the primary integrity verification hashes used by RomVault.
| Option | Attribute | Notes |
|---|---|---|
| MD5 | md5= |
Optional. Adds meaningful overhead per file. Written after sha1= in the rom tag |
| SHA-256 | sha256= |
Optional. Written after sha1= and before md5=. Informational — RomVault displays it but does not use it for matching |
| BLAKE3 | blake3= |
Optional. Forward-looking hash. Written after md5= and before date=. No current tool consumes it; unknown attributes are ignored by RomVault, so dats with BLAKE3 stay fully valid |
Attribute order in the output rom tag follows the RomVault DATReader source, with BLAKE3 (non-native to RomVault) appended at the tail before date:
name → size → crc → sha1 → sha256 → md5 → blake3 → date
BLAKE3 is faster than CRC32, MD5, SHA-1, and SHA-256, and is the preservation community's likely successor to the older hashes. No tool reads the blake3= attribute yet, but because Logiqx-consuming tools ignore attributes they do not recognise, a dat carrying BLAKE3 values loads and verifies exactly as it would without them. Including BLAKE3 now seeds real-world example dats that tool authors (RomVault included) can point at and build support against.
When incremental update runs with BLAKE3 enabled against a dat that predates BLAKE3, any unchanged entry that lacks a valid blake3= value is rehashed so the value gets populated — you never end up with a half-populated dat.
The hashing engine processes multiple archives in parallel. Thread count is set via the Threads control (1–8, default 4). Unlike the Python original, hashing here runs on true native threads with no interpreter lock, so parallelism scales cleanly with CPU cores and I/O.
For network-backed collections, the optimal thread count depends on your NIC speed and the latency of your storage server. On a 1 Gbps link, 4–8 threads typically saturates the connection. On a 10 Gbps link or fast local NAS, higher values may help.
The Network Cap applies across all threads combined — increasing the thread count does not bypass the cap.
The hashing engine reads files from a network share at full available speed, which can saturate a 1 Gbps connection and impact other network users. A token-bucket rate limiter keeps throughput below a configurable ceiling.
Auto mode (default, Net cap = 0): the app detects your fastest active network adapter and caps reads at 85% of its link speed, leaving 15% free for other traffic. NIC detection is built in — no external dependency.
Manual mode: enter a value in Mbit/s in the Net cap Mbit/s field. Setting 0 returns to auto mode.
The cap only applies when the input path is a network share (UNC or mapped network drive). Local NVMe/SATA/USB drives are never throttled.
Available in Mixed mode only — in Zipped mode the unit is always the complete .zip file.
| Field | Behaviour |
|---|---|
| Include only extensions | If set, only files matching these extensions are hashed and included. Blank = include everything |
| Exclude extensions / files | Files matching these extensions or exact filenames are always skipped |
Format: Comma-separated. Leading dots are optional. Full filenames are supported.
.ima, .mfm, .86f, .td0 ← include only floppy image formats
.nfo, .sfv, .md5, thumbs.db ← typical exclusion list
Filtering is applied during the folder scan phase, before any hashing begins. Excluded files never enter the work queue.
Zip archives compressed with RV-ZStandard (method 93) are handled natively — no external tools are required for reading zip contents.
Detection: An RV-ZStandard archive can be identified by its zip comment, which begins with RVZSTD- followed by a CRC32 checksum (e.g. RVZSTD-22DA5DD0). TorrentZip archives use a similar deterministic recompression approach that also sets standardised internal timestamps (1980/00/00 00-00-00).
⚠️ TheRVZSTD-comment is written exclusively by RomVault as a marker for its own internal handling. This tool reads and detects it but never writes it into archives it creates.
Supported compression methods:
| Method | Description |
|---|---|
| 0 | Stored (no compression) |
| 8 | Deflate (standard zip) |
| 93 | ZStandard / RVZSTD |
File date and timestamps (Zipped mode): When File date & time is enabled, the timestamp for each rom entry is read from the zip's internal metadata and written as date="yyyy/mm/dd hh-mm-ss". For TorrentZip and RV-ZStandard archives this will always be 1980/00/00 00-00-00 — the standardised DOS epoch timestamp these tools write. This is intentional — it documents that the archive has been deterministically recompressed.
7-Zip-ZStandard (7z.exe) is still required if you use the Recursive Archive Extractor tool for ZIP/7Z/RAR extraction. It is not used for dat hashing.
Every datfile is named using the following pattern:
[ParentName - ] TopLevelFolderName - SubFolderName (YYYY-MM-DD_RomVault).xml
The _RomVault suffix is deliberate — it flags dats produced by this tool to downstream tools and distribution platforms, and prevents name collisions with dats from other sources covering the same content. The Parent name field was added to support external dat distribution platforms where generic or duplicated dat names cause indexing conflicts.
Output always mirrors the input folder structure, rooted at a folder named after the input top-level folder. This matches RomVault's expected DatRoot layout, where datfiles and their parent folders establish the scanning hierarchy. Do not output flat — RomVault uses the folder structure of DatRoot to define collection boundaries.
After a run completes, the 🔍 Preview Dats button becomes active. It opens a preview window showing the XML of every dat produced during that run.
- List of all completed dats — click any entry to switch
- Four Structure radio buttons, independent from the main window — switching any option instantly re-renders the selected dat from in-memory data, with no re-hashing
- Full XML syntax highlighting (tag names, attribute names, attribute values)
- Selectable and copyable text
- Save Chosen Dat Structure As... — writes the currently displayed XML to a file of your choosing, named with the structure label appended
The preview re-renders entirely from the hash data held in memory — switching structures is instantaneous even for large dats. This is the equivalent of dir2datUI's live preview mode, and is the recommended way to evaluate structure options against your real data before deciding which to use for a project.
Instead of a separate progress window, live activity appears in an auto-sliding drawer docked at the bottom of the main window. It slides up automatically when a run begins and can be collapsed to a slim status strip at any time.
- Live status line, item counts, progress bar, and elapsed clock
- Colour-coded entries: amber for phase/scan events, blue for folder boundaries, tan for subfolder markers, green for successfully hashed items, grey for carried items (incremental mode), red for errors, bright green for completed dat files
- Per-zip diagnostics, e.g.
✓ GameName.zip (648.4 MB in 6.2s = 104.6 MB/s (1333 entries, stream)) - Right-click a highlighted path → Open in File Explorer
- Copy the full log or Clear it from the strip
- Start / Soft Stop / Hard Stop controls in the action bar
If anything ever goes wrong, an unhandled error is written to DatfileCreatorStudio.crash.log next to the executable.
For large collections — particularly those in the hundreds of GB or multi-TB range — rehashing every file on every run is impractical. Incremental update mode updates an existing datfile by hashing only new or changed content, carrying forward hash data for everything that hasn't changed.
Enable it: tick Incremental update — skip already-hashed files and point the Existing dat file or folder field to the dat you want to update (or the folder containing your dats for bulk updates). Optionally tick Rename superseded dat to .old to invalidate the previous datfile in RomVault once the update is complete.
When Start is pressed with incremental mode active, a Pre-flight Check dialog opens before any processing begins:
- Validation — the tool scans the dat source recursively and cross-checks each dat's entries against the source file/zip folder. It reports a match percentage per dat, flags missing entries, and identifies new items to be added.
- New version — optionally set a new
<version>string for the updated dat header. - Proceed / Rehash entire folder / Rescan Dats / Save Pre-inspection Log / Cancel — choose how to continue.
Zipped mode: Each zip is checked against the dat using filename + uncompressed size + CRC32 (read from the zip central directory — no decompression needed, takes milliseconds). If all three match, the existing SHA1, MD5, SHA-256, and BLAKE3 values are carried forward directly from the dat. Only new or changed zips are fully analyzed. (Exception: if BLAKE3 is enabled and a matched entry has no stored BLAKE3, it is rehashed so the value gets added.)
Mixed mode: Files are matched by filename + size only. If both match, existing hash data is carried forward across every file in every game subfolder. If a file was replaced with content of the same name and size, the change cannot be detected without a full rehash — the Pre-flight Check dialog warns of this, and offers a full-rehash option.
- The new datfile is written with today's date in both the filename and the
<date>header field. - If Rename superseded dat to .old is ticked, the original datfile is renamed to
filename.xml.old— this invalidates it from RomVault's perspective while preserving it for reference. If an.oldfile already exists, a numeric suffix is appended. - There is never more than one active
.xmldatfile in a folder at a time.
If the match percentage drops below 80%, the Pre-flight Check displays a warning. You can still proceed — entries not found in the source folder will be removed from the updated dat — but the warning gives you the chance to verify path alignment first.
Available via Tools → Analyze Folder Structure....
If you are unsure which Generation mode or Structure option is appropriate for a collection, the Analyzer examines the folder layout and makes a recommendation before any hashing takes place. It walks the folder structure in a background thread (no hashing, completes in seconds even for very large collections) and reports:
- Total folders and items found, and depth distribution
- Pattern breakdown — flat game folders, container folders, folders with nested subdirs
- Sample folder names for spot-checking
- Recommendation — a suggested Generation mode and Structure option, colour-coded by confidence
- Path length statistics — count of files approaching or exceeding the Windows 260-character
MAX_PATHlimit, with a direct Open Path Repair Tool button
Clicking Apply Recommended Settings fills the main window's Dat Type, Generation, Structure, Format, and Input folder fields automatically and closes the Analyzer.
Identifies files and folders whose full path length approaches or exceeds the Windows 260-character MAX_PATH limit, and lets you rename them interactively to bring them under threshold. Filter between All / Warning (≥200 chars) / Critical (≥260 chars) / Pending; edit the stem with a live character counter; preview, then Apply Selected or Apply All; Undo Last; rename a parent folder and cascade the change; Save/Import a rename log. Can be launched standalone or pre-loaded from the Analyzer.
Updates header fields of all datfiles in a folder (or a single file) in bulk. Leave a field blank to leave it untouched, enter a value to overwrite it in every dat, or tick Clear to erase it. Date is always required and updates both the <date> tag and the (YYYY-MM-DD_RomVault) filename token. Both .xml and .dat files are processed recursively; each file's existing formatting and encoding are preserved.
Scans a folder of datfiles and reports the game count, ROM count, and total uncompressed size for each dat — answering the question no ROM manager readily does: how many games (not just ROMs) are in each folder? Tree/flat views, clickable column sort, multi-selection with a live subtotal, a full Collection Summary panel, and CSV export. Sizes reported in decimal MB/GB/TB.
Scans every <rom> entry in a dat (or a folder of dats) and checks that required attributes are present and correctly formatted: size (decimal), crc (8 hex chars), sha1 (40 hex chars); optional md5/sha256/blake3 are validated when present. Every anomaly is reported with its line number.
Merges per-subfolder datfiles upward into a single dat placed at the first-level subfolder of a category root. Select the category root (e.g. Amiga); each first-level subfolder whose dats live in deeper subfolders is merged into one dat written into that subfolder.
Amiga\ ← select this as the root
[ADF]\ ← first-level subfolder
[#-B]\ ← has a dat ┐
[C-D]\ ← has a dat ┘ merged together
→ writes: Amiga - [ADF] (date_RomVault).xml into [ADF]\
[BIN]\ ← already has a dat directly → skipped
For dats nested three or more levels deep, rom names are prefixed with the intermediate folder path (e.g. [A-F]/foo.adf) so RomVault can still locate the files.
Recursively extracts ZIP, 7Z, and RAR archives into their own named subfolders, with optional auto-extraction of archives found nested inside extracted content. Same-as-source or mirror-to-custom-destination output; after-extraction options of Keep / Recycle Bin / Permanent delete / Move (mirror) / Move (flat dump). Uses the 7-Zip-ZStandard path set in the tool window. Windows only (relies on the Windows shell for the Recycle Bin option).
Wraps files in uncompressed ZIP_STORED containers — a neutral byte-preserving wrapper before downstream recompression by RomVault or other tools. Configurable target extensions (removable pill tags), verify-before-delete, skip-if-.zip-exists, and recursive or non-recursive scan.
Performs two operations recursively: clears the Windows read-only (R) attribute on all files and folders, then removes the Zone.Identifier NTFS alternate data stream (the "This file came from another computer" flag) via PowerShell's Unblock-File. The unblock step may require running as Administrator. Windows only.
All settings are saved to DatfileCreatorStudio.config in the same folder as the executable. Settings are written automatically when Start is pressed and can be explicitly saved at any time with the Save Settings button. The config is plain JSON and can be edited by hand if needed; unrecognised keys are silently ignored on load, so editing is safe. Theme selection (System / Light / Dark) is stored here too.
This section is for collectors and advanced users curious about the broader datfile ecosystem. None of this is required reading to use the tool.
To understand how the datfiles produced by this tool relate to the wider landscape, a structural analysis was performed across two large RomVault-managed collections.
| Collection | Dats analysed | Parse failures | Games | ROMs |
|---|---|---|---|---|
| Core (general) | 10,136 | 4 | 3,473,346 | 20,594,118 |
| Arcade | 350 | 7 | 62,481 | 49,555,576 |
| Combined | 10,486 | 11 | 3,535,827 | 70,149,694 |
| Structure | Total | Share |
|---|---|---|
Standard Logiqx <game>→<rom> (depth 3) |
7,225 | 68.8% |
R2Dat/MAME <machine> flat |
2,909 | 27.7% |
Complex <dir>+<game> (depth 4–9) |
215 | 2.0% |
| ClrMamePro text format | 134 | 1.3% |
Flat ROMs only (no <game> wrapper) |
3 | ~0% |
The standard Logiqx structure at depth 3 accounts for nearly 97.7% of all XML datfiles in the core collection. This is the structure produced by No-Intro, Redump, TOSEC, GoodMerge, and the vast majority of community dat projects. It is what this tool produces in Zipped mode with Structure 1 (Archives as Games).
| Value | Count | What it means |
|---|---|---|
| (absent) | 8,705 | RomVault defaults to Zip mode — contents verified against rom entries |
fileonly |
1,582 | Files are managed as atomic units — no inspection of archive contents |
unzip |
197 | RomVault extracts files before verification — R2Dat and ClrMame-specific |
zip |
2 | Explicitly request Zip mode — redundant with absent, almost never used |
This tool produces only fileonly (Mixed mode) and absent (Zipped mode).
SHA-256 support was introduced to the Logiqx dat format by No-Intro's Dat-o-Matic database and is present in almost all No-Intro dats. SHA-256 is available as an optional output field here for completeness, but for ensuring the uniqueness of files and avoiding hash collisions, it adds computation time without practical benefit. RomVault displays the SHA-256 value when it exists but does not use it for matching — CRC32 and SHA1 are the operative hashes.
At some point a consensus will be reached and, with luck, we'll all move to BLAKE3 hashing and get the best of everything wrapped up into one single fast-as-hell algorithm and stop living in the 1990's. For more on the different hashing methods and why it's time to retire most of them, see Hash Algorithm Comparison: MD5, SHA-1, SHA-256, SHA-3 & BLAKE3.
| Feature | CRC32 | MD5 | SHA-1 | SHA-256 | BLAKE3 |
|---|---|---|---|---|---|
| Hashing Speed | Extremely Fast | Very Fast | Moderate | Slower than BLAKE3 | Very Fast |
| Parallel Processing | None | Limited | Limited | Limited | Excellent |
| Collision Resistance | Very Low | Very Low | Low | High | High |
| Cryptographic Security | None | Broken | Broken | Strong | Strong |
| Integrity Verification | Excellent | Excellent | Excellent | Excellent | Excellent |
| CPU Efficiency | Excellent | Excellent | Good | Moderate | Excellent |
| Hardware Support | Excellent | Excellent | Excellent | Excellent | Growing |
| Relative Overall Rank | 5th | 4th | 3rd | 2nd | 1st |
CRC32 — one of the oldest and fastest integrity checks, designed to detect accidental corruption. Extremely low CPU overhead and universally supported, but its 32-bit value makes collisions relatively common in very large datasets.
MD5 — the de facto standard for file verification through the late 1990s and 2000s. Fast, widely compatible, stronger identification than CRC32, still common in preservation databases. Its weakness is collision resistance, rarely a practical concern for ordinary integrity verification.
SHA-1 — a larger 160-bit hash with stronger uniqueness than MD5, common in DAT files, Redump, and No-Intro sets. Slower than MD5/CRC32 and gradually being replaced by SHA-256 or BLAKE3.
SHA-256 — currently one of the most trusted, widely standardized hashes; a 256-bit value makes accidental collisions extraordinarily unlikely. The tradeoff is speed — noticeably more CPU time than CRC32, MD5, or BLAKE3.
BLAKE3 — a modern hash built around parallel processing and modern CPU architectures, hashing significantly faster than SHA-256 while retaining strong uniqueness. Ideal for very large archives, NAS systems, and multi-terabyte collections. Its main limitation is ecosystem maturity — support is growing but not yet as universal as the older hashes.
For users who want to understand exactly what the tool is writing. Skip this if you don't need to hand-edit datfiles.
<?xml version="1.0"?>
<datafile>
<header>
<name>Digitoxin - Floppy - Access Software PC Floppy Disk Image Collection</name>
<description>PC Floppy Disk Image Collection</description>
<category>PC</category>
<version>2026-04-24</version>
<date>2026-04-24</date>
<author>Digitoxin</author>
<url>https://github.com/Eggmansworld</url>
<homepage>https://github.com/Eggmansworld</homepage>
<comment></comment>
<romvault forcepacking="fileonly"/> <!-- Mixed mode -->
<!-- or: <romvault/> ← Zipped mode -->
</header>
...
</datafile>Attribute order follows the RomVault DATReader source (DatXMLWriter.cs):
<rom name="filename.ima"
size="368640"
crc="3a9f12b4"
sha1="d4e9c02a7f1b3e5d8c6a0f4b2e7d1a9c3f5b8e2d"
sha256="b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
md5="5eb63bbbe01eeed093cb22bb8f5acdc3"
date="1980/00/00 00-00-00"/>sha256 and md5 are only written when their respective checkboxes are enabled. date is only written when File date & time is enabled (Zipped mode only).
ZIP archives with filenames containing DOS CP437 graphical characters (bytes 0x01–0x1F — card suits ♥ ♦ ♣ ♠, smileys ☺ ☻, arrows ↑ ↓ → ←, and similar) are handled correctly. These bytes decode to Unicode control characters that are illegal in XML 1.0; the tool translates them to their correct graphical Unicode equivalents — exactly as RomVault's own CodePage437.cs does — before writing any XML. The result is a valid dat that RomVault can read and that preserves the original filename symbols faithfully.
In RomVault's internal model:
- A
<game>tag represents aDatDirwith aDGameattached — it appears in RomVault's scanner as a named game entry with fixable ROM slots. - A
<dir>tag represents aDatDirwithout aDGame— it appears as a structural folder in the tree, not a fixable entry.
Only <game> entries can be fixed (have files moved into them from the ToSort folder). <dir> entries are containers only.
- Output format is Logiqx XML only. ClrMamePro text format and RomCenter format are not supported.
- Zipped mode only processes
.zipfiles. Archives in other formats (.7z,.rar,.gz) are ignored. If your collection uses these formats in Mixed mode, they are hashed as files (which is correct for Mixed/fileonly collections). - The
forcepacking="unzip"andforcepacking="zip"values are not generated. Onlyfileonly(Mixed) and absent (Zipped) are produced. <softwarelist>and MAME XML formats are not produced.- Incremental update Mixed mode cannot detect same-name same-size file replacements. The Pre-flight Check dialog warns of this and offers a full rehash.
- The Recursive Archive Extractor and Remove ReadOnly tools are Windows-only. The core dat generation engine and all other tools run on both Windows and Linux; these two rely on Windows-specific facilities (the Windows shell Recycle Bin and PowerShell
Unblock-File).
The engine is a faithful port of the original Python suite, and that claim is enforced. tools/parity/compare.ps1 runs both engines over the same test collection — including deterministic RVZSTD archives with zero-byte files, empty folders, and nested empty folders — and compares every output byte for byte. The matrix covers both dat types across all three generation modes and all four structures, the legacy/<machine> variants, every hash (BLAKE3 included), extension filters, incremental update, the folder analyzer's recommendations, and the dat-writing tools (Merge, Header Updater, Counter, Validate). All checks pass byte-identical.
Original source code, scripts, and hand-authored documentation are licensed under the MIT License. Archived game data, binaries, firmware, media assets, and other third-party materials are not covered by the MIT License and remain the property of their respective copyright holders. See the LICENSE and NOTICE files for full details and scope clarification.
Created for the preservation community by Eggman, and built with Claude (Anthropic) using the Fable coding model — pair-programmed across a series of sessions to port the original Python/Tkinter suite to C#/Avalonia, with every datfile output verified byte-for-byte against the original.
If you improve the app, feel free to share your changes back with the community.
Made with ❤️ for the retro game preservation community.


