#!/usr/bin/env python3 """Compares two step traces of DivergenceTrace (docs/port/U1.5-UNITY.md). Reports the first step where raw bits differ (positions, hit points) and the first step where a decision differs (alive, target, hits, zone, combat end), with the units involved. Usage: python3 tools/port/trace_diff.py """ import struct import sys def load(path): steps = [] current = None for line in open(path, encoding="utf-8"): line = line.rstrip("\n") if line.startswith("step "): parts = line.split() current = {"step": int(parts[1]), "t": float(parts[3]), "finished": parts[5], "units": {}} steps.append(current) elif line.startswith(" u ") and current is not None: discrete, bits = line[4:].split(" | ") fields = discrete.split() b = bits.split() current["units"][int(fields[0])] = { "discrete": " ".join(fields[1:]), "hp": int(b[1], 16), "x": int(b[3], 16), "y": int(b[4], 16), } return steps def f32(bits): return struct.unpack("