- Python 63%
- HTML 34%
- Shell 3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| site | ||
| SPEC | ||
| tools | ||
| .gitignore | ||
| BRIEF.md | ||
| grn.py | ||
| grn2gltf.py | ||
| JNTEX-BRIEF.md | ||
| PROCESS.md | ||
| README.md | ||
| WEBSITE-BRIEF.md | ||
grn-re — reading Granny 1 .grn files
Granny 2 (.gr2) has community parsers. Granny 1 (.grn) had none,
so every game that shipped on Granny 1 had unreadable character meshes,
skeletons and animations unless you ran RAD's runtime — which cannot be
redistributed and is 32-bit Windows only.
Status: solved. The container, meshes, skeletons, skinning, materials and animations all read, end to end:
grn.py— a standalone, standard-library-only parser. Drop the one file into your project and read Granny 1 files.grn2gltf.py— a converter on top of it: skinned, animated glTF 2.0 (.glb), plus OBJ for quick static inspection.SPEC/GRN-V1.md— the specification every line of the parser traces to, with the corpus count behind each claim and the oracle it rests on.
Validated against 674 of 674 shipped files of SpongeBob SquarePants: Employee of the Month (AWE Games / THQ, 2002) and — the cross-title claim, now measured rather than expected — 389 of 389 files of Jimmy Neutron vs. Jimmy Negatron. The mesh layer is additionally checked corner-by-corner against a live capture of RAD's own runtime decoding the same files.
python grn.py SB_Model.grn what is in the file
python grn.py SB_Model.grn --skeleton bones, parents, names
python grn2gltf.py SB_Model.grn --anim SB_walk.grn -o sb.glb
python grn2gltf.py SB_Model.grn --texture sponge=sponge.png -o sb.glb
python tools/validate.py <corpus dir> every check, whole corpus
Textures are embedded in the files but compressed with RAD's own codec
(BIKi); this project reads their headers and deliberately stops there — see
PROCESS.md. The same art ships uncompressed enough to decode
in the sibling .omt containers (already specified by awefan's published
toolkit), which is where --texture images come from.
Corpus
No game assets are included here. You need your own copy of a game that
ships .grn files.
Exporter stamp across both corpora:
RAD 3D Studio MAX 4.x · 1.2b · 10-4-2000 · win32.
Scope, deliberately
This documents a file format, so that files can be read. It is not a
description of RAD Game Tools' granny.dll: no function of that library is
described, listed or reproduced, and none was needed — every claim in the
spec came from the data files, except where §13 explicitly names the live
runtime capture as the oracle. That boundary is the point, not a formality.
See PROCESS.md.
Method
The habits that produced this, each of which caught a real error here:
- Validate against the whole corpus, not one file. Every structural claim is stated with the number of files it holds for.
- A parse that tiles a file exactly is necessary, not sufficient. The spec keeps a standing section for what is not established.
- Test the competing reading to destruction. The record tree, the bone parents and the track-to-node mapping were each settled by eliminating alternatives, not confirming a favourite — the track mapping looked correct under the wrong reading for the one track everyone checks first.
- Distrust tidy histograms, and scan naively on purpose.
tools/grn_dir.py, grn_tree.py, grn_names.py, grn_spans.py and
grn_scan.py are the analysis instruments that got the container solved;
grn.py --tree/--objects/--skeleton supersedes them for everyday use.