It's possible multiple soaking ABMs are registered
against a single node, and if this happens, make sure
that the qty and time fields in the cache are kept
separate the same way they are in the node meta.
- Removes repeating patterns, creates a richer and
fuller sound experience
- Larger areas fill sound volume out better instead of
just repeating more loudly
- Spread network traffic across multiple ticks better
to reduce packet spikes
Each node position has a set delay, between 0 and 1
second, that's fixed for that pos but varies more or
less randomly between positions. This ensures that
sounds loop with the same frequency and alignment
for a given single node, but desync across nodes.
Instead of queueing inverted ABMs and then running
them out-of-band, run them inside the normal ABM
schedule time. This should:
- Prevent ABM mux lookup problems caused by nodes
changing after a delayed inverted ABM schedule and
the action actually running
- Allow the ABM scheduler to better account for the
time spent running inverted ABM actions, to ensure
that they properly count against the default 0.2s
ABM runtime budget and can't spike lag up higher.
Ensure that when meta is implicitly cleared by node replacement,
the cache doesn't keep an old copy and fast-forward through
soaking recipes if the old node is re-replaced later
This was triggering on all dirt nodes everywhere, so optimize the
most common code path, i.e. one where there is no water above
and the soaking data must be reset.
- Store next runtime instead of countdown, so metadata always has
one canonical representation for a given target time, allowing
us to more easily avoid rewriting the same data with different
representation.
- Tons of caching and duplicate write avoidance, reduced resetting
of node timers, and MT API calls in general.
- Unify logic for expanding nodenames/itemnames lists into indexes
of matching names, and comparing item names/defs to lists,
with group expansion and deferral.
- Add "autostart" option to DNTs which registers construction traps
and a patrol ABM automatically, use for some things that are a
good match.
- Note that some things are doing more complex logic in ABMs, such
as determining if a node is eligible, or custom timing logic;
leave these as-is for now.
- New fluid wandering API, mostly unified logic, only needs
some parameters, plus the "generation check".
- More sophisticated behavior seeking down-slopes beyond simple
immediate flowing node reach ("subtle slope" detection).
- More reliable timing using DNTs.
- Set firm movement rate of concrete, molten glass.
- Reduce molten glass generations, since it can now be more
reliably directed.
Soaking recipe fails will result in a lot of clearing
of old soaking values out of node meta, which is
very slow in the common case of e.g. dirt that's
not near water and thus should not be soaking in
the first place.
Skip node meta writes if the node meta already
contains the correct data, by doing a cached read
and check before writing, instead of blindly
writing.
This speeds up performance of soaking API by
quite a lot, especially in the more or less
pathological case of soaking dirt to sand, which
involves clearing the metadata from thousands
of nodes each run. Knowing that the nodes
had already had their metadata cleared is
very helpful.
The idea is to unify cement and glass flowing, plus
add additional features: if there is no available
space, try to find the nearest dropoff to wander
toward even if flows can't actually reach it (assume
that the terrain subtly slopes that way).
This was apparently causing sand not to cook if it
had another sand node on top of it, because the
inverted cooking ABM would detect the top sand
node only and not process the cook check for the
lower one.
This is useful when we want to perform an
action on a commonly-occuring node (like
sand or item stacks) with a requirement of
a neighbor of a less common node type (like
igniters). Checking for B with A nearby can
be a lot faster than A with B nearby if B is
less common, so fewer neighbor checks
actually need to happen.
This was already done "manually" for the
flammable/igniter interaction, but now this is
a general API for all ABMs, that allows the
inversion to be done nearly transparently
with just a flag in the definition, and so the
ABM rules can be written more simply, with
the inversion handled elsewhere.
TODO: Rewrite current manual-inversions,
including the ones for flammable/igniter and
lava/stone hardening/softening.
See if this helps smooth out performance
issues in 5.3+. It was never confirmed to
increase the number of ABMs we were able
to successfully process anyway.