Compact Duke Nukem 3D 1.3D Shareware .grp variants for constrained targets (e.g. duke3d-go in retro-go on ESP32-class devices).
| Version | Size (KiB) | Reduction in % | Size Zipped (KiB) | Reduction in % |
|---|---|---|---|---|
| DUKE3D_v1.3d_shareware.grp | 10777.1 | 0% | 4729.2 | 56.12% |
| E1L1-6.grp | 3797.8 | 64.76% | 2664.9 | 75.27% |
| E1L1-6_nearcomplete.grp | 3603.5 | 66.56% | 2478.8 | 77.00% |
| E1L1-6_compromise.grp | 3032.0 | 71.87% | 1967.9 | 81.74% |
| E1L1-3_nearcomplete.grp | 2813.1 | 73.90% | 2079.6 | 80.70% |
| E1L1-2.grp | 2625.3 | 75.64% | 2034.1 | 81.13% |
| E1L1-6_tiny.grp | 2624.0 | 75.65% | 1599.5 | 85.16% |
| E1L1-4_compromise.grp | 2556.4 | 76.28% | 1727.4 | 83.97% |
| E1L1-4_heavycompromise.grp | 2514.5 | 76.67% | 1689.4 | 84.32% |
| E1L1-2_nearcomplete.grp | 2467.3 | 77.11% | 1881.3 | 82.54% |
| E1L1-3_compromise.grp | 2311.0 | 78.56% | 1632.5 | 84.85% |
| E1L1.grp | 2260.4 | 79.03% | 1768.8 | 83.59% |
| E1L1-2_compromise.grp | 2003.4 | 81.41% | 1471.0 | 86.35% |
| E1L1_compromise.grp | 1700.0 | 84.23% | 1261.0 | 88.30% |
| E1L1_tiny.grp | 1375.8 | 87.23% | 972.6 | 90.97% |
| E1L1_minimal.grp | 1327.0 | 87.69% | 929.6 | 91.37% |
Notes:
- Baseline is
input/DUKE3D_v1.3d_shareware.grp. Both "Reduction in %" columns are compared to that same unzipped baseline. - Output sizes will vary slightly based on PNG compressor settings, PNG cache used, and tool versions. The above values are from a run using the precalculated PNG caches described in
longrun.sh. - See
generate_variants.shfor the exact per-variant arguments. - The "Zipped" files are a ZIP of the .GRP files, which is supported by DynaMight1224's experimental Duke3D-Go branch for Retro-Go on the ESP32
python3 compare_output_to_input_sizes.py --input input/DUKE3D_v1.3d_shareware.grp --outputs outputsCore:
- Python 3
- EDuke32 tooling:
kextract,kgroup,arttool,mapinfo - ImageMagick (
convert)
Optional (depending on flags/workflow):
zopflipng(for--zopflipng)pngquant(for--pngquant)ffmpeg(for--adpcmwav/--adpcmwidthworkflows)adpcm-xq(for--adpcmwidth)zip(for.grp.zipoutput)
Build a single compact variant:
python3 duke3d_compact_grp.py input/DUKE3D_v1.3d_shareware.grpBuild the full variant set:
./generate_variants.shRun a generated GRP in EDuke32:
./eduke32 -usecwd -g myvariant.grp -l2duke3d_compact_grp.py performs the main pipeline:
- Extracts GRP content using EDuke32
kextract. - Extracts tile data from
TILESNNN.ARTusingarttool. - Analyzes
.mapfiles to determine needed textures and MIDI files. - Converts
.pcxtextures to.pngwith ImageMagickconvert. - Optionally color-reduces PNGs via
pngquant(--pngquant quality_range). - Optionally optimizes PNGs with
zopflipng(--zopflipng). - Converts
.vocaudio to.wavwithffmpeg. - Optionally recompresses WAV to ADPCM via
adpcm-xq(--adpcmwidth2–5 bits). - Rebuilds the final GRP with EDuke32
kgroup.
Optional zipped output:
zip -9 out.grp.zip out.grpKey CLI flags:
--maxsoundsize N— exclude sound files larger than N bytes (raw VOC size).--excludefiles FILE— exclude specific files.--includefiles FILE— force-include files even if excluded by--maxsoundsize.--pngquant QUALITY— e.g.40-71,10for aggressive color reduction.--pngfolder DIR— reuse precalculated PNGs from a previous--keep-temprun.--adpcmwav/--adpcmwidth N— convert WAVs to ADPCM.--camerasdestructable— make security cameras destructible in game logic.--ultraminimalmenu— strip high-res menu images.--nomenusongs— exclude menu background music.--keep-temp— do not deletetemp_folder/after the run (to seed a PNG cache).
Already supports:
- PNG textures via
duke3d.defdefinetexture - WAV sound effects via
duke3d.defsound - Tile range animation via
duke3d.defanimtilerange
Added in this fork:
- ADPCM-compressed WAV sound effect support
Extended support includes:
- EDuke32-style PNG texture overrides
- EDuke32-style WAV sound effects
- EDuke32-style
animtilerangehandling - ADPCM-compressed WAV sound effects
This repository tracks:
eduke32-for-DukeNano3Dretro-go-for-DukeNano3D(branchDuke3D-with-fri3d-2026)
Clone with submodules (recommended):
git clone --recursive https://github.com/ThomasFarstrike/DukeNano3D.gitIf already cloned without --recursive:
git submodule update --init --recursiveSync URL/config after .gitmodules updates:
git submodule sync --recursive
git submodule update --init --recursiveUpdate submodules to latest tracked remote commit:
git submodule update --remote --merge --recursiveUpdate one submodule only:
git submodule update --remote --merge eduke32-for-DukeNano3D
git submodule update --remote --merge retro-go-for-DukeNano3DCommit updated submodule pointers in this superproject:
git add .gitmodules eduke32-for-DukeNano3D retro-go-for-DukeNano3D
git commit -m "Update submodules"-
Currently, all textures for a selected level set are included. If a required texture is missing, rendering artifacts appear (undrawn areas/"dragging"). One possible approach is to replace large textures with tiny placeholder PNGs (~200 bytes) that preserve dimensions and approximate average color. That could enable a future
--maxtexturesizeoption similar to--maxsoundsize. -
Some textures are not directly referenced in map sectors/walls but are still required (HUD, weapon sprites, kick animation, decorative animations). Better static analysis of
.congame logic could identify what can safely be removed.
Current options:
--excludefilesfor explicit sound file exclusions--includefilesto override--maxsoundsizeexclusions for must-have sounds--maxsoundsizeto skip all sound files larger than a threshold
Future improvement: smarter .map + .con usage analysis to remove unused or rarely used .voc assets while preserving gameplay quality.
