Skip to main content

Architecture Overview

Project Purpose

ddon-extractor reverse-engineers the proprietary binary file formats used by the Dragon's Dogma Online (DDON) game client. The primary output is a JSON (or YAML) representation of each file's structured data. The project also includes support for:

  • Binary serialization (round-trip: binary → JSON → binary) for a handful of resource types.
  • Network packet deserialization for captured game traffic (Season 3 only).
  • Archive unpacking including Blowfish-encrypted .arc files.

The main source of knowledge for understanding the file formats comes from the debug symbols of the PS4 client, recorded in the separate ddon-data repository.

Module Structure

The project is a multi-module Gradle build with seven subprojects:

ddon-extractor/                (root — build orchestration only)
├── lib-api/ (core interfaces, data types, I/O, crypto)
├── lib-common/ (shared deserializers & manager base class)
├── lib-season1/ (Season 1 specific deserializers & entities)
├── lib-season2/ (Season 2 specific deserializers & entities)
├── lib-season3/ (Season 3 specific deserializers, entities & packets)
├── cli/ (picocli command-line application)
└── lib-test/ (cross-module integration tests)

Publishable vs. Non-Publishable

CategoryModulesNotes
Publishable (Maven)lib-api, lib-common, lib-season1, lib-season2, lib-season3Published with maven-publish plugin, artifact IDs like ddon-extractor-lib-api.
Non-publishablecli, lib-testcli produces a native executable via JLink/jpackage. lib-test is test-only.

Module Dependency Graph

Note: Every season module depends on both lib-api (interfaces) and lib-common (shared deserialization logic). The CLI depends on all five library modules. The test module uses testImplementation dependencies to access all modules without being part of the production dependency chain.

Build System

Gradle Configuration

AspectDetail
JDKJDK 25 (Eclipse Adoptium). Configured via java.toolchain.languageVersion.
Module systemFull JPMS (Java Platform Module System). Each module has a module-info.java. modularity.inferModulePath = true.
Annotation processingLombok via io.freefair.lombok plugin.
Dependency versionsCentralized in settings.gradle using Gradle version catalogs (common, log, lib, libTest, cli).
Native packagingBadass JLink Plugin jlink + jpackage in the cli module.
BenchmarksJMH Gradle Plugin in lib-api and cli.
Code coverageJacoco (applied to all subprojects).
Dependency updatescom.github.ben-manes.versions.

Key Dependencies

LibraryUsage
Jackson (core, databind, YAML, CSV)JSON/YAML serialization, CSV translation loading
BouncyCastle (bcprov-jdk18on)Blowfish decryption of encrypted archives
Apache Commons Lang3Pair, StringUtils utilities
SLF4J + Log4j2Logging
picocliCLI argument parsing (cli module only)
JUnit JupiterTesting
MockitoTest mocking

JPMS Module Names

Gradle ModuleJPMS Module Name
lib-apiorg.sehkah.ddon.tools.extractor.lib.api
lib-commonorg.sehkah.ddon.tools.extractor.lib.common
lib-season1org.sehkah.ddon.tools.extractor.lib.season1
lib-season2org.sehkah.ddon.tools.extractor.lib.season2
lib-season3org.sehkah.ddon.tools.extractor.lib.season3
cliorg.sehkah.ddon.tools.extractor.cli
lib-test(classpath-based test module, no module-info)

Package Naming Convention

All production packages follow the pattern:

org.sehkah.ddon.tools.extractor.{scope}.logic.{domain}.{layer}.{subdomain}

Where:

  • {scope}: api | common | season1 | season2 | season3 | cli
  • {domain}: resource | packet
  • {layer}: deserialization | serialization | entity
  • {subdomain}: Game domain like EM, game_common, stage, quest, gui_cmn, npc_common, skill, texture, binary, etc.

Example: org.sehkah.ddon.tools.extractor.season3.logic.resource.deserialization.stage