Slipstream is a Next-Gen framework for packet interception and physics simulation in Minecraft (Paper). Built as an ultra-fast, modern alternative to heavy libraries (like ProtocolLib), designed specifically for Kotlin developers with an absolute focus on maximum performance and production stability.
Starting with v2.0.0, Slipstream utilizes a Multi-Module Architecture with automatic generation of @JvmInline value class wrappers directly from NMS, providing 100% type safety, Java Records support, and Zero-Allocation access without polluting the global namespace.
- 🚀 Zero-Reflection Bytecode Bridge: Uses
MethodHandlesand Kotlinvalue classes. Packets are processed at the speed of compiled JIT bytecode. - 🛡️ Type-Safe & Clean API: Forget
packet.isMovePacket(). Use our beautifully craftedpacket.wrapAs<WrapperMovePacket>()which usesinline reifiedmagic to guarantee zero runtime overhead and a clean autocomplete scope. - 📦 Zero-Allocation Nested Structures: Automatically generated wrappers for internal NMS types like
BlockPos,Vec3,ItemStackensure no objects are unnecessarily instantiated in the heap. - 🧵 Coroutine-First & Lazy Suspend: Asynchronous packet processing directly in the Netty thread. Slipstream only launches coroutines when a listener is interested, otherwise, it stays 100% synchronous.
- 🪄 Full Packet Mutation: Mutate packets easily via generated setters for mutable fields, or via
.copy()for immutable Java Records. - 🗺️ Native Mojang Mappings: Deeply integrated with Paper's native Mojang-mapped environment (1.21+).
- 🏗️ Architecture — Multi-module design, Code Generation, and Pipeline internals.
- 📖 API Guide — Listeners, Awaiters,
wrapAs, and Modifiers. - ⏱️ Performance — JMH Benchmarks, Inline Reified optimizations, and MethodHandles.
Gradle (JitPack)
repositories {
maven("https://jitpack.io")
}
dependencies {
// You only need to depend on the core module, the generated wrappers are pulled automatically!
implementation("com.github.ClCody.Slipstream:slipstream-core:2.0.0")
}The core of Slipstream's DX. Check and cast a packet in one single zero-overhead line:
val manager = SlipstreamPlugin.instance.manager
manager.registerListener(object : PacketListener {
override fun onPacketIn(player: Player, packet: Any): Boolean {
// wrapAs<T>() returns null if it's the wrong packet.
// Powered by inline reified, so 0 overhead!
packet.wrapAs<WrapperServerboundMovePlayerPacket>()?.let { movePacket ->
val pos = movePacket.pos // Returns a WrapperBlockPos (zero-allocation)
println("Player moved to X: ${pos.x}, Y: ${pos.y}")
}
return true
}
})Don't block the server and Netty! Make database queries right during packet processing:
manager.registerSuspendListener(object : SuspendablePacketListener {
override fun interestsInbound(packet: Any): Boolean = packet.wrapAs<WrapperServerboundChatPacket>() != null
override suspend fun onPacketInSuspend(player: Player, packet: Any): Boolean {
// The coroutine can suspend, the order of following packets is strictly preserved!
val isMuted = database.checkPlayerMute(player.uniqueId)
return !isMuted // false = cancel packet
}
})Linear, non-blocking packet awaiting (e.g., waiting for client transactions):
// Send a transaction to the client
player.sendPacket(TransactionPacket(id = 1337))
// The coroutine suspends until the client sends a response with the target ID
val response = manager.awaitPacket<WrapperServerboundPongPacket>(player) {
it.packet.id == 1337
}packet.wrapAs<WrapperClientboundSetEntityDataPacket>()?.let { dataPacket ->
// Modifying a mutable packet using generated MethodHandle setters
dataPacket.id = 999
}
packet.wrapAs<WrapperServerboundSwingPacket>()?.let { swingPacket ->
// For immutable Java Records, a copy() method is generated (just like Kotlin data classes)
val modified = swingPacket.copy(hand = InteractionHand.OFF_HAND)
}MIT License.