Skip to content

v0.12.0

Latest

Choose a tag to compare

@Fluffyalien1422 Fluffyalien1422 released this 25 Aug 02:24

Changelog for Bedrock Energistics Core and the Bedrock Energistics Core API package.

The add-on and the API package are now one release. As of v0.12.0 they share a single version number and ship together.

Requires Minecraft 26.30 or newer (was 26.0). The API package's peer dependencies are @minecraft/server ^2.8.0 (was ^2.5.0) and @minecraft/vanilla-data >=1.26.30 (was >=1.26.2).

This version is not compatible with earlier releases of either half. An add-on bundling an older API package will not work with this add-on, and vice versa.

Breaking Changes

Errors

  • Failures caused by the calling add-on now propagate to it instead of being logged by the core pack and answered with null.
  • Every API function that can throw a PublicError documents which PublicErrorTypes it raises, including the InvalidState raised when a function that needs the core pack is called before init.

API Renames

Before After
MachineOnStorageSetEvent MachineOnStorageSetEventArg
MachineRecieveHandlerArg MachineReceiveHandlerArg
RecieveHandlerResponse MachineReceiveHandlerRes
MachineUpdateUiHandlerResponse MachineUpdateUiHandlerRes
NetworkStatsEventArg MachineNetworkStatsEventArg
IoCapabilities#acceptsType IoCapabilities#acceptsTypeData
IoCapabilities#acceptsTypeWithId IoCapabilities#acceptsTypeId
IoCapabilities.fromMachine IoCapabilities.fromBlock
MachineNetworkStatsEventArg.networkData MachineNetworkStatsEventArg.allocationData

API Signature Changes

  • setMachineSlotItem returns Promise<boolean> instead of Promise<void>, and takes MachineSlotItemExpectOptions. It resolves false without writing when a condition was given that the slot does not meet; a write with no conditions always resolves true.
  • setMachineSlotItem throws if the amount exceeds the item's maximum stack size, or if the item type does not exist.
  • getMachineSlotItem throws a PublicError of type NotFound if there is no block at the given location, including when that location's chunk is not loaded. It previously read the stored data without consulting the block; it now flushes the machine's open UI container into block storage first, so the answer is current as of the call.
  • MachineItemStack.amount must be a positive integer — the constructor, the property setter, and withAmount all throw otherwise. Such a value used to be accepted but caused unpredictable behavior.
  • MachineNetwork#queueSend no longer takes a type: queueSend(blockLocation, amount) instead of queueSend(blockLocation, type, amount). A network distributes exactly one storage type, which is now available as MachineNetwork#ioType.
  • MachineNetworkStatsEventArg.allocationData is a single NetworkStorageTypeData rather than a record keyed by storage type ID, for the same reason.
  • IoCapabilities.accepting and IoCapabilities.acceptingAny take a NewIoCapabilitiesOptions object in place of the onlyAllowConduitConnections boolean. The IoCapabilities constructor also gained an isConduit parameter after onlyAllowsConduitConnections.
  • MachineUiElements.get returns a frozen object, shared between calls, instead of a fresh mutable deep copy. Code that modified the element it returned must copy it first.
  • RegisteredStorageType's definition — including the object returned by its texture getter — is copied and frozen on construction. A registered texture could previously be modified after the fact, either through the getter or through the add-on's own reference to the object it passed in.
  • STANDARD_STORAGE_TYPE_DEFINITIONS is deeply frozen.

Behavior

  • A receive handler can no longer accept more than it was offered. The returned amount is clamped to the offer, then re-clamped against the room left in the machine after the handler answers, since storage can change while the call is in flight; anything that no longer fits stays in the network's budget.

Standard Storage Types

  • StandardStorageType.LiquidAmmonia ("liquid_ammonia") was removed, along with its entry in STANDARD_STORAGE_TYPE_DEFINITIONS.
  • StandardStorageType.LiquidExp ("liquid_exp", liquid experience, category Fluid) was added.
  • The standard definitions were repointed to the new per-type texture presets: energy yellow → energy, lava red → lava, oil black → oil, water blue → water, ammonia orange → ammonia, carbon red → carbon, hydrogen pink → hydrogen, nitrogen purple → nitrogen, oxygen white → oxygen, steam white → steam.

Items, Textures and JSON UI

  • UI item IDs shortened. Storage bar segment items went from fluffyalien_energisticscore:ui_storage_bar_segment_<texture><n> to fluffyalien_energisticscore:ui_sbar_seg_<texture><n>, and progress indicator items from ui_progress_<indicator><n> to ui_prog_<indicator><n>. Any pack that references these item IDs directly must be updated.
  • Empty slot texture moved. textures/fluffyalien/energisticscore/ui/empty_slot was deleted; fluffyalien_energisticscore:ui_empty_slot now resolves to textures/fluffyalien/energisticscore/empty.
  • The legacy fluffyalien_energisticscore:common JSON UI namespace is deprecated and will be removed in a future update. It still ships and still works; use common_v2 instead.

Added

  • PublicError, InternalError, and PublicErrorType. A PublicError is the caller's mistake and crosses the pack boundary so it surfaces in the add-on that caused it; an InternalError is a bug in the library and is logged by the pack that raised it. PublicErrorType lets an add-on branch on the kind of failure.
  • Atomic machine item slot operations: takeMachineSlotItem and addMachineSlotItem. Reading a slot, computing a new value and writing it back held a read across two round trips — many ticks — so if the player emptied the slot in that window the write put the item back while they were still holding it, duplicating it. These run the whole read-modify-write inside the core pack, so there is no window to lose. takeMachineSlotItem returns what it removed (or undefined); addMachineSlotItem returns how many items it added.
  • MachineSlotItemExpectOptions, accepted by takeMachineSlotItem, addMachineSlotItem and setMachineSlotItem for transforms the atomic operations don't express: expectType, expectAmount, expectMinAmount and expectMaxAmount state what the slot must currently hold, and the operation reports that it did not apply rather than clobbering a change made since you last looked.
  • Configuration file. BP/scripts/__config.js is excluded from the script bundle and can be edited with any text editor after installation. Every option is optional and documented in the file; a missing or wrong-typed option falls back to its default and logs a warning to the content log. The first option is customCommandNamespace, which sets the namespace for the add-on's custom commands (/<namespace>:becdebugmode, /<namespace>:becprintnetworks) so the add-on can be rebranded when bundled into a modpack.
  • New common_v2 JSON UI namespace, replacing the deprecated common namespace with a documented, fuller set of elements: screen_template and content_template (a machine screen layout with the player inventory in the bottom half), container_title, container_slot_item (a slot that looks like a regular chest slot), container_slot_custom, container_slot_nobg, container_slot_nobg_noclick, container_slot_nobg_nohover, the matching container_item_* controls, and machine_storage_bar. Every element carries documentation, published as a generated JSON UI Reference.
  • A dedicated storage bar texture for each standard storage type, so fluids and gases are distinguishable at a glance instead of sharing the generic color presets. Eleven new StorageTypeTexturePreset values: ammonia, carbon, energy, hydrogen, lava, liquid_exp, nitrogen, oil, oxygen, steam, water. Nothing was removed — the generic color presets all still work.
  • Storage bar borders as separate textures, rather than being baked into each generated segment image. Added ui/sbar_border_inset_{top,middle,bottom} and ui/sbar_border_overlay_{top,middle,bottom}. common_v2.machine_storage_bar uses the inset set by default, through its $border_top_texture, $border_middle_texture and $border_bottom_texture props. The deprecated common.machine_storage_bar uses the same border as before.
  • StorageTypeTextureDescription.segments (default 16), how many fill levels one slot of a bar has. A bar's resolution was fixed at 16, so a custom texture had to supply seventeen items whatever it looked like; a coarser bar now needs correspondingly fewer. Registration rejects a count that isn't a positive integer.
  • MachineNetwork#getLatestAllocationData, so allocation statistics can be read on demand rather than only when the onNetworkAllocationCompleted event fires. Returns the same statistics passed to that event, for the network's latest allocation.
  • MachineNetwork#ioType, the StorageTypeData this network distributes.
  • MachineNetworkStatsEventArg.network, the network that triggered the event.
  • IoCapabilities#isConduit, IoCapabilities#acceptsTypeIdExplicit (a type accepted explicitly or via acceptsAny, ignoring categories), and IoCapabilities#canConnectTo.
  • NewIoCapabilitiesOptions, with onlyAllowsConduitConnections and isConduit.
  • isRegistrationOpen, answering whether machines, item machines and storage types can still be registered. Registration is open from the moment scripts start running until 20 ticks after worldLoad, then closes permanently.
  • MACHINE_ENTITY_NO_UPDATE_UI_TAG (fluffyalien_energisticscore:no_update_ui). A machine entity carrying this tag receives no UI updates.
  • MachineDefinitionDescription.defaultEntityNameTag and RegisteredMachine#defaultEntityNameTag, the name tag given to the machine entity when spawned. Defaults to the machine ID, which is what was always used before.
  • init validation. init now throws a PublicError of type InvalidArgument if the unique ID is empty or longer than mcbe-addon-ipc's MAX_ROUTER_UID_LENGTH, reporting the real range and the length given. It is also now documented that uid is passed straight to the Router as its own unique ID, which matters if your add-on constructs a Router of its own — two sharing an ID receive each other's messages.
  • isBedrockEnergisticsCoreInWorld throws a PublicError of type InvalidState if called before worldLoad, rather than letting the engine's error about item types through. It works by looking for one of the core pack's items, which is why init has to be called after worldLoad.
  • A Using the API guide, covering init, the registration window, why reads are asynchronous, and error handling. Guides were also added or updated for UI buttons, progress indicator frame counts, custom storage bar textures, and item machine I/O.

Changed

  • Allocations can now distribute unevenly. Previously a budget that did not divide evenly across the consumers in a priority group was not distributed at all. The remaining budget is now respread across the machines still to be processed on each iteration, so anything a machine does not take — because it is full, or because its receive handler reduced or refused the amount — rolls forward to the rest of the group instead of being lost.
  • Machine item slot changes are shown in the open UI as they are made, rather than up to an update interval later. For that window the container used to show an amount the machine had already changed, so a player could take items that were no longer there. The machinery that tried to reconcile the two afterwards (the changed-slot registry, the recorded pre-change values, and the merge between them) is gone, since the case it handled no longer arises.
  • Item slots are synced outside the async UI render. They no longer wait on the machine's updateUi handler, which takes several ticks to answer across the pack boundary; they are now driven synchronously on container open, on every interval tick regardless of a redraw in flight, and on container close.
  • Player-in-UI tracking moved to container events. entityContainerOpened and entityContainerClosed replace the per-tick getPlayers({ maxDistance: 10 }) distance query that persistent entities ran on every interval tick. UI updates run every 4 ticks (was every 5).
  • Network performance. Machine definitions are looked up once during the allocation scan and carried through to distribution; block tags and I/O capabilities are computed once per block during network discovery instead of once per side (explicit-side machines are still evaluated per direction); and the static "find the network(s) at this location" lookups compute the block UID once instead of once per network.
  • Storage bar label colors changed for three generic presets: blue §9§1, orange §6§v, yellow §e§6. The color composite source images were also redrawn, so existing bars using the generic presets look slightly different.
  • MachineItemStack.toItemStack clamps an amount above the item's maximum stack size and logs a warning, instead of throwing.
  • ItemMachine#getStorage is now async, so an invalid-object failure rejects rather than throwing synchronously, matching the other methods.
  • ItemMachine#setStorage validates that it is given a non-negative integer.
  • MachineNetwork.getAllWith defaults to an empty list. An unexpected error in the core pack is answered with null, which was previously dereferenced.
  • hasCallback returns false for an unrecognized name on both RegisteredMachine and RegisteredItemMachine, rather than implicitly returning undefined to JavaScript callers.
  • Registering a machine or item machine fails up front if the library has not been initialized, instead of partway through with the registration half-applied.
  • A destroyed machine reached during allocation logs at info instead of warning. Finding air where a registered machine was expected is a normal consequence of a machine being broken mid-allocation, so it no longer looks like a fault. Allocation log messages now name the phase they came from and render locations consistently.
  • Scoreboard write failures are handled instead of propagating out of setMachineStorage.
  • MachineItemStack documents what it can and cannot carry. It holds an item's type, amount, name tag, damage, lore and enchantments and nothing else, so an item holding more than that does not survive a round trip — a shulker box with items in it comes back out empty. Restrict slots with UiItemSlotElementDefinition.allowedItems, or use a persistent entity's container if a slot has to accept any item.
  • Machine registry types are documented throughout, including which handlers can change what the add-on does and which events only observe.

Fixed

  • Allocation could freeze permanently if a receive handler threw or timed out: the per-tick lock was never released. The pump now releases the lock in a finally and discards the broken job.
  • A handler that throws (receive, getIo) answers with null, which is now guarded instead of being used as a result.
  • onNetworkAllocationCompleted never fired for machines that don't consume the network's I/O type. Listening is independent of consuming, but the listener lookup sat behind the consumer filter, so a non-consuming observer was never registered. Non-consumers also ran outside the allocation job's cross-tick chunking.
  • Read-modify-write race in distributeToGroup: the stored amount was read before the receive handler was called and written back after it, overwriting anything that changed in between.
  • Machine override was broken for any machine with a custom entity ID. The entity-attachment guard compared the stored machine ID against the new entity ID rather than the new machine ID. A stale entity ID → machine ID mapping is now cleared when an override changes the entity ID.
  • Item name tags and lore containing a backslash threw "Illegal escape code" when read back. Backslashes are now escaped on serialization.
  • Machine item slots ignored stack size. An amount above the item's maximum stack size threw while rendering the machine's UI — taking out the whole UI render, and the machine's contents as it broke, over one slot. Oversized amounts are now rejected when stored, and rendering clamps with a warning so anything stored before this check still renders.
  • MachineItemStack shared its lore and enchantments with the options object it was constructed from, so clone and withAmount produced objects backed by the originals' arrays: mutating one changed the other, and isSimilarTo then wrongly reported them as similar. Enchantment entries are copied too, since their level is writable.
  • RegisteredStorageType.getAllIds could permanently cache an incomplete list. It read the registration window after awaiting the response, so a call made late in that window could cache a list the core pack built while other packs were still registering. It also never included the calling pack's own registrations, so it could omit a storage type that get reported as existing.
  • Concurrent redraws of the same machine UI could race on the item slot sync, because the redraw awaits the updateUi handler and the interval could start a second one while the first was still in flight.
  • A disabled storage bar ignored the element's size, always writing four slots: a larger bar kept stale segments in the extra slots and a smaller one wrote into slots it does not own.
  • The label option was ignored on a disabled storage bar (type set to "_disabled").
  • Custom progress indicators were off by one: passing the highest valid frame index rendered the error item instead of the last frame.
  • The changed-item-slot registry grew without bound for a machine whose UI was never opened.
  • Network link nodes: connecting to or destroying a node whose partner chunk is not loaded now raises a clear error or is skipped, instead of orphaning the backing entity and leaving dangling links. Duplicate connections are no longer stored — a single removal filtered out every match, which made the two directions of a link asymmetric and grew the stored property each time.
  • A machine entity without an inventory component threw out of an event handler; it is now logged and skipped.
  • An ItemMachine whose item is held by a block or entity with no inventory asserted non-null; it now raises a clear error.
  • A storage type texture override was reported even when nothing changed, because two add-ons registering an identical texture were compared by reference. Override diagnostics also read more clearly now.
  • Interacting with a machine entity did not check that the target was still valid.
  • The debug menu's set-variable form turned an invalid entry into an unhandled rejection.
  • Re-registering a machine or item machine threw partway through, leaving the registration half-applied. It now overrides the previous one, and logs that it did, since an override usually means two packs claim the same ID.