Minecraft devices and addon ownership
- Minecraft devices and addon ownership
World-thread effects and devices
The Minecraft carrier owns exactly one actor endpoint and submits ordinary advancement once per server tick. Eligible host continuations may reuse the remaining frame credit, deadline and cumulative quotas described in runtime ownership. Rust starts
/rom/boot, compiled from system/programs/boot.kt; boot delegates to /rom/shell, compiled from
system/programs/shell.kt. A foreground child suspends its parent until it exits or fails. There is one active
foreground lane today, while the runtime contract leaves room for later parallel execution. Hibernation preserves the machine stack and terminal across unload/reload; reboot replaces the
complete machine stack and clears the terminal. Minecraft sends full state to a new viewer and ordered deltas
thereafter. Terminal viewers submit bounded asynchronous key, text, state, resync, and resource-snapshot operations,
which merge in server-arrival order without client-side echo or a terminal input lease. A valid standalone-terminal
viewer samples resources immediately and then every ten server ticks through the same single-poll admission. Its
viewer-local window retains one prior sample to derive semantic consumed/granted Guest-unit usage; it is discarded on
close, invalidation, machine replacement, or server stop. Replies are published only after returning to the server
thread and only while the viewer still refers to the same machine epoch.
Raw terminal
The raw terminal is a synchronous Rust device: cell writes, positional writes, rectangular fills, colors, cursor changes, and input polling never cross into Minecraft. The authoritative fixed 51x19 cell grid and its replication journal live in the machine, alongside a bounded 512-row history of scrolled cells. History survives viewer close/reopen and hibernation; reboot replaces it. Screen clear preserves history. Full states include history, and ordered append/replace changes preserve it through journal compaction. Minecraft owns only history navigation, rectangular selection and clipboard interaction over replicated cells. Waiting for an absent input event and foreground process execution are explicit suspension points. Kotlin guests consume ordered raw Text and Key events; there is no compatibility line buffer or second input protocol. The Guest Terminal facade returns an owned event snapshot and finishes its native event before returning, so starting an interactive child cannot retain that event ownership. The server host never blocks the Minecraft thread.
Redstone
Minecraft owns the persistent 30-bit redstone output register and samples dirty local faces before VM advancement. Rust owns the complete input snapshot, predicate waiters, and confirmed output mirror. Input crosses FFI as one scalar changed-mask-plus-levels packet; output requests are reduced in publication order and committed through one loader-independent host port at most once per computer per tick. A successful physical commit is confirmed to Rust before every original blocking request resumes. Completion and the next bounded advance share one actor command and one result without allowing multiple advances in a server tick. VM halt, fault, shutdown, reboot, and replacement never synthesize a zero output.
Sound
One-shot sound requests cross the same actor boundary as immutable (note, volume) batches. Minecraft emits the
vanilla note-block pling in the block sound category, using equal-temperament pitch around neutral note 12, before the
VM task receives its Boolean admission result. Each loaded computer has a four-tick cooldown, and one server-wide
counter admits at most 64 computer sounds per tick. Rejected sounds return false immediately and are never queued;
unloaded block entities retain no sound state or background work.
Computer GPIO sides are independent inputs and outputs. The chassis is not a passive redstone conductor: a strong input (such as a lever attached above it) cannot power a device on another face through the computer. Input sampling still reads the neighboring source, while explicit weak/direct program outputs retain their directional behavior. Samples collected before asynchronous boot completes are retained and replayed once as a complete input snapshot; normal changed-side packets resume afterward, so a steady input present at startup is not lost.
Peripheral fabric
The Minecraft carrier resolves its six direct provider contacts and persisted remote network members. Providers
map contacts to canonical logical identities. A versioned overworld SavedData directory owns network UUIDs, names
and member identities independently of computer lifetime; NeoForge persistent block-entity UUIDs prevent replacement
blocks from inheriting membership. Member names belong to that directory; unbound adjacent devices retain the separate
world-owned naming directory. Configurator selection lives in item custom data, with server-side proximity, held-item
and exact-instance validation for edits. Explicit configurator joins assign unnamed members the first free
device_kind_N name in that network, including unavailable members in collision checks. Existing names survive
repeated joins; ordinary binding used by migration, screen assembly and split does not generate names. Composite
display names remain authoritative in DisplayStorage, so configurator joins synchronize the generated name there.
Numbered names use stable technical kinds rather than translated labels, and reuse vacated suffixes without a new
persisted counter or schema. Chunk-load callbacks queue address-hint refresh without forcing chunk loads.
They never read the overworld directory inline during level construction: force-loaded Sable plots
can report loaded block entities before the overworld is registered on the server.
Membership does not imply reachability. A computer resolves only loaded, same-dimension members within the configured
Euclidean radius (64 blocks by default), then deduplicates them with direct contacts. Discovery sorts canonical
identities and rejects ambiguous reachable names. Networks are bounded to 1,024 members each, 4,096 networks and
65,536 total members per world. Computers in a network are membership anchors, not Guest peripheral endpoints.
Cable blocks no longer contribute discovery. Guest signatures and permanently stale handles remain unchanged.
The optional CompuktersPeripheralWorldIntegration SDK adapter projects storage coordinates to live world positions
and supplies already-loaded nearby block entities for configurator overlays. Ordinary worlds use the identity
projection. Range checks and configurator proximity use logical poses on client and server and project both endpoints,
while exact block identities still use storage addresses. The independent physical-client installRenderProjection
adapter receives the current frame’s partial tick; Sable projects attached displays and configurator outlines through
the same interpolated render pose as its blocks. Without that adapter, rendering retains the logical projection.
Unloaded/removed plot locations return unavailable without falling back to storage coordinates. Outline vertices and
display quads are resolved during frame extraction, so deferred submission never rereads mutable construction poses.
Explicit batch transfers capture exact source identities before copying blocks and guard source removal and destination display creation until the whole batch completes. Closing the scope relocates only matching destinations whose source was removed; a copied member whose saved address differs from the source cannot transfer another block’s membership. The scope is cleared even when the move throws. Complete displays retain canvas UUID, name and published RGB state; relocation retires location-bound handles and private frames. Moving part of a display splits it into panels, retaining the network, each published tile and the name on the first panel. Ordinary removal outside a transfer remains destructive.
Bulk construction storage deletion must call CompuktersPeripheralWorldIntegration.removeBlocks before
discarding its loaded blocks. Its ownership predicate retires only those display tiles and respects active
transfer guards. Sable invokes this for permanent REMOVED plots; UNLOADED preserves saved displays.
Serialized construction adapters can hold a loaded-address guardTransfer while calling
prepareTransferAsync. Its future includes final VM hibernation and filesystem attachment release;
poll completion without blocking the server thread. Keep source ticks and computer admission gated
until the coordinator opens beginTransfer for the exact source/destination block map. Close the move
scope after source removal (or destination discard on rollback), before publishing the world checkpoint.
The existing void preparation entrypoint remains available to synchronous block-move adapters.
For journal recovery, recoverTransfer guards both recorded address sets without manufacturing device
identities. After removing obsolete copies, call resolve with the selected survivor already loaded;
this relocates matching membership and complete display canvases. Plain close only releases guards,
so cancelling or shutting down a coordinator cannot accidentally commit destination authority.
A copied, missing or replaced endpoint still cannot satisfy an exact-instance descriptor.
Displays
compukters:display capability 1.2 preserves graphical operations 4–16 and the original operations 0–3,
adding click polling at operation 17. Guest compukter:core 7.3.0 exposes GraphicalDisplay, resolution
modes, RGB colors, drawing, typed clicks, widgets and an inline frame extension. TextDisplay remains source-compatible and rasterizes its 20x10 grid at HIGH density.
A dimension-owned DisplayStorage SavedData contains a bounded DisplayDirectory: logical screen UUIDs, one
plane and fixed rectangular geometry, actual panel UUIDs, a shared name, density and packed published RGB bytes.
Missing panels are holes in the logical image. Last-panel destruction removes the record; chunk unload does not.
Panel block entities persist only their instance identity, never duplicate the authoritative canvas. The configurator
assembles at most 8x8 blocks, selects existing screens, expands to include standalone panels and splits into 1x1 canvases.
New exact block instances automatically join a same-facing hole only when one saved screen claims that slot; exterior
placement never merges screens. Multiple matching holes leave the panel separate for explicit selection. Expansion
copies published pixels to preserve their physical locations, with black new area and stable canvas UUID/name/density.
Replacing geometry retires old leases/private frames and invalidates existing endpoints through surface identity.
Split crops only installed tiles, preserves density and removes the shared name/old rectangle. Quotas and loaded exact
panels are checked before splitting; the matching network member becomes one member per new independent screen.
DisplayNetworkAccess stores one network member under the canvas UUID, retaining the existing display provider and
text device key. A physical panel is only an address hint; discovery and availability validate any loaded exact
member within the computer’s radius. Binding, selection and removal through any panel address the same canvas.
Assembly and joining inherit a single source network, or remove all participating memberships when networks differ.
Partial destruction refreshes the hint; last-panel destruction removes membership. Legacy physical-panel bindings
are consolidated only after their loaded block entities validate the saved panel identities and physical stamps.
An incomplete legacy upgrade waits for remaining chunks without forcing loads or granting replacement blocks access.
The network SavedData schema and Guest capability remain unchanged; screen names remain authoritative in DisplayStorage.
Each program holds an exclusive canvas lease. Reset, termination or loss of every reachable panel releases it without erasing pixels. Private frames belong to one cooperative task, are bounded to 262144 pixels per program, and carry a cumulative work counter. Resource checkpoints preserve leases and private frames without replaying published pixels. Asynchronous computer hibernation retains its lease validity through checkpoint capture, then host reset releases it. Guest operations still reject detached endpoints throughout that transition. Composite contracts opt into their own member reachability; the original four-argument JVM constructor remains available to already compiled addons.
The server captures owned committed canvas pixels and membership on its owner thread. A per-server, two-thread encoder prepares RGB tiles and delta rectangles without world access. Admission permits at most 16 jobs and 64 MiB of estimated snapshot/output storage, with one job per surface; busy surfaces retain their authoritative newest canvas rather than queuing intermediate copies. Completion returns through the server executor, checks the exact level/surface/canvas/membership generation and immediately offers ready ordinary block tiles. Level unload and server shutdown invalidate pending results. Attached panels use the same encoder and their existing viewer transport.
A publication stays frozen while panel tiles are sent under the dimension’s unchanged 512KiB/tick budget. Ordinary block tiles use bounded custom payloads containing block instance UUID, screen identity, publication, member positions and full/delta RGB. Chunk tracking carries identity/metadata only. Clients request independent full tiles for first tracking or missing delta bases; the server keeps bounded, expiring recovery requests while encoding/admission waits. Requests never load chunks and require the player to be tracking the requested chunk, including distant visible screens. The client validates the loaded block instance on its owner thread, then prepares images in one ordered worker lane with at most 64 queued tile jobs. Switching levels shuts down that lane. Workers touch captured images only, so retired block objects cannot update replacements.
Clients retain at most two pending immutable tiles per panel: the latest complete publication and the next partial publication. The render-thread barrier chooses the newest complete set across loaded members and commits the exact candidates it checked, preserving newer partial data. A following partial frame cannot hide an already complete frame before rendering. Publication is frozen after the first visible panel of each render frame; worker delivery between panel draws waits for the next render frame. Unloaded members and holes do not block it. Texture upload stays on the render thread; dynamic emissive textures change only on committed revisions and are released when panels unload. Deterministic clipping and a 4M pixel-work/tick budget bound server drawing. Saved canvas schema, Guest calls and terminal transport are unchanged.
Foreground termination
Ctrl+C is reserved in computer terminal input (key code 67, CONTROL modifier), including the IDE target terminal.
The native computer consumes it independently of Guest input polling and queue capacity. A press marks the foreground
child below the nearest /rom/shell frame, or the first child of a standalone parent, for termination. An idle shell
and a root without a parent are preserved; an idle press reaches Guest input. Successive native advances unwind its descendants with status 130 and
ordinary ProcessExited lifecycle events, allowing the existing host scope cleanup to release peripheral leases and
reject stale completions. The host cancels pending compilation and wakes an input/compiler wait; native termination
discards the corresponding compiler transaction. Queued input for the terminated command is discarded at the press. After unwinding, line-oriented output resumes
below visible content without clearing the terminal; normal scrolling applies when the screen is full. Held-key repeats are consumed
without scheduling another stop.
Terminal keys C (67) and U (85) extend the admitted key set compatibly: existing key values, payload layouts, artifact ABI and C ABI
remain unchanged; both native transports use their existing terminal-key function.
Typed peripheral discovery
The canonical compukter:core 2.0.0 library defines compukter.peripheral.Peripheral,
PeripheralProvider<T>, relative Side values and TypedPeripheralProvider<T>. Companions supply a registered
contract id and the typed device wrapper. Selection runs in Guest; snapshots close in finally, including
predicate failure and early selection. Predicates are ordinary typed callbacks with local returns.
The base compukters:peripheral capability is ABI 1.0 with six asynchronous operations, in order:
openSnapshot(String):Int, snapshotSize(Int):Int, snapshotGet(Int,Int):Int, closeSnapshot(Int):Unit,
at(String,Int):Int, and named(String,String):Int. Optional direct lookup returns handle zero only for absence.
Malformed requests, unavailable contracts, ambiguity, wrong device types and limits remain host failures.
This adds a capability while preserving the artifact, Runtime instruction and native transport ABI.
core owns PeripheralSession and PeripheralProgramHost, independently of Minecraft. A typed contract identifies
its provider and logical device kind and resolves exact endpoint instances. A program has at most four snapshots,
1024 discovered entries per snapshot and 1024 retained handles. Snapshot opening captures physical identities
without retaining handles for unread entries; handles are allocated only on selection. Typed operations verify
contract object identity before exposing a retained endpoint. Invalidity latches, stale tokens cannot acquire
replacement instances, and reset discards state without reusing tokens. World discovery order and face/name lookup
belong to the Minecraft adapter. Addons retain ownership of device operations and capability schemas.
PeripheralOwnership is shared by all program sessions on a Minecraft server, across computers and dimensions.
Handle acquisition reserves an exact logical instance exclusively for that program, before reads or writes.
Contract aliases share the same ownership key; unread snapshot entries are not reserved. Program stop and reset
release retained leases; a server tick expires disconnected endpoints even without Guest operations. Server stop
clears the registry. Device adapters may implement PeripheralHandleLease for acquisition/release effects.
The built-in Redstone Port uses compukter:redstone_port and additive compukters:redstone-port capability ABI 1.0:
input(Int,Int):Int, setOutput(Int,Int,Int):Unit, awaitChange(Int,Int):Int,
awaitLevel(Int,Int,Int,Int):Int, close(Int):Unit, setAllOutput(Int,Int):Unit. All operations are asynchronous.
The ALL output operation commits all faces before one changed-face neighbor notification. The common host owns waiters;
the server block entity samples six inputs and owns transient output levels. The final handle release clears
outputs and notifies neighbors. No output NBT or persistent endpoint stamp is supplied; interrupted hibernation
waits fail rather than replaying control. The existing artifact and native transport ABI is unchanged.
Evidence: PeripheralSessionTest, PeripheralProgramHostTest, and
canonical peripheral companion specializes shared typed queries through testKotlinPeripheralQueriesVmConformance,
including predicate short-circuiting, imported Peripheral upcasts, nullable absence, strict exceptions and snapshot
cleanup after predicate failure.
The Minecraft adapter binds registered ComputerPeripheralContract<T> descriptors once per program, through
ComputerPeripheralRuntime. Loaded network/direct contacts sort by x/y/z, provider and device key; side lookup
resolves the contacted face directly. SDK 0.5.0 adds typed CompuktersPeripheralContract<T> registration and
CompuktersComputerContext.peripheral access, retaining the earlier overloads. SDK JARs depend on core only at
compile time and retain their explicit thin-archive class inventory. Both Minecraft version families compile the
canonical shared adapter sources. SDK 0.6.0 adds optional SDK-owned
acquisition/release callbacks mapped to the existing core handle lease, retaining old endpoint constructor ABIs
without exposing core lifecycle types to addon consumers. The existing server-tick ownership expiry remains the
source of disconnection cleanup. Transient actuators must not replay commands from saved block state on world load.
The shared Compukters creative tab appends lazy addon item groups from ComputerAddonCreativeItems, ordered by
addon ID after base items. The host SDK exposes registration; both Minecraft target registries consume the same
catalog. Empty addons create no tabs, and duplicate items are suppressed without reordering their first occurrence.
TextDisplay is a scalar value class implementing Peripheral, with a canonical box and a managed companion provider. All public acquisition uses typed providers and the common Side; the earlier Display/Create/Propulsion helpers and separate side types are removed. Display operations still own output leases; discovery creates no lease, and reset releases writer leases without erasing published pixels. The real text-display GameTest fixture covers typed selection, interface casts, predicates, optional/strict absence and cleanup after a thrown predicate before exercising a world write and network disconnection.
Addon module selection and Propulsion
Terminal, standard output and error, redstone, sound, process, filesystem, and compiler declarations live in the base
guest-platform bundle under compukter:core; core language declarations belong to kotlin:builtins and environment-independent helpers to stdlib:core. Optional integrations publish bounded addon Guest API
bundles instead. The server admits those bundles, includes their content hashes in the target and compilation-cache
identity, and sends their metadata and optional sources to the attached IDE. Analysis indexes the bounded catalog of
available addons for completion, while K2 semantics and compilation activate only the modules selected in the project
lock. Compiler and analysis workers decode only this data format: they never load or execute addon code. Exact admitted
bindings extend intrinsic lowering, while a
same-named Guest declaration remains ordinary Guest code. General stream handles, pipes, and process redirection remain
later layers.
Addon host handlers report failures with a broad HostFailureKind and a non-empty UTF-8 detail of at most 256 bytes.
The kind remains suitable for runtime classification; the producer-owned detail is diagnostic text and is not a stable
programmatic identifier.
The independent addons/propulsion build owns named Creative Thruster and Creative Vector Thruster control and its
propulsion.api Guest module.
It depends on upstream Propulsion/Create/Sable types, without depending on other Compukters addon implementations.
Commands and observations execute through the existing server-thread addon request boundary; physics and VM cadence
are unchanged. Controller identity and device reachability bind each handle. A server-confined lease registry owns
only temporary program control, validates active leases on server ticks, and restores normal redstone on release.
It does not mirror authoritative thrust or physics state. Typed observations copy current upstream fields in kN.
The pinned Propulsion binary persists digital commands, so a dedicated read/write mixin marks owned full NBT saves
and clears the unowned digital input/mode when those saves or construction copies load; client packets are unaffected.
Vector steering temporarily overrides mapped local targets without changing live redstone-link inputs. On release,
targets follow the latest signals; digital input and the old shutdown envelope are cleared before the creative thrust
override is removed, then physical thrust is recalculated from the current redstone input. This prevents residual
program throttle from multiplying the restored engine setting. Full saves retain
redstone signals and the saved engine configuration, clearing owned steering/tween and absolute thrust commands;
client packets retain the live visual state. Full NBT also persists an engine UUID for exact-device peripheral
rebinding. Logical computer checkpoints retain owned command values separately; restoration reacquires leases and
applies power/steering before the setter that publishes custom physical thrust. Read-only handles remain read-only,
replacements remain stale and competing writers cause rollback plus the common cold-boot recovery. Capturing detached
resources does not revalidate world reachability. Unloaded/restoring computers do not guarantee continuous thrust;
physics continues. Vector mount operation 12 copies integer computer-relative block
offsets, a neutral force axis and the common construction ID. It rejects cross-construction mounts; ordinary-world mounts have an empty ID and world axes.
Guest flight programs own geometry-to-torque allocation; names do not encode corner orientation.
Vector capability operations append IDs 5..12, preserving ordinary
operations 0..4 at capability version 1, Runtime ABI 1.13 and C ABI 20. The independent addons/dev run build composes
all three
addon archives and their GameTests with the upstream Aeronautics/Propulsion runtime.
Sable construction lifetime
The Compukters Sable addon supports assembly, full construction unload/reload and return to the ordinary world through the same carrier checkpoint path. Physics keeps running during computer restoration; no activation barrier or upstream Sable/Rapier patch is installed. The live-physics GameTests continue suspended Guest programs and query the same construction after reload. In unthrottled GameTests on the development machine, activation to continued Guest physics queries took 35 ms for one computer on a two-block construction and 68 ms for both computers on a 29-block construction, with the second computer eight blocks from the assembly anchor. Cold compilation precedes the measured interval. These results do not bound arbitrary heaps, construction sizes, disk latency or server load.
Cosmonautics dimensional construction transfer
The independent Cosmonautics addon wraps the pinned SubLevelWarper.WarpSubLevels transaction. All source computers
capture their world-owned resources before template serialization, using asynchronous hibernation and the existing
filesystem attachment barrier. The adapter opens one explicit block-transfer scope using upstream MoveInfo plot
translations before any destination template loads, and closes it after source plots are retired, including exceptional
completion. A source plot’s removed chunks do not invalidate an otherwise verified exact-instance destination.
Network member UUIDs follow the moved addresses; copied live source metadata outside this scope cannot steal membership.
Retained handles resolve their saved member UUID through the authoritative directory and still require the same endpoint
stamp and exclusive process ownership. Unbound direct devices use computer-relative offsets for translated constructions.
A removed or replaced peripheral remains stale; a failed/partial move does not adopt an arbitrary same-name device.
Physics continues while checkpoints publish and restore. Pending world requests can resume with their ordinary interruption failure; ascent programs recheck actual Deep Space membership before issuing cutoff through the retained handle. This is not an activation barrier or a guarantee of uninterrupted thrust. Old absolute-location checkpoints can resume at their saved addresses, but do not gain portable identities retroactively.
Interactive display input
Display capability 1.2 preserves operations 0–16 and appends operation 17, pollClick(handle: I32): BYTE_ARRAY.
Minor 0/1 requests cannot invoke operation 17. An empty array means no event; otherwise exactly eight bytes
contain unsigned little-endian x and y in published canvas pixels. compukter:core 7.3.0 wraps this private
encoding as GraphicalDisplay.pollClick(): DisplayClick?, with a Position2i position.
Empty-hand front-face right-clicks use renderer-aligned coordinates for all four orientations and add panel offsets in a composite canvas. Shift-use passes through. Server-thread input is a FIFO limited to 64 entries; overflow drops new arrivals. Input belongs to the program’s exclusive writer lease. Polling claims that lease. Lease release/expiry, world restore, layout retirement and committed density changes clear input. Aborted frame density changes preserve it. Pending queue entries are never included in canvas or program resource checkpoints. Values already returned to Guest code are ordinary program data and follow its normal execution/checkpoint semantics.
World-display pointer gestures
The physical client sends a held-use heartbeat while empty-hand RMB is down and no GUI is open, and one release message on transition. The server derives aim/range/face/panel offsets from the actual player, never accepting client coordinates. A bounded controller keeps at most 64 player records and eight captures per canvas; only initial Down acquires a target. Moves across panels in the same exact canvas retain capture; leaving the screen cancels until release, and five missing ticks cancel stale capture. Disconnect and server shutdown release controller state. The client bridge is shared by both target families and registration is on the dedicated-server payload path as well.
Guest pollPointer and legacy pollClick are independent transient queues. The widget tree consumes only
explicitly supplied events; no Minecraft-side mirror of widget state exists. Drawing regions are carried
per command, so there is no ambient clipping stack to restore across frame or VM checkpoint boundaries.
Peripheral structure geometry
A provider resolves every contact on a formed multiblock to the same controller anchor and device key.
The controller owns the exact-instance stamp, configured name and persistent network membership.
The optional CompuktersPeripheralGeometryProvider interface supplies block-aligned world bounds for
presentation; existing SAM providers and identity constructors remain unchanged. Geometry never enters
peripheral equality, Guest schemas or saved network records. The overlay adapter accepts only finite
bounds containing both anchor and contact, at most 64 blocks on each axis; invalid metadata falls back
to the anchor block. Overlay protocol 2 transports validated inclusive block bounds, deduplicates by
anchor and uses the same geometry for hover, HUD and the existing depth-tested pulsing outline.
The Create adapter resolves active Fluid Tank boilers through Create’s real controller and width/height. Inactive or unformed tanks remain unavailable. Explicit configurator interaction consolidates old per-block memberships only when their current exact-instance stamps and provider resolution still match the structure. One source network is inherited; conflicting networks leave the resulting device unbound before the requested binding action. An unambiguous name is retained. Holding the configurator only observes structures and never creates stamps or consolidates memberships.
Attached display transfer guards can open before the destination native plot exists. Publication requires loaded destination backing blocks matching the captured source. Permanent bulk removal notifies active transfer scopes before retiring metadata, proving source vacancy after plot deletion; chunk or construction unload must never send that signal. Journal recovery uses the coordinator’s existing address map and selected authority to relocate saved attached surfaces, without a second persisted manifest or a Sable dependency in the host.