Merge pull request #11756 from TheMrZZ/fix/item-display-default-transformation

Save item-display transformations from modeled state
This commit is contained in:
rdbt authored and GitHub committed 2026-11-07 12:33:35 +00:00
commit dd3c1d17a2
8 files changed
+587 -8

No files matched your search

@@ -93,6 +93,7 @@ pub(in crate::game) struct OtherEntity {
pub position: Vec3,
pub yaw: f32,
pub pitch: f32,
pub item_transformation: Option<super::native_entities::ItemDisplayTransformation>,
}
pub(super) fn err(key: &str, args: &[&dyn std::fmt::Display]) -> CommandError {
CommandError::tr(key, args)
@@ -244,6 +244,7 @@ impl Game<'_> {
&super::OtherEntity {
id,
kind: "minecraft:area_effect_cloud".into(),
item_transformation: None,
position: horizon_core::geometry::Vec3::new(x, y, z),
yaw: 0.0,
pitch: 0.0,
@@ -12,6 +12,74 @@ use super::{
use horizon_core::geometry::Vec3;
use horizon_world::nbt::{Compound, Tag};
/// The modeled four-part transformation of an item display; durations stay in their existing route.
#[derive(Clone, Copy, Debug, PartialEq)]
pub(super) struct ItemDisplayTransformation {
translation: [f32; 3],
left_rotation: [f32; 4],
scale: [f32; 3],
right_rotation: [f32; 4],
}
impl From<&NativeDisplay> for ItemDisplayTransformation {
fn from(display: &NativeDisplay) -> Self {
Self {
translation: display.translation,
left_rotation: display.left_rotation,
scale: display.scale,
right_rotation: display.right_rotation,
}
}
}
impl ItemDisplayTransformation {
pub(super) fn from_tag(tag: Option<&Tag>) -> Option<Self> {
match tag {
None => Some((&NativeDisplay::default()).into()),
Some(tag @ Tag::Compound(_)) => {
let (translation, left_rotation, scale, right_rotation) =
horizon_client::text_display::transformation(tag)?;
let value = NativeDisplay {
translation,
left_rotation,
scale,
right_rotation,
..NativeDisplay::default()
};
// Keep unsupported numerical forms on the existing raw path, too.
value.valid().then(|| (&value).into())
}
// Matrix and invalid shapes keep their previous unprojected/raw path.
Some(_) => None,
}
}
pub(super) fn to_tag(self) -> Tag {
transformation_tag(
self.translation,
self.left_rotation,
self.scale,
self.right_rotation,
)
}
}
/// The transformation-only portion of Display.addAdditionalSaveData and the native writer.
fn transformation_tag(
translation: [f32; 3],
left_rotation: [f32; 4],
scale: [f32; 3],
right_rotation: [f32; 4],
) -> Tag {
let floats = |v: &[f32]| Tag::List(v.iter().map(|x| Tag::Float(x.to_bits())).collect());
let mut t = Compound::new();
t.insert("translation".into(), floats(&translation));
t.insert("left_rotation".into(), floats(&left_rotation));
t.insert("scale".into(), floats(&scale));
t.insert("right_rotation".into(), floats(&right_rotation));
Tag::Compound(t)
}
/// A display's transformation and interpolation (`Display`'s
/// `transformation`, `interpolation_duration` and `teleport_duration`):
/// a translation, a left rotation (a quaternion `[x, y, z, w]`), a scale and a
@@ -61,13 +129,15 @@ impl NativeDisplay {
/// interpolation only when the start comes, so each write flips it
/// between 0 and -1.
fn write(&self, tag: &mut Compound) {
let floats = |v: &[f32]| Tag::List(v.iter().map(|x| Tag::Float(x.to_bits())).collect());
let mut t = Compound::new();
t.insert("translation".into(), floats(&self.translation));
t.insert("left_rotation".into(), floats(&self.left_rotation));
t.insert("scale".into(), floats(&self.scale));
t.insert("right_rotation".into(), floats(&self.right_rotation));
tag.insert("transformation".into(), Tag::Compound(t));
tag.insert(
"transformation".into(),
transformation_tag(
self.translation,
self.left_rotation,
self.scale,
self.right_rotation,
),
);
tag.insert(
"interpolation_duration".into(),
Tag::Int(self.interpolation),
@@ -254,6 +324,13 @@ impl Game<'_> {
return false;
};
display.write(c);
if let Some(item) = self
.others
.iter_mut()
.find(|o| o.id == id && o.kind == "minecraft:item_display")
{
item.item_transformation = Some(display.into());
}
true
}
/// Removes entity `id`, one Horizon keeps without simulating, as `/kill`
+314
View File
@@ -941,6 +941,11 @@ impl Game<'_> {
fn load_other(&mut self, mut tag: Tag, kind: &str) -> Option<u32> {
strip_finalize(&mut tag);
let position = entity_nbt::position(&tag)?;
let item_transformation = if kind == "minecraft:item_display" {
super::native_entities::ItemDisplayTransformation::from_tag(tag.get("transformation"))
} else {
None
};
let rotation = match tag.get("Rotation") {
Some(Tag::List(l)) => {
let f = |i: usize| match l.get(i) {
@@ -961,6 +966,7 @@ impl Game<'_> {
position,
yaw: rotation[0],
pitch: rotation[1],
item_transformation,
});
Some(id)
}
@@ -991,6 +997,9 @@ impl Game<'_> {
]),
);
c.insert("UUID".into(), Tag::IntArray(uuid.to_vec()));
if let Some(transformation) = o.item_transformation {
c.insert("transformation".into(), transformation.to_tag());
}
if matches!(o.kind.as_str(), "minecraft:interaction" | "interaction") {
// Interaction.addAdditionalSaveData always writes these settings.
c.entry("width".into())
@@ -2803,3 +2812,308 @@ mod loaded_tag_tests {
);
}
}
#[cfg(test)]
mod item_display_saved_transform_tests {
use super::*;
use crate::game::{Audio, Options, Progress, Settings, commands::Target, load_resources};
use horizon_client::{chunk::Chunk, motion::PlayerMotion};
use horizon_core::{geometry::Vec3, position::ChunkPos, random::LegacyRandom};
fn with_game(test: impl FnOnce(&mut Game<'_>)) {
let root = std::path::PathBuf::from(std::env::var_os("HORIZON_TEST_RESOURCES").unwrap());
let settings = Settings::default();
let loaded = load_resources(
root.clone(),
None,
&root,
&settings,
std::time::Instant::now(),
false,
true,
&Progress::new(),
&mut |_, _| unreachable!(),
)
.unwrap();
let mut options = Options::parse(std::iter::empty()).unwrap().unwrap();
options.resources = root.clone();
options.game_dir = Some(
std::path::PathBuf::from(std::env::var_os("HORIZON_HOME").unwrap())
.join(format!("h132-{:?}", std::thread::current().id())),
);
options.execution_role = crate::game::execution_role::ExecutionRole::IntegratedServer;
let mut game = Game::new(
&loaded.resources,
loaded.pack,
loaded.gui.unwrap(),
options,
settings,
Audio::silent(&root),
None,
)
.unwrap();
game.build_registries();
game.set_allow_commands(true);
game.world
.chunks
.insert((0, 0), Arc::new(Chunk::empty(0, 0)));
game.block_ticks
.add_empty_chunk(ChunkPos::new(0, 0))
.unwrap();
assert!(game.run_command("difficulty normal"));
assert!(game.run_command("forceload add 0 0"));
for (x, z) in [(0, 1), (1, 0), (1, 1)] {
game.world
.chunks
.insert((x, z), Arc::new(Chunk::empty(x, z)));
game.block_ticks
.add_empty_chunk(ChunkPos::new(x, z))
.unwrap();
}
game.player = Some(PlayerMotion::new(game.motion, Vec3::new(2.5, 200.0, 2.5)).unwrap());
game.creative = true;
assert!(game.run_command("fill 0 199 0 31 199 31 stone"));
assert!(
game.run_command("summon pig 13.5 200 2.5 {UUID:[I;132,0,0,99],NoAI:1b,NoGravity:1b}")
);
game.world.random = LegacyRandom::new(132);
test(&mut game);
}
const IDENTITY: &str = "{translation:[0f,0f,0f],left_rotation:[0f,0f,0f,1f],scale:[1f,1f,1f],right_rotation:[0f,0f,0f,1f]}";
const CHANGED: &str = "{translation:[1.25f,-2.5f,3f],left_rotation:[0f,1f,0f,0f],scale:[2f,3f,4f],right_rotation:[0f,0f,0f,1f]}";
fn expected(translation: [f32; 3], left: [f32; 4], scale: [f32; 3]) -> Tag {
let floats = |v: &[f32]| Tag::List(v.iter().map(|x| Tag::Float(x.to_bits())).collect());
Tag::Compound(
[
("translation".into(), floats(&translation)),
("left_rotation".into(), floats(&left)),
("scale".into(), floats(&scale)),
("right_rotation".into(), floats(&[0.0, 0.0, 0.0, 1.0])),
]
.into_iter()
.collect(),
)
}
fn summon(game: &mut Game<'_>, n: i32, transform: Option<&str>) -> u32 {
let suffix = transform
.map(|t| format!(",transformation:{t}"))
.unwrap_or_default();
assert!(game.run_command(&format!("summon item_display 6.5 200 6.5 {{UUID:[I;132,0,0,{n}],Rotation:[12.5f,-20f],NoGravity:1b,CustomName:\"display\",Tags:[\"h132\"],item:{{id:\"minecraft:diamond\",count:2,components:{{\"minecraft:custom_data\":{{h132:7}}}}}}{suffix}}}")));
let o = game
.others
.iter()
.find(|o| game.persist.uuid_of(o.id) == Some([132, 0, 0, n]))
.unwrap();
assert_eq!(o.kind, "minecraft:item_display");
assert_eq!(o.position, Vec3::new(6.5, 200.0, 6.5));
assert_eq!([o.yaw, o.pitch], [12.5, -20.0]);
let id = o.id;
let saved = game.entity_nbt(Target::Other(id)).unwrap();
let stack = horizon_client::save::item_from_nbt(saved.get("item").unwrap()).unwrap();
assert_eq!(&*stack.item, "minecraft:diamond");
assert_eq!(stack.count, 2);
assert_eq!(
saved
.get("item")
.unwrap()
.get("components")
.unwrap()
.get("minecraft:custom_data")
.unwrap()
.get("h132"),
Some(&Tag::Int(7))
);
id
}
#[test]
#[ignore = "prepared resources; actual item-display registered load and no-raw save"]
fn omitted_item_display_transformation_is_saved_as_typed_identity() {
with_game(|game| {
let clock = game.world.game_time;
let id = summon(game, 1, None);
let identity = expected([0.0; 3], [0.0, 0.0, 0.0, 1.0], [1.0; 3]);
let tag = game.entity_nbt(Target::Other(id)).unwrap();
assert_eq!(tag.get("transformation"), Some(&identity));
let raw = game.persist.raw.remove(&id).unwrap();
let fresh = game.entity_nbt(Target::Other(id)).unwrap();
assert_eq!(fresh.get("transformation"), Some(&identity));
assert_eq!(fresh.get("UUID"), tag.get("UUID"));
assert_eq!(fresh.get("Pos"), tag.get("Pos"));
for key in [
"interpolation_duration",
"teleport_duration",
"start_interpolation",
] {
assert!(fresh.get(key).is_none());
}
game.persist.raw.insert(id, raw);
assert_eq!(game.world.game_time, clock);
});
}
#[test]
#[ignore = "prepared resources; actual explicit load must survive removal of raw source"]
fn admitted_compound_item_transforms_are_actual_saved_state() {
with_game(|game| {
let clock = game.world.game_time;
for (n, text, want) in [
(
2,
CHANGED,
expected([1.25, -2.5, 3.0], [0.0, 1.0, 0.0, 0.0], [2.0, 3.0, 4.0]),
),
(
3,
IDENTITY,
expected([0.0; 3], [0.0, 0.0, 0.0, 1.0], [1.0; 3]),
),
] {
let id = summon(game, n, Some(text));
let before = game.entity_nbt(Target::Other(id)).unwrap();
assert_eq!(before.get("transformation"), Some(&want));
let raw = game.persist.raw.remove(&id).unwrap();
let fresh = game.entity_nbt(Target::Other(id)).unwrap();
assert_eq!(
fresh.get("transformation"),
Some(&want),
"real loaded state survives without raw"
);
game.persist.raw.insert(id, raw);
}
assert_eq!(game.world.game_time, clock);
});
}
#[test]
#[ignore = "prepared resources; actual native setter, stale raw and no-raw writer"]
fn existing_native_item_display_setter_carries_only_transform_state() {
use crate::game::native_entities::NativeDisplay;
with_game(|game| {
// Same actual server-context setup as existing native machine/contact fixtures.
game.options.dedicated = Some(Vec::new());
let id = summon(game, 4, None);
let uuid = game.persist.uuid_of(id);
let clock = game.world.game_time;
let update = NativeDisplay {
translation: [9.0, 8.0, 7.0],
scale: [2.0; 3],
interpolation: 13,
teleport: 5,
..NativeDisplay::default()
};
assert!(game.native_set_display("minecraft:overworld", id, &update));
let raw = game.persist.raw.get_mut(&id).unwrap();
assert_eq!(raw.get("interpolation_duration"), Some(&Tag::Int(13)));
assert_eq!(raw.get("teleport_duration"), Some(&Tag::Int(5)));
assert_eq!(raw.get("start_interpolation"), Some(&Tag::Int(0)));
let Tag::Compound(c) = raw else {
panic!("compound")
};
c.insert(
"transformation".into(),
expected([0.0; 3], [0.0, 0.0, 0.0, 1.0], [1.0; 3]),
);
let want = expected([9.0, 8.0, 7.0], [0.0, 0.0, 0.0, 1.0], [2.0; 3]);
assert_eq!(
game.entity_nbt(Target::Other(id))
.unwrap()
.get("transformation"),
Some(&want)
);
let raw = game.persist.raw.remove(&id).unwrap();
let fresh = game.entity_nbt(Target::Other(id)).unwrap();
assert_eq!(fresh.get("transformation"), Some(&want));
for key in [
"interpolation_duration",
"teleport_duration",
"start_interpolation",
] {
assert!(fresh.get(key).is_none());
}
game.persist.raw.insert(id, raw);
let invalid = NativeDisplay {
left_rotation: [0.0; 4],
..update
};
let before = game.persist.raw.get(&id).unwrap().clone();
assert!(!game.native_set_display("minecraft:overworld", id, &invalid));
assert_eq!(game.persist.raw.get(&id), Some(&before));
assert_eq!(
game.entity_nbt(Target::Other(id))
.unwrap()
.get("transformation"),
Some(&want)
);
assert_eq!(game.persist.uuid_of(id), uuid);
assert_eq!(game.world.game_time, clock);
});
}
#[test]
#[ignore = "prepared resources; preservation controls, not Java matrix/invalid admission"]
fn unprojected_forms_and_non_item_classes_keep_their_existing_saved_route() {
with_game(|game| {
for (n, form) in [
(5, "[1f,0f,0f,0f,0f,1f,0f,0f,0f,0f,1f,0f,0f,0f,0f,1f]"),
(6, "{}"),
(7, "\"invalid\""),
] {
assert!(game.run_command(&format!("summon item_display 6.5 200 6.5 {{UUID:[I;132,0,0,{n}],transformation:{form},item:{{id:\"minecraft:diamond\",count:1}}}}")));
let id = game
.others
.iter()
.find(|o| game.persist.uuid_of(o.id) == Some([132, 0, 0, n]))
.unwrap()
.id;
let before = game
.persist
.raw
.get(&id)
.unwrap()
.get("transformation")
.unwrap()
.clone();
assert_eq!(
game.entity_nbt(Target::Other(id))
.unwrap()
.get("transformation"),
Some(&before)
);
let raw = game.persist.raw.remove(&id).unwrap();
assert!(
game.entity_nbt(Target::Other(id))
.unwrap()
.get("transformation")
.is_none()
);
game.persist.raw.insert(id, raw);
}
for (n, kind, extra) in [
(8, "marker", ",data:{audit:7}"),
(9, "leash_knot", ""),
(10, "text_display", ",text:\"control\""),
] {
assert!(game.run_command(&format!(
"summon {kind} 10.5 200 10.5 {{UUID:[I;132,0,0,{n}]{extra}}}"
)));
let id = game
.others
.iter()
.find(|o| game.persist.uuid_of(o.id) == Some([132, 0, 0, n]))
.unwrap()
.id;
assert!(
game.entity_nbt(Target::Other(id))
.unwrap()
.get("transformation")
.is_none()
);
}
assert_eq!(
game.mobs
.iter()
.find(|m| game.persist.uuid_of(m.id) == Some([132, 0, 0, 99]))
.unwrap()
.health,
10.0
);
});
}
}
+1 -1
View File
@@ -344,7 +344,7 @@ pub fn text_display_data(tag: &Tag, all: bool) -> Vec<(u8, i32, Value)> {
/// `Transformation.EXTENDED_CODEC`'s translation, left rotation, scale and
/// right rotation: all four parts, or a `MATRIX4F` (sixteen floats, row-major)
/// that `new Transformation(matrix)` decomposes (`MatrixUtil.svdDecompose`).
fn transformation(tag: &Tag) -> Option<([f32; 3], [f32; 4], [f32; 3], [f32; 4])> {
pub fn transformation(tag: &Tag) -> Option<([f32; 3], [f32; 4], [f32; 3], [f32; 4])> {
use horizon_assets::math::{
Mat4, normalize_quaternion, quaternion_from_axis_angle, svd_decompose,
};
@@ -0,0 +1,20 @@
{"variants":["original-v2","old-v3"],"label":"omitted-transformation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation","messages":[[["omitted has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]}",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation","messages":[[["Found no elements matching transformation",[16733525,false,false,false,false,false]]]],"results":[[false,0]]},"diagnostic":true}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation-result","expected":{"cmd":"/scoreboard players get result h132","messages":[[["result has 4 [h132]",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/scoreboard players get result h132","messages":[[["result has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation-success","expected":{"cmd":"/scoreboard players get success h132","messages":[[["success has 1 [h132]",[null,false,false,false,false,false]]]],"results":[[true,1]]},"actual":{"cmd":"/scoreboard players get success h132","messages":[[["success has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.translation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation.translation","messages":[[["omitted has the following entity data: [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]",[null,false,false,false,false,false]]]],"results":[[true,3]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation.translation","messages":[[["Found no elements matching transformation",[16733525,false,false,false,false,false]]]],"results":[[false,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.translation-result","expected":{"cmd":"/scoreboard players get result h132","messages":[[["result has 3 [h132]",[null,false,false,false,false,false]]]],"results":[[true,3]]},"actual":{"cmd":"/scoreboard players get result h132","messages":[[["result has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.translation-success","expected":{"cmd":"/scoreboard players get success h132","messages":[[["success has 1 [h132]",[null,false,false,false,false,false]]]],"results":[[true,1]]},"actual":{"cmd":"/scoreboard players get success h132","messages":[[["success has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.left_rotation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation.left_rotation","messages":[[["omitted has the following entity data: [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation.left_rotation","messages":[[["Found no elements matching transformation",[16733525,false,false,false,false,false]]]],"results":[[false,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.left_rotation-result","expected":{"cmd":"/scoreboard players get result h132","messages":[[["result has 4 [h132]",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/scoreboard players get result h132","messages":[[["result has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.left_rotation-success","expected":{"cmd":"/scoreboard players get success h132","messages":[[["success has 1 [h132]",[null,false,false,false,false,false]]]],"results":[[true,1]]},"actual":{"cmd":"/scoreboard players get success h132","messages":[[["success has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.scale-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation.scale","messages":[[["omitted has the following entity data: [",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]",[null,false,false,false,false,false]]]],"results":[[true,3]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation.scale","messages":[[["Found no elements matching transformation",[16733525,false,false,false,false,false]]]],"results":[[false,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.scale-result","expected":{"cmd":"/scoreboard players get result h132","messages":[[["result has 3 [h132]",[null,false,false,false,false,false]]]],"results":[[true,3]]},"actual":{"cmd":"/scoreboard players get result h132","messages":[[["result has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.scale-success","expected":{"cmd":"/scoreboard players get success h132","messages":[[["success has 1 [h132]",[null,false,false,false,false,false]]]],"results":[[true,1]]},"actual":{"cmd":"/scoreboard players get success h132","messages":[[["success has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.right_rotation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation.right_rotation","messages":[[["omitted has the following entity data: [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation.right_rotation","messages":[[["Found no elements matching transformation",[16733525,false,false,false,false,false]]]],"results":[[false,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.right_rotation-result","expected":{"cmd":"/scoreboard players get result h132","messages":[[["result has 4 [h132]",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/scoreboard players get result h132","messages":[[["result has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"omitted-transformation.right_rotation-success","expected":{"cmd":"/scoreboard players get success h132","messages":[[["success has 1 [h132]",[null,false,false,false,false,false]]]],"results":[[true,1]]},"actual":{"cmd":"/scoreboard players get success h132","messages":[[["success has 0 [h132]",[null,false,false,false,false,false]]]],"results":[[true,0]]},"diagnostic":false}
{"variants":["original-v2","old-v3"],"label":"identity-transformation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000002 transformation","messages":[[["identity has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]}",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000002 transformation","messages":[[["identity has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,falLine truncated
{"variants":["original-v2","old-v3"],"label":"nondefault-transformation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000003 transformation","messages":[[["nondefault has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.25",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["-2.5",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["3.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["2.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["3.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["4.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]}",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000003 transformation","messages":[[["nondefault has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.25",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["-2.5",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["3.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["2.0",[16755200,false,false,false,false,false]],["f",[16Line truncated
{"variants":["fixed-v3"],"label":"omitted-transformation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation","messages":[[["omitted has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]}",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000001 transformation","messages":[[["omitted has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,Line truncated
{"variants":["fixed-v3"],"label":"identity-transformation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000002 transformation","messages":[[["identity has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]}",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000002 transformation","messages":[[["identity has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,falLine truncated
{"variants":["fixed-v3"],"label":"nondefault-transformation-read","expected":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000003 transformation","messages":[[["nondefault has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.25",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["-2.5",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["3.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["2.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["3.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["4.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["]}",[null,false,false,false,false,false]]]],"results":[[true,4]]},"actual":{"cmd":"/execute store result score result h132 store success score success h132 run data get entity 00000084-0000-0000-0000-000000000003 transformation","messages":[[["nondefault has the following entity data: {",[null,false,false,false,false,false]],["left_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["right_rotation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["0.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["1.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["translation",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["1.25",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["-2.5",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],[", ",[null,false,false,false,false,false]],["3.0",[16755200,false,false,false,false,false]],["f",[16733525,false,false,false,false,false]],["], ",[null,false,false,false,false,false]],["scale",[5636095,false,false,false,false,false]],[": [",[null,false,false,false,false,false]],["2.0",[16755200,false,false,false,false,false]],["f",[16733525,falseLine truncated
@@ -0,0 +1,97 @@
# Item-display saved transformation
Item displays kept in the actual Other collection now own an optional transformation
with only four typed Float arrays: translation, left rotation, scale and right rotation.
Actual item-display loads alone initialize it. Missing input becomes the independently
Java-admitted identity; valid supported compound TRSR uses the existing pure decoder.
Matrix/invalid shapes and unsupported numerical forms stay unprojected on their prior
raw path. The existing parser body is unchanged; this does not establish full codec parity.
The saved writer projects only these four modeled arrays. It does not call the native
writer that also writes interpolation/teleport/start fields. The transformation-only Tag
construction is shared mechanically with that writer; its duration/start body is byte
identical. Successful existing native setter writes carry the item-display state afterward;
its failure guards, order and other-subtype behavior remain unchanged. That setter carry
is Game-unit/source coverage, not a live native-mod delivery claim.
No display data-adoption, rendering, interpolation, packet engine, item codec, other subtype
or general Other schema is repaired. All unrelated raw fields/identity remain on their
existing route. H129 remains independent: when combining the two branches, retain both
class-specific fields/initializers, with knot counter None on displays and transformation
None on knots/Cloud. Preserve H129's own attachment phase and common-default branch.
No pending H129 production is imported here.
## Authority and frozen proof
Pinned Java26.3 `Display.readAdditionalSaveData` reads Transformation.EXTENDED_CODEC with
IDENTITY fallback; `addAdditionalSaveData` always writes Transformation.CODEC. Current
PR8362 is a port-map change citing the mod writer, not this missing default repair; PR4631
is the existing matrix reader and PR5408 the native setter. Actual diffs were reviewed.
The frozen base is `98b882712308386bbb48acbc60968f7d7a991902`. Fresh Java admits three
independent actual item displays: omitted input, explicit identity, nondefault valid
compound. All hold diamond2 with custom_data7, have fixed UUID/type/Pos/Rotation/NoGravity,
loaded floor and real relative clock0. Pig and Marker are unrelated controls. The complete
transformation and all four typed Float lists are read with fresh result/success stores;
full bodies/styles/callbacks are retained.
Original V2: old203/220, including15 omitted-field failures and two independent whole-
compound key-layout differences. All typed explicit controls already match. V1/V2 Java
references and executable inputs are byte-identical; V2 strengthens positive callback guards.
Before production, V3 predeclares all three whole-transformation query text rows diagnostic,
not just the two failing explicit rows. Their stores and all four typed-list reads remain
strict: **203/217 old**. Full220 remains executable and its actual residuals are retained;
there is no output masking, tolerance, formatter repair or claim of full220 parity.
Four registered Game tests run through actual load/model/save: omitted identity,
nondefault/identity without raw source, actual native-setter mutation against contradictory
raw and no-raw saving, and preservation of unsupported forms/non-item classes. Old has
three meaningful failures and one passing preservation control. The fixed source passes
all four. The existing writer's pure start-flip/validation units remain affected controls.
## Reproduction
From the repository root, using prepared local resources and fresh output directories:
```sh
python3 tools/item_display_transformation_fixture.py --reference-only --work-dir /tmp/display-java
python3 tools/item_display_transformation_fixture.py --binary /absolute/path/to/horizon-client \
--reference /tmp/display-java/vanilla.jsonl --work-dir /tmp/display-native
```
This manual driver reuses the existing Game command harness and reruns fresh Java to
verify the exact reference bytes. It writes a full220 report and separate strict217 report.
Run the unchanged script/reference on old and fixed binaries. Resources, original programs,
full bodies/diagnostics, invalid or unsupported records, source/binary hashes and phase
metadata stay in the protected local task archive. Unknown phase starts remain null.
Runtime scope is the three admitted compound/default item-display cases. Matrix/invalid
unit controls prove preservation of the prior native path, not Java input admission or
matrix equivalence. Negative teleport duration, subtype defaults and full-body formatting
remain separate diagnostics. No all-display, renderer, reopen or complete-codec claim.
The final frozen pair is **203/217 →217/217** on the declared typed contract. The actual
full220 result is **203/220 →217/220**, with all three whole-transformation text rows still
different in key layout. All stores and typed-list reads match. These residuals are public
in [item-display-transform-residuals.jsonl](item-display-transform-residuals.jsonl); the two
old captures have byte-identical full220 observations and share a variant-labelled payload.
No residual is suppressed or counted as a full220 match. Raw whole-body/absolute-clock
traces remain separate protected diagnostics, without normalizing their outputs.
## Local checks
The final required `pr_ready.py --quick --base 98b882712308386bbb48acbc60968f7d7a991902`
run passes public-tree, formatting, 3,310 Rust tests (Game and shared client library) and
doc tests. It exits1: three known optional-release Python cases hit system Bash's
`musl[@]`/`arm64[@]` unbound variables (719 run, two skipped); workspace Clippy stops on
one untouched `horizon-core/src/storage.rs:223` `manual_is_multiple_of` lint. No unrelated
repair, suppression or pending fix is imported. The four resource-backed regressions and
217-record runtime gate pass separately. Its414 broad harnesses are listed, not run.
The full required result is not green.
Affected package-only Clippy (`horizon-client` plus `horizon-client-lib`, all targets,
`--no-deps -D warnings`) and the server configuration (`horizon-client`, all targets,
`--no-deps --no-default-features -D warnings`) both pass. These are scoped diagnostics,
not a replacement for the failed required workspace check. Later main
`18840db9146b2521dd46ad52a4559a49be180f8f` has no relevant source changes; no pair rerun
was needed for those unrelated commits.
@@ -0,0 +1,69 @@
import hashlib,json,sys,uuid
from pathlib import Path
sys.path.insert(0,str(Path.cwd()/'tools'))
import test_command_exec_parity as driver
import harness_args
IDENTITY='{translation:[0f,0f,0f],left_rotation:[0f,0f,0f,1f],scale:[1f,1f,1f],right_rotation:[0f,0f,0f,1f]}'
CHANGED='{translation:[1.25f,-2.5f,3f],left_rotation:[0f,1f,0f,0f],scale:[2f,3f,4f],right_rotation:[0f,0f,0f,1f]}'
CASES=[('omitted',None),('identity',IDENTITY),('nondefault',CHANGED)]
TIMES=[0]
def program():
ops=[]
def cmd(text,label,result=None,admission=True,trace=False):
o=dict(op='cmd',cmd=text,label=label,admission=admission)
if result is not None:o['expect_result']=result
if trace:o.update(record=False,trace=True)
ops.append(o)
def read(text,label,admission=False,expected=None):
for k in ['result','success']:cmd(f'/scoreboard players set {k} h132 -99',label+'-reset-'+k,-99)
cmd('/execute store result score result h132 store success score success h132 run '+text,label+'-read',result=expected,admission=admission)
for k in ['result','success']:cmd(f'/scoreboard players get {k} h132',label+'-'+k,admission=admission)
cmd('/tick freeze','freeze')
for g in ['spawn_mobs','advance_time','advance_weather','mob_griefing']:cmd('/gamerule '+g+' false',g)
cmd('/gamerule random_tick_speed 0','random0');cmd('/difficulty normal','normal')
cmd('/forceload add 0 0 31 31','forceload',4);ops.append(dict(op='settle',required_chunks=[[0,0],[0,1],[1,0],[1,1]]))
cmd('/fill 0 199 0 31 199 31 stone','floor',1024);cmd('/fill 0 200 0 31 204 31 barrier','prefill',5120);cmd('/fill 0 200 0 31 204 31 air','air',5120)
cmd('/tp @s 2.5 200 2.5','player-pos',1);cmd('/gamemode creative @s','player-mode')
cmd('/execute if entity @s[type=player,nbt={Health:20f,Pos:[2.5d,200d,2.5d],playerGameType:1}]','player-body',1);cmd('/data get entity @s UUID','player-uuid',4)
cmd('/scoreboard objectives add h132 dummy','objective');cmd('/execute store result score start h132 run time query gametime','start',trace=True)
cmd('/summon pig 20.5 200 10.5 {UUID:[I;132,0,0,99],NoAI:1b,NoGravity:1b,Health:10f}','pig',1)
cmd('/summon marker 22.25 200.5 12.75 {UUID:[I;132,0,0,98],data:{h132:9}}','marker',1)
for n,(name,transform) in enumerate(CASES,1):
x=4*n+2;uid=str(uuid.UUID(int=(132<<96)|n));suffix='' if transform is None else ',transformation:'+transform
cmd(f'/execute if loaded {x} 200 6',name+'-loaded',1);cmd(f'/execute if block {x} 199 6 stone',name+'-support',1)
cmd(f'/summon item_display {x}.5 200 6.5 {{UUID:[I;132,0,0,{n}],Rotation:[12.5f,-20f],NoGravity:1b,CustomName:"{name}",Tags:["h132"],item:{{id:"minecraft:diamond",count:2,components:{{"minecraft:custom_data":{{h132:7}}}}}},item_display:"fixed"'+suffix+'}',name+'-summon',1)
cmd(f'/execute if entity @e[type=item_display,nbt={{UUID:[I;132,0,0,{n}],Pos:[{x}.5d,200d,6.5d],Rotation:[12.5f,-20f],NoGravity:1b}}]',name+'-typed-body',1)
cmd('/execute if entity '+uid,name+'-direct-uuid',1)
for key,result in [('UUID',4),('Pos',3),('Rotation',2),('item.id',17),('item.count',2),('item.components."minecraft:custom_data".h132',7),('item_display',5)]:
read('data get entity '+uid+' '+key,name+'-'+key,True,result)
for key in ['transformation','transformation.translation','transformation.left_rotation','transformation.scale','transformation.right_rotation']:
read('data get entity '+uid+' '+key,name+'-'+key)
cmd('/data get entity '+uid,name+'-full-body',trace=True)
cmd('/execute if entity @e[type=item_display]','display-count',3)
cmd('/execute if entity @e[type=pig,nbt={UUID:[I;132,0,0,99],Health:10f,NoAI:1b,NoGravity:1b,Pos:[20.5d,200d,10.5d]}]','pig-control',1)
cmd('/execute unless data entity 00000084-0000-0000-0000-000000000063 transformation','pig-no-transform',1)
cmd('/execute if entity @e[type=marker,nbt={UUID:[I;132,0,0,98],Pos:[22.25d,200.5d,12.75d],data:{h132:9}}]','marker-control',1)
cmd('/execute unless data entity 00000084-0000-0000-0000-000000000062 transformation','marker-no-transform',1)
for kind in ['pig','marker']:cmd('/data get entity @e[type='+kind+',limit=1]',kind+'-full-body',trace=True)
cmd('/execute store result score now h132 run time query gametime','end-absolute',trace=True);cmd('/scoreboard players operation now h132 -= start h132','relative-op',0);cmd('/scoreboard players get now h132','relative-clock',0)
for op in ops:
if op.get('label') in {name+'-transformation-read' for name,_ in CASES}:op['diagnostic']=True
return ops
if __name__=='__main__':
reference=None
if '--reference' in sys.argv:
i=sys.argv.index('--reference');reference=Path(sys.argv[i+1]).read_bytes();del sys.argv[i:i+2]
build=harness_args.ensure_work_dir(Path('.local/h132/capture')).resolve();assert not (build/'vanilla.jsonl').exists();ops=program();rows=[o for o in ops if o['op']=='cmd' and o.get('record',True)]
build.mkdir(parents=True,exist_ok=True);(build/'declaration.json').write_text(json.dumps({'script_sha256':hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),'records':len(rows),'strict_records':sum(not o.get('diagnostic',False) for o in rows),'diagnostic_labels':[o['label'] for o in rows if o.get('diagnostic',False)],'labels':[o['label'] for o in rows],'cases':CASES,'samples':TIMES,'scope':'Item-display saved omitted/identity/nondefault compound transformation and four typed Float lists strict; valid stack and identity/load/zero-clock guards strict. Full bodies, subtype defaults and durations retained raw, not whole-display parity.'},indent=2)+'\n')
driver.corpus_module.groups=lambda:[('Item display saved transformation',ops)];sys.argv.append('--allow-gaps');driver.main()
fresh=(build/'vanilla.jsonl').read_bytes()
if reference:assert fresh==reference,'fresh reference changed'
if '--reference-only' in sys.argv:sys.exit(0)
a=[json.loads(x) for x in fresh.splitlines()];b=[json.loads(x) for x in (build/'rust.jsonl').read_bytes().splitlines()];assert len(a)==len(b)==len(rows)
diffs=[dict(label=o['label'],expected=x,actual=y,diagnostic=o.get('diagnostic',False)) for o,x,y in zip(rows,a,b) if x!=y]
(build/'full-report.json').write_text(json.dumps(dict(records=len(rows),passed=len(rows)-len(diffs),differences=diffs),indent=2)+'\n')
strict=[o for o in rows if not o.get('diagnostic',False)];gaps=[d for d in diffs if not d['diagnostic']]
(build/'strict-report.json').write_text(json.dumps(dict(records=len(strict),passed=len(strict)-len(gaps),differences=gaps),indent=2)+'\n')
for o,x,y in zip(rows,a,b):
if o['admission']:assert x==y,('admission',o,x,y)
print('full',len(rows)-len(diffs),'/',len(rows),'strict',len(strict)-len(gaps),'/',len(strict));sys.exit(bool(gaps))