ZZAR (Zenless Zone Zero Audio Replacer) modifies game audio by patching PCK (package) files that contain WEM audio streams and BNK (sound bank) files. The tool works by:
Extracting original game audio files from PCK archives
Converting user audio to WEM format using Wwise
Patching modified audio back into PCK files
Placing the modified PCK files in a persistent directory that the game loads
# BNK consists of RIFF-style chunks (bnk_handler.py:144-176)'BKHD' # Bank Header - metadata about the sound bank'DIDX' # Data Index - WEM file offsets and sizes'DATA' # Data Section - contains all WEM audio files'HIRC' # Hierarchy - sound object relationships (optional)
# Each entry is 12 bytes (bnk_handler.py:43-49)wem_id # uint32: WEM file identifieroffset # uint32: Offset into DATA sectionsize # uint32: WEM file size in bytes
# WEM files are stored sequentially with 16-byte alignment# (bnk_handler.py:98-110)[WEM_1 data][padding to 16-byte boundary][WEM_2 data][padding to 16-byte boundary]...
16-Byte Alignment Details
Wwise requires WEM files in BNK archives to be aligned to 16-byte boundaries:
# bnk_handler.py:8-10def align16(x): return (16 - (x % 16)) % 16# Applied during packing (bnk_handler.py:98-110)if i == 0 and i != len(wems) - 1: # First file: align from start of DATA section file_padding = align16(len(wem_data) + start_pos)elif i != len(wems) - 1: # Middle files: align from current position file_padding = align16(len(wem_data))else: # Last file: no padding needed file_padding = 0
Patches existing PCK files in-place, preserving the original structure:
# pck_packer.py:292-383# 1. Copy original PCK to output locationshutil.copy2(original_pck, output_pck)# 2. Open output PCK in read-write modewith open(output_pck, 'r+b') as f: # 3. Seek to each file's offset f.seek(original_offset) # 4. Write new data if new_size == original_size: f.write(new_data) # Perfect fit elif new_size < original_size: f.write(new_data) f.write(b'\x00' * padding) # Pad with zeros else: f.write(new_data[:original_size]) # Truncate if larger
Patching mode will truncate audio files that are larger than the original. This can result in incomplete audio playback. Use rebuild mode for files with different sizes.
ZZAR places modified PCK files in a persistent directory that takes precedence over the original game files:
Game Directory/├── ZenlessZoneZero_Data/│ └── StreamingAssets/│ └── Audio/ # Original game audio│ ├── GeneratedSoundBanks/│ │ ├── SoundBank_SFX_1.pck│ │ └── ...│ └── Streamed/│ ├── Streamed_SFX_1.pck│ └── ...└── Persistent/ # ZZAR modified files (higher priority) └── GeneratedSoundBanks/ └── SoundBank_SFX_1.pck # Modified version
The game’s asset loading system checks the Persistent directory first, allowing ZZAR to override original audio without modifying game installation files.