Compare commits

...
Author SHA1 Message Date
Horizon agentandClaude Opus 5.5 b878daa568 item_rarity moves to commands/items.rs: commands.rs may not grow
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-09 17:43:03 +01:00
Horizon agentandClaude Opus 5.5 1f51d1ed96 A compass with a lodestone tracker is named Lodestone Compass
CompassItem.getName returns item.minecraft.lodestone_compass for a stack
with a lodestone_tracker, ahead of item_name; /item, /give and the other
command messages named it Compass. stand_lodestone, which now runs, also
recorded the absolute game time, which is how long each engine ran
before the script (the oracle settles its spawn first: 270 against 0).
Those three reads still run but are no longer recorded; the relative
clock stays compared.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-09 13:31:17 +01:00
Horizon agentandClaude Opus 5.5 4fce0cf7e4 stand_lodestone runs without arguments, as tools/parity.py calls it
Without --work-dir the harness now captures fresh Java into
.local/stand-lodestone-parity/java, builds the fast game and compares a
native run against that capture. The capture-preserving mode with
--work-dir, --reference-dir and --binary is unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-09 13:15:08 +01:00
4 changed files with 47 additions and 16 deletions

No files matched your search

+7 -13
View File
@@ -1449,7 +1449,7 @@ impl Game<'_> {
})
}
/// `ItemStack.getDisplayName`: the hover name (custom name in italics,
/// a written book's title, a potion's effect name, else the item's
/// a written book's title, a potion's effect name, a lodestone compass, else the item's
/// translated name) in brackets, in the rarity colour and showing the
/// stack on hover unless it is empty.
pub(super) fn stack_display_name(&self, s: &ItemStack) -> Text {
@@ -1461,6 +1461,12 @@ impl Game<'_> {
} else if let Some(key) = horizon_client::brewing::contents_name_key(s) {
// A potion's or tipped arrow's own name, over its `item_name`.
Text::translate(&key, &[])
} else if item == "minecraft:compass"
&& s.data()
.is_some_and(|d| d.other("minecraft:lodestone_tracker").is_some())
{
// `CompassItem.getName`: a lodestone tracker names it, over `item_name`.
Text::translate("item.minecraft.lodestone_compass", &[])
} else if let Some(name) = s.data().and_then(|d| d.other("minecraft:item_name")) {
// `ItemStack.getItemName`: the `item_name` component wins over the
// item's own name (`Item.getName`), so a datapack's or a server's
@@ -1523,18 +1529,6 @@ impl Game<'_> {
.with_color(color)
.with_component_fields(vec![("hover_event".into(), shown)])
}
pub(super) fn item_rarity(&self, item: &str) -> String {
static RARITY: std::sync::OnceLock<std::collections::HashMap<String, String>> =
std::sync::OnceLock::new();
let map = RARITY.get_or_init(|| {
horizon_world::item_defaults::read(&self.options.resources)
.unwrap_or_default()
.into_iter()
.filter_map(|(k, c)| c["minecraft:rarity"].as_str().map(|r| (k, r.to_owned())))
.collect()
});
map.get(item).cloned().unwrap_or_else(|| "common".into())
}
fn cmd_give(&mut self, ctx: &Context) -> R<i32> {
let Some(Arg::Item(ItemInput { id, components, .. })) = ctx.get("item").cloned() else {
return Ok(0);
@@ -89,6 +89,19 @@ fn matches_name(pattern: &str, name: &str) -> bool {
}
impl Game<'_> {
/// The item's default `minecraft:rarity` ("common" when it has none).
pub(in crate::game) fn item_rarity(&self, item: &str) -> String {
static RARITY: std::sync::OnceLock<std::collections::HashMap<String, String>> =
std::sync::OnceLock::new();
let map = RARITY.get_or_init(|| {
horizon_world::item_defaults::read(&self.options.resources)
.unwrap_or_default()
.into_iter()
.filter_map(|(k, c)| c["minecraft:rarity"].as_str().map(|r| (k, r.to_owned())))
.collect()
});
map.get(item).cloned().unwrap_or_else(|| "common".into())
}
fn owner_of(&mut self, ctx: &Context, prefix: &str, many: bool) -> R<Vec<Owner>> {
let kind = ctx
.literals
+7 -2
View File
@@ -28,7 +28,12 @@ def program():
guard('/execute if entity @s[type=player,name=Player,nbt={Health:20f,playerGameType:1,Pos:[14.5d,200d,14.5d]}]','player-admit')
cmd('/data get entity @s UUID','player-uuid',4,True)
guard('/scoreboard objectives add lodetick dummy','objective')
cmd('/execute store result score start lodetick run time query gametime','clock-start',category='raw')
# The absolute game time is how long each engine ran before the script (the oracle settles its spawn
# first): run, not recorded. The relative clock below is compared.
def clock(label):
cmd('/execute store result score '+('start' if label=='clock-start' else 'now')+' lodetick run time query gametime',label,category='raw')
ops[-1]['record']=False
clock('clock-start')
holders=[]
for n,(name,dim,tracked,target) in enumerate(CASES,1):
who=str(uuid.UUID(int=(0xA551<<96)|n));x=2*n+.5
@@ -52,7 +57,7 @@ def program():
guard('/execute if loaded 12 200 12','target-still-loaded')
cmd('/tick step 1','step-request',admission=True)
ops.append(dict(op='player_loop',n=1,label='actual-one-tick',expect_result=1,admission=True,category='control'))
cmd('/execute store result score now lodetick run time query gametime',phase+'-raw-clock',category='raw')
clock(phase+'-raw-clock')
guard('/scoreboard players operation now lodetick -= start lodetick',phase+'-clock-op',int(phase=='after'))
guard('/scoreboard players get now lodetick',phase+'-clock',int(phase=='after'))
for name,who,path,target,tracked,marker in holders:
+20 -1
View File
@@ -5,6 +5,7 @@ import hashlib
import json
import os
from pathlib import Path
import shutil
import subprocess
import test_command_exec_parity as runner
@@ -18,11 +19,29 @@ def sha(path):
def main():
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--work-dir',type=Path,required=True)
parser.add_argument('--work-dir',type=Path,help='a new capture folder; without it, a fresh Java capture and '
'the native run go to .local/stand-lodestone-parity (what tools/parity.py runs)')
parser.add_argument('--reference-only',action='store_true')
parser.add_argument('--reference-dir',type=Path)
parser.add_argument('--binary',type=Path)
args=parser.parse_args()
if args.work_dir:
return run(args)
assert not args.reference_only and not args.reference_dir,'--reference-only and --reference-dir need --work-dir'
base=runner.lab.LOCAL/'stand-lodestone-parity'
shutil.rmtree(base,ignore_errors=True)
run(argparse.Namespace(work_dir=base/'java',reference_only=True,reference_dir=None,binary=None))
binary=args.binary
if not binary:
subprocess.run(['cargo','build','--profile','fast','-p','horizon-client','--bin','horizon-client'],
cwd=runner.lab.ROOT,check=True)
metadata=json.loads(subprocess.check_output(['cargo','metadata','--no-deps','--format-version','1'],
cwd=runner.lab.ROOT,text=True))
binary=Path(metadata['target_directory'])/'fast'/('horizon-client.exe' if os.name=='nt' else 'horizon-client')
return run(argparse.Namespace(work_dir=base/'native',reference_only=False,reference_dir=base/'java',binary=binary))
def run(args):
out=args.work_dir.resolve();out.mkdir(parents=True,exist_ok=False)
ops=program()
recorded=[x for x in ops if x['op'] in ('tick','player_loop') or x['op']=='cmd' and x.get('record',True)]