#optimizing my tick function

1 messages · Page 1 of 1 (latest)

verbal arrow
#

my datapack doesn't feature much custom functionality (my tick function only has 40 lines) and mostly utilizes vanilla mechanics. nevertheless, i experience poor performance. i am not a beginner datapacker, but i am a beginner when it comes to optimization - is there anything here that sticks out as poorly-optimized?

verbal arrow
#

my apologies for the file attachment instead of text btw - cant fit the whole text into a discord message

alpine lily
#

in this case it would convert to a message.txt, but that file format is slightly easier to work with. what version is this pack for?

verbal arrow
#

this is for 1.21.11

alpine lily
#

you're using a lot of nbt selectors and other data tests, which are massively unperformant and should be avoided wherever alternatives exist. a couple of your nbt tests don't have an alternative so for those cases i can only recommend trying to find a way to limit how often they run. but mostly i see things that can easily be moved to better triggers, e.g. all the nbt tests you're using under the "Effects of chemical weapons and swarm spear" section can be done better using an advancement or a custom enchantment
but you're also using a lot of if data tests to check for items, which can just be replaced with if items checks, and a few nbt selectors also testing for specific items which can be replaced with predicates (or the command slightly modified to use if items as well)
for your end teleportation effect, you'd want to do something more like execute in <dimension> as @a[x=0] at @s if entity @s[y=<target height>,dx=0,dy=0,dz=0] run ...

#

note the x=0 in that selector is a simple way to limit it to only checking the same dimension as the command is executed in
(i feel like that example can be cleaned up slightly, but the specifics are eluding me atm. hopefully the logic is clear regardless)

#

i see a few other nbt tests that can be replaced directly with predicates, and i see you do have at least one predicate already so presumably you're already somewhat familiar; regardless i'll recommend misodes generator if you're not already using it

verbal arrow
#

is there a way to implement a custom enchantment that doesnt interact with the game how enchantments typically do (e.g. barring enchanting table use, being removed by grindstones, etc)

alpine lily
#

you can prevent a custom enchantment being removed by grindstones by adding it to the curse enchantment tag, but there's no real way to let it still be enchanted in the enchanting table unfortunately

verbal arrow
#

thats unfortunate

#

in that case i think i'll work to implement advancements wherever i can

#

checking for and removing advancements isn't a performance burden i hope?

#

also fwiw the performance issues i face are relatively persistent and don't spike when, for example, using the weapons described

alpine lily
#

that's because the tests are all running constantly, and serializing nbt on presumably many, many entities regardless of anything you do. i'm not sure what entities are excluded by type=!#survivedesert:non_motile but everything that isn't (as well as every arrow multiple times, every player at least four times for just your end teleportation functions, etc.) is getting tested every tick
advancements can run functions directly, so you don't generally need to check for them. broadly it's better to run triggered events through advancements since you can save on checks being run every tick this way

#

(though note that something like a tick advancement which is just always granted is basically the same as testing in the tick function directly, so a tick advancement that revokes itself immediately is slightly worse than a tick function test if for no other reason than the slight overhead from the advancement revoke command)

spare jetty
#

If there is stuff that doesn't have to be checked every 0.05 seconds you could also make your own scheduled loop that doesn't do a check each tick.

You can also do some profiling to see which parts consume most resources.

verbal arrow
verbal arrow
#

and non_motile isnt huge - its a tag for non-living entities like boats, item frames, arrows, etc

#

so I can avoid testing items and such for tests that only should affect mobs

alpine lily
#

most data is not stored or written in the nbt format regularly, so essentially every nbt check first has to convert the data from that format to the nbt format. this process is slow, and gets slower the more data the entity has (so players in particular tend to be really bad, as their data includes things like every recipe they know, every advancement they have, etc.)

alpine lily
verbal arrow
#

oy vey alright, good to know

#

is there any way to serialize those entities' nbt a single time and work from there?

alpine lily
#

you should start with trimming down cases where you need nbt at all in the ways i've described above. from what i saw you should be able to mostly avoid it outright

verbal arrow
#

that makes sense, I figure a lot can be done with advancement triggers

alpine lily
#

a fair bit, yeah. mostly you'll be looking at the if items and predicates changes here
(but in any case where you actually did need to test/use the same entities data multiple times in a row, a common trick is to copy it to a storage: storages are always stored in nbt, so you don't have to worry about serialization with them)

spare jetty
#

you can also try to first do the checks that eliminate most entity matches, and to the more expensive nbt check after the list is shorter.

verbal arrow
#

would a tag check a la @e[type=item,tag=!dsitemcleared] cause nbts to be serialized? or are tags store differently

spare jetty
#

tags are handled more efficiently

#

put the type check at the end

#

if you want to really optimize TheSalt made a vscode extension that gives hints/warns when things might not be optimized

#

sometimes you can't do things and have to ignore the hints/warns

#

but it does help

verbal arrow
#

this is a great extension, ty

#

i've been using notepad++ up until now and vs code's linting is a breath of fresh air

#

btw, what's the x, y, z, or distance warning about

#

wouldnt that limit command execution to the overworld?

alpine lily
#

it does, yes. and technically that helps with optimization, but there's plenty of cases where you don't want it to be limited to the same dimension. i haven't used that extension so i'm not sure if there's any way to ignore warnings like that

spare jetty
# verbal arrow btw, what's the x, y, z, or distance warning about

in your case you can ignore those, if you have nothing that can be constrained to x,y,z just add the line # warn-off-file rule-id target-selector-no-dimension at the top of your file.

If it is only some lines you can do # warn-off rule-id target-selector-no-dimension

#

its all on the docs of the extension

verbal arrow
#

oh perfect!

#

thank yall so much for the help, optimization is going swell