Issues with mergeEntityData and /data merge command
Nemirel345 opened this issue ยท 1 comments
Trying to edit the machine's nbt with commands does nothing.
Using /data get
to read the machine's data works, but using /data merge
to modify the data says it successfully wrote the new data but using /data get
again shows nothing has changed.
The same behaviour is observed using KubeJS event.block.entityData
and event.block.mergeEntityData()
.
Example
My custom machine has a single tank which holds a fluid called kubejs:tree_sap
.
using /data get
on my machine yields
{componentManager:{active:0b,data_component:{},fluids:[{config:{BACK:1b,BOTTOM:1b,FRONT:1b,LEFT:1b,RIGHT:1b,TOP:1b,input:0b,output:0b},id:"sap",stack:{Amount:500,FluidName:"kubejs:tree_sap"}}],fuel:0,maxFuel:0,radius:1},craftingManager:{phase:"ENDING",recipeProgressTime:0.0d,type:"custommachinery:machine"},id:"custommachinery:custom_machine_tile",machineID:"custommachinery:sap_extractor",message:'{"text":"","strikethrough":false,"obfuscated":false,"font":"minecraft:default","bold":false,"italic":false,"underlined":false,"childrens":[]}',status:"idle",x:330,y:142,z:-14}
I want to right-click the machine with an empty bottle and extract 250mb of fluid and get a filled bottle, thus I have the following KubeJS script:
BlockEvents.rightClicked (event => {
switch(event.block.id)
{
case 'kubejs:sap_extractor':
if (event.item == Item.of('minecraft:glass_bottle'))
{
//console.log(event.block.entityData)
var amount = event.block.entityData.componentManager.fluids[0].stack.Amount;
var fluid = event.block.entityData.FluidName;
if (amount >= 250)
{
event.item.count--;
event.block.mergeEntityData({"componentManager.fluids[0].stack.Amount":amount-250});
event.player.giveInHand("kubejs:tree_sap_bottle");
event.cancel()
}
}
break;
default:
break;
}
})
Written differently to replace the entire array at once:
BlockEvents.rightClicked (event => {
switch(event.block.id)
{
case 'kubejs:sap_extractor':
if (event.item == Item.of('minecraft:glass_bottle'))
{
//console.log(event.block.entityData)
var amount = event.block.entityData.componentManager.fluids[0].stack.Amount;
var fluid = event.block.entityData.componentManager.fluids;
if (amount >= 250)
{
fluid[0].stack.Amount = amount-250;
//console.log(fluid);
event.item.count--;
event.block.mergeEntityData({"componentManager.fluids":fluid});
event.player.giveInHand("kubejs:tree_sap_bottle");
event.cancel()
}
}
break;
default:
break;
}
})
While I do get a filled bottle when right-clicking my machine, it doesn't reduce the amount stored inside the tank.
To explore the issue I tried replicating the behaviour using the /data
command, using /data merge
to attempt reducing the fluid in the tank. While /data merge
won't let me modify an array directly, I tried replacing it entirely using /data merge block ~ ~-1 ~ {componentManager.fluids:[{config:{BACK:1b,BOTTOM:1b,FRONT:1b,LEFT:1b,RIGHT:1b,TOP:1b,input:0b,output:0b},id:"sap",stack:{Amount:250,FluidName:"kubejs:tree_sap"}}]}
Hovever, using /data get
again shows the command was ineffective even though the command outputs a success message.
In all cases, we can read the data but not write to it.
You should never manipulate a BlockEntity's nbt, mainly because the nbt doesn't exist when the machine is loaded, only when the chunk containing the machine is saved to disk.
So what you're currently doing is serialize the machine to nbt, modifying it and then loading a new machine from this modified nbt.
This is not only very bad performance wise, but also really prone to issues (like the one you're having).
If you want to interact with the content of a machine use the KubeJS integration :
https://frinn.gitbook.io/custom-machinery-1.19/mod-integrations/kubejs/recipes/function/machine#of
If you need help come to the discord.