Cross-platform Java rendering/game engine scaffold using a stable Java-first API boundary and backend SPI.
- JDK 25 (project enforces Java 25 via Maven Enforcer)
- Maven 3.9+
If you use jenv:
jenv local 25.0.1
java -version
mvn -versionOr shell-only:
export JAVA_HOME=$(/usr/libexec/java_home -v 25)
export PATH="$JAVA_HOME/bin:$PATH"
java -version
mvn -versionengine-api: immutable DTOs and runtime contracts (org.dynamislight.api.*)engine-spi: backend discovery SPI (ServiceLoader)engine-impl-common: shared lifecycle/runtime base for backend implementationsengine-impl-opengl: OpenGL backend implementationengine-impl-vulkan: Vulkan backend implementationengine-bridge-dynamisfx: host bridge/mapping layerengine-host-sample: minimal console host that runs the lifecycle
org.dynamislight.api.runtime: lifecycle and execution surface (EngineRuntime, callbacks, frame/stats/capabilities)org.dynamislight.api.config: runtime config and quality tierorg.dynamislight.api.input: host input DTOsorg.dynamislight.api.scene: scene/fog/smoke DTOsorg.dynamislight.api.event: event/warning DTOsorg.dynamislight.api.error: engine error model (EngineException,EngineErrorCode)org.dynamislight.api.logging: structured runtime log DTOsorg.dynamislight.api.resource: resource cache/reload service contracts
- SPI contract:
engine-spi(EngineBackendProvider,BackendRegistry) discovers backends throughServiceLoader. - OpenGL implementation:
engine-impl-opengl(OpenGlBackendProvider,OpenGlEngineRuntime) is the primary active backend. - Vulkan implementation:
engine-impl-vulkan(VulkanBackendProvider,VulkanEngineRuntime) provides a real baseline render path (context, swapchain, pipeline, indexed draw). - Host integration:
engine-bridge-dynamisfxprovides the DynamisFX bridge/session and mappers to engine DTOs.
mvn clean compile
mvn testIf JAVA_HOME is stale in your shell, use the repo launcher to force .java-version (25):
./scripts/mvnw25 testRun backend compare-harness parity tests explicitly:
mvn -pl engine-host-sample -am test -Ddle.compare.tests=true -Dtest=BackendParityIntegrationTest -Dsurefire.failIfNoSpecifiedTests=falseWrite compare outputs to a stable folder for inspection/artifacts:
mvn -pl engine-host-sample -am test -Ddle.compare.tests=true -Ddle.compare.outputDir=artifacts/compare -Dtest=BackendParityIntegrationTest -Dsurefire.failIfNoSpecifiedTests=falseThis includes tiered fog/smoke, shadow, and texture-heavy checks plus shadow-cascade-stress, fog-shadow-cascade-stress, smoke-shadow-cascade-stress, and texture-heavy compare profiles.
Run real-hardware AA compare rebaseline on macOS (OpenGL/Vulkan, non-mock, first-thread JVM):
./scripts/aa_rebaseline_real_mac.shOptional overrides:
DLE_COMPARE_OUTPUT_DIR=artifacts/compare/aa-real-manual ./scripts/aa_rebaseline_real_mac.sh# Vulkan mode: mock (default), auto, or real
DLE_COMPARE_VULKAN_MODE=real ./scripts/aa_rebaseline_real_mac.sh# TSR validation depth (extra temporal frames) + optional upscaler hook tuning
DLE_COMPARE_TEMPORAL_FRAMES=10 \
DLE_COMPARE_TEMPORAL_WINDOW=5 \
DLE_COMPARE_TSR_FRAME_BOOST=6 \
DLE_COMPARE_UPSCALER_MODE=xess \
DLE_COMPARE_UPSCALER_QUALITY=quality \
DLE_COMPARE_VULKAN_MODE=real \
./scripts/aa_rebaseline_real_mac.sh# Run repeated real-Vulkan AA samples and lock thresholds from the aggregate
DLE_COMPARE_LONGRUN_RUNS=5 \
./scripts/aa_longrun_real_sampling_mac.sh# Run repeated motion-focused AA stress suites (animated/pan-heavy) and lock thresholds
DLE_COMPARE_LONGRUN_MOTION_RUNS=4 \
./scripts/aa_rebaseline_real_mac.sh longrun-motion# Run TSR+upscaler vendor matrix (FSR/XeSS/DLSS hook/native-state audit from metadata)
./scripts/aa_rebaseline_real_mac.sh upscaler-matrix# Build threshold-lock recommendations from repeated real-Vulkan compare metadata
# Default minimum profile samples: 3 (override with DLE_COMPARE_THRESHOLD_LOCK_MIN_RUNS)
./scripts/aa_rebaseline_real_mac.sh lock-thresholds artifacts/compare# Promote generated recommendations into repo-owned default threshold files
./scripts/promote_compare_thresholds.sh artifacts/compare/threshold-lock/recommended-thresholds.properties real
./scripts/promote_compare_thresholds.sh artifacts/compare/threshold-lock/recommended-thresholds.properties mock# Apply locked thresholds automatically during compare runs
DLE_COMPARE_THRESHOLDS_FILE=artifacts/compare/threshold-lock/recommended-thresholds.properties \
DLE_COMPARE_VULKAN_MODE=real \
./scripts/aa_rebaseline_real_mac.sh# Optional: enforce a pinned MoltenVK version during preflight/real runs
DLE_COMPARE_REQUIRE_MOLTENVK_VERSION=1.4.0 \
DLE_COMPARE_VULKAN_MODE=real \
./scripts/aa_rebaseline_real_mac.sh preflightTSR implementation reference: docs/tsr-temporal-upsampling-notes-2026.md
External native upscaler bridge options (OpenGL and Vulkan):
<backend>.upscaler.nativeEnabled=true|false<backend>.upscaler.bridgeClass=com.example.MyUpscalerBridge<backend>.upscaler.bridgeLibrary=/abs/path/libvendor_upscaler.dylib(or comma-separated list)
Compare metadata now includes warning code snapshots per backend:
compare.opengl.warningCodescompare.vulkan.warningCodes
Example (vulkan backend):
MAVEN_OPTS="-Dvulkan.upscaler.nativeEnabled=true \
-Dvulkan.upscaler.bridgeClass=com.acme.upscale.VulkanDlssBridge \
-Dvulkan.upscaler.bridgeLibrary=/opt/acme/lib/libacme_dlss_bridge.dylib" \
DLE_COMPARE_UPSCALER_MODE=dlss \
DLE_COMPARE_VULKAN_MODE=real \
./scripts/aa_rebaseline_real_mac.shGitHub Actions CI runs:
- matrix build/test (
mvn test) onmainand pull requests using JDK 25 across Linux, macOS, and Windows - guarded backend parity compare harness tests on Ubuntu (
dle.compare.tests=true) .github/workflows/ci.yml
Install snapshots, then run the sample host:
mvn -DskipTests install
mvn -f engine-host-sample/pom.xml exec:javaSelect backend by argument:
mvn -f engine-host-sample/pom.xml exec:java -Dexec.args="vulkan"Inspect and hot-reload resources in sample host:
mvn -f engine-host-sample/pom.xml exec:java -Dexec.args="opengl --resources"Run compare harness from sample host (writes images under artifacts/compare):
mvn -f engine-host-sample/pom.xml exec:java -Dexec.args="--compare --compare-tier=HIGH --compare-tag=shadow-high"Compare mode backend toggles:
--compare-opengl-mock=true|false--compare-vulkan-mock=true|false--compare-vulkan-offscreen=true|false
Tune sample host shadow/post parameters from CLI:
mvn -f engine-host-sample/pom.xml exec:java -Dexec.args="vulkan --tier=HIGH --shadow=on --shadow-cascades=4 --shadow-pcf=5 --shadow-bias=0.001 --shadow-res=2048 --post=on --tonemap=on --exposure=1.1 --gamma=2.2 --bloom=on --bloom-threshold=1.0 --bloom-strength=0.8"Interactive tuning + diagnostics overlay:
mvn -f engine-host-sample/pom.xml exec:java -Dexec.args="vulkan --interactive --overlay --frames=99999"Interactive commands:
help,show,reload,quittier LOW|MEDIUM|HIGH|ULTRAshadow on|off,shadow_cascades <1-4>,shadow_pcf <1-9>,shadow_bias <float>,shadow_res <256-4096>post on|off,tonemap on|off,exposure <0.25-4.0>,gamma <1.2-3.0>bloom on|off,bloom_threshold <0.2-2.5>,bloom_strength <0.0-1.6>
OpenGL backend options (via EngineConfig.backendOptions):
opengl.mockContext=true|false(defaultfalse) skips native context creation for headless/test runs.opengl.forceInitFailure=true|falseforcesBACKEND_INIT_FAILEDfor failure-path testing.opengl.windowVisible=true|false(defaultfalse) controls visible presentation window.
Vulkan backend options:
vulkan.mockContext=true|false(defaulttrue) toggles real Vulkan instance initialization.vulkan.forceInitFailure=true|falseforcesBACKEND_INIT_FAILEDfor failure-path testing.vulkan.windowVisible=true|false(defaultfalse) controls visible presentation window.vulkan.forceDeviceLostOnRender=true|falseforcesDEVICE_LOSTfor failure-path testing.vulkan.postOffscreen=true|false(defaulttrue) enables dedicated Vulkan post pass (intermediate copy + fullscreen composite) with automatic shader fallback if unavailable.
Sample-host default keeps OpenGL in mock mode for portability. To run real OpenGL init/render from sample host:
mvn -f engine-host-sample/pom.xml exec:java -Dexec.args=\"opengl\" -Ddle.opengl.mockContext=falseDynamicLightEngine now provides real baseline rendering in both OpenGL and Vulkan backends behind the same API/SPI contracts.
Vulkan now includes:
- attribute-rich mesh ingestion (
POSITION,NORMAL,TEXCOORD_0,TANGENT) with.gltf/.glbparsing - descriptor-backed camera/material/lighting data
- 3-frames-in-flight global uniform + descriptor-set ring path
- persistently mapped Vulkan staging memory for frame-uniform uploads
- fog/smoke quality-tier behavior and degradation warnings aligned with OpenGL warning semantics
- multi-frame-in-flight command/sync model and device-local mesh buffers uploaded via staging transfers
Cross-backend parity tests now cover:
- lifecycle/error parity
- material/lighting scene behavior parity signals
- repeated resize stability
- quality-tier fog/smoke degradation warning parity
- tonemap-enabled post-process parity profile (
post-process)
Post-processing status:
- scene-level
PostProcessDescis supported on OpenGL and Vulkan. - scene-level
AntiAliasingDesc(viaPostProcessDesc.antiAliasing) can override AA mode/debug and temporal controls (blend,clipScale,lumaClipEnabled,sharpenStrength,renderScale). - temporal debug view supports a composite overlay mode:
dle.taa.debugView=5(quadrants: reactive/disocclusion/historyWeight/velocity). - OpenGL now uses a dedicated post pass (offscreen FBO color target + fullscreen post shader) with shader-driven fallback safety.
- Vulkan now runs a dedicated post pass when available and surfaces explicit
VULKAN_POST_PROCESS_PIPELINEdiagnostics (including fallback mode when needed).
OpenGL includes a fog path driven by SceneDescriptor.fog with quality-tier dependent sampling:
LOW: coarse fog stepsMEDIUM/HIGH: progressively smoother fogULTRA: unquantized fog factor
OpenGL also consumes SceneDescriptor.smokeEmitters with a screen-space smoke blend.
At lower tiers (LOW, MEDIUM) smoke quality is degraded intentionally and reported through EngineWarning code SMOKE_QUALITY_DEGRADED.
Resource baseline is now available through EngineRuntime.resources():
- in-memory asset cache with ref-count ownership
- automatic scene asset acquire/release on scene swap and shutdown
- filesystem-backed
LOADED/FAILEDstate transitions - checksum-aware hot reload via
EngineResourceService.reload(ResourceId)(changed vs unchanged detection) withResourceHotReloadedEvent - per-resource metadata in
ResourceInfo(resolvedPath,lastChecksum,lastLoadedEpochMs) - v1 eviction policy: no TTL; zero-ref resources remain cacheable and are evicted by
resource.cache.maxEntriespressure
Resource runtime options (EngineConfig.backendOptions):
resource.watch.enabled=true|false(defaultfalse) enables filesystem watcher auto-reload.resource.watch.debounceMs=<int>(default200) debounce window for watcher-triggered reloads.resource.cache.maxEntries=<int>(default256) maximum cached resource records.resource.reload.maxRetries=<int>(default2) retry attempts for failed reload scans.
Resource telemetry is available via EngineRuntime.resources().stats():
- cache hits/misses
- reload requests/failures
- evictions
- watcher event count
Optional integration-test flags:
-Ddle.test.resource.watch=trueenables watcher auto-reload integration test.-Ddle.test.vulkan.real=trueenables guarded real-Vulkan integration tests (init/reuse/reorder/resize-endurance/device-loss paths). Tests skip automatically if LWJGL native runtime prerequisites are unavailable.-Ddle.compare.tests=trueenables compare-harness image diff integration tests.-Ddle.compare.opengl.mockContext=true|false,-Ddle.compare.vulkan.mockContext=true|false, and-Ddle.compare.vulkan.postOffscreen=true|falsecontrol compare-harness backend modes.
- Rendering roadmap (2026):
docs/rendering-roadmap-2026.md - Mechanical sympathy + GPU-driven + Dynamic GI roadmap:
docs/mechanical-sympathy-gpu-driven-roadmap-2026.md - Superset rendering roadmap (2026):
docs/superset-rendering-roadmap-2026.md - Capabilities compendium:
docs/capabilities-compendium.md - Expanded rendering feature comparison (2026):
docs/expanded-rendering-feature-comparison-2026.md - API reference:
docs/api-reference.md - Release workflow:
docs/release-workflow.md - Milestone and issue backlog:
docs/github-milestones.md - Architecture note:
docs/architecture/backend-strategy.md - ADR:
docs/adr/0001-backend-strategy.md