# Utils

Util Widgets provide a complete solution that Minecraft does not support that easily out of the box and make your workflow easier and faster. They are often generating packs, scoreboards and files themselves.

# Timeout

A Timeout is a simple delay in your code. It is done with the Schedule Command and generates a File under the hood.

constructor
String the name of the timeout(used as filename)
children the content that should be delayed
ticks the delay as Time object
path the folder path(optional, default = "timers")

Example:

Timeout(
	"timeout1",
	children: [Say("Timeout reached")],
	ticks: 100.ticks
)
⇒ schedule function example:timers/timeout1 100t
// timers/timeout1:
⇒ say Timeout reached

# Timer

A Timer is very similar to a Timeout, but instead of delaying the code it is run over and over again always delayed by the ticks. In the end it creates a loop with slower tick speed as 20t/s to perform some operations more performant.

constructor
String the name of the timeout(used as filename)
children the content that should be delayed
ticks the delay as Time object
infinite should it run infinitely? (default = true)
path the folder path(optional, default = "timers")

Example:

Timer(
	"timer1",
	children: [Say("Timer reached")],
	ticks: 2.minutes
)
⇒ function example:timers/timer1
// timers/timer1:
⇒ say Timer reached
⇒ schedule function example:timers/timer1 100t

It is recommended to start these timers in your load function.

With a finite timer, you can also stop the timer with Timer.stop:

Timer(
	"timer2",
	infinite:false,
	children: [Say("Timer reached")],
	ticks: 10
)
Timer.stop("timer2")

This uses a tag internally to stop scheduling the next timeout if the tag is existing.

# Repeat

The Repeat Widget repeats a given action multiple times with a tick delay.

constructor
String name of the Repeat
child the action to perform(required)
to times to repeat(required)
ticks time between repetitions(default = 1 tick)
path where to generate a new repeat file(default = timers)
counter the objective used to hold the current iteration(default = objd_repeat)

Example:

Repeat("repeat1",
	to:  10,
	child:  Log("test"),
	ticks:  20.ticks
)
⇒ scoreboard players set repeat1 objd_repeat 0
⇒ function mypack:timers/repeat1

This would save the current iteration in a fake player repeat1 in objd_repeat and generate a schedule function:

# timers/repeat1
tellraw @a [{"text":"Console > ","color":"dark_aqua"},{"text":"test"}]
scoreboard players add repeat1 objd_repeat 1
execute if score repeat1 objd_repeat matches ..10 run schedule function mypack:timers/repeat1  20t

This function is executed until the score becomes 11.

# ArmorStand

An armorstand wraps the Summon Widget with special properties for an ArmorStand.

constructor
Location the location as type Location(default Location.here())
invisible bool
marker bool
basePlate bool
hasArms bool
mainHand An Item placed in the main hand
offHand An Item placed in the offhand
head An Item placed in the head slot
chest An Item placed in the chest slot
legs An Item placed in the legs slot
boots An Item placed in the boots slot
pose A Pose describing rotations of all body parts
... all properties from Summon

Pose

Pose
head List of double values for the rotation
body same...
lleg same...
rleg same...
larm same...
rarm same...

On an existing pose, you can also get a new pose from an existing one with setHead, setBody, setLegs and setArms

This generates a summon command:

ArmorStand(
Location.here(),
name:  TextComponent("Test", color:  Color.DarkPurple),
nameVisible:  true,
marker:  true,
mainHand:  Item(Items.clock),
)
⇒ summon armor_stand ~  ~  ~  {"Marker":1,"HandItems":[{"id":"minecraft:clock"},{}],"CustomName":"{\"text\":\"Test\",\"color\":\"dark_purple\"}","CustomNameVisible":1}

Often times you need a static armorstand that just acts as a marker for a location, there is ArmorStand.staticMarker that sets properties automatically.

ArmorStand.staticMarker(Location.glob(),tags:["experimental"])
⇒ summon armor_stand 0  0  0  {"Marker":1,"Invisible":1,"Invulnerable":1,"NoGravity":1,"Tags":["experimental"]}

# AreaEffectCloud

An areaeffectcloud can be created with the Summon Widget, but there is also a specific Widget with special properties for an AreaEffectCloud.

constructor
Location the location as type Location(default Location.here())
name a TextComponent respresenting the name of the entity
age int
radius the radius an effect applies
applicationDelay int
tags List of tags
duration int
waitTime int
nbt additional nbt as Map

This would create an Areaeffectcloud that only lasts the current tick:

AreaEffectCloud(
	Location.here(),
	name: TextComponent("myname"),
	waitTime: 10,
)
⇒ summon area_effect_cloud ~  ~  ~  {"WaitTime":10,"CustomName":"{\"text\":\"myname\"}"}

To keep the entity alive there isAreaEffectCloud.persistent that sets the age to multiple years.

AreaEffectCloud.persistent
Location the location as type Location(default Location.here())
name a TextComponent respresenting the name of the entity
radius the radius an effect applies
applicationDelay int
tags List of tags
nbt additional nbt as Map

Example:

AreaEffectCloud.persistent(Location.here(),tags:["new_tag"])
⇒ summon area_effect_cloud ~  ~  ~  {"Duration":-1,"WaitTime":-2147483648,"Tags":["new_tag"],"Age":-2147483648}

# Marker

Added in Minecraft 1.17 this entity only exists serversides and thus has no performance constraints for the client. Best used to save locations and even custom nbt data with the data field.

Marker
Location the location as type Location(default Location.here())
tags List of tags
nbt additional nbt as Map
data custom data to store(will just be added to nbt data field)

Example:

Marker(Location.here(),tags:["new_tag"],data: {'custom': 1})
⇒ summon marker ~  ~  ~  {Tags:["new_tag"],data: {custom: 1}}

Tip: you can also use Entity.Marker() to make it easier to select these markers(generates @e[type=minecraft:marker])

# Interaction

Spawns an interaction entity. Can be used to detect player left/right clicks efficiently.

Interaction
Location the location as type Location(default Location.here())
height double denoting the height in blocks (optional)
width double denoting the width in blocks (optional)
response if true, the player shows animations (optional)
tags List of tags
nbt additional nbt as Map

Example:

Interaction(Location.here(),height: 2, width: 5)
⇒ summon minecraft:interaction ~  ~  ~  {width: 5.0d, height: 2.0d}

In your tick function, you can use .onInteract() or .onAttack to detect the interaction. This uses the execute on command, and removes the interaction nbt data if present:

final i = Interaction(Location.here(),height: 2, width: 5)
i.onInteract(select: i.select(limit:1).sort(Sort.nearest), run: [Say('clicked')])

Note: it might be more efficient to do this with Advancements.

# Display

Spawns an diplay entity used to display and animate text, items and blocks in the world, having the following common fields.

Display.[item| block | text ]
interpolationDuration Time denoting the duration for the interpolation (optional)
startInterpolation Time denoting when to start the animation (optional)
shadowRadius double size of the shadow (optional)
shadowStrength double strength of the shadow (optional)
viewRange range from which entity is visible (optional)
billboardType BillbordType.fixed(fixed location), BillbordType.horizontal(rotates horizontally facing the camera) or BillbordType.center(always faces the camera) (optional)
transformation a Transformation object describing the scale, rotation and translation of the display (optional)
tags List of tags(optional)
nbt additional nbt as Map (optional)
Display.item
Location the location to spawn at
Item the item to show
itemDisplay type of ItemDisplay to use (eg ItemDisplay.ground. Itemdisplay.gui...)
... any common properties from above
Display.block
Location the location to spawn at
Block the block to show
... any common properties from above
Display.text
Location the location to spawn at
TextComponent the text to show
alignment a TextAlignment object aligning the text (TextAlignment.left, TextAlignment.center or TextAlignment.right)
textOpacity Alpha value of rendered text. Alpha value is from 0 to 255. (optional)
seeThrough Whether the text is visible through blocks(optional)
line_width Maximum line width used to split lines(optional)
... any common properties from above

# Transformation

An object describing the scale, rotation and translation of a display entity.

constructor
right_rotation Rotation after scaling, tuple with x,y,z components (default 0,0,0)
left_rotation Rotation before scaling, tuple with x,y,z components (default 0,0,0)
scale scaling(1 being one block), tuple with x,y,z components (default 1,1,1)
translation translation, shifting the display tuple with x,y,z components (default 0,0,0)

There are also Transformation.scale, .translate, .rotate with which you can change one property at a time. Transformation.scaleAll takes one double and scales uniformly. Transformation.centered has the same effect as the default constructor, but automatically calculates the translation, such that the entity stays centered when scaled.

# Animations

To animate a display entity, you can use the static method Display.animate. Given the entity to animate, duration, start time, and animatable fields, this constructs a data command.

Display.animate
Entity Display entity to animate
Time duration of the animation
start time to wait until animation starts(default=0t)
shadowRadius double size of the shadow (optional)
shadowStrength double strength of the shadow (optional)
transformation a Transformation object describing the scale, rotation and translation of the display (optional)
textOpacity Alpha value of rendered text. Alpha value is from 0 to 255. (optional)

You can also use Display.set with the same properties to omit the animation duration.

Example:

Display.animate(
	Entity(type: Entities.item_display),
	10.seconds,
	textOpacity: 50,
	transformation: Transformation.centered(
		scale: (2, 2, 2),
	),
),
⇒ data merge entity [type=minecraft:item_display] {interpolation_duration:200,start_interpolation:0,textOpacity:50,transformation:{right_rotation:[0.0d,0.0d,0.0d,1.0d],left_rotation:[0.0d,0.0d,0.0d,1.0d],scale:[2.0d,2.0d,2.0d],translation:[-1.0d,-1.0d,-1.0d]}}

# Hologram

A Hologram shows a floating text at a specific Location using Armorstands. Note: from version 1.19.4 use Display entities instead.

constructor
String the text to display(can also be multiline string)
location the position(required)
color a Color
tags additional tags for the armorstands
space the space in between the lines(default = 0.25)

Example:

Hologram("""
Hello,
World!
""",
	location:  Location.here(),
	color:Color.Aqua,
)
⇒ summon armor_stand ~  ~0.25  ~  {"Marker":1,"Invisible":1,"CustomName":"{\"text\":\"Hello,\",\"color\":\"aqua\"}","Invulnerable":1,"CustomNameVisible":1,"NoGravity":1,"Tags":["objd_hologram"]}

⇒ summon armor_stand ~  ~  ~  {"Marker":1,"Invisible":1,"CustomName":"{\"text\":\"World!\",\"color\":\"aqua\"}","Invulnerable":1,"CustomNameVisible":1,"NoGravity":1,"Tags":["objd_hologram"]}

If you wish you can also assign each line a seperate TextComponent with Hologram.multiple

Hologram.multiple
List of TextComponents Component for each line
... same as Hologram

# RandomScore

The RandomScore Widget assigns a random value to a score using the UUID of an areaeffectcloud.

constructor
Entity the entity to save the result to
to the max value(required)
from the minimum value(default = 0)
objective The scoreboard objective to save the values(default = objd_random)
targetFileName force a specific file
targetFilePath force a specific folder(other than objd)

Example:

RandomScore(
	Entity.Selected(),
	from: 5
	to:  100,
	targetFileName:  "random"
)
⇒ scoreboard players set #max objd_random 96
⇒ function mypack:objd/random
⇒ scoreboard players add  objd_random 5
# objd/random1
summon area_effect_cloud ~ ~ ~ {"Tags":["objd_random"]}
execute store result score @s objd_random run data get entity @e[tag=objd_random,sort=nearest,limit=1] UUIDMost 0.0000000001
scoreboard players operation @s objd_random %= #max objd_random

# Storage

The Storage Widget gives you easy tools to store and recieve nbt data globally. A Store takes in a name, by default it already uses the current pack namespace.

constructor
String name
autoNamespace bool wheater to include the namespace automatically(default = true)

Example:

var storage = Storage("mystorage",autoNamespace:true)

Or you can directly use named constructors to modify data.

# Storage.set

Here you can set one key to a specific value.

Storage.set
... same as constructor
key the Nbt key(String)
value a List, Map, String, Number or Boolean

Example:

Storage.set("mystorage",key: "test",value:5)
⇒ data merge storage example:mystorage {"test":5}

# Storage.merge

But of course you can also insert a Map with multiple keys and values.

Storage.merge
... same as constructor
nbt the Nbt Data as Map

# Storage.get

To get a value back, use Storage.get.

Storage.get
... same as constructor
path the path of the data(String)
scale the double scale for numbers

# Storage.remove

Removes certain Nbt Data.

Storage.remove
... same as constructor
key the path of the data(String)

# Storage.modify

Modifies Nbt Data(look at Data Widget).

Storage.modify
... same as constructor
modify a DataModify Object

# Storage.copyData

Copies Nbt Data from a Data.get Widget.

Storage.copyData
... same as constructor
data a Data Object to copy from
key the path to copy the data into

# Storage.copyScore

Similar to copyData is copyScore which copies the value of a score into a nbt path.

Storage.copyScore
... same as constructor
score a Score Object to copy from
key the path to copy the data into
scale the scale of the new data(optional)
datatype the datatype that the number should take

# Methods

All the constructors also exist as Methods and like the Score you can modify the created Storage through these.

  • set
  • merge
  • get
  • remove
  • modify
  • copyData
  • copyScore
  • toData (Gives you the corresponding Data Widget)

Check the arguments in your IDE to get more insight into these.

Example:

var storage = Storage("mystorage",autoNamespace:true)

storage.get("key")

storage.copyScore("key",score: Score.fromSelected("score"))

⇒ data get storage example:mystorage key
⇒ execute store result storage mypack:test new byte 1 run scoreboard players get  test

# AroundLocation

Often times you need to check blocks or entities around one Location. AroundLocation utilizes this by using just one build method for all sides:

constructor
double the amount you want to go to each side(required)
build a method requiring one Location argument and returning a Widget(required)
top bool for +y
bottom bool for -y
left boo for +x
right bool for -x
front bool for +z
back bool for -z

Example:

AroundLocation(
	1,
	build: (Location loc){
		return Setblock(Blocks.stone,location:loc)
	}
)
⇒ setblock ~1 ~ ~ stone
⇒ setblock ~-1 ~ ~ stone
⇒ setblock ~ ~1 ~ stone
⇒ setblock ~ ~-1 ~ stone
⇒ setblock ~ ~ ~1 stone
⇒ setblock ~ ~ ~-1 stone

# Raycast

The Raycast Widget is one of the most powerful widgets by giving you many options to configure raytracing in Minecraft. Internally it uses local coordinates, a distance counter and recursion.

constructor
Entity from which entity to go from
onhit a List of Widgets that execute on a hit
max maximum block distance(optional)
step how many steps to go forward each iteration(default = 1)
through a Block or Blocktag with passable Blocks(default = air)
ray a Function with an interface for each iteration(optional)
scoreName option to specify counter score(default = objd_count)

There are a lot of values to play around, but this here would make a fully functioning raycast function:

Raycast(
	Entity.All(),
	onhit: [
		SetBlock(Blocks.sandstone,location:Location.here())
	]
)
⇒ execute as  at  anchored eyes positioned ^  ^  ^ anchored feet run function mypack:objd/ray1
# objd/ray1 file
execute unless block ~ ~ ~ minecraft:air run tag @s add objd_ray_hit
execute unless entity @s[tag=objd_ray_hit] positioned ^ ^ ^1 run function mypack:objd/ray1
execute if entity @s[tag=objd_ray_hit] run function mypack:objd/rayhit1
execute if entity @s[tag=objd_ray_hit] run tag @s remove objd_ray_hit

# objd/rayhit1 file
setblock  ~  ~  ~  minecraft:sandstone

objD takes the hard work and generates the commands based on your inputs.

# Customization

There is the ray argument to give you more control over the ray. Here you can execute Widgets for each step and optionally stop or let the ray hit an obstacle. In Dart this is done with a Function:

Raycast(
	Entity.All(),
	onhit: [
		SetBlock(Blocks.sandstone,location:Location.here())
	],
	ray: (stop, hit){
		return If(...,then:[stop()]);
		// stop and hit are functions as well
		//that can be executed to perform actions
	}
)

Let's also change other inputs:

Raycast(
	Entity.All(),
	onhit: [
		SetBlock(Blocks.sandstone,location:Location.here())
	],
	ray: (stop, hit) => If(...,then:[stop()]),
	max: 10, // set maximum distance to 10 blocks
	step: 0.1,
	through: Block("#minecraft:transparent"),
)
⇒ scoreboard players set  objd_count 0
⇒ execute as  at  anchored eyes positioned ^ ^ ^ anchored feet run function mypack:objd/ray1
# objd/ray1 file
# our blocktag:
execute unless block ~ ~ ~ #minecraft:transparent run tag @s add objd_ray_hit
# the result of the ray function:
execute if ... run tag @s add objd_ray_stop
# our distance increases:
scoreboard players add @s objd_count 1
# command changed depending on our inputs:
execute unless entity @s[tag=objd_ray_hit] unless entity @s[tag=objd_ray_stop] if score @s objd_count matches ..100 positioned ^ ^ ^0.1 run function mypack:objd/ray1
execute if entity @s[tag=objd_ray_hit] run function mypack:objd/rayhit1
execute if entity @s[tag=objd_ray_hit] run tag @s remove objd_ray_hit
tag @s remove objd_ray_stop

# Do Until/While Loop

This Loop repeats a set of widget as long/until a condition is/becomes true. The Loop uses a Grouped File and Recursion to repeat commands.

Do.While
Condition or conditional value a condition to test for each iteration
then a List of Widgets to execute each time
testBefore test before entering the loop if condition is true(optional)

Until just negates the Condition

Example:

Do.Until(Tag("istrue",entity:  Entity.All()),then:[
	Say("repeat")
])
⇒ execute unless entity [tag=istrue] run function  mypack:objd/doloop1
# objd/doloop1 file
say repeat
execute unless entity @a[tag=istrue] run function  mypack:objd/doloop1

# ForEach Loop

The ForEach Loop repeats a set of widgets for each value in a Score. Therefore a file is called recursively and a counter score is increased.

constructor
Score the score to iterate through
then A Function that takes in the count Score
from the initial value for the counter(default = 0)
counter an Entity to hold the count value(default = #objd_foreach)
translate a relative Location applied each step
step how much to increase or decrease the counter each time(default = 1)

Example:

ForEach(
	Score(Entity.All(), "myscore"),
	translate: Location.rel(x:1),
	then: (score) {
		return  Log(score);
	}
)
⇒ scoreboard players set #objd_foreach objd_count 0
⇒ execute if score #objd_foreach objd_count <  myscore run function mypack:objd/foreach2
# objd/foreach2 file
tellraw  @a  [{"text":"Console > ","color":"dark_aqua"},{"score":{"name":"#objd_foreach","objective":"objd_count"}}]
scoreboard players add #objd_foreach objd_count 1
execute if score #objd_foreach objd_count <= @a myscore positioned ~1 ~ ~ run function  mypack:objd/foreach2

# Builder

The Builder Widget embedds a builder function in your Widget Tree. Here you can provide a similar method to the generate method of a Widget. This allows you to define new variables, make calculations and conditions.

constructor
BuilderFunction a Function that takes in the context and returns a Widget.

Example:

Builder(
	(Context context){
		var var1 = 1
		if(true) return Widget()
		return Widget()
	}
)

# ItemBuilder

The ItemBuilder provides an interface to convert a List into Widgets using a Builder. Each Item maps to a new Widget that you return in the build Function.

constructor<T>
items the List of Type T
build the build function, takes in one item(type T) and returns a Widget

Example:

List<String> list = ["hello","world"]
ItemBuilder<String>(
	items: list,
	build: (String item) => Log(item),
)
==> For.of([Log("hello"),Log("world")])

# PassTrait

The PassTrait Functionality allows you to pass data down your widget tree without struggles. Imagine having one unique value in your pack that special widgets below it regarless of their position or parent should know of. The PassTrait Widget injects your value in the Context, allowing you to access it everywhere.

constructor
any a value that you would like to pass down
child The underlying widget tree(required)
PassTrait(
	10.0,
	child: ...
)

In some other Widgets generate function you can retrieve the value by using PassTrait.of now. The values are passed by type, so you can just get one value per type(of course custom classes are also valid):

  
  Widget generate(Context context) {
    var value = PassTrait.of<double>(context); // => 10.0
    return ...;
  }

# StraitWidget

A StraitWidget allows you to build up a List of Widgets inside of a Widget. Like the Builder, you have to provide a Function, which takes in a List and then you can add on to this list.

constructor
Function the strait function that gives you a List of Widgets to modify

Example:

StraitWidget(
	(List<Widget> widgets){
		widgets.add(Command(...))
		...
	}
)

# Queables

StraitWidget supports the RestAction and Entity Queables. Read more about Queables here

# Return Value

It is also possible to return something(Widget, Queable, RestAction, List):

StraitWidget(
	(List<Widget> widgets){
		return Entity.Self().kill()
	}
)
==> kill 

# VersionCheck

Checks whether the player updated or downdated your datapack.

constructor
int the datapacks current version
onDowndate a List of Widgets that are executed if it detects that you have downgraded
onUpdate a List of Widgets that are executed if it detects that you have upgraded
then a Function that takes in the used Score and reacts respectivly returning a Widget(optional)
score change the scores name(optional)

Example:

VersionCheck(
	2,
	onDowndate: [Log('Notice: You installed an older version')],
	onUpdate: [Log('Thank your for updating the pack!')],
)

# ServerVersionCheck

Checks the used Minecraft Version and can give feedback on it(e.g. Errors).

constructor
minVersion the aimed version number as int(1.15 = 15)
versionTooLow a List of Widgets that are executed if it detects that the version is lower that minVersion
then a Function that takes in the used Score and reacts respectivly returning a Widget(optional)
serverVersion change the scores name(optional)

Example:

ServerVersionCheck(
	minVersion: 14,
	versionTooLow: [Log('Please use at least Minecraft Version 1.14')],
	then: (Score s) => ...
)

This methods summons an entity and puts some exclusive items in their inventory to detect the version.

# PlayerJoin

Allows you to specify what should happen if a player joins. This can be triggered every time or just once with PlayerJoin.inital or when rejoining with PlayerJojn.rejoin.

constructor
then A Widget that gets executed by the player that joins
target The targeted player that will throw this event(default = @a)
score The scoreboard that is used(default = objd_join)

This will create a [score] that counts leave_game stats and checks if the player has the [score] thus detecting when a player joins.

Example:

PlayerJoin(
	then: Log('Jesus returned!')
)
=> execute as [scores={objd_join=1..}] run tellraw  [{"text":"Console > ","color":"dark_aqua"},{"text":"Jesus returned!"}]
=> execute as [scores={objd_join=1..}] run scoreboard players set  objd_join 0
PlayerJoin.inital
then A Function accepting a Score that gets executed by the player that joins
target The targeted player that will throw this event(default = @a)
score The scoreboard that is used(default = objd_join)

This gives every player a unique id on join and enables you to do something the first time around with the [score] holding the players id.

Example:

PlayerJoin.initial(
	then: (score) => Log(score)
)

=> scoreboard players add #current objd_join 1
=> tellraw  [{"text":"Console > ","color":"dark_aqua"},{"score":{"name":"#current","objective":"objd_join"}}]
=> scoreboard players operation  objd_join = #current objd_join
PlayerJoin.rejoin
then A Widget that gets executed by the player that joins
target The targeted player that will throw this event(default = @a)
score The scoreboard that is used(default = objd_join)

This will create a [score] that counts leave_game stats and thus detects if a player rejoins.

# Recipe

A Widget used to generate minecrafts json recipes as well as objDs custom recipes. A basic recipe takes in ingredient Items with the slot and a result Item.

Recipe
Map<slot,Item> The ingredients as a Map with the Slot(1 to 9) on the one side and your Item on the other
Item your result Item
name name of your recipe file(default = recipe)
id overrides the automatically generated id(optional)
exactlyPlaced bool that requires to leave all unused slots empty(default = false)
exactResult a number that limits the result count(optional)

Example:

Recipe(
    {
        1: Item(Blocks.oak_planks),
    	2: Item(Blocks.oak_planks),
        4: Item(Blocks.oak_planks),
        5: Item(Blocks.oak_planks),
    },
    Item(Blocks.crafting_table,Count:2,nbt:{'MyNBT':1})
 )

# Recipe.pattern

Want to stay close to the original minecraft notation and want to prove a pattern? You can also do that with:

Recipe.pattern
List<String> Each String of Length 3 represents one row in the crafting grid, use the same char for same items
Map<String,Item> For each used character in the pattern, define a corresponding item
... stays the same

Example:

Recipe(
	[
		'##',
		'##'
	],
	{'#': Item(Blocks.oak_planks)},
    Item(Blocks.crafting_table,Count:2,nbt:{'MyNBT':1})
 )

The API also supports shapeless crafting. That means you can set the ingredients in any shape and it would be the same result.

Recipe.shapeless
List<Item> The ingredients in any shape(without slots)
... stays the same

Example:

Recipe.shapeless(
    [
       Item(Blocks.oak_planks),
       Item(Items.diamond)
    ],
    Item(Items.diamond_sword)
 )

# Recipe.smelting

Since smelting requires just one ingredient, just give it an Item and its result. Futhermore you can change the cooktime and experience gained:

Recipe.smelting
Item The ingredient (without slot)
cooktime The cook time of the recipe in ticks(default = 200)
experience output experience as double(default = 0.1)
type Can be changed to RecipeType.blasting, smoking or campfire_cooking (optional)
... stays the same

# Recipe.smithing

For smithing you can define an additional item on top to the base item:

Recipe.smithing
Item The ingredient
Item result Item
addition additional Item
... stays the same

In case you need to, you can also serialize a recipe to and from json(represented as Map):

Recipe.fromJson(r.toJson());

# InitScore

Initializes a Score to value if not set previously .

constructor
Score the mandatory Score
value the aimed value(default = 1)

Example: (preferably used in a load function)

InitScore(
	Score(Entity.Self(), 'myscore'),
	value: 10,
)
Last Updated: 6/17/2023, 11:39:58 PM