Skip to content

Astral Sorcery ​

Since after 21.1.2

Astral Sorcery integration adds lumen and starlight as recipe capabilities, a trait that holds each, three conditions that read the sky and a player's research, and a trait that records whose research a machine uses. It is in MBD2 versions newer than 21.1.2.

MBD2 inspector for the Astral Lumen Storage trait: the common trait fields from Name to GUI IO, then Capacity 4000, Lumen Types, Max Receive, Max Extract, Provide To Network checked, Draw From Network unchecked, Draw Interval 20 and Transfer Particles checked
The `astral_lumen_storage` trait at its defaults: a lumen buffer that offers what it holds to Astral Sorcery's lumen network but does not draw from it.

Versions

MBD2 is built against Astral Sorcery 2.0.3.63 for Minecraft 1.21.1, and Astral Sorcery 2.0.3 refuses to start without Curios 9.5.1 or newer. Astral Sorcery has no API, so MBD2 uses its internal classes: another Astral Sorcery version can break the integration. Test the exact versions in your pack.

What is added ​

LayerRegistry namePurpose
Recipe capabilityastral_lumenLumen of one type, whole amounts, input and output
Recipe capabilityastral_starlightStarlight of one constellation or of any, decimal amounts, input only
Traitastral_lumen_storageA lumen buffer per type, exposed as Astral Sorcery's lumen capability and able to join the lumen network
Traitastral_starlight_receiverKeeps the starlight that lenses deliver to the machine
Traitastral_researcherRecords which player's Astral Sorcery progress the machine uses
Conditionastral_constellationA constellation is in the sky
Conditionastral_celestial_eventA solar or lunar eclipse
Conditionastral_researchThe machine's researcher has progressed far enough
Starlight network nodembd2:machine_starlight_receiverWhat the receiver trait registers in Astral Sorcery's starlight network
KubeJSinputLumen, outputLumen, inputStarlight, astralConstellationCondition, astralCelestialEventCondition, astralResearchConditionSee KubeJS

All entries are conditional on mod ID astralsorcery. Each of the three traits can be added only once per machine.

Lumen and starlight ​

The two resources travel differently in Astral Sorcery, so each has its own trait.

LumenStarlight
In Astral SorceryA stored resource of several types, such as Aevitas, Armara and Vicio, held in Lumen ArraysA flow a Starlight Focus Crystal gives off every tick, tagged with its constellation. Nothing stores it
How it travelsA pull-only network: a device requests lumen from a source within 16 blocks that it can see, or further through Lumen FilamentsLinks made with the Linking Tool, from the focus crystal through Lenses and Prisms
Traitastral_lumen_storageastral_starlight_receiver
Recipe directionInput and outputInput only
AmountWhole number; one flask is 500Decimal

Lumen storage ​

SettingRangeDefaultMeaning
Capacity1 or more4000How much of each lumen type the machine holds. A Lumen Array holds 4000
Lumen TypesLumen IDsemptyWhich types may be put in; empty accepts every type. Also the types Draw From Network asks for
Max Receive0 or more4000Most lumen taken in per action: per insert through the capability, and per type on each draw from the network
Max Extract0 or more4000Most lumen given out per action, including to an Astral Sorcery device that draws from the machine
Provide To NetworkonJoin the lumen network as a source
Draw From NetworkoffPull lumen in from the network, the way an altar does
Draw Interval1–1200 ticks20How often to draw
Transfer ParticlesonShow Astral Sorcery's transfer effect along the chain when drawing
Recipe Handler IOINSet it to BOTH or OUT for recipes that output lumen
Capability IOPer sideBOTHWhat other mods may insert or extract through ILumenHandler.BLOCK on each side. internal is the side the lumen network uses

The machine's own recipes ignore Max Receive and Max Extract. Lumen Types only gates what goes in: lumen already stored stays, and can still be spent, after its type leaves the list. Lowering Capacity throws away whatever no longer fits.

Connecting it to the lumen network ​

Lumen does not go through pipes. Astral Sorcery keeps a network of nodes: sources such as Lumen Arrays offer lumen, devices such as altars and Lumen Crystallizers request it, and Lumen Filaments pass a request on. A request reaches a node up to 16 blocks away when nothing blocks the view between the two; a chain of filaments, each able to see the next, carries it further.

To feed the machine from Astral Sorcery:

  1. List the types it needs in Lumen Types and turn on Draw From Network. With an empty list it draws nothing.
  2. Place the machine within 16 blocks of a Lumen Array with a clear view between them, or bridge the gap with Lumen Filaments.
  3. Every Draw Interval ticks the machine asks for each listed type and takes up to Max Receive of it, as far as its buffer has room.

To let Astral Sorcery devices use the machine's lumen, leave Provide To Network on. The machine offers every type it holds, and a device in reach takes at most Max Extract per request. The network drains through the internal capability IO side: set that to IN or NONE and the machine offers nothing.

With both on, the machine does not offer the types listed in Lumen Types, so two machines drawing the same type never pass it back and forth. A type it only produces in recipes, and does not list, is still offered.

The machine checks its node every 20 ticks, so a newly placed machine or a changed setting takes up to a second to show on the network. Breaking the machine removes its node. With Provide To Network off the machine has no node at all, and drawing then requests from its position, with the same reach.

Starlight receiver ​

MBD2 inspector for the Astral Starlight Receiver trait: the common trait fields from Name to Recipe Logics, then Capacity 1000 and a collapsed Constellations list
`astral_starlight_receiver` at its defaults: a starlight buffer per constellation, with no capability IO. Astral Sorcery stores no starlight, so this buffer is what lets a recipe cost a fixed amount.
SettingRangeDefaultMeaning
Capacity1 or more1000How much starlight of each constellation the machine keeps. A Starlight Focus Crystal gives roughly 1 to 2.5 per tick before relay losses
ConstellationsConstellation IDsemptyWhich constellations' starlight is kept; empty keeps all. The rest is discarded on arrival
Recipe Handler IOINLeave it on IN or BOTH: starlight is only ever an input

The trait has no capability IO and no auto IO. Starlight only comes in over a link from Astral Sorcery's starlight network.

Sending starlight to the machine ​

  1. Build a Starlight Focus Crystal as Astral Sorcery's tome describes. It gives starlight of its own constellation by night while that constellation is in the sky, and nothing on other nights.
  2. With the Linking Tool, right-click the focus crystal, a Lens or a Prism, then right-click the machine. A link spans at most 16 blocks and needs a clear line of sight. Relay further with Lenses (one outgoing link each) and Prisms (several, the flow shared evenly). Every relay made from an impure crystal loses part of the flow.
  3. The machine registers itself as an mbd2:machine_starlight_receiver node within 20 ticks of loading, replacing any node a previous block left at its position. A link made to it before then starts delivering at that point.
  4. Every tick, what arrives goes into the buffer of its constellation, up to Capacity. The machine's chunk has to be loaded.

A recipe that asks for starlight of any constellation takes it from the fullest constellation first, then from the next.

Researcher ​

astral_researcher has one setting, Refresh Interval (1–12000 ticks, default 100).

MBD2 machines have no owner, so this trait binds the machine to the player who places it and keeps a snapshot of that player's Astral Sorcery progress: research tier, attuned constellation and discovered constellations. The astral_research condition reads that snapshot.

  • While the player is online, the snapshot is re-read every Refresh Interval ticks and every time an astral_research condition is checked. While they are offline, the last snapshot counts.
  • A machine placed by a fake player, a command or a structure stays unbound, and its astral_research recipes never run. A script can bind it with the trait's bindTo(player), which takes a server player; MBD2 keeps a binding a script made in MBDMachineEvents.onPlaced.
  • With Keep data on drop on, the binding travels with the machine item: the machine keeps its first researcher whoever places it next.
  • On a multiblock, the condition finds the trait on the controller or on a part.

Conditions ​

MBD2 inspector for an Astral Constellation condition with reverse unchecked, Constellation set to Armara and Min Distribution 0.5
An Astral Constellation condition: Armara must be in the sky with a distribution of at least 0.5. The constellation picker searches both IDs and display names.
ConditionEditor nameSettingsPasses when
astral_constellationAstral ConstellationConstellation (default Armara); Min Distribution, 0–1 (default 0)The constellation is active in the sky of the machine's dimension, with a distribution of at least Min Distribution
astral_celestial_eventAstral EclipseEvent: Solar Eclipse or Lunar Eclipse (default Solar Eclipse); Whole Day (default off)The eclipse is happening; with Whole Day, at any time on the day it falls on
astral_researchAstral ResearchMin Tier: Shimmer, Illumination, Resonance, Luminance or Radiance (default Shimmer); Attuned To (default any); Discovered (default any)The machine's researcher has reached Min Tier, is attuned to Attuned To and has discovered Discovered
  • Astral Sorcery picks the active constellations once per day, so astral_constellation passes all day long. Add the day_time condition set to night for "while it is in the night sky".
  • Min Distribution is the 0-to-1 weight Astral Sorcery gives an active constellation, the same multiplier a focus crystal's output is scaled by. 0 accepts any active one.
  • astral_research never passes on a machine without an astral_researcher trait, or with one that is not bound.
  • Conditions only look and spend nothing. They are re-checked every tick while a recipe runs, so the recipe waits when its constellation leaves the sky or the eclipse ends.
  • As with every condition, reverse inverts the test, and conditions of the same type are combined with OR: two astral_constellation conditions pass when either constellation is up. See the condition reference.

KubeJS ​

js
ServerEvents.recipes(event => {
  // spend Aevitas lumen and Armara starlight, give back Vicio lumen
  event.recipes.example.starlit_infuser()
    .id('example:starlit_amethyst')
    .duration(200)
    .inputLumen('500x astralsorcery:aevitas')
    .inputStarlight('100x astralsorcery:armara')
    .inputItems('minecraft:quartz')
    .outputItems('minecraft:amethyst_shard')
    .outputLumen('250x vicio')

  // starlight of any constellation, every working tick
  event.recipes.example.starlit_infuser()
    .id('example:starlit_glowstone')
    .duration(100)
    .perTick(r => r.inputStarlight('0.5'))
    .inputItems('minecraft:redstone')
    .outputItems('minecraft:glowstone_dust')
})
MethodEach argumentAmount when left out
inputLumen(...), outputLumen(...)'500x astralsorcery:aevitas', 'astralsorcery:aevitas' or 'aevitas'500, one flask
inputStarlight(...)'100' for any constellation, '100x astralsorcery:armara' or 'armara'100

The namespace defaults to astralsorcery, and the x is followed by a space. Lumen amounts are whole numbers. An amount of zero or less, or an ID that names no lumen or constellation, throws when the recipe script runs. There is no outputStarlight. Keep a per-tick starlight cost below what the lenses deliver, or the buffer runs dry and the recipe waits.

js
ServerEvents.recipes(event => {
  event.recipes.example.starlit_infuser()
    .id('example:eclipse_infusion')
    .duration(200)
    .astralConstellationCondition('armara', 0.5)          // constellation, min distribution 0 to 1
    .dayTime(false)                                        // only at night
    .astralCelestialEventCondition('lunar_eclipse', true)  // 'solar_eclipse' or 'lunar_eclipse', whole day
    .astralResearchCondition('resonance', 'armara', '')    // min tier, attuned to, discovered; '' for any
    .inputStarlight('100x armara')
    .inputItems('minecraft:diamond')
    .outputItems('minecraft:nether_star')
})

Tier names are shimmer, illumination, resonance, luminance and radiance; tier and event names ignore case. Pass all three arguments to astralResearchCondition.

Every method above throws when Astral Sorcery is not installed. In a pack where it is optional, wrap these recipes in Platform.isLoaded('astralsorcery').

Machine UI and recipe viewers ​

Astral trait bars in an MBD2 machine UI: lumen bars for Aevitas at 1200/4000, Armara at 300/4000 and Vicio at 0/4000, starlight bars for Aevitas at 0/1000 and Armara at 42.50/1000, then a researcher label reading Dev · Shimmer
The generated bars of a machine with all three traits, in game. Every listed lumen type and constellation gets a bar in its own colour, empty ones included; the last row is the researcher's name and tier.

All three traits generate UI with a BAR layout:

  • Lumen storage: one bar per type in Lumen Types, or per stored type when the list is empty, showing amount/capacity; a single grey bar when there is nothing to show. A type still held after it left the list keeps its bar. Hover a bar for the full text.
  • Starlight receiver: the same per constellation, with fractions shown to two decimals.
  • Researcher: the bound player's name and research tier, or No researcher bound.

The bars are built at runtime from the trait's data, not saved in the UI template, so they follow what the machine holds.

In recipe viewers, lumen shows as the lumen's icon with an amount and name in its colour, such as -500 Aevitas. Starlight shows a star in the constellation's colour; its tooltip has the full text, such as -100 Starlight of Armara. A per-tick content adds /t.

Runtime values ​

These settings can be overridden per placed machine as runtime values:

TraitKeys
astral_lumen_storagecapacity, lumen_types, max_receive, max_extract, provide_to_network, draw_from_network, draw_interval
astral_starlight_receivercapacity, constellations

Transfer Particles and the researcher's Refresh Interval are not overridable.

Failure checklist ​

  • Traits or capabilities missing from the editor: Astral Sorcery was absent during registry discovery, or it did not load. Astral Sorcery 2.0.3 needs Curios 9.5.1 or newer.
  • A recipe with outputLumen never starts: the trait's Recipe Handler IO is still IN, the output type is not in Lumen Types, or that type's buffer is full.
  • The machine never draws lumen: Lumen Types is empty, no source holding that type is within 16 blocks and in sight, or Max Receive is 0.
  • Astral Sorcery devices ignore the machine's lumen: Provide To Network is off, the internal capability IO does not allow output, or the type is listed in Lumen Types while Draw From Network is on.
  • The starlight bar stays empty: nothing is linked to the machine, it is day, the focus crystal's constellation is not in the sky, something blocks a link, or Constellations leaves that constellation out.
  • Starlight as a recipe output: not possible, nothing accepts it.
  • An astral_research recipe never runs: the machine has no astral_researcher trait, it was placed by a fake player or a command, or the researcher has not reached Min Tier.
  • astral_constellation passes during the day: expected, add day_time.
  • Cannot add a second trait of the same kind: expected, each is limited to one per machine.

Released under the MIT License.