Verwendung und Grenzen

ServiceLoader lädt die Erweiterung über META-INF/services/dev.nebulastorage.api.NebulaExtension. Adapter und Rezeptquellen werden ohne Weltzugriff registriert. Abfragen aus serverStarted müssen an den authentifizierten Spieler gebunden sein und nach serverStopped verworfen werden.

  1. EntdeckenFähigkeiten und Rezepte lesen
  2. PlanenExakte Ressourcen reservieren
  3. AusführenAn realen Besitzer übertragen
  4. FortsetzenGespeicherten Beleg lesen
Entdeckung liest nur. Erst die Ausführung überträgt Besitz; Wiederherstellung erzeugt keine verbrauchten Eingaben neu.

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>
}
Quelle

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

43b4d12d69e6033c24fa8c39dac383ef2429b446