Pipeline Overview
The GRPG asset pipeline follows this flow:Manifest Format (GCFG)
GRPG uses the GCFG format for all manifests. It’s a structured configuration format similar to INI but with better type support.Basic Syntax
Supported Types
- String:
name = "value" - Integer:
id = 42 - Array:
items = ["one", "two", "three"] - Boolean:
enabled = true(though not commonly used in GRPG manifests)
Asset Types and Workflows
1. Textures (.grpgtex)
Textures are the foundation of the asset pipeline - all other assets reference textures.Create Texture Manifest
textures.gcfg
name- String identifier used by other assets to reference this textureid- Unique numeric ID (uint16, cannot be 0)path- File path to PNG texture file
Pack Textures
- Reads PNG files from paths
- Converts PNG to JPEG XL format (better compression)
- Writes binary file with magic header
GRPGTEX\x00 - Stores internal name (string) and ID (uint16) for each texture
data-packer/textures/manifest.go:25:2. Tiles (.grpgtile)
Tiles define ground types that fill the base layer of maps.Create Tile Manifest
tiles.gcfg
name- Tile identifierid- Unique tile ID (uint16)tex_name- References a texture name from your.grpgtexfile
3. Objects (.grpgobj)
Objects are interactive entities placed on top of tiles.Create Object Manifest
objects.gcfg
name- Object identifierid- Unique object ID (uint16)flags- Array of capability flags:"STATE","INTERACT"textures- Array of texture names (index = state number)interact_text- Text shown on interaction (required ifINTERACTflag set)
4. Items (.grpgitem)
Items are objects that can be placed in player inventories.Create Item Manifest
items.gcfg
name- Item identifierid- Unique item ID (uint16)texture- Single texture name for inventory icon
5. NPCs (.grpgnpc)
NPCs are non-player characters with dialogue and movement.The data-packer CLI
Installation
grpgpack executable.
Command Structure
Fromdata-packer/main.go:18:
tex- Pack texturestile- Pack tilesobj- Pack objectsitem- Pack itemsnpc- Pack NPCs
Common Flags
| Flag | Short | Description | Default |
|---|---|---|---|
--manifest | -m | Path to manifest file | (required) |
--output | -o | Output file path | Type-specific |
--textures | -t | Path to .grpgtex file | (required for non-tex types) |
Example Workflow
Always pack textures first! Other asset types reference textures and will fail validation if the texture file doesn’t exist or is missing referenced textures.
Binary Format Details
Why Binary Formats?
GRPG uses custom binary formats instead of JSON/YAML for several reasons:- Size - Binary data is more compact than text
- Speed - Faster to parse (no text-to-number conversion)
- Type Safety - Fixed-size types prevent runtime errors
- Compression - JPEG XL textures are much smaller than PNG
The GBuf Abstraction
All binary reading/writing usesdata-go/gbuf, a buffer wrapper that simplifies binary I/O:
data-go/gbuf/gbuf.go
- Handles endianness automatically (uses big-endian)
- Tracks read/write offset
- Provides clean error handling
- Prevents buffer overflow vulnerabilities
Magic Headers
All GRPG binary formats start with an 8-byte magic header for validation:| Format | Magic Header |
|---|---|
| Textures | GRPGTEX\x00 |
| Tiles | GRPGTILE\x00 |
| Objects | GRPGOBJ\x00 |
| Items | GRPGITEM\x00 |
| NPCs | GRPGNPC\x00 |
| Maps | GRPGMAP\x00 |
Advanced Topics
Texture Compression
Fromdata-packer/textures/manifest.go:47:
- Better compression than PNG (typically 30-50% smaller)
- Lossless quality at Quality: 100
- Fast decoding on modern hardware
- Wide format support (8-bit, 16-bit, HDR)
Manifest Validation
The data-packer validates manifests during packing:data-packer/objs/manifest.go:36
- Texture ID cannot be 0 (reserved)
interact_textrequiresINTERACTflag- Texture references must exist in provided
.grpgtexfile - IDs must be unique within each asset type
Automated Build Scripts
Thedata-packer/buildtobin.sh script automates the entire pipeline:
data-packer/buildtobin.sh
Performance Considerations
File Sizes
Typical file sizes for a small game:- Textures: 500KB - 5MB (depends on JPEG XL compression)
- Tiles: 1-10KB (just references + metadata)
- Objects: 2-20KB (includes state/interaction data)
- Items: 1-5KB (minimal data)
- Maps: ~1KB per chunk (fixed size)
Loading Strategy
The server loads assets at startup:- Load texture file once (shared by all systems)
- Load tile/object/item/NPC files
- Map chunks loaded dynamically as players move
Because binary formats are compact and fast to parse, loading even thousands of assets takes milliseconds.
Troubleshooting
Error: Integer ID 0 is reserved
Error: Integer ID 0 is reserved
From
data-packer/textures/manifest.go:57, ID 0 is reserved for “empty” or “null” values.Solution: Start your IDs from 1:Error: interact_text without interact flag not allowed
Error: interact_text without interact flag not allowed
You set
interact_text but didn’t include the INTERACT flag.Solution:Error: failed to decode png image
Error: failed to decode png image
The texture path points to a non-PNG file or corrupted file.Solution:
- Verify the path is correct
- Ensure the file is a valid PNG
- Check file permissions
Texture references not resolving
Texture references not resolving
Other asset types can’t find textures by name.Solution:
- Ensure you packed textures first
- Verify texture names match exactly (case-sensitive)
- Pass correct texture file with
-tflag
Build Automation Example
Create aMakefile for your game assets:
Makefile
Next Steps
Custom Objects
Create your first custom object with the asset pipeline
Map Creation
Use your packed assets in the map editor