Every sound in the game (and all known mods for
it) should play either at a specific location, to a
specific player (e.g. chat beeps or notifications),
or bound to a specific physical object. Detect any
that might be played globally by accident, e.g.
like a bug that existed in NC ZipRunes for a while,
to aid in debugging.
TurkeyMcMac's JIT Profiler mod provides much
better performance data anyway, and these
ABM stats haven't pointed out any really
useful actionable issues for a while.
Add a centrifugal/centripetal component to door
conveyance when it's on the vertical axis, to
help prevent gravity from immediately undoing
the work.
- Items propelled by the bottom of a door are
also pushed outward.
- Items propelled by the top a door are also
pulled inward, landing atop where the door was.
Door recursion is now always:
- Breadth-first, so paths with fewer door-to-door
interactions always "win".
- Random-ordered within each depth layer, so
there are are no biases in door operation order.
This information is now presented in its
optimal compact form on the About GUI,
so we no longer need the same level of
human-readability for the chat command
and can restore its compatibility for
e.g. script purposes.
It's the light level incident on the rush itself, not
in the space above, that we care about. We also
don't need air above the rush, because there's air
IN the rush node.
This allows e.g. non-sunlight-propagates nodes to
behave like sunlight-propagates ones for purposes
of nametag display.
This should complete the changes necessary to
make NodeCore "darkcore" mode feasible with
true darkness by disabling sunlight_propagates
for air to block moonlight, but still pass optics,
nametags, and radiant heat as if transparent.
Looking into the possibility of making everything
overridable for game-logic purposes by group, it
turned out to be a bit of a nightmare. Also, instead
of overriding them at the "heuristic" layer, it's
probably better to simply allow overriding at the
specific game logic level, e.g. so that multiple
systems that use the same source data for heuristic
purposes can have differing behavior.
- If we fail to get the player name, instead of returning a dummy
object with no privs, defer to the wrapped function without the
cache, to preserve the old behavior.
- Clear cache more aggressively when the player joins or leaves.
This may help ensure that stale cache data doesn't affect things
for too long, and also allow the cache to be GC'd more on servers
with more player turnover.
Instead of caching privs only for the current tick, and only for
NodeCore itself, change the base API to use caching universally,
including for naive mod code. Privs are cached until invalidated
by a change; it's assumed here that the "auth_reload" command
exists in the first place because this kind of caching is allowed
and accounted for, even if it's not actually done by the engine
or builtin.
- Clear the cached timer when the timer has fired.
- Simplify the save-timer-save cycle and just rely
on dnt_timer to do the save, to eliminate
redundant saves.
If the previously set timer is exactly the correct
value for the existing DNT, then don't update/reset
the node timer.
Not sure why this was the way it was before (it
seems like it might have been intentional) but it
caused measurable performance impact, didn't
seem right, and fixing it didn't seem to introduce
new problems in preliminary testing.
Instead of checking to make sure one of the objects
found at a location is the glowing entity (which is
very slow and has to search every object for each
light) just make sure that the entity still exists
(get_pos() does not return nil) and that it's still
within the same node position as before.
This fixes a huge lagspike that was caught on NCC
due to a bunch of dropped glowing lenses.
Don't use the stored pos, which might be at the time of
player login, and thus arbitrarily far from where the player
is now, such that it might never actually be loaded.
- Split "discovery" into 2 stages: a check (to see if
there is even anything new to discover) and a
commit.
- When doing witness checks, check to see if there
is anything to be discovered first, before doing the
more expensive visibility checks. If the player
already knows all the discoveries, then we don't
need to do any of the raycasts.
This should speed up especially pathological cases
like door catapulting, which can cause witnessing to
happen at multiple points, and causes major
slowdowns when multiple players are within the
distance range and facing the correct direction due
to tons of raycasts happening.
Clear the dirty flag after cleaning the cache. In
practice this will probably make no difference
since game logic makes it very likely the cache
would be dirty after every tick anyway, but it's
more correct at least, and MAY reduce lag on
empty servers.
All base-game priv checks should now only
require one priv lookup per player per tick,
except in special cases where a player's privs
changed during that tick.
Apparently accessing player privileges is
weirdly expensive, regardless of whether
get_player_privs or check_player_privs is used,
and because interact privs are checked so
frequently, it adds up to quite a lot (as much as
a third of the playerstep time). Since things
controlled by interact privs are probably safe
to delay for a tick (it won't be toggled very
often), just cache it for the current tick to
mitigate this.
In the future it might make sense to (1) trap
the privilege change calls to invalidate the
cache, and (2) consider doing this for some
other privilege checks.
The problem was pointed out by Josh
(gitlab.com/krazy-j) in merge request !22.
Apparently MT is not very smart about marking
mapblocks dirty to send to clients based on
calling mt.set_node(), i.e. it will mark them
dirty presumptively even if you set the node to
the same value it had already been.
This behavior can be confirmed by registering
an ABM against a common node like grass and
setting action = minetest.set_node. This
causes every mapblock containing that node
to be invalidated every interval, causing a big
spike in the packets received each interval
that you can clearly see on the F5 graph.
Rather than just fixing it for the most easily
observed case (fire checks), add utlity functions
to check this for ALL node change situations,
and apply it more or less universally anywhere
that we are not certain that the node is being
changed and we don't need to worry about the
extra overhead cost of the check.
Note that we don't need a
nodecore.set_loud_check call, as set_loud was
only ever being used already in cases where
we were pretty sure we were actually changing
a node.
- Smoke API uses expandable options param instead of positional
- Separate burst qty from automatically adjusted rate
- Backward compat with old API for now
- Standardize burst of smoke puffs for crafting
- Torches emit small smoke particles at increasing rate as they
start to wear out, to warn players holding them to light another
- Torches now emit a puff of smoke upon snuffing
A single eggcorn that finds itself "forced" into a node
of loose dirt (e.g. by being displaced by a falling loose
dirt node that settles where it was) will become a
sprout.