Usage and constraints

Convert a FluidStack to an exact key and millibucket quantity using the current registries. Preserve components. Decoding must create a fresh valid stack and reject unknown or oversized data.

FluidResourceCodec

FluidResourceCodec
package dev.nebulastorage.api.platform

import dev.nebulastorage.api.resource.ResourceKey
import dev.nebulastorage.api.resource.ResourceTypeId
import net.minecraft.core.HolderLookup
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.TagParser
import net.neoforged.neoforge.fluids.FluidStack

/** Registry-aware fluid identities independent of amount, with exact component patches and integral mB. */
class FluidResourceCodec(private val registries: HolderLookup.Provider) {
    /** Tests the shared Nebula component-size bound before a fluid is admitted to a transfer. */
    fun transferable(key: ResourceKey): Boolean = CanonicalComponents.transferable(key.components)

    fun key(stack: FluidStack): ResourceKey {
        require(!stack.isEmpty)
        val encoded = stack.copyWithAmount(1).save(registries) as CompoundTag
        val components = encoded.get("components")?.let(CanonicalComponents::encode) ?: ""
        return ResourceKey(ResourceTypeId.FLUID, BuiltInRegistries.FLUID.getKey(stack.fluid).toString(), components)
    }

    fun stack(key: ResourceKey, amount: Int = 1): FluidStack {
        require(key.type == ResourceTypeId.FLUID && amount > 0)
        val data = CompoundTag().apply {
            putString("id", key.id)
            putInt("amount", amount)
            if (key.components.isNotEmpty()) put("components", TagParser.parseTag(key.components))
        }
        return FluidStack.parse(registries, data).orElseThrow { IllegalArgumentException("Unknown fluid or components: ${key.id}") }
    }
}
Source

src/main/kotlin/dev/nebulastorage/api/platform/FluidResourceCodec.kt; editorial/en.json

43b4d12d69e6033c24fa8c39dac383ef2429b446