FAQ¶
Short answers. Follow the links for the deep dive.
Do I need JDK 26?¶
Yes. japes uses the finalised java.lang.classfile API (JEP 484) to
emit per-system hidden classes, and the build targets JDK 26.
Earlier JDKs will not compile the library. See
Installation.
How do I turn off the bytecode generator for debugging?¶
Call useGeneratedProcessors(false) on WorldBuilder before
build(). Every system then runs on the tier-2 reflective path,
which is easier to step through and produces shorter stack traces.
Verified in ecs-core/.../world/WorldBuilder.java.
Why are components records?¶
Records give you value-type semantics for free — immutable fields,
generated equals / hashCode, predictable layout — which lets the
storage and change tracker treat every write as a whole-record swap.
It also makes Valhalla migration a one-line change once the JDK lands
value classes. See Components.
Can I use non-record components?¶
No. ComponentRegistry.register throws if the type is not a record.
Wrap whatever you need in a record — it's usually a two-line change.
Is japes thread-safe?¶
Systems declared in different stages run serially. Systems inside a
single stage can run in parallel on disjoint component sets —
Commands is safe to use from parallel systems and flushed at the end
of the stage. Manual cross-thread writes to components or resources
outside a system are not supported. See
Multi-threading.
Why is my system running on tier-2?¶
Cross-reference the skipReason string with the
Tier-1 vs tier-2 dispatch lookup table. Every
entry lists the concrete fix — most are one-liners (split a system,
fold services into a Res<Bundle>, move a @Where predicate into
the method body).
What's the chunk size default?¶
1024 entities per chunk. Change it via
WorldBuilder.chunkSize(int) before calling build(). Verified in
ecs-core/.../world/WorldBuilder.java.
Why does @FromTarget @Write not work?¶
It's rejected at parse time, not a tier-2 drop. Write conflicts between pairs sharing a target are ambiguous — if predators A and B both hunt prey P, neither has well-defined "last writer wins" semantics. Write onto the source, the payload, or split the system into a target-side reader followed by a per-entity writer. See @ForEachPair and @FromTarget.
How do I enable flat-array storage?¶
Pass -Dzzuegg.ecs.useFlatStorage=true to the JVM. It's an
experimental storage layout in DefaultComponentStorage — see
Benchmarks for the numbers that triggered
the SoA work.
Is Valhalla required?¶
No. japes runs on stock JDK 26 and ships a separate
ecs-benchmark-valhalla module for comparison against Valhalla
early-access builds. See Valhalla EA benchmarks.
How do I depend on japes?¶
Grab the coordinate off Installation. Gradle, Maven, and source-build instructions are all there.
How do I report a bug?¶
Open an issue at
github.com/zzuegg/japes/issues.
Include the JDK version, a minimal failing system signature, and —
for performance problems — the skipReason from the plan dump plus
a JMH run you can reproduce locally.
Where do I find the complete parameter list?¶
The system parameters cheat sheet. Every annotation and service type is listed, with links back to the tutorial chapter that explains each in depth.