|
Download docs/FINDINGS.md from nmarshall/nanobrush: direct link, hf CLI and curl.
- Browser
- Download file 20 kB
-
https://huggingface.co/nmarshall/nanobrush/resolve/main/docs/FINDINGS.md
- Command line
-
hf download hf://nmarshall/nanobrush/docs/FINDINGS.md
-
curl -L -o FINDINGS.md https://huggingface.co/nmarshall/nanobrush/resolve/main/docs/FINDINGS.md
20 kB
| # Initial findings | |
| Inspected 2026-10-21. See [SETUP.md](SETUP.md) for implemented setup and the current layout. This is an initial evidence baseline, not a completed reverse engineering report. Archive paths below identify members inside the named ZIP. The implemented extraction is under `assets/references/extracted/<version>/`. | |
| ## F01 β Current checkout | |
| Observed: the starting directory contains `README.txt`, `RECOVERY-REPORT.txt`, `manifest.json`, `SHA256SUMS`, five ZIPs under `packages/`, five historical reference files under `references/`, and `.DS_Store`. No `.git`, `assets/`, `.envrc`, Nix flake, Rust workspace, scripts, or existing `docs/` was present. No applicable `AGENTS.md` was found in the checkout or its ancestor chain. | |
| The initial planning pass added documentation only; the subsequent setup pass initializes Git, configures the user-created HF remote, installs filters, and relocates/extracts the references (see SETUP.md). Selected reference files were unpacked into a temporary inspection directory; no bundled executable, batch file, compiler, plugin, or shader was executed. | |
| ## F02 β Archive integrity and coverage | |
| Recomputed SHA-256 hashes match `manifest.json` and `SHA256SUMS`. Independently read every member and checked internal ZIP CRCs; all five passed. | |
| | Build | ZIP bytes | ZIP entries, including directories | Regular files | Uncompressed file bytes | IXPL files | | |
| | --- | ---: | ---: | ---: | ---: | ---: | | |
| | 2015-10-03 | 946,822 | 131 | 109 | 2,729,974 | 42 | | |
| | 2015-11-15 | 948,939 | 130 | 108 | 2,736,264 | 42 | | |
| | 2015-11-24 | 956,351 | 131 | 109 | 2,754,350 | 42 | | |
| | 2015-12-08 | 961,924 | 133 | 110 | 2,790,280 | 43 | | |
| | 2016-03-10-c | 986,340 | 147 | 124 | 2,910,061 | 47 | | |
| The latest archive has 35 TXT, 17 BAT, 15 CFG, 4 PNG, 3 EXE, 3 SHADER, and 47 IXPL files. These counts describe regular files; do not confuse them with archive-entry counts. See [the complete member inventory](REFERENCE_INVENTORY.md) for paths and hashes. | |
| ## F03 β Executables and startup are separate research tracks | |
| Observed PE headers in the latest build: | |
| | Member | Bytes | Header observations | Implication to investigate | | |
| | --- | ---: | --- | --- | | |
| | `data/Microbrush 3.exe` | 1,371,136 | PE32, machine `0x014c`, no CLR directory | Native x86 Windows editor; identify actual dependencies later | | |
| | `tools/IXPL.exe` | 335,872 | PE32, machine `0x014c`, nonempty CLR directory | Managed CLI assembly; compiler/toolchain investigation | | |
| | `tools/Mb3 file formats.exe` | 91,136 | PE32, machine `0x014c`, nonempty CLR directory | Managed converter; independent format investigation | | |
| A PE32 managed header alone does not establish CLR platform flags, required framework version, or supported host architectures. These were header reads, not decompilation or runtime tests. | |
| `First start and tasty fresh cookies!.bat` moves GPU configuration scripts, invokes model and plugin build scripts, moves the editor to the archive root, and deletes itself. The build scripts invoke IXPL `cxo` to produce `.ixm` and `cso` to produce `.plugin`, then move outputs to runtime directories. The ZIPs contain no regular `.ixm` or `.plugin` members. Running the editor directly from an untouched extraction may therefore fail to represent normal startup. | |
| `WINE support.txt` reports a historical 32-bit Wine prefix with .NET 4.5 and core fonts. This is a 2015 recipe, not current compatibility evidence. The supplied recovery report separately records an author report of MB3 startup breaking after a Windows 10 update. Neither was reproduced here. | |
| ## F04 β Source boundary | |
| `data/sources/include/core/Akula.ixpl`, `Core-Grid.ixpl`, `Core-Mb3.ixpl`, and `Core-QuakeWorld.ixpl` expose host operations through numbered `interrupt` calls. The many readable IXPL plugins implement substantial UI/tool behavior, but these include files are not the editor/engine implementation. | |
| `Core-QuakeWorld.ixpl` exposes brush planes, string and UV properties, ray intersections, selection/visibility, geometry operations, computed contours, undo/redo, world load/save, render-cache policy, spatial balancing, and rendering controls. `Akula.ixpl` exposes tool registration, callbacks, tasks, views, GUI and host services. Enumerating and tracing this boundary is likely more productive initially than treating the executable as an opaque application. | |
| The IXPL grammar is 62,052 bytes; language utilities include file I/O, IXModel serialization, matrix and rectangle operations, lists, text configuration, strings, and a geometry solver. They warrant separate specifications, not an assumption that IXPL is C or C#. | |
| ## F05 β Brush/patch data evidence | |
| `Core-QuakeWorld.ixpl:7β25` defines a plane using origin `p0` and spanning vectors `u` and `v`, UV using two vectors plus scales/shifts, and Patch9 using two odd anchor counts of at least three plus per-tile quad counts of at least two. This is declaration evidence; winding, numerical stability, invalid inputs, and tessellation details remain unverified. | |
| Selection constants are none, main, set 1, and set 2 (`Core-QuakeWorld.ixpl:27β31`). Do not treat βnoneβ as an extra selectable group. The API also exposes hidden brushes and notes that cached selected-brush bounds can be outdated for hidden brushes. | |
| The small `GeometrySolver.ixpl` uses a `0.000001f` determinant threshold and an unnormalized cross-product plane-distance expression. This does not establish the engine's global tolerance or distance conventions. Each algorithm needs its own measured contract. | |
| ## F06 β Editing surface | |
| Observed tool registrations and English help enumerate box creation, move, copy-move, mirror, left/right 90-degree rotation, facing-plane drag, two/three-point clipping, merge, intersection, double/halve scale, delete, hide/show, paint selection, select/deselect/invert, auxiliary selection-set actions, AABB/brush spatial selection, undo, and redo. Alternate operations use grid spanning vectors. Several tools have sticky interaction states, alternate actions, cleanup, and abort semantics. | |
| Spatial-selection help explicitly describes approximate corner/AABB tests rather than general exact geometric overlap. Rewrite tests must distinguish reference behavior from improvements. There is no basis yet to promise arbitrary boolean subtraction or nonconvex solid modeling. | |
| `extra stuff/` contains bevel, blank templates, Lego, and patch-test sources and labels them experimental. They are not part of the default top-level plugin build; the readme describes copying them up and adding bindings. | |
| ## F07 β Views, grids, UI, and configuration | |
| Observed source/string/settings families cover camera, grid, projection, view events, raycast, world controller, main menu, editing toolbar, render-mode toolbar, view layouts, notes, log, plugins menu, plugin management, task priorities, GUI layout designer, and window controls. | |
| Six render modes are exposed: plain faces with borders, normal colors with borders, see-through, plain faces, normal colors, and wireframe. Six view-layout presets cover one view, side-by-side, top/bottom, four views, and two asymmetric three-view arrangements. | |
| Grid references and strings describe rectangular/circular grids, origin and axis vectors, axis bias, resolutions and bases, angular subdivisions, planar offset, per-axis snapping, secondary orthogonal snapping, widths/colors, and ten memory slots. Projections also have ten memory slots and editable boundaries/clip distances. Exact math is not inferred from the labels. | |
| `config-Akula.cfg` contains UI/font settings and separate base/fly key maps. FAQ and engine notes describe F12 main menu, F10 tools, Escape fly mode, mouse selection overrides, focus/window behavior, and several historical platform bugs. `data/settings/task priorities.cfg` explicitly orders plugin collection and world-close tasks at priority -1000; only the first priority entry for a task name is used. | |
| ## F08 β Formats and conversion boundary | |
| Seven included grammars describe MB3 TXT, HL1 MAP, HL2 VMF, Q3 MAP, configuration, key configuration and IXPL. A separate text-markup demo illustrates display markup. MB3 TXT declares a world with computed-features flag, optional named string/UV property lists, brushes, per-plane properties and optional polygons, and Patch9 anchors plus optional points/normals. | |
| The nine conversion BAT files connect MB3 DAT to four text formats in both directions, plus DAT-to-Wavefront OBJ. `main menu.ixpl` calls these scripts and loads/saves `load.mb3dat` / `save.mb3dat` intermediates. The converter command includes input type/path, output type/path, and conversion log path. Determine exact errors, numeric formatting, concurrency, and filesystem behavior later. | |
| Crucial reference limitation: main-menu help says imported textures and entities are discarded, and unsupported format features are lost on save. Full MAP/VMF support is not demonstrated by having a grammar. The rewrite must document compatibility subsets and offer loss reporting. | |
| No regular `.mb3txt`, `.mb3dat`, `.map`, `.vmf`, `.obj`, `.ixm`, or `.plugin` example outputs occur in any supplied archive. Build a generated fixture corpus and seek independently shareable real-world examples. MB3 DAT has no dedicated supplied grammar; its byte layout remains unknown. IXModel writer source exists and writes a header/version value `20160119`; do not confuse IXModel with MB3 DAT. | |
| ## F09 β Rendering and resource gaps | |
| The three shader files are `brushes.shader`, `grid.shader`, and `patch9s.shader`. Inspected brush/patch sections are marked `@vertex330` / `@fragment330`; the grid shader is much larger and requires separate analysis. The original uses a custom shader container and host integration, not WGSL. | |
| Latest PNG dimensions: font 512Γ512; editing icons 512Γ256; render-mode icons 256Γ128; layout icons 256Γ128. The plugins request icon filenames without the shipped `56` suffix (`Mb3 main editing tools.ixpl:410`, `Mb3 render modes.ixpl:158`, `view layouts.ixpl:156`). The loader may resolve aliases or variants; this is an unresolved lookup question, not a confirmed broken package. | |
| `config-Mb3.cfg` points to `content textures/index.cfg`; no such file is listed in the latest ZIP. `ReadMe.txt` points to `data/reference/SIL Open Font License.txt`; **none of the five ZIPs contains that file**. Identify the font and notice before treating it as redistributable runtime content. | |
| ## F10 β Historical differences | |
| Relative to each old build, the latest has respectively 23/23/22/21 added regular paths, 8/7/7/7 removed paths, and 71/71/72/72 changed same-path files. These are byte-hash comparisons, not semantic diffs. Older builds use `config.cfg`, the 2014 font, `Mb3 tools`, and a differently named base-window plugin. The latest separates Akula/MB3 configuration and adds the new toolbars/layout modules. Inspect renamed implementations before classifying removals as lost functionality. | |
| ## F11 β Actual archive terms | |
| Observed in latest `License and legal information.txt`: section 2 restricts executable/library modification and reverse engineering; section 4 restricts redistribution to an unchanged whole archive with original filename and attribution and excludes general download sites; section 5 restricts commercial use; section 6 restricts accompanying advertising. The archive does not carry a general open-source grant for the included source or assets. Earlier license texts still need a version-by-version comparison. | |
| Implications for planning: record the intended use and permissions for binary investigation, reuse, extraction publication, and HF hosting separately. A private HF repo is a proposed storage choice, not proof that the license permits uploading. Continue original documentation and independent design while resolving the relevant permissions; do not represent restricted reference material as newly authored Rust code. This records the supplied terms, not a legal conclusion about exceptions or enforceability. | |
| ## F12 β Local environment/storage precedents | |
| Inspected sibling `../glade`: | |
| - `.envrc`: `use flake`. | |
| - `flake.nix`: flake-parts, `github:nmrshll/my-nix`, nixpkgs/fp follows, essentials group plus Rust module, four Linux/Darwin systems, Linux graphics dependencies, Python and asset/inspection tools. | |
| - `.gitattributes`: required project code clean filter; `.gitignore`: ignores `/assets/`. | |
| - `scripts/setup-repository.py`, `storage_policy.py`, `assets.py`: repository-local filters, commit/push guards, separate asset checkout, pinned asset revision, Xet configuration, and history scanning. | |
| - `config/asset-repository.gitattributes`: all payloads, including text/JSON, use LFS filters; only control metadata uses ordinary text Git. | |
| - Code remote `hf` points to `git@hf.co:nmarshall/mini-gl`; its `assets.lock.json` has dataset ID and revision unset, and no `assets/` checkout was present. Therefore this is a design precedent, not a verified working HF asset deployment to clone blindly. | |
| Inspected `/Users/me/src/templates/nix-rust/.envrc`: watches local `my-nix` and `my-nix/tools` Nix sources, supplies local Git input overrides, and uses flake without rewriting the committed lock. Current `/Users/me/src/scripts/my-nix/flake.nix` exports `flakeModuleGroups.essentials`, a Rust module, and a compatibility essentials alias. `todo-lofi` demonstrates the newer module-group pattern but has older input URLs/tool choices; adapt the current exports rather than copying every line. No new flake has been evaluated. | |
| ## F13 β Current upstream rendering/storage evidence | |
| Checked 2026-10-21. The [bevy_solari 0.20.0 package](https://docs.rs/crate/bevy_solari/0.20.0) depends on the matching Bevy family and wgpu 30. Its [tagged source](https://raw.githubusercontent.com/bevyengine/bevy/v0.20.0/crates/bevy_solari/src/lib.rs) identifies Solari as experimental, exposes required ray-query/binding-array features, and separates realtime lighting, scene acceleration, and validation path tracing. This is a candidate spike version, not a project pin. | |
| The [upstream macOS issue #26131](https://github.com/bevyengine/bevy/issues/26131) reports an M2 Max failure; a maintainer states that raytracing requires M3 or newer. Treat this as an upstream compatibility risk and validate actual devices, limits, and drivers. Do not conclude that all macOS machines lack Solari or that every M3+ machine is proven supported. | |
| [Hugging Face's Xet instructions](https://huggingface.co/docs/hub/xet/using-xet-storage) describe Git LFS prerequisites and Git Xet integration; the [protocol documentation](https://huggingface.co/docs/xet/index) identifies git-xet as an LFS custom transfer agent. Project policy should verify pointer objects and Xet registration, rather than inventing a separate `filter=xet` attribute. Naming, authentication, visibility, and uploads remain unperformed. | |
| ## Main unknowns | |
| - Runtime startup and functional oracle on a reproducible Windows/Wine host. | |
| - Actual binary dependencies, host implementation behind interrupt APIs, native-editor DAT conformance, plugin representation, and full IXPL semantics. | |
| - Geometry winding/tolerances, Patch9 evaluation, snapping math, exact tool state machines, and source-versus-runtime discrepancies. | |
| - Formats/commands available only in older versions or hidden paths; full preservation behavior of converters. | |
| - Missing runtime notices/resources, font origin, icon resolution, and content-texture configuration behavior. | |
| - Permission and distribution model; actual HF namespace/repositories; supported GPU/OS combinations and measured performance. | |
| ## F14 β Confirmed single-repository precedent | |
| `urban-terror-rs/.gitattributes` selects `urt-code` by default and LFS for `assets/**`; its local config registers git-xet and its tracked asset objects are LFS pointers. Unlike glade, this is an active mixed repository. The user selected this pattern for Nanobrush, including every directory named `references/`. No separate dataset/asset branch/asset lockfile is used. | |
| ## F15βF20 β Format and shader source map | |
| The [format report](FORMATS.md) separates MB3 TXT/DAT, map dialects, OBJ export, IXModel, plugin artifacts, configuration and shader containers. It records actual grammar constraints, the `I10MODEL` writer/version/opcodes, two writer inconsistencies, config/keymap consumer differences, selection visual patterns, and the patch shader's unused lighting calculation. These findings are observed source evidence; no codec round trip or visible behavior is yet verified. | |
| ## F21 β Core endpoint enumeration | |
| The [host API map](HOST_APIS.md) resolves 408 latest Core IDs and all 448 wrapper sites, with a complete [ID-to-wrapper index](API_INDEX.md). The declaration set grows from 382 to 408 IDs across recovered builds. File I/O's overlapping 0β24 IDs remain a separate interface. Lifecycle, state, task buffers, declared preconditions and versioning boundaries are documented without assuming runtime ownership or dispatch behavior. | |
| ## F22 β Dependency closure and evolution | |
| The [dependency map](DEPENDENCIES.md) records all 487 include directives across the five builds, their single existing candidates, direct/transitive source edges, literal/dynamic resource candidates, conversion/build processes and byte-level version differences. Missing generated intermediates are distinguished from absent exact-name resources. Actual compiler precedence, plugin loader ordering and executable dependencies remain open. | |
| ## F23 β Plugin/service map | |
| The [plugin map](PLUGINS.md) accounts for 17 top-level plugins, five experimental sources and nine task clients. It indexes 201 tool registration call sites, identifies named service protocols, lifecycle callbacks, the raycast selection-mutation sequence, cached failed interface lookups, and single mutable callback slots. This establishes source relationships, not live execution traces or complete interaction parity. | |
| ## F24βF28 β Executed converter investigation | |
| [MB3 DAT](MB3_DAT.md) specifies the two recovered binary layouts, complete hierarchy/width/string/UV/computed-geometry contracts and method RVAs. [Converter behavior](CONVERTER.md) documents property optimization, encoding loss/drift, point/basis transforms, MAP/VMF/Q3/OBJ preservation/loss, CLI/log/overwrite behavior and malformed-file defects. [E02](experiments/converter-2026-10-21.md) ran 101 controlled probes using unchanged executables under Mono on macOS ARM64, retained raw evidence in Xet and added a bounded independent inspector. The authored network-free suite now has 52 tests. Native editor, Windows/Linux parity and full hostile-file coverage remain unverified. | |
| ## F29 β Native DAT serialization and compatibility profile | |
| The [Rust DAT codec](RUST_DAT.md) reads and writes both recovered layouts with checked counts/products, finite f32 and strict ASCII policies, bounded allocation/streaming and explicit rejection of ambiguous or incomplete data. It preserves property table order and absent-versus-empty values, refuses silent property loss on downgrade, and repairs the old signed-16 count range by choosing four bytes. All 58 captured DAT outputs round-trip exactly; intentional departures from legacy corruption, normalization and permissive parsing are documented separately from remaining editor/platform interoperability work. | |
| ## F30/F31 β TXT serialization and native CLI | |
| The [TXT codec](RUST_TXT.md) implements the latest grammar and old property-free subset with bounded UTF-8 parsing, canonical BOM output, finite round-trip decimals and consistent computed arrays. The [CLI](CLI.md) inspects/validates and converts TXT plus both DAT versions, refusing silent loss and publishing validated outputs with explicit no-clobber/force behavior. [E04](experiments/txt-cli-2026-10-21.md) covers 58 exact DATβTXTβDAT round trips through the real process, seven TXT outputs, 16 direct TXTβDAT pairs and nine invalid/lossy source rejections. | |