Skip to content

Commit 8beec06

Browse files
committed
Use Sparrow virtual items for item visuals
1 parent 392a52d commit 8beec06

6 files changed

Lines changed: 458 additions & 39 deletions

File tree

README.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,19 @@ outside the supported range.
1717

1818
## Rewrite highlights
1919

20-
- Native Paper `ItemDisplay` and `TextDisplay` entities replace Armor Stands and
21-
raw metadata packets.
22-
- One Paper API implementation replaces the old per-version NMS modules.
23-
- Per-viewer visibility uses Paper's `showEntity` / `hideEntity` API.
20+
- Native Paper `ItemDisplay` and `TextDisplay` entities replace Armor Stands.
21+
- Dropped-item visuals use shaded
22+
[Sparrow Heart](https://github.com/Xiao-MoMi/sparrow-heart) client-side vanilla
23+
`ITEM` entities. Empty Paper display anchors retain tracker and chunk lifecycle
24+
without enabling server item collision physics.
25+
- One Paper API implementation replaces the old in-project per-version NMS modules.
26+
InteractionVisualizer uses Heart 0.72 only for the client-side item packet path
27+
on the supported 26.1/26.2 runtimes.
28+
- Per-viewer anchor visibility uses Paper's `showEntity` / `hideEntity` API;
29+
tracker enter/leave events create and destroy the matching virtual `ITEM`.
30+
- Static items bob and spin entirely client-side with no animation task; only
31+
active gravity motion needs per-viewer correction because Heart marks its
32+
fake items as no-gravity.
2433
- Display updates are revision-coalesced; there is no 5 ms packet scan loop.
2534
- Player/chunk proximity queries use one allocation-light snapshot per world and
2635
server tick.
@@ -30,9 +39,8 @@ outside the supported range.
3039
- Gradle replaces the former Maven multi-module build and verifies the same
3140
sources against both supported Paper API lines.
3241

33-
The other Sparrow modules were deliberately not added: metadata, reflection,
34-
NBT, heart, and Redis messaging either duplicate Paper 26 APIs, reintroduce
35-
version/NMS coupling, or do not serve this single-server rendering path.
42+
Other Sparrow modules were deliberately not added: metadata, reflection, NBT,
43+
and Redis messaging do not serve this single-server rendering path.
3644

3745
## Building
3846

abstraction/src/main/java/com/loohp/interactionvisualizer/entityholders/Item.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
import org.bukkit.inventory.ItemStack;
2121
import org.bukkit.util.Vector;
2222

23-
/** Logical state for a real, non-persistent Paper item entity. */
23+
/**
24+
* Logical state for a client-side vanilla item visual.
25+
* Velocity and gravity are animation inputs; no server item physics is enabled.
26+
*/
2427
public class Item extends VisualizerEntity {
2528

2629
private ItemStack item;
@@ -117,6 +120,7 @@ public Vector getVelocity() {
117120

118121
public void setVelocity(Vector velocity) {
119122
Vector normalized = velocity == null ? new Vector() : velocity.clone();
123+
normalized.checkFinite();
120124
if (!this.velocity.equals(normalized)) {
121125
this.velocity = normalized;
122126
markDirty();

build.gradle.kts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ val pluginVersion = version.toString()
1313
val paper26_1Version = "26.1.2.build.74-stable"
1414
val paper26_2Version = "26.2.build.56-alpha"
1515
val craftEngineVersion = "26.7.2"
16+
val sparrowHeartVersion = "0.72"
1617

1718
val paper26_2CompileClasspath = configurations.create("paper26_2CompileClasspath") {
1819
isCanBeConsumed = false
@@ -35,6 +36,7 @@ dependencies {
3536
compileOnly(files("common/lib/LightAPI-fork-3.5.2.jar"))
3637

3738
implementation("net.momirealms:sparrow-yaml:1.0.7")
39+
implementation("net.momirealms:sparrow-heart:$sparrowHeartVersion")
3840

3941
testImplementation(platform("org.junit:junit-bom:5.13.4"))
4042
testImplementation("org.junit.jupiter:junit-jupiter")
@@ -113,7 +115,7 @@ val compilePaper26_2 = tasks.register<JavaCompile>("compilePaper26_2") {
113115
}
114116

115117
val verifyPaperOnlyArchitecture = tasks.register("verifyPaperOnlyArchitecture") {
116-
description = "Rejects reintroduction of NMS, Armor Stands, or legacy compatibility layers."
118+
description = "Rejects direct in-project NMS, Armor Stands, or legacy compatibility layers."
117119
group = LifecycleBasePlugin.VERIFICATION_GROUP
118120
val sources = sourceSets.main.get().allJava
119121
inputs.files(sources)
@@ -194,6 +196,7 @@ tasks.named<ShadowJar>("shadowJar") {
194196
mergeServiceFiles()
195197

196198
relocate("net.momirealms.sparrow.yaml", "com.loohp.interactionvisualizer.libs.sparrow.yaml")
199+
relocate("net.momirealms.sparrow.heart", "com.loohp.interactionvisualizer.libs.sparrow.heart")
197200

198201
isPreserveFileTimestamps = false
199202
isReproducibleFileOrder = true
@@ -208,6 +211,26 @@ tasks.named<ShadowJar>("shadowJar") {
208211
"CraftEngine must remain compileOnly, but provider classes were bundled:\n" +
209212
bundledCraftEngine.joinToString("\n")
210213
}
214+
check(jar.getEntry("com/loohp/interactionvisualizer/libs/sparrow/heart/SparrowHeart.class") != null) {
215+
"The shaded Sparrow Heart runtime is missing"
216+
}
217+
listOf("r26_1", "r26_2").forEach { adapter ->
218+
check(jar.getEntry(
219+
"com/loohp/interactionvisualizer/libs/sparrow/heart/impl/$adapter/Heart.class",
220+
) != null) {
221+
"The shaded Sparrow Heart $adapter adapter is missing"
222+
}
223+
}
224+
val unrelocatedHeart = jar.entries().asSequence()
225+
.map { it.name }
226+
.filter { it.startsWith("net/momirealms/sparrow/heart/") }
227+
.toList()
228+
check(unrelocatedHeart.isEmpty()) {
229+
"Unrelocated Sparrow Heart classes were bundled:\n" + unrelocatedHeart.joinToString("\n")
230+
}
231+
check(jar.getEntry("META-INF/licenses/sparrow-heart.txt") != null) {
232+
"The Sparrow Heart MIT license notice is missing"
233+
}
211234
}
212235
}
213236
}

0 commit comments

Comments
 (0)