primitive chunk table in world snapshot instead of colliding long-keyed hashmap, bounded cache for tinted/composited mob and banner textures, vanilla dump with nested model json, village benchmark and perf test scenes

This commit is contained in:
MineTec committed 2026-11-04 16:59:42 +01:00
1 parent b5baffebbd
commit 88bae41a03
10 files changed
+306 -38

No files matched your search

+49 -1
View File
@@ -24,7 +24,7 @@ import java.util.logging.Logger;
* times (after {@code -Dwarmup} runs), prints the median wall time and writes one PNG per scene to
* {@code -Dout} (default ~/Dokumente/PixelPics-Entity-Renders/bench) for before/after pixel diffs.
* Args: scene names to run (default all): farm_mobs, farm_empty (same view, no entities), farm_mobs_close,
* farm_items, normal. {@code -Djava.util.concurrent.ForkJoinPool.common.parallelism=N} pins the thread count.
* farm_items, village, normal. {@code -Djava.util.concurrent.ForkJoinPool.common.parallelism=N} pins the thread count.
*/
public class EntityBenchmark {
@@ -114,6 +114,33 @@ public class EntityBenchmark {
}
out.add(new Scene("farm_items", new Vector(0, 7, -1), new Vector(7, 1, 7), List.of(), items));
// Village: 300 mobs with per-mob texture compositing (villager type/profession/level overlays, dyed
// sheep wool, dyed leather armor, tinted wolf collars) — exercises the tinted-texture cache.
List<EntityState> village = new ArrayList<>();
String[] vTypes = {"plains", "desert", "jungle", "savanna", "snow", "swamp", "taiga"};
String[] profs = {"armorer", "butcher", "cartographer", "cleric", "farmer", "fisherman", "fletcher",
"leatherworker", "librarian", "mason", "shepherd", "toolsmith", "weaponsmith", "nitwit", "none"};
Random rv = new Random(7);
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 20; j++) {
double x = i * 1.4 + rv.nextDouble() * 0.3, z = j * 1.4 + rv.nextDouble() * 0.3;
float yaw = rv.nextFloat() * 360;
int dye = DYES[rv.nextInt(DYES.length)];
EntityState m = switch (rv.nextInt(4)) {
case 0 -> villager(x, z, yaw, vTypes[rv.nextInt(vTypes.length)], profs[rv.nextInt(profs.length)],
1 + rv.nextInt(5), rv.nextInt(6) == 0);
case 1 -> with(mob("sheep", x, 1, z, yaw, rv.nextInt(6) == 0), dye, null, 0);
case 2 -> {
EntityState.EquipPiece le = new EntityState.EquipPiece("leather", dye, null, null, false);
yield with(mob("zombie", x, 1, z, yaw, false), 0, new EntityState.Equipment(le, le, le, le), 0);
}
default -> with(mob("wolf", x, 1, z, yaw, rv.nextInt(6) == 0), 0, null, dye);
};
village.add(m);
}
}
out.add(new Scene("village", new Vector(-5, 10, -5), new Vector(10, 1, 13), village, List.of()));
// Normal scene: a handful of mobs incl. translucent (slime) and additive (charged creeper) layers,
// a text display with the default translucent background and two items.
List<EntityState> few = new ArrayList<>();
@@ -142,11 +169,32 @@ public class EntityBenchmark {
false, 0, 0, 0, false, null, null, null, 0, false, null);
}
/** Vanilla DyeColor texture colours (white … black). */
static final int[] DYES = {0xFFF9FFFE, 0xFFF9801D, 0xFFC74EBD, 0xFF3AB3DA, 0xFFFED83D, 0xFF80C71F, 0xFFF38BAA,
0xFF474F52, 0xFF9D9D97, 0xFF169C9C, 0xFF8932B8, 0xFF3C44AA, 0xFF835432, 0xFF5E7C16, 0xFFB02E26, 0xFF1D1D21};
static EntityState villager(double x, double z, float yaw, String type, String prof, int level, boolean baby) {
return new EntityState("villager", x, 1, z, yaw, baby, 0.6, 1.95,
false, null, false, type, 0, 1.0, prof, level,
null, false, false, false, null, null,
false, 0, 0, 0, false, null, null, null, 0, false, null);
}
/** {@code s} with wool tint, humanoid armor and collar dye replaced. */
static EntityState with(EntityState s, int tint, EntityState.Equipment eq, int collar) {
return new EntityState(s.typeKey(), s.x(), s.y(), s.z(), s.bodyYaw(), s.baby(), s.width(), s.height(),
s.player(), s.skinUrl(), s.slim(), s.variant(), tint, s.sizeScale(), s.profession(), s.villagerLevel(),
s.markings(), s.saddle(), s.chest(), s.arms(), s.bodyEquip(), eq, s.invisible(), s.pitch(),
s.bodyDye(), s.tint2(), s.passenger(), s.rightHand(), s.leftHand(), s.headItem(), collar, s.powered(),
s.mouthItem());
}
/** The variant the game always supplies (cow/pig/chicken have no texture without one). */
static String variant(String type) {
return switch (type) {
case "villager" -> "plains";
case "cow", "pig", "chicken" -> "temperate";
case "wolf" -> "pale";
default -> null;
};
}