使い方と制約

META-INF/services/dev.nebulastorage.api.NebulaExtensionでServiceLoaderに登録します。ワールドに触れずにアダプターとレシピを登録します。serverStartedの照会は認証済みプレイヤーに紐付け、serverStopped後に保持しません。

  1. 検出能力とレシピを読む
  2. 計画正確な資源を予約する
  3. 実行実際の所有者へ転送する
  4. 復旧保存された受領記録を読む
検出は読み取りのみです。所有権は実行時に移り、復旧で消費済み入力を再生成しません。

NebulaExtension

NebulaExtension
package dev.nebulastorage.api

import dev.nebulastorage.api.production.ProductionCapabilityId
import dev.nebulastorage.api.production.ProductionMachine
import dev.nebulastorage.api.production.ProductionRecipeOffer
import dev.nebulastorage.api.resource.ResourceKey
import dev.nebulastorage.api.resource.ResourceTypeId
import java.util.UUID

/** Discovered once through META-INF/services. Registration must not access a running world. */
interface NebulaExtension {
    fun register(registrar: NebulaRegistrar)
    fun serverStarted(queries: NebulaNetworkQueries) {}
    fun serverStopped() {}
}

interface NebulaRegistrar {
    fun hardwareAdapter(id: String, adapter: dev.nebulastorage.api.hardware.NebulaHardwareAdapter)
    fun resourceType(type: NebulaResourceType)
    fun capability(id: ProductionCapabilityId)
    fun capability(id: ProductionCapabilityId, requirements: dev.nebulastorage.api.production.ProductionRequirements) {
        throw UnsupportedOperationException("This Nebula runtime does not support production requirements")
    }
    fun machineAdapter(id: String, adapter: NebulaMachineAdapter)
    fun recipeSource(id: String, source: NebulaRecipeSource)
    fun observer(observer: NebulaObserver)
}

interface NebulaResourceType {
    val id: ResourceTypeId
    val unit: String
    /** Capacity allocated in newly created Storage Cores; zero means this type needs another storage provider. */
    val defaultStorageCapacity: Long get() = 0
    /** Validates canonical identity without mutating state; an unsupported key must return false. */
    fun accepts(key: ResourceKey): Boolean
}

fun interface NebulaMachineAdapter {
    /** Returns null when the exact installed item is unsupported. The returned machine must retain [instance]. */
    fun adapt(instance: UUID, item: ResourceKey): ProductionMachine?
}

interface NebulaRecipeSource {
    /** Increment after recipes or their constraints change. Queried on the server thread. */
    val revision: Long get() = 0
    fun discover(capabilities: Set<ProductionCapabilityId>): List<ProductionRecipeOffer>
}

fun interface NebulaObserver {
    /** Null observes public historical networks only. An authenticated actor is rechecked for each event. */
    fun actor(): UUID? = null
    /** Called on the server thread after mutation. Queries are read-only and must not be retained across server lifetimes. */
    fun onEvent(event: NebulaEvent, queries: NebulaNetworkQueries)
}

sealed interface NebulaEvent {
    data class NetworkChanged(val network: UUID, val online: Boolean) : NebulaEvent
    data class ResourcesChanged(val network: UUID) : NebulaEvent
    data class MachinesChanged(val network: UUID, val count: Int) : NebulaEvent
    data class JobChanged(val network: UUID, val job: PublicJob) : NebulaEvent
}

/** Creation time is Unix milliseconds, or zero when migrated from a format without a timestamp. Produced amount excludes initial stock. */
data class PublicJob @JvmOverloads constructor(val id: UUID, val state: String, val completedSteps: Int, val totalSteps: Int,
                                              val createdAtMillis: Long = 0, val producedAmount: Long = 0)
data class PublicNetwork(val id: UUID, val online: Boolean, val machineCount: Int, val energyStored: Long, val energyCapacity: Long)

interface NebulaNetworkQueries {
    /** Resolves every query against current permissions. The server extension must supply the authenticated actor, never a client-claimed UUID. */
    fun forPlayer(actor: UUID): NebulaNetworkQueries { throw UnsupportedOperationException("This runtime does not expose actor-scoped queries") }
    fun configuration(): NebulaConfiguration { throw UnsupportedOperationException("This Nebula runtime does not expose balancing configuration") }
    fun at(dimension: String, x: Int, y: Int, z: Int): PublicNetwork?
    fun resources(network: UUID): Map<ResourceKey, Long>
    fun jobs(network: UUID): List<PublicJob>
}
ソース

src/main/kotlin/dev/nebulastorage/api/NebulaExtension.kt; editorial/ja.json

43b4d12d69e6033c24fa8c39dac383ef2429b446