In one line: a health-manipulation engine. It disassembles a mob's bytecode at runtime, reverse-engineers the dataflow behind
getHealth(), finds where the health value actually lives, writes to it, then verifies by reading it back.
vitalprobe (bccore is kept as a command alias)"Set that mob's health to 20" is entity.setHealth(20) in vanilla. The moment another mod wants to stop you, that path is blocked in a dozen different ways:
| What the other mod does | Why a naive health write fails |
|---|---|
Overrides getHealth() to read its own field |
the field can be named anything, or live in another class |
| Stores health negated / modulo a cap / accumulated | value inversion and many-to-one mappings can't be statically inverted |
Keeps health in a HashMap / SynchedEntityData / custom hash table |
the value isn't a field at all |
| Encrypts health into a string, with a MAC | one character change invalidates it, and getHealth() then pretends to be full |
| Keeps health in native memory (a DLL), with three decoy read paths | there is no number on the Java heap to write |
Delegates health to a function object (operate(...) dispatch) |
it's neither a field nor a container |
| Defines the runtime class as a hidden class and filters members out of reflection | no bytecode, no visible methods |
| Force-heals or damage-caps every tick | your write gets pushed back immediately |
VitalProbe exists for exactly these cases. It never guesses member names and never hardcodes a target mod's classes or fields — it works by runtime disassembly plus measured read-back verification.
Every write tries these in order. Each step is judged by reading getHealth() back afterwards; on failure it falls through to the next:
getHealth() expression into an equation in T and solve for the value to write.Map holding this entity, match the value and rewrite it.setHealth, after first checking whether its semantics really are "set" (an additive/heal-only override is skipped).internal), then write through its own hand.maxHealth - health.Push-backs are handled separately: pulled back to the original value → limited rewrites; pulled back to a third value (the signature of a per-tick invariant) → a sustained-pressure window that walks the reading to the target at the other side's own rate, and counts as success once it holds stable for several ticks.
general.strength, defaulting to UNSAFE (maximum):
| Level | Mechanism | Notes |
|---|---|---|
REFLECTION |
reflective assignment | most conservative; cannot write final |
VARHANDLE |
VarHandle |
can write private fields |
UNSAFE |
sun.misc.Unsafe memory offsets |
penetrates final, i.e. rewrites constants |
If a write fails, allowEscalation promotes the level automatically.
Hold hall:void_sword from RottenRuins:The Hall and right-click to set every living entity within 100 blocks to getHealth() - 20:
All require OP level 2. /bccore is an equivalent alias of /vitalprobe.
| Command | Purpose |
|---|---|
/vitalprobe probe [target] |
full-chain diagnosis: bytecode readable? what was reversed? which candidate tables exist? current value, and a real write's read-back result |
/vitalprobe inspect [target] |
print the reversed getHealth() and every candidate write plan |
/vitalprobe set <targets> <health> |
write directly (no clamp to 0; negatives allowed) |
/vitalprobe add <targets> <delta> |
adjust relative to the current effective health |
/vitalprobe strength <level> |
switch strength at runtime (the config file still wins after restart) |
/vitalprobe delta [value] |
view/set the scroll-wheel amount |
/vitalprobe diagnose [detail] |
read-only: nearby mob classes and the strategy they're expected to take |
// Soft dependency: call reflectively and degrade gracefully when VitalProbe is absent
org.bytechen.bccore.api.BCHealth.get(LivingEntity); // read effective health
org.bytechen.bccore.api.BCHealth.set(LivingEntity, float); // exact write (no 0 clamp)
org.bytechen.bccore.api.BCHealth.add(LivingEntity, float); // add/subtract
org.bytechen.bccore.api.BCHealth.triggerVoidSword(Player, ItemStack); // one area-wide pass
Resolve it behind ModList.get().isLoaded("vitalprobe") and wrap the whole chain in try/catch.
getHealth() was inlined at compile time, there is no writable location at runtime.getHealth()). It does not alter armor, resistances or attribute caps unless the MAX_HEALTH step is reached.Drop it into mods/. Config: config/vitalprobe-common.toml.
License MIT. Use it, change it, redistribute it. If something breaks, attach the lines containing [VitalProbe] from logs/latest.log.