#Pathfinding Lag Fix | Pathfinding Lib | Smart Enemy Pathfinding
1 messages · Page 4 of 1
I wouldn't tend to say you should go and rewrite it, since I'll end up having to do that too whenever I get around to making the elevator API
well it's so heavy handed it would absolutely come with a toggle
There's already so many mods that touch the masked, this should be fun
and when that future comes i can design it to work in tandem or just dump it completely if your patch is sufficient
this is the other problem too yeah
yeah I don't really care lmao
they can use the API themselves if they want to
it definitely will solve the problem better than the things I've seen for these types of problems in the past
it's just a lot of work and I have to make sure the API is solid enough to actually not need a rework later
that's the most daunting part
probably should run my idea by you once I revise it actually @crimson jolt
I gotta figure out how to communicate a path to an arbitrary transporter device while giving the API user enough control to animate things how they want
I had talked this through with Matty before and come up with something decent, but it didn't account for entrance teleports, only elevators
hahahahaaa yeeess my chidlren
with the elevator?
feel free to do a prefix cancel
making a transpiler for this would be too much of a pain
thanks Zeekerss
i know there is absolutely no way i can figure it out
you can probably change the flag variable to be whether someone is in the top area of the elevator, but then you also have to hijack isInElevatorStartRoom or create a new variable for whether the masked is also in that top area
but it's a pain
if you wanna set up bounds for that then patching it may be workable
i can get a pretty clean and solid answer for "are they on the same side of the elevator or not"
their wandering behavior is really simple at the heart of it all
if there's a player on the same "layer" as them, they wander randomly
otherwise they travel to where they can find players
all i need to do is probably a version of this function that works for the factories and manors
then write a special version for the mineshafts that considers the elevators and does the bound checks i mentioned, etc.
and then i need to force the masked to not be able to use the elevator unless it is guaranteed to take them closer to where the players are
basically I think the intention was that flag is whether the player is in that top room of the elevator, and same for isInElevatorStartRoom (obviously), so you could just change both of those to bounds checks and it should theoretically work
so they stop going up and down forever
i thought this might be heavy-handed at first, but this is already pretty much how they work in vanilla
if no players are in the building, they "just know" and automatically path straight to the main entrance with no meandering
so zeekerss probably intended the same for the elevator and it just got messy to work out a way to do that
so i pretty much have no qualms just boiling it down to that to absolutely ensure they won't get stuck
anyways all that being said
i definitely am not waiting to do all of this before i release the first version of this plugin
this will be v1.1 work probably
yeah
sounds good
maybe I should beat you to it with the API lol but god I don't look forward to maintaining two APIs for something that might be used so heavily
someone is undoubtedly gonna find holes in it and make me have to make breaking changes
(not that I'm afraid to do that if I have to
)
lol well im maybe not your best consumer anyway
i would be most interested in utilizing it just to ensure compatibility
but i have close-to-zero interest in custom content for lethal company and almost all of my stuff is just designed with fixing/polishing/restoring vanilla concepts
I get to dogfood my API, and I can ensure that people have a single mod to depend on that gives them a way to create any number of elevators
so i would solely be using it to make masked work solely in mineshaft elevators and would probably not be able to provide much testing in other departments
yeah I wouldn't be inclined to do this if I wasn't already in the business of async pathfinding and also creating an elevator in Black Mesa
it's not my idea of a great time but I don't think anyone else is ever gonna do it
and yet everyone wants to make elevators

yeah
wish I wasn't lol
I have so many other things that I've put off for a long while already
ok ive gotta go pull the trigger on 3 separate releases
if im lucky maybe i wont forget to ship the DLL in one of them
this is about to be sort of stressful
be back
probably
good luck
You got this
i can check really quick if nobody has the answer on hand
but is the entrance room always rotated the same way
for a particular interior type
Not sure
yeah I don't actually know either
but whatever the case may be, I would recommend making a list of vertices instead and then transform them to world space by the tile transform, then encompass those in an axis-aligned bounding box
lol i was just going to make a giant boxcollider as a child of the tile, apply a pre-calculated position/scale, calculate bounds, and then delete the object
then maybe i ought to learn me a thing
https://github.com/2394425147/LC_CullFactory/blob/master/CullFactory/Data/Portal.cs#L16-L61
this is kinda in the vein of what you need
only 4 corners here, but you can expand it to 8 no problem
and you can use this to transform them https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Transform.TransformPoints.html
oh i see
so i guess im just defining like
the shape i'd want my box collider to be
basically
and then i am transforming them by the start tile's transform
to get where they'd be in actual world space
if i had gone through all of this
ya
well ok that seems pretty easy
as long as transformpoints accounts for rotation
which i see no reason to assume it wouldnt
it does
then yeah i'll probably do that
it's getting to be pretty late and im probably about to head off
but i already have a skeleton of the new roaming behavior basically done
bool wantsToBeInside = closestInsidePlayer != null && (!maskedAI.isOutside || closestOutsidePlayer == null);
if (wantsToBeInside == maskedAI.isOutside && Time.realtimeSinceStartup - maskedAI.timeAtLastUsingEntrance > 3f)
UseEntrance(maskedAI);
else if (!maskedAI.searchForPlayers.inProgress)
maskedAI.StartSearch(maskedAI.transform.position, maskedAI.searchForPlayers);
this is a snippet
it is so much easier boiled down like this
but tomorrow i need to write the actual meat of UseEntrance which is going to need to sample bounds in mineshafts
and have all the logic to make masked use the elevator
unless i can actually reuse zeekerss' function without issue
we'll have to see
I think UseEntrance just sends the AI to the entrance if it's pathable, so yeah it should work
also sounds good, good night!
oh to clarify UseEntrance is a custom function im going to write with all the pathfinding stuff handled
although i might be able to reuse whatever the vanilla function is, depending
GoEntrance i think it's called?
oh right yeah
but yeah
GoToEntrance
I wasn't looking at the code so I assumed you were talking about duplicating it lol
anyways fun stuff happening but it can wait until the morning
i appreciate the chatter
hope it didnt distract you too much
from this weekend i can probably help you again with that, in case you need :D
yeah, if I have time that definitely wouldn't hurt to run some ideas by you
i had to grow the scope of my AI a bit this morning
because i realized i was making some bad assumptions
but i think this is a really easy way to integrate the elevator into it
UseElevatorIfNeeded immediately returns true if the masked is outside or the elevator does not exist
and then it goes straight into its behavior of "path straight to main entrance, or search for players on this layer"
the idea is that, in a mineshaft, UseElevatorIfNeeded would check:
- where the masked is in the interior
- where the closest player is in the interior (if players are inside)
- if the masked wants to go outside
and then there would be a boolean flag like "needsToUseElevator" that would be set to true if the masked can't reach its goal without using the elevator
if that is the case, it would path straight to the elevator, call it, ride it, etc. do whatever is needed to get it to the other side of the elevator
but it'll be blocked from using the elevator otherwise
@keen ruin i did want to check with you on this since i believe this is what you warned against
in vanilla, masked used to do CalculatePath in v56 before they would path to the main entrance
and if main entrance wasn't reachable, they would wander the interior randomly
i'd like to restore that behavior if it is possible, since i think it's a little less ugly than them getting stuck in place
but iirc CalculatePath was extremely expensive to be calling every frame
or, well, every AI interval
and i thought that's what pathfindinglib was supposed to offer a better alternative for
yeah it is, and I would definitely say it would be nice to make use of it if you have a good place to do so
but it is a little involved to set up
the readme should give you an idea of how to, but there maybe missing info
well im between two places right now
1 is "dont make them calculate path" and leave it as-is, since they dont do it in v60+ and it works mostly fine
2 is "use pathfindinglib to do it the right way"
so im definitely interested
i was just reading that in the meantime
Well what do you consider "the right way"?
not using CalculatePath every AI interval
Well that's definitely the right way yeah lol
if it's expensive, and vanilla masked get away with not doing it, i dont want to add a high performance cost just for this minor feature
hence pathfindinglib or leaving it out
one CalculatePath per interval is far from the worst thing you can do but it's also not ideal
yeah
basically you would have to have a class where you track the status of all jobs you care about, both so you can query them and so you can dispose of them so that PathfindingLib can reclaim memory
in PathfindingLagFix I just have a class wrapping an array that expands to fit all thisEnemyIndex
Depending on how you do it, you can expand on the masked by allowing them to use fire exits too
, but idk if you consider this expansion "bad" since zeekerss just uses main entrance
Though I kinda remember they used fire exits once upon a time
https://github.com/XuuXiaolan/CodeRebirth/tree/main/Plugin/CodeRebirth/src/MiscScripts/PathFinding I think I'm currently the only mod that uses pathfindinglib too, if it helps this is my code, most of it was just me following what zaggy said lol
yeah lol
also that code is set up more for something where you have full control over the AI pathfinding code, so it might not totally fit the use case
but the disposal stuff might be useful if you want to ensure you don't keep data around when it shouldn't be kept
PathfindingLagFix doesn't use any PathfindingLib pools and just maintains its own jobs instead so I can't necessarily say what is best in that regard
anyways i will probably do the pathfindinglib integration in a v1.2 or such
for now i just want to get to the core of the issue with v1.1, replacing the roam state with one that functions 99% of the time
this is something i'd like to allow in the future
probably as a disabled-by-default config
it is going to make my mineshaft behavior a bit tricky though
since right now im making the assumption masked have to use the main entrance, and it helps me keep the "expected elevator behavior" really straightforward and easy
if they can skip the elevator by taking fire exits i need to account for that possibility
and then i would need to decide if i want the masked to do some sort of consideration like "is the closest inside player closer to the fire exit or closer to the elevator"
or if i just want it to be random
etc.
lots of stuff to consider and im not in a hurry to tackle that immediately
Makes sense
For me in my own logic, if I wanna go outside and I'm in mineshaft below elevator, I just prioritise fire exits, and if there's no route with those exits I try to check if there's a route with elevator etc
the pathfinding through fire exits thing is probably gonna be an option in whatever solution I come up with for elevators
would certainly be nice
I'll have to make it so that it can reject certain paths though
wait nvm
they do have it in v60
it was just moved
so i guess i will just make use of calculate path in the meantime
@keen ruin how would you suggest creating the bounds?
should I just create the bounds using the first vertex and a size of 0,0,0
and then feed it all the other vertices using https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Bounds.Encapsulate.html
ah right
it's more efficient to work on the min/max yourself than feed it to the bounds struct, since the underlying fields for that are not min/max but rather center and extents
yea
so if you repeatedly read and set min/max on bounds, it is recalculating it in both directions
yeah
it doesn't have to be super optimized because im just calculating the bounds after the level is done generating and then caching it
but like
i see no reason to do it wrong if i can do it right
basically
yeah
not gonna say you have to do it that way since it will be imperceptible, but the example was there lol
i got it to work
unfortunately
vanilla's behavior uses a lot more PathIntersectedByLineOfSight than i thought
so I had like
4 total CalculatePath calls
i think it only does one per frame, IIRC
with how the logic is laid out
so it's not the worst
but it does seem like it'll be a puzzle to implement pathfindinglib when the time comes
I know this thread is for the path finding mod but is anyone here up to help me debug something?
If its unrelated then #help-and-troubleshooting
Ok thanks
Like you said, this thread is for the pathfinding mod, if you notice vanilla enemies or enemies have been acting super weird with pathing, then you'd ask here, otherwise won't be of much help
this is what i ultimately settled on
i think this is at least clean and easy to read through and understand
there are some performance concerns with CalculatePath() but i got full frames on my computer with 10+ masked
i really only noticed slowdown in stress test scenarios (like the 50 masked elevator queue test)
definitely some room for improvement in the future but for now I'm pretty happy
well, this made it possible for this mod to run smoothly hehe
https://thunderstore.io/c/lethal-company/p/SimonTendo/LCMaskedInfestationMod/
did you check what the frame time consistency was like?
also, using PathfindingLib shouldn't be so bad, you'll probably end up wanting to implement it similarly to PathfindingLagFix
assuming you always only need the status of one path anyway
it just stores an integer representing the current pathfinding operation, and if that changes, it resets the status and keeps whatever destination it had before until the next result is ready
i'll have to take a look at what your original patch is doing
but it calculates paths to several different positions
so it'll probably be a bit more involved than that
each different position happens with a different set of criteria, and iirc im only calculating 1 (maybe 2 sometimes?) paths in the same ai interval
it calculates multiple in one frame?
multiple in a frame is the only reason why it might be an issue
and that is still manageable, it just requires a bit more setup
oh oops
i forgot to add a shortcut for indoor players
or wait no i didnt
okay yeah, currently it calculates a path to each indoor player if the masked itself is also indoors
the path calculation happens last after all the other targetable criteria is checked to try and avoid that as much as possible, but it will still happen in circumstances where the masked is wandering inside and multiple players are inside to target
it looks like under any other circumstances, the masked only calculates one path per frame
if i remember how i set this all up
and didn't make any mistakes
vanilla does GetClosestPlayer
that does path checks?
which, if PlayerIsTargetable is successful, does PathIsIntersectedByLineOfSight
ew
it doesnt actually check the line of sight but it does use that function for CalculatePath
okay well I should be able to patch that
I could've sworn that one omitted the path check but I guess I'll have to look at it
it runs all of this
everything below this is skipped
if im reading this correctly
in my case, i didnt even check the path corners or do the distance check
i just did CalculatePath
so im probably returning slightly different results than vanilla would be
and maybe i ought to patch that
I didn't mean that method, I meant GetClosestPlayer
that method is used all over the place, it's what I'm replacing with my own code wherever possible
i think i must be crazy because i thought i remembered GetClosestPlayer called this function
but i just checked again
and no it doesn't
you will want to do that or you might get some stuttery movement if they try to path too far
I think you must have looked at TargetClosestPlayer then
that is the method that does that
i didn't notice any issues with this while i was testing but i will go ahead and fix it pre-emptively
just in case
anyway
i can actually remove the path check for indoor players then
since vanilla doesn't do it
it just cares if a targetable player is in the building at all, not if the current masked can reach it
and at that point im pretty sure im back to only calculating one path every frame again
im getting a weird lag spike whenever i enter a mineshaft fire exit with an insane amount of masked spawned (~50)
i think it's related to some of the changes i made after publishing the github files because i didn't have this issue before
it was slowing my game to a crawl for about ~3 seconds and then clearing back up
profiler showed a ton of log callbacks, and outside of that, it seems like maskedplayerenemy.update (presumably DoAIInterval) and occludeaudio.update (which is probably also related to the masked, since they have 3 per)
sort of bizarre
by forcing the unity log level not to print anything it cleared up most of the lag but not all of it
it doesn't cause performance issues for me with a reasonable amount of masked (10) but im wondering where this suddenly came up from
if the profiler is just showing LogToConsole you might want to install AsyncLoggers to reduce that
yeah i normally have it disabled on my test profile because it causes logs to get out of order
it collects stack traces always when attached I think
but i do use it in normal games
(unless you change a setting)
im gonna test it again with async to see how much that helps
it's a super weird issue
I think the out of order thing is either less of an issue or not an issue anymore, but Matty would have to confirm
but yeah, I tend not to run it because I like being able to pause the game
it is a terrible lag spike specifically when entering fire exits, only when it's mineshaft, only with masked on the map
huh that's really curious
yeah it mostly goes away with asyncloggers
it's definitely not invisible, but i could stomach a 1 second blip
i assume it has to be worse for anyone running lower spec hardware though
what on earth is happening
definitely shouldn't need to have any delay as far as I'm aware
this is my first time ever using a profiler so i'm maybe not aware of the best practice
huge spike, most of it coming from scripts, which checks out
pretty unsurprisingly, it gets way worse with pathfindinglagfix disabled
oh huh this happens in vanilla too
i disabled my patch and im still getting it
that's a relief but still an oddity
@keen ruin can you publish the PathFindingLib mod on NuGet?
did you manage to see what behaviors are doing it?
no, it didn't go any deeper than MaskedPlayerEnemy.Update
taking up about half as much of that was OccludeAudio.Update
that's what i would need deep profiling or profiling markers for right?
to get more specific information
uhhh I could look into it.. I would have to set up a build system to be at all consistent with that though, and I haven't ever looked at how others have done that
there's a thunderstore source that I just use for everything though
not sure if I can bundle docs into a NuGet package, that feels like the only big benefit over using that source
if anyone has any repos where they have github actions set up to upload to NuGet then I could just adapt that though 
otherwise, I just sent this to giosuel today and you could reference it to get the lib assembly from thunderstore as well
an example of the thunderstore nuget setup is here
https://github.com/Zaggy1024/LC_OpenBodyCams/blob/master/NuGet.Config#L5
and here
https://github.com/Zaggy1024/LC_OpenBodyCams/blob/master/OpenBodyCams/OpenBodyCams.csproj#L33
that nuget from windows10ce is really handy
it should habe been solved in V2. it was one of the issues reported before so i tried to ensure that, at least in the managed listeners ( eg: BepInEx LogOutput.log ) they are printed in the order they are received
and for unity logs i made so asyncloggers doesn't touch it by default, so should be all in order there too
@keen ruin @tardy pivot any idea if you guys can look into getting this error spam fixed
Baboon hawks throwing this with Mimics all the time is so annoying
this isn't a pathfinding thing
yea definitely not
True it's just an error that I see all the time in my logs
and it also would change behavior to fix it, so I am wary of this
would it meaningfully change behavior?
im not even sure how this error is happening in the first place
the masked is probably getting destroyed by some other enemy
i dont understand how the masked can exist where the baboon pings it
but the navmeshagent is null
.velocity doesn't throw nullref if the agent is disabled or something, does it?
one second
Unity's NullReferenceExceptions are very deceptive
they have a MissingReferenceException in editor that I really wish they had hooked up in release
or maybe it's two, MissingReference and something to indicate destruction, I forget
ahh i see, the baboons are caching a threat, i thought this would only apply if they had grabbed the masked on the same frame
no kidding
weird that it throws a nullref on get_velocity if it shouldn't even be able to get a reference to the agent in the first place
is it just weird with interfaces? or does it do this with everything? i've never seen this before
the agent is a managed field, not a native one
Unity can only throw NullReferenceExceptions when you call one of the runtime functions
you can do anything with a destroyed behavior as long as you're not interacting with the runtime
that's why you can still access stuff on your plugins with the BepInEx setting to destroy them after chainloader
it's only confusing because the Unity devs decided it should reuse an exception with a very specific meaning lol
classic Unity
also the behavior change would be that the code could continue execution
yeah im seeing it now
not sure if this is possible to happen in vanilla though, I wouldn't doubt that someone is screwing with something to make this happen
in my mind i thought this was just causing an exception for one frame, then it would resolve itself the next
but since it's a cached value it is going to be persistent yeah
it is possibly something to do with mirage or one of the hundreds of other masked mods
Probably Mirage
just the other day i was talking about a weird bug that is caused by vanilla behavior but only occurs in modded circumstances
I've seen this error for a long time
zeekerss added some code to the masked to make them turn invisible if they are mimicking a player and that player has a corpse spawned
since being converted into a masked first spawns a ragdoll, then spawns the masked mimicking you, then deactivates your ragdoll
in vanilla that works fine, and it prevents 2 bodies of the same player being displayed at the same time
but then if you have a mod like mirage that lets masked mimic living players, it causes those mimics to turn permanently invisible if that player dies to any means that spawns a corpse
because that modded behavior breaks this assumption that works fine in vanilla
it's possible there could be something similar happening here but TBH i don't think the worm is a bad guess either
huh, I think the mimickingPlayer field is intended to be used in conjunction with PlayerControllerB.redirectToEnemy, so that seems a bit sus to me
I can say a mimic didn't die to a worm, we didn't have a worm that game. Not saying it couldn't happen though if a masked died to one
but I'm unsure how it should be set up
if it wasn't destroyed by a worm then im thinking it would have to be caused by some mod changing vanilla behavior
why was the stack trace part of baboonhawk's doaiinterval?
baboon hawks call IVisibleThreat.GetThreatVelocity() on the enemy they are focusing
Full log if it helps
all outdoor enemies (or enemies that can go outdoors) implement this *interface so they can be targeted by baboons (and old birds)
i noticed another weird bug with masked the other day while testing my mineshaft patch
ye i messed with that interface before, StarlancerEnemyEscape also implements this interface on enemies that dont have iirc
masked cause nullreferenceexceptions in quicksand triggers because zeekerss tagged their body as Player
this is kinda funny though, radmech threattype lol
I'm guessing this was meant to have a null check for the threat interface's object as well perhaps
the quicksand triggers are reused for mineshaft water tunnels so if a masked walks in/out of them they spam nullreferenceexceptions and it is super ugly
but i doubt the player tag is contributing directly to this bug
lol what the hell, I wonder why it's not player
i was gonna guess that it was to make old birds not target masked
but that is done with a typecheck for RadMechAI instead
unless im missing it, it looks like baboons never check the type either
so im not sure what's up
but it seems like it shouldn't have any effect on anything, in that case
I have an odd question, this mod doesn't replace the Bracken's animations at all does it? I've just noticed when we have the Nymph Bracken recently when she's going after a player her animations are really weird and she doesn't do her normal skipping animation
only thing it could affect is the conditions where it switches states if they depend on pathing
or if they are using transpilers to change animation parameters and they are failing
I don't know anything about how they set up the mod though so who knows what it would be
https://thunderstore.io/c/lethal-company/p/AntlerShed/NymphBrackenSFW/source/ Lucky for you it has source
das decomp but sure
wait
why does it have animancer bundled ?????
I don't even know what the legal way to use animancer in a mod here is but bundling it like that doesn't seem right to me lol
and also if they are using animancer for this then it's almost undoubtedly some issue with their animator and/or its syncing to the bracken's AI state
not much I can do if they screw that up
I also have no clue what BitoSkin is
it's a replacement for the animation system that LC uses
yeah then it doesn't surprise me at all if things get out of sync
the amount of code in here is insane
would be nice if there was an actual GitHub link instead of it linking to the skin registry mod lol
idk how to explains this
Maneater AI just gave up chasing us
i don't have any logs with pathfinding trowing errors, but it was chasing us and just decided to stop in the middle of the corridor
we look at him and he was just stading there looking at us
we ran away and he didn't chase us
maneater has something in that AI man idk
were you on the other side of a powered door?
chasing as in he screamed at you and charged?
the maneater is pretty complicated, I don't even fully understand how it's supposed to work yet
IIRC it stalks people within a certain radius of its "hiding spot" up until it gets close enough to someone to lunge
and then once it lunges for the first time, it starts chasing the player with no more emphasis on stealth up until that player escapes the radius
i havent seen how the maneater behaves with pathfindinglagfix because personally i avoid it like the plague once it's transformed
and it's also pretty difficult to survive that first lunge even if you tried
Nope
Nope
My friend left the maneater alone and when we're getting back we saw him trying to approach, we freaked out and started running but he suddenly stopped chasing us and stood still on the corridor just looking at us
We didn't try to approach it but he wasn't moving
oh then it would still be trying to do the stealth behavior
yeah probably
i think for the most part it's intended to work like how the bracken approaches players, moving towards them but only in a way where it can avoid crossing anybody's line of sight
it's similar but it switches nodes more often
except it doesn't retreat when it is spotted, so it might be locking up instead?
idk
the line of sight cubes are not very long
The only mods I'm using that may alter maneater in some way is pathfinding lag fix and ButteryBalance
if it was a long hall it makes sense it would stop in line of sight
i dont alter maneater pathfinding, just override its agent's angular speed and acceleration during a lunge
so i don't think i'm causing it here
only thing I change related to the maneater is when it is selecting a target player
tbf it might not be pathfinding lag fix either, zaggy discovered a vanilla bug with the bracken while he was writing PLF patches, so it's possible some of his behavioral changes might be exposing something similar for vanilla maneater
Ok then
The best way I can describe what happened to the maneater was the same thing as that video I sended a long time ago
He gave up
Really strange why he does that sometimes
like buttery mentioned, it has a certain sphere around a cave node (or a random node if not mineshaft) that it wants to "protect" by sneaking around near the player
if you leave that sphere, then it will stop following you afaik
Does it's nest get bigger when at least 1 person is inside
something like that, yea
Well, that must been the case
@keen ruin something i meant to ask but maybe didnt phrase very well
how does pathfindinglib handle changing destination each frame?
i optimized my masked patch a bit and now im pretty confident masked never CalculatePath more than once a frame (and if they do it's a bug i can probably fix)
but their destination changes depending on a couple of factors
my understanding is that pathfindinglib doesnt guarantee a path will be found in a single frame, since it's designed to be async, so what happens if it's still looking for a path to an old destination and i need to feed it a new one
PathfindingLagFix doesn't handle destinations, those are all done by Unity
they are already done in slices, so they don't complete in one frame normally unless you modify the budget
the agents stop moving while they are calculating a path
I assume its not noticeable because of a couple things like it being a small amount of time and acceleration carrying an already moving agent
ah okay
so then there should be minimal behavioral *difference anyway, then
yeah it doesn't sound any different than what vanilla enemies do
out of curiosity
do you know why the bracken acts weird when it first enters anger mode
and does that need fixing + is it within scope of fixing in pathfindinglagfix
for some reason it kind of turns away from players and runs away for just a brief moment, and then immediately starts chasing
it's always felt kind of awkward and i doubt it's intentional
in the absence of having clips recorded, i tried to find some instances of it online, if you want to see what i mean:
https://youtu.be/A7A36i0v9yA?t=213
https://youtu.be/A7A36i0v9yA?t=285
https://youtu.be/A7A36i0v9yA?t=330
https://youtu.be/A7A36i0v9yA?t=358
turns out alter ego's video had 4 separate instances that were pretty clear
what im guessing is happening is this:
- Bracken has a spot it's moving towards while facing the player
- Player forces it to switch to Threaten state.
- Bracken gets the data a bit delayed so it's still moving, but no longer looking at player.
- This makes it look like it moves away for a bit since it's destination hasn't been set to targetPlayer yet.
yeah that's what i had in mind too
i think it would make more sense if it were to freeze until a path gets calculated
because right now it looks goofy
and it ruins the tension a bit
yeah that makes sense, im just trying to figure out where he sets the destination rn to confirm this lol
probably part of AvoidClosestPlayer
my guess is that it avoids the player, but when it wants to do the staredown, it sets agent speed to 0 and doesn't reset the destination, then when staredown transitions to aggro, it sets agent speed to non-zero and then sets the agent's destination, but setting the destination must not be resetting the previous path in time to stop it moving
I'm not sure if that's what Xu was trying to describe, but it seems to make the most sense to me that that is the reason
that said, I'm not sure why it wouldn't be resetting the path when setting the destination to the player, since it does reset the path when setting destination to a new path while a partial path is calculated
and it also seems to reset it when the bracken is pathing away from the player and is "discovering" new pathable nodes along the way, due to its distance cap
but I don't know what else it would be
if (!this.carryingPlayerBody && this.evadeModeStareDown && this.evadeStealthTimer < 1.25f)
{
this.AddToAngerMeter(Time.deltaTime * 1.5f);
this.agent.speed = 0f;
}
it looks like when it's staring down players (the part that immediately precedes its anger) it does just set speed to 0 yeah
doesn't change destination
yeah, I didn't figure it would
i doubt it sets its destination immediately when entering phase 2
two solutions are possible:
- calculate path ahead of time, set it in the agent (I haven't tested if this works effectively)
- set the speed to 0, then wait until the agent's path is complete, then set it to non-0
so i assume it's just the delay xu mentioned, where it's moving with "anger mode" speed towards its retreat point until it can set its target to the player
look like it's here
if (this.stunNormalizedTimer > 0f)
{
this.creatureAnimator.SetLayerWeight(2, 1f);
this.agent.speed = 0f;
this.angerMeter = 6f;
}
else
{
this.creatureAnimator.SetLayerWeight(2, 0f);
this.agent.speed = Mathf.Clamp(this.agent.speed + Time.deltaTime * 1.2f, 3f, 12f);
}
this is phase 2 in Update()
if it's not stunned, it starts accelerating, and is forced to be 3+
hm, looks like entering anger mode also immediately jumps it to 9?
in EnterAngerModeClientRpc()
oh yeah
weird
maybe the acceleration was too slow
not sure why he put that in the client RPC, but the bracken was the first AI he wrote for the game I believe
so maybe he hadn't entirely worked out the navmeshagent owner relationship yet
well
i was going to say
i think what's happening is Update() is changing the bracken's speed immediately
but it looks like the player isn't targeted until DoAIInterval()
so if the bracken had an extremely slow interval, it would obviously cause some weirdness there
this block of code should run every time it switches to anger state, so you could possibly use this to either
- set the destination to transform.position
- set the destination to the player that DoAIInterval() will eventually set it to
but the bracken uses an AI interval of 0.2
yeah
it is undoubtedly the delay from the interval
well
do you mean in your experience with PathfindingLagFix or generally?
well, i suppose i haven't seen it happen since the beta
just because im not usually in a situation where i could see it or paying attention to it
doubtful that it would've changed, if anything it would be more delayed, but unlikely
but it defo happens in vanilla and happened in the previous PLF (before v2)
200ms can feel pretty long though, idk if maybe you're underestimating how long that is
i'd take acceleration into account with that 0.2 seconds
oh you mean because the agent has inertia?
which would probably extend it by a bit
oh that is fair
i mean the agent just doesnt brake on its own
bracken has really slow angular speed and acceleration
huh
acceleration is actually high, (i havent seen if he changes it via code), but yeah angular speed isnt too high and it doesnt brake
default values ignoring any code changes since i know he does a bit
i would say to turn acceleration really high, put auto braking to on, and see what happens
I feel like that might only result in it being slightly quicker
also to answer your question about whether PathfindingLagFix might do anything to that, it's unlikely
if it had been the sliced path calculation delaying the change in direction, possibly, but I doubt it is actually
seems like a logical issue rather than a pathfinding one, if its even related to the navmeshagent
yeah
i think maybe it could be "fixed" by checking if evadeModeStareDown is true when entering state 2 from other states, and if it is, immediately set destination to the agent's position
and you'd need to also check within ~0.2s of the bracken taking damage, since that maxes out its anger immediately
I mean if it's entering the anger behavior you know that it should have a player destination regardless of whether it came from staredown
if you want to make it somewhat retain the vanilla "reaction time" that the interval causes, though, you could check that and set destination to self
true, but i just figured the least intrusive fix would be to freeze it in place so it still has a delay before acquiring target
although this is probably what's intended
oh oopsie that's what you said
i suppose
I think
since its the first AI i would also just look into EnemyAI itself, i know there's some fields that if he populated would just mess with the destination on it own separate from what he's doing/included
not sure what you mean by this though?
there's like a movingTowardsDestination thing and similar
I'm not sure if setting movingTowardsDestination to false causes it to stop moving though?
hmm
in the last clip i sent, you can see that whacking the bracken while it's actively retreating doesn't make it stop retreating
i dont even know if the bracken ever turns that on to true, since he has his own movingTowardsTargetPlayer thing iirc
it keeps moving in the same direction, but it speeds up and stops facing the player, up until it targets the player and starts chase
hmm, I see, so the speeding up is what's weird about that
i guess now that i think about it, you don't even need to check what happened to the bracken
if it entered anger mode you can just freeze it or immediately set a target to a player
it doesn't sound that weird but I suppose it's a little odd if it accelerates
doesn't matter if it was from staredown or being attacked
yeah, in theory that could look okay
is it weird?
especially if it retains its momentum
once it enters anger mode it immediately sets its speed to 9
I mean if it accelerates along its previous path and then turns afterwards
oh
no I don't mean implementation-wise, I mean from the player's perspective
ahh
yeah
that's why i was thinking it'd feel better if the bracken stopped in place
as long as it decelerates naturally, yeah
if it stops dead then I don't think that would be better
well, i could be wrong, but i think setting its destination to its own position wouldn't stop it from "overshooting"
thats why i was thinking of just amping acceleration and auto bracking momentarily
it would still decelerate and then move back towards its original position if it overshot too far
but by the time it thinks about doing that it should've already acquired a player target probably
i dont know if bracken uses it but zeekerss also has a thing to overshoot destination
but also, now that i think about it, if it were to decelerate naturally, it's probably not an issue to just set it to target players immediately
wacky stuff
yeah, I think if it slows and then turns around it makes sense for it to switch immediately
especially since the path may take a few frames to calculate
i wonder when MoveTowardsDestination is set to false, if ever
i dislike this part of EnemyAI's movement logic
oh is the add player velocity to destination thing how the masked strafes?? I figured it was some offset of the position in Update() or something
I guess it makes sense that a destination offset could work though
no idea, i dislike the movement logic, i stopped using SetDestinationToPosition on my newer enemies and it caused them to have a bug where they exclusively moved to Vector3.zero because he sets teh destination in update if MoveTowardsDestination is true, which it is on start
to use my agent script with my enemies and non-enemies without making it rely on enemyai
i think the masked just always moves directly towards the player
but is forced to face their direction
though i didn't actually look into it
sort of like how the bracken always faces players while retreating, so it'll sidestep and stuff
no they don't, they will sometimes follow the player's movement when they strafe to prevent them from dodging the masked
you can test this by strafing side to side, the masked will do so as well
okay, apparently that function is always on, it's sometimes felt like the masked can't do it but now I'm not sure why that is

hmm i will check
oh I see, that makes sense
looking at optimizing the blob physics and I just found out that the blob changing shapes just straight up doesn't work properly when your fps is too high

@crimson jolt free patch for you
[HarmonyPrefix]
[HarmonyPatch(nameof(BlobAI.FixedUpdate))]
private static bool FixedUpdatePrefix(BlobAI __instance)
{
return false;
}
[HarmonyPostfix]
[HarmonyPatch(nameof(BlobAI.Update))]
private static void UpdatePostfix(BlobAI __instance)
{
if (!__instance.ventAnimationFinished)
return;
for (int i = 0; i < __instance.SlimeBonePositions.Length; i++)
{
if (Vector3.Distance(__instance.centerPoint.position, __instance.SlimeBonePositions[i]) > __instance.distanceOfRaysLastFrame[i])
__instance.SlimeBones[i].transform.position = Vector3.Lerp(__instance.SlimeBones[i].transform.position, __instance.SlimeBonePositions[i], 10f * Time.deltaTime);
else
__instance.SlimeBones[i].transform.position = Vector3.Lerp(__instance.SlimeBones[i].transform.position, __instance.SlimeBonePositions[i], 5f * Time.deltaTime);
}
}
as an explanation
It turns out that the blob's rigidbodies for the edges of the goop never move unless there are multiple fixed updates in a frame, apparently because the blob needs the transforms to be synced before it will make any movement happen
related to this: https://stackoverflow.com/questions/68801079/unity-rigidbody-moveposition-is-not-working-if-transform-position-is-just-cha
it's better for this to happen in Update() anyway, since that results in much smoother movement, given that the rigidbodies aren't set to interpolate
looks like the blob dealing and receiving damage works correctly as well, so no worries about triggers being weird or anything it seems like
lol
so does that mean the blob is just completely broken at 51+ fps
yeah basically
gets progressively less responsive to terrain as fps approaches 50
I just thought it was normal for blobs to clip through walls all the time lmao
then I realized just how bad it was sometimes today
oh lemme edit, I should've made it lerp from Transform.position instead of Rigidbody.position
didn't seem to make a difference in practice, presumably because the transforms are synced from the previous frame fairly consistently, but it might make it move more consistently each frame to do that
it's obviously slightly unfortunate not to use the existing code from FixedUpdate in this patch, but in theory nobody's gonna be transpiling FixedUpdate unless they're trying to fix the same thing this is fixing
and the call to MovePosition needs to be changed to an assignment to transform.position, I've never tried to transpile a reverse patch
noticing a huge improvement after implementing this
neat find
i assume you are cool with me releasing it? given the context of the message
credited, of course
yeah go for it
it's not something I can put in PathfindingLagFix since it changes the damage area
should this blob thing have a post in https://discord.com/channels/750645598293590077/1258564990533636186 too maybe?. this seems something that zeekers could fix relatively easily if he wanted.
I could probably post about it at some point yeah
i think it'd be a good post
it's a relatively simple fix and it is a huge improvement
lil preview of a blob optimization
basically just doing one edge distance calculation per frame instead of 8
doesn't seem noticeable in my testing, despite the fact that it includes the player collision test
i dont know if this a bit off topic but why does SOMETIMES when i play with friend the enemies do not see players?? like nutcrackers, barbers, butlers spiders, and bugs going into 1 random place in the map and sitting there also coilhead and brackens are stuck near the vents and do not move, i have around 230 mods so i dont know WHAT can cause it(basically enemies does not know we are inside) maybe anyone had this issue too or know what may cause it?
hmm, not really sure what would cause that either
PathfindingLagFix does patch how targeting is done, but I haven't observed any issues with it nor gotten any reports about issues from others
I don't know what types of mods might cause that to start happening, unless it's failure to target players that join after the 4th player with MoreCompany, though I haven't seen issues like that in a while either
if you do get a situation like that though, it would be good to grab logs from the host and whatever client was not being targeted, and feel free to send them my way in case anything interesting shows up
in fact, preferably grab Player.log from %appdata%\..\LocalLow\ZeekerssRBLX\Lethal Company\ after such a bug happens, then it will have logs from the pathfinding threads if there are any errors there
you basically telling us to guess what 230mods you have 
not sure if this is a vanilla bug or a Pathfinding Lag Fix bug but whenever you have an Snare Flea chasing you and you jump it simply forgets about you
that's vanilla, if you are the only one inside
it will give up the chase if it can't target any players inside, and when you jump it is unable to path to you
it affects a few other enemies although not quite as majorly
bracken locks up when you jump during a chase, but doesn't immediately deaggro
maneaters get hella confused mid-lunge
Alien life in LC’s universe all live in an ecosystem where nobody jumps. If you jump they get confused and/or scared.
factual information actually
yeah because then you're not routeable while jumping so they cant go to your destination 
about time I released this lol
Version 2.2.0 (Beta)
- Patched masked to use the cached elevator controller instead of finding it fresh every AI interval.
- Patched the method to find the main entrance to use a cache and avoid a
FindObjectsOfTypecall when masked are pathing to it. - Patched hygroderes to reduce the physics casts per frame from 8 to 1.
- Patched the maneater AI to avoid synchronous pathfinding when the adult is sneaking and when it checks if it is stuck.
- Patched coilheads' player targeting pathfinding to run asynchronously.
surely I have not broken anything

I'm sure it'll be fine, regardless I'll be running this for the next stream so if things explode you'll be sure to find out x)
sounds good
So I ran into a freeze once today but dunno if it relates cus I never reprod it, however I did notice a bug with Masked when they were around on the Galetry, they would be missing the MoreCompany cosmetics of people they were mimicing for some reason
Which 100% would be something from the PathdinfindingLagFix Beta somehow
kinda seems unlikely that cosmetics not spawning could be caused by the patches I made, since they only affect DoAIInterval
if they're patching that to spawn cosmetics I would be shocked
freeze is curious, but I think unlikely to be anything I've done here? I don't recall any suspicious loops but maybe I goofed something subtle
if it happens multiple times I would wonder if downgrading removes the problem, but if it only froze once then you probably need to use it at least 5 times with beta and 5 times with stable to ensure it wasn't a coincidence for it to stop when you downgrade
something happening only once during a play session and then switching something out isn't gonna be conclusive
We never did swap from the beta back to stable after it happened
just rebooted
right, I kinda figured that's what you meant
I just meant that if you end up encountering it again and want to test without beta, would be good to make sure you play a good number of sessions to confirm that it's not something else
Yeah
I'm gonna try to repro masked being weird on Galetry with some other things I added disabled
reprod
sounds goog
Okay I confirmed it's somehow PathfindingLagFix
with it enabled masked that spawn at the Galetry have no cosmetics, but with the Beta disabled or the Stable version present they're fine
I used the Twitch API to spawn it lol
It was bald when I had the Beta enabled
XD
Idk why it's specifically the Galetry though
I'll reenable it and try sending a log cus there were no Stack Traces
I'd assume it's causing some odd conflict with Mirage somewhere though but why I noticed it mainly on Galetry is odd
But yeah with Beta enabled the cosmetics vanish
Lol
@keen ruin
01956515-f83f-afc2-3e70-e2a7cb7a86a6
[06:51:19.1878346] [Error : Unity Log] Error when initializing enemy variables for MaskedPlayerEnemy(Clone) : System.NullReferenceException: Object reference not set to an instance of an object
at PathfindingLagFix.Patches.PatchFindMainEntrance.FindMainEntrancePositionPrefix (System.Boolean getTeleportPosition, System.Boolean getOutsideEntrance, UnityEngine.Vector3& __result) [0x00010] in ./Patches/PatchFindMainEntrance.cs:87
at RoundManager.FindMainEntrancePosition (System.Boolean getTeleportPosition, System.Boolean getOutsideEntrance) [0x0000d] in <bdf6a080e98a49fd84b92b24894f768c>:IL_000D
at MaskedPlayerEnemy.Start () [0x000be] in <bdf6a080e98a49fd84b92b24894f768c>:IL_00BE
Ah yeah I never caught any stack traces
ty diff I was just lookin at that
That makes sense cus Galetry has no main entrance
So that error goes off which probably then prevents the cosmetics and stuff from initializing lol
just pushed 2.2.1 Beta to fix dat
Should I be using the beta or the normal pathfindinglagfix mod?
the beta is not guaranteed to be stable
it gets updates earlier and can be used if you dont mind potential need for troubleshooting
the normal mod is less prone to issues because it gets the releases after they've been in beta for a short while
oh speaking of the beta, @ashen harbor have you been using beta 2.2.1? wondering if it has been fine on galetry since then
if so, I'll push to stable, I've just been busy with PathfindingLib API and haven't been able to specifically test it really thoroughly
Oh yeah I haven't had any issues and have been using the beta
01958d38-7331-b245-2a97-54b29fabdf06
Enemies on certain moons seemed pathfind weirdly. Truth be told, we only went on generic's moons this session but I still figured I'd let whomever know. I had a thumper, a hoarding bug, a snare flea, and even a rollinggiant just pathfind toward something but they didn't move as fast and like stuttered when doing so
a video would be immensely helpful if you have one
If you scroll up in helpandtroubleshooting, you'll find the exact collection of mods (disabled and enabled) plus the correct log for that session
Also, I noticed this whenever I saw a snare flea bugging out in the logs
let me get it rq
[Debug :PathfindingLagFix] Player paths from Centipede(Clone) (CentipedeAI, -495494) are 55594.64ms old, which is more than twice 140ms, using synchronous paths.
It went toward me, then went away, then went toward me
It was as if it couldn't decide on whether or not to target me
This has happened to a thumper, a lord of the manor
The hoarder bugs idk. They seem to just stutter walk
And I'm not 100% but it seems this happened only only generic's moons. Mostly collition but also icebound. I'm not 100% sure if it's just tied to those moons but that is where I've been routing to, to see
Considering I've never ran into it it's prolly a moon or interior issue
usually those error messages print because something else is causing excessive frame lag
it is usually a symptom and not a cause
but that clip is definitely strange
doesn't feel like framerate is low enough that it should be causing that much jank
the framerate wasn't low at all, it most likely was just 180 or around there. The lag in the video was cuz I used snippit tool. Never used it before so idk if I did it right
I've spent all day disabling mods trying to figure out the cause
I hope something is found, that's like all the info I can provide
my guess is it's interior related
This has happened on multiple interiors
i see
Also I meant colateral. the scrap moon
It's prolly an issue with the moon then
I've seen Spiders tweak out specifically on Infernis before lol
But they're fine everywhere else
I asked generics but noone seemed to find an issue with the monsters on the two moons I listed
even said that it isn't generics that is doing it though I didn't provide a log so they was assuming ig
Could just be they didn't notice it
So the moon itself can mess with the pathfinding of monsters? Cuz again, a lot of monsters would work then occasionaly it would be as if a monster kept deciding over and over to chase me. I remember a thumper going the opposite way of me. Even a coilhead was going in the wrong direction every time I looked away from it
Plus, I didn't have this problem with that moon by itself. I went there with just imperium and checked. And yes this has happened without imperium so I don't believe imperium would be the cause
Well anyways, nobody is required to look at everything I gave but I ask someone please do. I have been stuck on this last night and all day today. I just can't find the cause and it's very demotivating. Thank to whoever has looked at it so far.
I mean I've been using PathfindingLagFix for a while and never ran into this, however I've had some occasions where all clients freeze from masked enemies and I've been unable to trace the culprit of that, currently we're pretty sure it's a bug with Mirage based on an error I found
They all freeze and then I get lag as host that makes even my stream drop frames cus something freaks out in terms of networking
I haven't ran into any masked issue so far but idk if it's the norm but I'm using pathfindinglagfix beta. seems more updated. I don't know if that isn't recommended
That's what I'm using and I've still ran into it
Hmm. Well in short it just feels like monsters can't target me properly or something sometimes. I had a bunch of snare fleas barely move from their spot when they fall because they stutter when they move. Also had some go away from me, then back at me, then away like their couldn't make their mind. I am just know remembering something that sounds very familiar with a forest giant on assurance. It happened like a week ago. It just stuttered walked toward me.
That could be a different reason entirely but that 100% did happen now that i'm recalling it
Anybody know what it could be the problem? Just had a spider and a hoarder bug run away from me
really not sure, I also haven't observed that I don't think
I haven't had time to look at this for the last few days, but hopefully tomorrow or Monday I can
if you happen to have this happen early on a day, a seed and profile code might help so I can try to reproduce it
especially if it happens to you in singleplayer
did Mirage have an update that you suspect caused this regression? what's the error? I would have to have a look at my patches again to make sure that couldn't be related to them, seems unlikely but possible
All these weird issues was on generic moons specifically. Most of this happened on collateral. Though the 1 time I noticed a giant sttuter walk it was on assurance near the entrance. I was standing at the door, it saw me, went toward me but that giant pipe thing was above it. Then it just slowly stutter walked toward me
does this happen every time on generic moons you think?
I can try to repro with just that if so, but if it's intermittent, or especially if it only happens in multiplayer, that makes it very likely in my mind that it won't happen for me too easily
(without what I mentioned above at least)
Yes, I just came to the conclusion it was just generics moons. it was happening without anything else enabled in my modpack. I mentioned it to generic and they did notice a few of their monsters acting wonky so they said they'll message wesley about it
ah I see, hmm
and that's even without PathfindingLagFix then?
I'm not sure what would cause the AI to stutter step while roaming unless the AI nodes themselves are missing or outside the playable area
and I believe you mentioned some AI that would be only roaming
It was weird. I noticed snare fleas like stuttering toward me when they fall but barely move, hoarding bugs stutter walking, enemies going aggresive but going away from me instead of toward me. And enemies that seemed like they where in fast sessions going from toward me to away from me
hmm, you didn't mention if this was happening without PathfindingLagFix too? I would like to avoid trying to investigate this if it's not a bug caused by it, since I want to focus on the elevator pathing API
I'm gonna be working on that today if this doesn't turn out to be my issue
well the giant stutter thing happened with it but after an entire day I just disabled all mods and went to generic moons and it was still happening. I didn't know what I was which is why I was trying to find answers on it
0195a6ff-0d47-58d7-653f-69303c1bf0ff
Was on titan in the ice/snow version of the Rajigar Mines interior on Titan. A bracken was sliding instead of moving and when looking it at it just didn't move for a bit. Eventually it did though
bracken sliding around is an Imperium bug, you have to jump to fix them after they spawn
at least if you are solo
Okay I'm glad on that. I got worried it was an interior issue.
I have been noticing a thing in my modpack lately where Butlers are opening doors much faster than in vanilla, does what AI this mod is set to use impact this?
well
butlers normally only take 2 seconds to open doors
the reason it usually takes longer is just because their colliders dont overlap correctly sometimes
mineshaft doors are notoriously difficult for butlers to open for example
Respectfully, is that a yes or no?
I am playing my modpack and a friend with probably over 100 vanilla Butler kills cannot shut up about Butlers constantly going through doors like they are nothing
I would like to confirm if a mod is causing this
i am doubtful it is this mod
what im trying to say is that butlers taking a long time to open doors is unintended behavior and basically happens by coincidence
so expecting it to be consistent in the first place is probably misguided
this mod changes how enemies calculate paths, but (and zaggy can correct me if im wrong) should have no effect on their spacing
if a butler wants to walk through a door they are going to overlap it with their collider the same way they would in vanilla
out of curiosity, does your friend (or did your friend ever) run "doorfix"?
that mod shrinks door colliders which makes it almost impossible for any enemy to open doors
I know of that mod, I will have to ask
PathfindingLagFix doesn't affect door opening at all
there is zero possibility of that being affected
Well thanks, I just wanted some confirmation
yeah no problem, just wanted to be absolutely clear
I think I’ve been having the exact same problem. Enemies either don’t pathfind at all (like coilheads just running in place) or they all pathfind to some random corner of the facility and kinda ignore players. It was definitely happening on generic moons even though it had vanilla interiors. That said, things like this were happening before, but installing pathfindinglagfix seemed to make it worse. So probably not this mod’s issue.
it does seem odd if it gets worse with PathfindingLagFix
but as far as issues on a particular moon, I wonder if it might be something screwed up with the navmesh surface on those moons, that's the only thing I'm thinking of that would affect the interior in such a way
other than if the moon has modifier volumes, but that seems much less likely to me
I figured it out and it wasn't this mod's fault, or even generic moons. It was an incompatibility between brutalcompanyminusextrareborn and some of demonmae's moons
I forgor to push this out onto stable, it's been in beta for way too long lol
Version 2.2.0
- Patched masked to use the cached elevator controller instead of finding it fresh every AI interval.
- Patched the method to find the main entrance to use a cache and avoid a
FindObjectsOfTypecall when masked are pathing to it. - Patched hygroderes to reduce the physics casts per frame from 8 to 1.
- Patched the maneater AI to avoid synchronous pathfinding when the adult is sneaking and when it checks if it is stuck.
- Patched coilheads' player targeting pathfinding to run asynchronously.
Pathfinding Lag Fix | Pathfinding Lib
I think the recent hygrodere change makes the slimes really uh tall
maybe its a conflict with something else but it and lobby control are the only two mods that have updated
and now we're getting this
i hate tall slime its cursed ðŸ˜
Idk I never had this with the Beta so maybe it's some oddity that got pushed to the stable update
hmm I did see this one time but I'm not sure why
not sure if it was with my beta actually, it was a good while ago
but if you catch a seed or especially if you see one spawn and can record it that would be incredibly helpful
ah actually, I might have an idea why it does that
I have a feeling it would look normal with ButteryFixes
it is probably using a bad initial value in the first fixed update and not fixing itself due to the screwy way it updates the positions
do you think it'd be worth consolidating that change back into pathfindinglagfix?
it's your patch to begin with so like... not like im gonna fight to keep it or anything
or do you think this issue would've replicated still in vanilla
I... could maybe consider doing so, but I think I would rather fix the incorrect initial state so that it works in the vanilla case, since the patch is supposed to not have much of an effect on gameplay, at least when the game is performing normally
that's if it is what I'm thinking it is, I'll have to see when I get to this
it'll take a little fiddling with the patches I think
it's implemented as a transpiler so it's a bit more of a pain to do than it would otherwise be
well, let me know if there's something on my side that needs adjustment for compatibility
supposed to not have much of an effect on gameplay, at least when the game is performing normally
i agree with this (and the general mission statement of vanilla gameplay parity) but i think this is sort of a special case
in a way
since it makes the slime work consistently at all framerates, instead of just at low framerates (an "issue" that might be exacerbated by PLF improving the framerate)
hard to say there's a clear answer
though
yeah
I just talked to tomato who helps administer (or something) the speedrunning community and it sounds like it would be reasonable to bring into PathfindingLagFix under the OnlyFixes preset actually
but I still need to fix the unfixed behavior for the sake of the Vanilla preset
actually, I forgot that the damage area of the blob is more affected by the bone positions than I thought (though still not totally because it's a bit spaghetti how that works), so maybe I'll have to discuss that further
that said, the fix for the tall blobs works
Version 2.2.1
- Fixed blobs often being stretched to the origin for a while after they spawn.
Hello!
I really hate to blame anything in particular, but I wanted to let you know that I'm having a general problem with all the monsters.
None of them are able to open doors; instead, when they stay in the doorway for too long, they end up going right through.
The first one I noticed was the masked monsters in StorageComplex, thinking it was a dungeon bug, but I realized this bug is present in any interior and with any monster: crawlers, coilheads, brackens, etc.
As far as I know, this is the only mod that could make a change that could affect that, so I'd rather let you know and get some help fixing this.
are you using doorfix?
i think it's kind of fallen out of the public eye
but it was a known issue for a while that it prevents monsters from opening doors
because it changes the size of the door trigger (which enemies have to overlap to open the doors)
it's why testaccount fixed the grab action instead of changing the doors
in itemgrabfix
if it's this mod, no
yeah that's the one
i wonder if something else you have might be making similar changes
but that's my ace in the hole gone
at least
someone reported having a similar (but opposite) issue a while back
but zaggy's pretty confident it shouldn't be related
that is probably also the case here
yeah the only way it should affect that is if the enemies have stopped pathing to closed doors entirely, and it would be difficult for the pathfinding patches to even cause that
if you're using ReXuvination can you try without?
it should just still be fine though
yes, I have it
I'll try without it
this is what happens (this is the crawler)
it wiggles on the door
now testing without Xuvination
i think it is rexuvination, that's interesting
ill get a fix in a sec, weird that my enemies work but vanilla doesnt lol
thanks!
will update ina a sec
gotcha!
that is curious indeed
do you have your colliders set up differently?
i didnt think i did, maybe i had interactableobject not excluded but i thought i did
Version 0.1.0
- Made
NavMeshQueryUtils.FindStraightPathcall through to the Unity runtime instead of reimplementing the algorithm. The results should now match the output fromNavMeshPath.cornersperfectly. - Deprecated the original overload of
NavMeshQueryUtils.FindStraightPathin favor of one that requires less allocations to match the native Unity function's signature.
maybe if we get enough testing in with the upcoming API 
call me up for it anytime bbg
oh I definitely will
it's gonna be an adventure
this is what I have on my list still though, I feel like it might take a bit longer
- vanilla elevator API impl component
- allowed link flags
- masked smart pathfinding mod
- option to include all nodes and skip going in/out based on player positions? they don't roam too well with this yet??
- option to allow fire exits to be used
- is there a good way to prevent masked from using offmesh links that are intended for non smart AI?
- teleports within area
- testing...
the big one is the masked mod
I gotta turn my hacky implementation into proper transpilers
I thought I should note this here, but I'm looking into an issue on the latest version of PathfindingLib where the change to use Unity's FindStraightPath method is resulting in paths "succeeding" when they shouldn't be, which can cause enemies patched by PathfindingLagFix to stutter step
currently investigating what is causing it, but I'm not seeing any differences in how I'm calculating it versus how NavMeshPath.CalculateCorners does
hopefully I can find what the issue is before too long, but for now I would recommend downgrading it
does it always succeed or just in some cases?
not sure, but I have a test case where the results differ from NavMeshPath.CalculateCorners and I'm trying to figure out why
in the job it's succeeding and returning a partial path followed by a corner that is exactly at the destination
the partial path doesn't match the NavMeshPath version
trying to figure out if there's somewhere in the native code that causes the difference
the difference between NavMeshPath and the job version is in the last corner in the partial path only, every other corner is exactly the same afaict
very odd indeed
and the input polygons match identically
wait it returns it as partial?
i belive native always returns the destination as the last but if the status is marked as partial it ignores it
the result of EndFindPath is partial yeah
but FindStraightPath is unaware of that and I couldn't find a place where it reduces the size of the managed array by 1 if it is partial in the NavMeshPath
I'll have to double check on ghidra this tho
I was wondering the same thing but I see no place where that logic lives
are you able to look now or is this a later thing?
it's probably a "in 5min" thing if my RDP works
ohh I see
NavMeshPath.m_Status (my name for the field @ 0x4) should be comparable to the result of NavMeshQuery.EndFindPath I believe, but it doesn't get referenced in CalculateCornersInternal afaict
looks like the actual result of NavMeshQuery methods isn't kept so I think that's all that's relevant here
it did appear to be yeah
success being 0x40000000 makes it seem very unlikely not to be
so that's what I'm currently interpreting it as, and in the case where I'm getting false positives it is giving only that result
local_78 = local_78 & 0xffffffff00000000; that's one way to zero out an int out of a long field 👀
huh
not the same as a cast though if it's signed 
or wait I'm getting it backwards
what is that used for??
to store the PathQueryStatus
or more precisely to dynamically retreive it from a "memoryManager"
and that local is the destination and the output of CalculathePathCorners
yeah
that's getting the non-detail flags from the status
I'm seeing it returning the number of straight path corners from NavMeshManager::CalculatePathCorners though
it's very screwy to follow here since it's doing some weird stuff in the decomp for the calling convention but it is passing a local to FindStraightPath in the second to last parameter as an uint64* and then returning that as an int
on my end all I see it doing with the result of FindStraightPath is checking if it failed and returning a corner count of 0 if so
uh?
(which is irrelevant here because I'm getting a partial path back from NavMeshPath.corners, it's not hitting that)
oh actually it's passing it as int* I forgor
with int local_res8[2]
thoose are the pathRefs right?
I'm guessing that maybe what makes it do all this crap with puVar11 is the call site addresses it's assigning to -8
what are pathRefs?
what I highlighted?
second to last param is the out int straightPathCount
on ho it's the path count
we drop the last parameter in our wrapper
uh
local_res8 you mean?
yeah
it's just confused about the stack a little in the decomp
or you just retyped it
🤔
are you seeing something different?
nono that checks out
i'm trying to find where it's adding/removing that extra corner
how sure are you that you saw that?
not too much anymore
I haven't seen any evidence of it, and the fact that corner index 3 (with 5 total in our version) is differing from NavMeshPath makes me think something else is going on
not sure what though........
for your reference, this is with NavMeshQuery:
- float3(-19.05093f, -219.5336f, 86.91694f) @ 562954802036800
- float3(-25.335f, -219.5336f, 84.71749f) @ 562954802036794
- float3(-26.91203f, -219.5336f, 84.02847f) @ 562954802036837
- float3(-28.71834f, -216.0919f, 69.90083f) @ 281479821131788
- float3(-28.21279f, -182.1419f, 73.91283f) @ 281479821131788
and with CalculatePath/NavMeshPath:
[Info :PathfindingLib] 0: (-19.05, -219.53, 86.92)
[Info :PathfindingLib] 1: (-25.34, -219.53, 84.72)
[Info :PathfindingLib] 2: (-26.91, -219.53, 84.03)
[Info :PathfindingLib] 3: (-28.72, -212.83, 63.75)
Y and Z differ significantly for the fourth corner for some reason
not sure what you mean
nothing
with NavMeshQuery, the destination is the 5th corner
i'm trying to see if somehow CalculateCorners populates differently the parameters of FindStraightPath
what do you have mapped as "param2" of the CalculatePathCorners?
it appears to be the capacity of param_1
I believe they allocate a corner array that is the number of polygons + 2 since it's the maximum amount of corners that it can result in
I'll probably mirror that in my job code later
I'll call them corners and cornerCapacity
could it be that it does not have the space for computing?
in ours?
ye
no we waaaay overallocate
uh?
uhm. the param is not the corner count but the node count
where are you seeing this?
I dkon't have a param_2 in NavMeshPath::CalculateCornersInternal
in CalculatePathConrners based on what it's passing to FindStraightPath
CalculateCornersInternal -> CalculatePathConrners -> FindStraightPath
CalculatePathConrners passes it's param_2 as the last param of FindStraightPath. and it's param_1 as the 4th
and by the analysis we did before param_2 is 2 elements larger than the original size
yeah 5th
we called it like that but it also seems to be the size of the in array too
I mean
it's based on the size of the input array
but that's because the input array limits the size of the output array
it allocates arrays to the size of the maximum number of output corners
or I assume it does
which is polygons + 2
we give it 128 instead
then why also resize the input array?
where?
in the "internal" one
i also wonder how an uint + 2 can result in 0 but that's another story XD
yeah idk that might be a macro lol
also another intresting thing in the non-internal one:
the path size ( aka. param 4 of FindStraightPath ) is taken from a field of NavmeshPath instead of the size of the array 🤔
yeah, NavMeshPath has a field for the number of polygons
