#Pathfinding Lag Fix | Pathfinding Lib | Smart Enemy Pathfinding

1 messages · Page 3 of 1

green gust
#

The horseshoot code scares me sometimes, I didn't know about externalForces back then so all the focus was on implementing my own version of it Dead

keen ruin
#

also no source code available for that mod so I guess I will have to decompile it to figure out why it is running that less than once every two AI intervals

green gust
#

What code is it running that's bad? I can take a look

keen ruin
#

oh did you work on it?

#

uh

green gust
#

Yeah Co author after original coder left

#

Never made github public because good question

#

Might be because of unity not gitignored or smthn like that

keen ruin
#

I mean the method that is either running infrequently or getting run for the first time repeatedly due to a ton of these guys spawning is the TargetClosestPlayer method

green gust
#

Actually it looks fine, iunno why we never made it public, but I'd have to check the files if we have any assembly csharp there

#

Lol that's kinda funny

#

It keeps running it until it finds a target player that's nearby

#

Then it switches state and never runs it again because it doesn't switch states back

#

Though it does run it every doaiinterval

#

In its first state

keen ruin
#

hmm, then I wonder if it was just because a lot of them were spawning

#

or because they were switching back to the state where they were searching for a target?

#

that wouldn't be abnormal even for vanilla enemies

#

I'm assuming these enemies like to spawn in groups?

green gust
#

Ye

#

Daytime enemies + prob in groups

green gust
keen ruin
#

I just check if the time since the paths to players job was scheduled is greater than twice the interval time defined on that enemy, and if so, I check the paths on the main thread and print that I'm doing it there

worn steppe
#

I've always had this error, but the mod isnt even on my modpack

green gust
#

Ic, I think

worn steppe
#

Never used this fabled Lc optim

crimson jolt
#

i think it is "FixCentipedeLag" you are looking for

keen ruin
#

bad mod

#

it will kill centipedes for you if they spawn at the beginning of the day or if everyone leaves the interior

#

don't use it

worn steppe
#

Really? I assumed it was Lostenemyfix

#

Ill remove it then

keen ruin
#

idk what that is

#

I'm scared

cursive sonnet
#

LostEnemyFix despawns enemies that aren’t on NavMesh

#

(After X time)

keen ruin
#

hmm I see

#

could really be solved at the source without destroying enemies but sure

cursive sonnet
#

I think it’s one of jacob’s mods

keen ruin
#

right

cursive sonnet
keen ruin
#

I would tend to say it'd be preferable to patch SetDestination and set_destination_Injected both directly to cancel them if the agent is off the navmesh, that is much less invasive

#

but it's probably fine, I don't think I have any need to look for that specific call to SetDestination

#

...unless I decide to add a fix for the stutter stepping that AI do when they can't find a complete path to their destination

#

which might be nice...

#

I forgot I was thinking about that yesterday

#

I realized I was silly and forgor to push but now it is up on GitHub

green gust
#

Ah icic

green gust
keen ruin
#

not really

#

well, or not exactly I guess I should say

#

if an enemy tries to path to somewhere unpathable, it can instead go to the closest point

#

however, calling SetDestination repeatedly as vanilla does causes the agent to instead reset its path and recalculate it asynchronously, so it stays stationary until that path is ready to be used

#

if it

  • used async pathfinding to create a path, then placed that into the agent's path object when it was ready, or
  • checked if the destination had changed
    that would be either reduced or eliminated
#

(in cases where they are setting unreachable destinations)

#

also xu, why doesn't the HorseAI check the closest player more often? is it supposed to run away from the first player it sees on its navmesh?

green gust
#

The funny part is that this is just a bug no ones noticed/devs noticed but never bothered fixing cuz it didn't take away from the gameplay

#

It never reset states back to wandering

keen ruin
#

huh, I see

#

when is it supposed to?

green gust
#

Probably after the target player is like 15+ distance away

keen ruin
#

oh wait I should have hooked TargetClosestPlayer, looks like it is calling it rn

#

lemme check if it does if I get closer

green gust
#

Ye it calls it in DoAIInterval

#

Shouldn't when u get closer

keen ruin
#

huh yeah okay it was other ones repeatedly calling it, I don't get any calls even when going inside with only one spawned that I went within range of

green gust
#

Yep

keen ruin
#

so I guess the logs were spamming just from a lot of them spawning most likely

#

in any other scenario it shouldn't print that log consistently

green gust
#

Yuh, there's meant to be prob like 5+ that spawn at once

keen ruin
#

yee

#

that's fair

#

I think it's a non-issue kinda, although I could move it to debug level in order to hide it from console in the stable release

#

it's only there rn to ensure that it's not marking these paths stale incorrectly

#

huh, why does the mantis shrimp call TargetClosestPlayer with both requireLineOfSight = false and = true?

#

seems a bit excessive, but I guess with PathfindingLagFix's patch it doesn't matter much anyway

#

definitely would have been a bit of a problem with lots of those spawning in a lobby with lots of people

#

oh and now it stopped calling it entirely

#

glad to see the worth of this patch proven though, the fps goes from 208 to 224 when I enable async player targeting

#

(tbf it's with 14 of these spawned, but any other enemies also calling TargetClosestPlayer should cause at least some reduction in performance similarly to this)

green gust
#

14 sounds a normal-ish number

#

Mantis shrimps spawn in groups so it's normal to see like 8 of em in a spot

keen ruin
#

gotcha, yeah

#

it was spawning 2 at a time just with the debug button, but I wasn't sure how many groups to expect

green gust
#

I would've expected it to use vector.dot for that though

keen ruin
#

yeah, a dot and a linecast would make sense

slender wadi
#

while i do know that the mod is currently not fit for player consumption rn, there's multiple repeating logs spamming the console that (i believe) is causing the game to lag

#

if that's intended because of debugging purposes then yeah just ignore this
just wanted to double check

keen ruin
#

it was indeed, and those will be gone in the next version

#

although they definitely shouldn't spam at any high frequency

#

honestly the fact that you seem to be seeing it from the same enemy multiple times makes me wish I had put more information into those logs

#

maybe I should bring them back for the next version and print out the instance ID lol

#

if it is printing that, that means you're losing out on the benefit of the async player targeting

#

it's normal for it to print at least once per enemy, but for enemies that check for targetable players every interval, it should never print again

keen ruin
#

@slender wadi I'm keeping the logs in with extra information in v2.0.10 Beta, while also avoiding printing it in scenarios where I know for sure it should be using the sync method, would be interested to hear if you see these logs printing still and how often

#

also, what exactly was the performance impact you were noticing that you associated with the logs?

wild igloo
#

I have no evidence to support my claim, but dogs have been acting really weirdly after the most recent updates of Pathfinding Lib/Fix
0194b682-2af4-8599-28f0-ec9a285a6c0c

#

What the fuck is this

#

There is straight up a baboon hawk walking in place

wanton salmon
slender wadi
#

but yeah i’ll be interested

#

it was spamming quite a lot and was def tanking framerate because of it
though it wasn’t like a consistent frame decrease, more like constant stuttering

slender wadi
#

these are the logs after the new update

#

and it only spams worse the more enemies it does it to

#

i gtg to school now so i won't be able to test anything for like a good couple of hours

keen ruin
keen ruin
# wild igloo

not sure what would cause that, I don't patch that method

keen ruin
keen ruin
slender wadi
#

I still have around 2 hours of school, but i don’t think i’ve ever heard of a Player.log before

#

Where would i find that?

keen ruin
#

it should be in your save folder if you know where that is

slender wadi
#

I do not

#

I’m assuming either the local files or appdata

keen ruin
#

%appdata%/../LocalLow/ZeekerssRBLX, if I remember correctly

slender wadi
#

Okay yeah

#

I’ll be sure to check once im home

keen ruin
#

in some subdirectory

#

thanks

#

how many players were in your game by the way?

slender wadi
#

Yesterday, before the update, it was me and my friend
Today, after the update, it was only me

keen ruin
#

Hmm okay that's strange then

#

it worked fine for me solo testing

#

will have another look though

crimson jolt
#

also 1a3 taught me a handy shortcut %appdata%\..\LocalLow\ -> %localappdata%Low

crimson jolt
#

if you've relaunched twice or more since the session where you got the issue, you'd need to replicate it again, though

keen ruin
#

ahh, I think I found the issue, it happens after you become targetable and then untargetable

#

just had a little goof where I'm checking invalid indices of an array that I only grow

slender wadi
keen ruin
#

thanks! doesn't look like it had any errors, so I think it's fair to assume the spam came from what I'm about to push out a fix for

#

just pushed Beta 2.0.11 with a fix for that

slender wadi
#

and the log spam is def decreased

#

now it's only in short bursts, which to be fair does cause stutters in-game

slender wadi
#

OKKAYYYY NVM SAVE ME

#

(closer look)

keen ruin
#

huh, that's at least more in line with what I would have expected, but your frame rate would have to be incredibly low for that to happen normally

#

was it stuttering?

slender wadi
#

i'm testing this on oldred
when i first landed, i got some lag spikes where my game froze for a bit, then returned to normal, which was when the logs were only in short bursts
then everything was perfect for a while, was able to go in, grab some stuff
saw goku and prayed he wouldn't get me
then while i was searching a room the game just turned into a powerpoint, which is when it started SPAMMING spamming the logs

keen ruin
#

Hmm okay well that is definitely curious

#

the logs would print when you get lag spikes, so it may very well be an issue with another mod

#

unless logs in general just absolutely murder your frames

#

I would be curious to see
a. this is reproducible on that map/seed
b. if it stops happening when PathfindingLagFix Beta is disabled

#

I could try to test it on that map and seed later if you toss me a profile code, or if you wanna repro yourself that would also work

slender wadi
#

i'll try to see if i can reproduce it, but if you want i can also send a code

#

0194b9f6-3f0b-afde-5823-c0ae9425cd44

#

the modpack's pretty hefty (112 mods), so i wouldn't be suprised if it's another mod causing it

#

also if you get like a gigantic wall of constant error logspam on the main menu after playing a round or two and exiting to it, just don't mind it

#

it's 100% not pathfindinglagfix (though idk what mod's causing it), it's hard to pinpoint it since the only info it gives is that it's an occludeaudio error, and it doesn't impact the performance somehow

#

i'm constantly tweaking with stuff on the pack so i'll figure it all out eventually

slender wadi
#

okay yeah it looks like the majority of these logs are just coming from the hydrogere

keen ruin
#

I mean I think it's unlikely as well, but it's nice to rule it out completely

#

the logs do depend on whether a frame or two run long, but it seems pretty surprising that it's happening so often

slender wadi
keen ruin
#

wait, this occlude audio thing you mentioned? does that only show in the log files? I'm not seeing it in the excerpts you screenshotted

#

oh sorry I kinda missed the context skimming your messages, I thought you were referring to something that was contributing to the frame drops

#

I didn't get a chance to look too closely at this today, but if the low fps happens consistently on oldred I can have a look at it in profiler tomorrow

#

I did play a bit of almost vanilla with PathfindingLagFix beta and encountered some unusual and long stutters though, not sure if that was my machine behaving weird or if I may have regressed something

slender wadi
#

Honestly i should probably try to use the unity profiler for some stuff, could help a lot in identifying what mod’s causing lag so i don’t just blame it on smth else on accident

#

That’d probably require me having to make an entire new unity project to do so, but i think the assistance it provides would be worth it

nova relic
#

If I install the beta version, do I need to keep the normal version at the same time?

slender wadi
#

You don’t download the beta along with the current

nova relic
#

So these two versions are not compatible with each other. It's best to keep only one of them, right? I see.Are there no serious problems with the beta version at present?

crimson jolt
#

for the most part i would suggest using the beta, it's pretty stable now and doesn't present any major issues, but it might have minor gameplay differences compared to vanilla (or the original mod, which is almost perfectly faithful)

nova relic
#

If I add a lot of extra monsters, can the pathfinding patch still optimize performance?

#

I think I have added more than a dozen new enemies, including many enemies in coderebirth.

crimson jolt
#

pathfindinglagfix has the highest amount of support for vanilla enemies

#

because it's designed with them in mind and has some specialized patches for them

#

but it does patch some general pathfinding methods that most modded enemies will use

crimson jolt
nova relic
#

Thank you very much, at least for now, the performance of the game can still maintain a relatively high level with a large number of additional enemies. Adding this mod in the game at night has improved the performance by more than 40%.

tardy pivot
#

i belive Beta and stable use the same id, so if you have both BepInEx will skip stable and only load beta as it has a higher version number.

it is still better if you only have one of them enabled

keen ruin
#

only slightly annoying part is that you have to use separate executables for the game, so I just have two copies of the entire game and swap between them in Gale

slender wadi
#

Thats actually much better

#

glad i don’t have to patch an entire other project for that

#

I already have like 3 my harddrive is pleading to me

slender wadi
slender wadi
#

ahh cool

#

thank you

keen ruin
#

oh ew, just booted up that last profile you sent and immediately I see a heartbeat in the menu

#

time to profile

#

oh it's just LethalThings

keen ruin
#

tossing this bit of the deep profile here since I have no clue what a "commando" nutcracker is

#

but whatever it is, it takes up way too much time setting itself up through LethalEmotesAPI it seems like

#

also something called "nutcracker3"

ashen harbor
#

🤔

keen ruin
#

shrug I don't play heavily modded much

ashen harbor
#

From Colorful or ExtraEnemyVariety

#

I might be wrong

slender wadi
#

mod that basically adds skins to existing enemies through the API it uses

#

coulda sworn i already removed that from the modpack

keen ruin
#

why does it need to use an emotes api though?

#

wouldn't this just be a model replacement?

#

it's spending a disgusting amount of time on Start() for it being purely cosmetic though

ashen harbor
#

I thought the same

slender wadi
#

hm

#

only thing that'd need to use the emotes api is BadassCompany

keen ruin
#

@slender wadi looks like StarlancerEnemyEscape is causing some massive stutters on that map, you may want to disable it and see if the problem goes away

#

if it doesn't, lemme know and I can profile again

#

I wanna say though that if there aren't any other pressing issues, I'll demote that log to debug and push v2 to stable

#

it's taken long enough

slender wadi
#

besides the log spam from the hydrogeres (which considering you profiled it, probably means it wasn't an issue that impacted performance), i don't believe i experienced anything else

keen ruin
#

I did see the masked causing an AI interval stutter due to trying to find the elevator

#

masked is just really really bad in vanilla on any interior other than Mineshaft

#

I might add a patch to PathfindingLagFix if nobody else has patched it already

#

but if anyone has, I will break their patches by doing so and some mods may not handle that too happily

crimson jolt
#

nobody has patched masked yet

#

if it's not too much to ask

#

it might be a good idea to do a diff between v56 and v69 to see what exactly changed with their AI

#

if any issues are noticeable

keen ruin
#

well I know what the issue is

crimson jolt
#

because a bunch of people have reported issues with their pathfinding ever since the mineshaft update

slim prism
# keen ruin tossing this bit of the deep profile here since I have no clue what a "commando"...

Commando the internal name for emotesAPI skeleton initialization. Every enemy has a skeleton that can be animated so they are compatible with emotes made for the player skeleton if so desired. This is only called on start and has no tangible impact on gameplay performance that we have been able to measure through extensive testing. If you wish to see a mod utilizing this feature of emotesAPI you can test it with EnemyInteractions.

keen ruin
#

it calls FindObjectOfType every interval

crimson jolt
#

in mineshaft interiors they tend to get stuck going up and down forever

#

the elevator

#

i don't think i've seen them hide in the player's ship ever since v60

keen ruin
crimson jolt
#

they seem to just walk around outside for a brief second then immediately walk back inside the building

#

but only sometimes

crystal chasm
keen ruin
#

yes

#

but I think it may have been more than that, perhaps that's because it was the first spawn? not sure

crystal chasm
#

on a start call that get's called like, at most like 2-3 times a run?

slim prism
keen ruin
#

let me fire it up again shrug

#

maybe I'm being a stickler, but I don't really think it's acceptable for an API to cause a significant deviation like that, even if it is only at Start(), if there is any possibility of amortizing or offloading that cost

#

although arguably maybe this is an issue with the assets being loaded? I don't know anything about the API

#

(speaking specifically about during normal gameplay)

crimson jolt
#

i wasn't just referring to the spikes

#

although yeah, obv Object.FindObjectOfType is unnecessarily expensive

keen ruin
#

oh you mean the inconsistent/strange behavior?

slim prism
# keen ruin maybe I'm being a stickler, but I don't really think it's acceptable for an API ...

Part of the API allows you to use any emotes to work with enemies, in doing so and to make one animation compatible with all rigs in the game, a secondary control armature is prepared during that time that can be activated whenever an emote mod choses to do so to allow any enemy to use said emote. As far as I'm aware only EnemyInteractions utilizes this feature as of current but in our past testing, all frametimes fell within margin of error of vanilla having no impact unless there were literally hundreds of enemies at once.

crimson jolt
#

could check if RoundManager.Instance.currentDungeonType == 4 before searching for a mineshaft elevator, if you believe that is an acceptable fix

#

but anyways yeah

#

it feels like their wandering behavior doesn't work like it used to at all

#

and despite zeekerss putting "fixed masked getting stuck on the elevator" in 2(?) update changelogs it is still definitely a problem

#

i did a diff between v56 and v69 on my own end and it looks like he just completely rewrote the masked behavior in state index 0

#

so it's a bit hard to tell what exactly changed

#

maybe i will look into it on my end and just make masked fixes

#

Lol

keen ruin
keen ruin
#

I'll try to get another profiler recording of that frame on the same seed to give you a better view

#

and I'd like to make it clear, I don't know if there's a better way to do what you're doing, I just see something spending a lot of extra time and I'm immediately suspicious that there may be

#

be it object pooling, threading, async/coroutine, etc

crimson jolt
#

no caching whatsoever

keen ruin
#

huh, I'll have to look out for that then

crystal chasm
#

does that account for waiting time in coroutines?

keen ruin
#

also, I don't see EnemyInteractions in here

keen ruin
slim prism
keen ruin
#

indeed, I'm aware it's a separate mod

#

that's my point, this doesn't have that, so presumably the functionality is unused?

slim prism
#

No, enemy interactions calls the secondary armature instantiated on enemies that spawn, it does not mess with the spawning of the armature

keen ruin
#

calls?

#

what do you mean by calls?

#

it requests to use it?

#

if the skeleton is unused, why is it being instantiated?

slim prism
#

Every entity, player and enemy, are capable of emoting with emotesAPI, thats kinda the point of emotesAPI, its up to emote packs or plugins to utilize the feature.

keen ruin
#

you can't do so lazily?

crystal chasm
#

what

keen ruin
keen ruin
#

if someone asks for the skeleton, can you not create it then instead of doing it in Start()?

#

assuming that is not already the case, but from what you said I'm getting the impression it isn't

crystal chasm
#

I mean you are technically correct yes, but that was deemed not necessary

keen ruin
#

it certainly appears to have a non-negligible effect on frame pacing to me

#

debug builds aren't significantly slower than release, when not using deep profiling, so this should be pretty indicative of the actual cost

#

the fact that it's calling LoadAsset every Start() seems very strange to me

#

doing that ahead of time at game startup would cut the runtime of the first iteration of this coroutine from 1.75ms to 0.22 ms

#

and not only that, but you can do it async so that it doesn't block the main thread (if Unity does things correctly)

crystal chasm
#

A: didn't think about it

B: from quick google search (so correct me if you have more experience with it), if I call loadasset on the same item while still having references to it, people are saying unity keeps a cached version of it

keen ruin
#

I mean, I don't use the mod personally, so I have no stake in it, but it would be good to run the profiler on these things to determine if they are worth doing or not

#

caching it ahead of time means that you don't get a stall for each new enemy spawned, regardless, so I don't think it makes sense to tell me that it was "deemed not necessary" if you didn't know this was happening

#

I didn't mean any of this to sound like an attack on your mod, but it definitely pays to do your due diligence with regard to performance

crystal chasm
#

oh I couldn't agree more

keen ruin
#

with v2 of PathfindingLagFix, I'm aiming for a deviation due to the work the mod is doing of less than .1ms, and it doesn't seem like that should be too hard to achieve in most cases

#

frame times become drastically better by cutting out synchronous pathfinding, so anything like this becomes painfully obvious on a frame time graph

#

anything that is a non-optional dependency should not be allowing this unless it's absolutely necessary in my opinion

slender wadi
#

alr on second thought it's almost 1:30 in the morning for me, so i'll try to get you that profiler log in the morning
i disabled StarlancerEnemyEscape and added the LethalThings dart mod, and i'm currently not experiencing any big lag spikes, if i'm experiencing any at all

keen ruin
#

obviously it's much much worse if it happens in an Update() call, but enemy Start() isn't exactly a rare occurrence, and I find that there are way too many mods doing way too much in hooks on those methods, to the point where a heavily modded pack gets a deviation of something like 10-20ms from an enemy spawn (not even just due to logging)

#

that's good to hear, and yeah, get your sleep NODDERS

#

if it happens again we can have another look

keen ruin
#

Well, here goes nothing:

Version 2.0.0

Note that this has the same mod ID as PathfindingLagFix Beta, but a lower version, so that will need to be disabled in order to run the stable version.

  • Rewrote the mod to run all pathfinding patches off the main thread using PathfindingLib, reducing the performance impact of many forms of vanilla enemy pathfinding to near zero. This provides a general framerate improvement when many enemies are spawned, especially for hosts.
  • All patches have been completely rewritten.
  • Patched behaviors now include:
    • All roaming AI (i.e. thumpers, lootbugs, coilheads, and many more)
    • All omniscient player targeting (i.e. blobs, jesters, brackens, and more)
    • Bracken hunting, evasion, and hiding spot pathfinding
    • Snare flea hiding spot pathfinding
    • Spore lizard evasion pathfinding
    • Tulip snake dismounting pathfinding, and calls to FindObjectsByType<FlowerSnakeEnemy>()
    • Manticoil evasion pathfinding

For anyone currently running the beta, nothing has really changed since beta version 2.0.11, but hopefully things will remain stable for the inevitable massive influx of downloads on this mainline release 😅

#

(apologies for not matching the stable version to the beta version, but I don't want to just leave a big gap in versions for the stable branch, blame Thunderstore for not supporting version revision numbers)

keen ruin
#

Pathfinding Lag Fix v2

old sapphire
#

Hi, I would like to know if this mod has or could have incompatibilities with Diversity that does AI revamps, LostEnemyFix, StarlancerIAFIX, SpiderPositionFix, FairAI.

Sorry for the inconvenience and thanks in advance. ^^

keen ruin
#

I haven't been informed of any issues with those mods, and I would expect any conflicts to occur during startup

#

it's definitely not intended to conflict with or compete with any of those, so any such issues should be reported and fixed

old sapphire
#

Ok perfect, thanks

steep tartan
#

That's just a guess, but idk if this mod can do something about the masked

keen ruin
#

I tend to stay away from bug fixes in this mod because it's mainly intended to be faithful to vanilla, only exception is the bracken stopping in front of the player when within a certain range since that bug is directly affected by one of the async patches for the bracken

#

at some point maybe I would end up making another mod that introduces actual bug fixes, but if Butter beats me to it on the masked I wouldn't complain

steep tartan
#

Technically, it would be faithful to vanilla because masked worked like that before the mineshaft update Trollface

keen ruin
#

that's arguable, yeah, but there are people that depend on certain behaviors for high quota, and I don't want to interfere with that in a mod that is otherwise intended to be purely for performance

#

I personally have no aversion to making new projects to keep things separated, I've never been bothered by big mod lists if everything has its defined purpose and does it well :^)

steep tartan
#

Ok that's fair

#

If you're to make another project dedicated to the masked, I would also like to request a feature related to him spawning with a random suit from the rack yoiled

keen ruin
#

oh if I did make such a mod it would be strictly for bug fixing, there's already enough mods that screw with making them more "player-like"

#

I don't want to get into that rabbit hole where I'll have a million compatibility bugs, unless I have a good motivation to do so

steep tartan
#

Well, at least I tried 😔 anyway it would be a cool mod

tardy pivot
#

that feels more fitting for mirage tbh. but i belive it already does

keen ruin
#

yeah, my first thoughts were of Mirage, Lethal Intelligence, MaskedAIRevamp, and GeneralImprovements

#

all of them mess with the masked in fairly overlapping ways, so it's kinda shocking to me that people don't have more issues with compatibility when it comes to mods affecting masked

steep tartan
#

But all of them make the masked copy the player suit/cosmetics

#

I wanted the masked to be able to spawn with a random suit from the rack, not exactly mimicking the player

#

(And be client-side ofc)

#

I don't believe all previous employees had the same orange suit 😭

green gust
#

I love the "and be client side ofc"

tardy pivot
#

to be fair that can be done quite easily

tardy pivot
#

Postfix to Start and call setSuit with a random suit id

if there is a Awake postfix that instead

crimson jolt
#

or the generic AI functions

#

i would've never discovered the cause of that bracken bug you mentioned in v60 because it's a mess of reused variables across multiple generic AI functions, for example

#

I was just wondering if you had any idea what specifically seems to be going wrong with the masked and if it's possibly related to something similar

#

i do care a lot about the possibility of fixing this bug though, it's a noticeable downgrade in behavior

#

so i'll probably try to figure out when im not busy working on other stuff

green gust
#

Is the bug a downgrade in mineshaft, in general, or non mineshaft?

crimson jolt
#

it feels like they don't act like they used to at all, regardless of the interior type

#

but they act especially incorrect in mineshaft because they seem to just get stuck taking the elevator up and down forever

green gust
#

Interesting, I'm not good with transpilers at all but I could try giving the code a read since I've had to implement the same elevator behaviour beforehand

crimson jolt
#

in v45 they would exit the map and wander around outside

#

and they'd even hide aboard the ship if they made it there and didnt encounter any players along the way

#

all of the code for functionality like that still exists and he never made any mentions of removing it, but it doesn't seem to happen anymore

#

most of the time they just leave the main entrance, walk around for a few seconds, and then walk right back into the main entrance

#

and get stuck in a loop doing that for forever

green gust
#

Hmm that's gonna help narrow it down if they're just in a kind of loop, hopefully it's not in too much of a mess though I know that's kind of hard with how the elevator is built

crimson jolt
#

in vanilla (this seems to be the case in mods like mirage and generalimprovements as well) masked never change suit more than once

#

and i fixed the bunny suit and bee suit not displaying their costume pieces on masked

#

but i never implemented any functionality to remove those costume pieces if they switch suit to something else

#

that is a problem i would need to address on my end to support this behavior, because otherwise, it would create visual issues if they randomly select the bee/bunny suit on spawn, and then get reassigned to another suit (such as if the mimic spawn coroutine recognizes they should be mimicking a player's appearance some frames later)

#

if im bundling all of my masked fixes into a separate mod then i guess that'd be a good opportunity to implement that

crimson jolt
#

he completely replaced the code in behaviourStateIndex == 0 from v56 -> v69

green gust
#

Yeah im looking now too, I know decompiled numbers aren't too accurate but 2600 lines is quite a bit to go through

crimson jolt
#

and im at least 99% confident that's where the issues lie

#

but he turned it from a 38-liner to a 107-liner

#
bool flag = false;
PlayerControllerB closestPlayer = base.GetClosestPlayer(false, false, false);
if (!this.isOutside && closestPlayer != null && RoundManager.Instance.currentDungeonType == 4 && Vector3.Distance(closestPlayer.transform.position, this.mainEntrancePosition) < 30f)
{
    flag = true;
}
if (closestPlayer == null || flag != this.isInElevatorStartRoom)
{
    bool flag2 = false;
    bool flag3 = false;
    bool flag4 = true;
#

and it's always a joy to work with unnamed locals like this

green gust
#

Is elevatorTransform the ship transform?

#

Stored in startofround so I'm assuming it is

crimson jolt
#

elevatorTransform is gameobject HangarShip

#

yes

green gust
#

I'm also guessing mineshaft is dungeontype 4

crimson jolt
#

yes

#

at least as of v64

#

there was a bug before v64 where march didn't have any interior types assigned and wouldnt reset currentDungeonType from whatever value it previously stored

green gust
#

Amazing

crimson jolt
#

i forget if he fixed the core issue or just assigned a dungeon to march's interior list

#

so i would be subtly aware of the possibility that custom content might not properly handle that value

green gust
#

Oh the flags are starting to blend in my head now lol

crimson jolt
#

maybe i will move this to #dev-enemies since it's not strictly relevant to pathfindinglagfix anymore

spring prairie
#

And also masked going up and down the elevators was fixed by Zeekerss a while back

#

In v69

#

I feel like masked allegedly not working the same as they used to is placebo effect, obviously because they had been buggy the last few months until v69 so most people didn’t see them as frequently or just assumed they’re still buggy.

crimson jolt
#

they are definitely still buggy

#

it's not exclusively placebo effect

#

it's true there is most likely some factor of placebo

#

but i have played actual games and watched them take the elevator up and down forever

#

even in v69

#

and i've never seen them properly wander outside in actual games since v60, only in very specific conditions on my debug profile

#

doesn't necessarily mean it's not happening, since you have limited info on most enemies in actual conditions

#

but the few masked i've actually observed in game seem to just go back and forth inside/outside like i was mentioning before

green gust
#

might be related, but i believe the main entrance point in some mineshaft generation actually doesnt spawn next to the entrance so stuff like masked wouldnt be able to go through the entrance (i think)

#

i'd had to check it more often but mineshaft's different door location could be a thing to check

slender wadi
#

okay was testing out again today, and i can confirm i didn't get any lag from pathfinding

#

i have however found this though from JLL and wesley's moons

#

which is probably why i've been lagging?

#

i saved the .data file but it's like

#

300mb

#

so i might need to get out mediafire for that

#

i also don't think i spotted that masked thing from yesterday after i disabled StarlancerEnemyEscape

#

though i have to check to make sure

keen ruin
keen ruin
#

makes sense that you were having the log spam if it was having constant spikes to 40-60 ms

#

what is your frame rate like on vanilla moons? assume based on that profile that your machine must not be super powerful?

#

definitely is very interesting to see a profile from a machine that struggles to run the game, it would be awesome to get a look at a profile even just from late night March with a fairly vanilla profile (preferably with PathfindingLagFix), too

#

(as well as this modded one that you grabbed)

slender wadi
#

i have a pretty

#

okay? gaming laptop

#

it's suited me well for the six years i've had it now

keen ruin
slender wadi
#

yeah same here

#

im abt to profile it again so i can test it rn

keen ruin
#

yeah, if you have UnityExplorer you could simply open the inspector in its free cam and mouse inspect the mines to see what they're called

#

I am still curious what kind of fps you expect to get generally

slender wadi
#

i usually expect to get like 40-65 fps

#

though it feels like it's around 20-30

scenic zinc
#

I’m curious what the actual fps data displayed here is

#

I’d think Current FPS, Average FPS, 1% Lows, 0.1% Lows

#

But that doesn’t work since the third one is larger than the second in the after image

#

Also is that vanilla vs 2.0 or 1.4 vs 2.0?

slender wadi
#

alright, brought the unity explorer on board, left image is without Oldred's mine's and the art gallery's lassoman features (mysterious paintings, hanging ropes, etc.), middle image is with with only the lassoman features on, and right image is with only the oldred mines on

#

righttt discord formats images like that
left image is with nothing
top right image is with only lassoman features
bottom right image is with only oldred mines

keen ruin
#

left number and the frame time graph are the main things to pay attention to

keen ruin
#

er wait no

#

lassoman is the issue?

#

not that I know what that is lol

green gust
#

@heavy carbon does the lasso stuff in art gallery have any custom code or is it just a combination of interact triggers and JLL scripts with animations?

heavy carbon
keen ruin
#

huh, then maybe it was a fluke, it not showing up in the last profile there

#

what's WesleyMoonScripts.dll and its LoneTrap component?

#

looks like it's doing way more work than is reasonable, but not sure how yet

#

I've never once seen OverlapSphere take a whole millisecond

ashen harbor
#

I've never had any lag from the Lassoman stuff so it might be shenenaigans happening when running a debug build to profile

keen ruin
#

very doubtful, I've never seen physics queries take that long

#

it's easy enough to confirm though

ashen harbor
#

It might just be in actual gameplay it's not really noticeable

#

Idk

keen ruin
#

finally got around to looking at the script though, and I see two issues:

  • It's using the allocating version of OverlapSphere
  • It's not passing a layer mask to the OverlapSphere to avoid calculating intersections with and allocating space for colliders that are not involved in this component's interaction
#

not only that, but I would tend to think that a distance calculation on each player in allPlayerScripts would be faster, though that definitely should be profiled

#

if the radius of the OverlapSphere is large enough, it definitely seems like that could explain the long runtime of that call

green gust
keen ruin
#

JLL I guess

#

idk why it's called WesleyMoonScripts but that's what it is

green gust
#

ah lol

#

ill bother jacob about it when he's back

keen ruin
#

I mean really what we probably need is a seed to reproduce this extreme slowdown, just so that he can confirm that a new method of doing this actually fully solves the slowdown, but I think that the iterative approach should be something like 30 microseconds max, and therefore could run every frame instead of fixed update if desired

#

(FixedUpdate is generally not advised for running anything except rigidbody stuff)

green gust
keen ruin
#

animating transform rotation in there especially seems ugly, that would result in a stuttery movement that cannot be solved by turning on interpolation as it isn't actually going through a kinematic rigidbody

#

also worth noting that any extra work you put into FixedUpdate() will mean that you'll have frametime variance due to running things on a 50Hz update instead of every frame

#

better to schedule your things to run on some interval that you can space out between all components if it's at all heavy

#

or zeekerss's solution for AI of randomizing an interval within a very small range kinda helps with that somewhat

#

but physics updates themselves cause the frame times to fluctuate constantly anyway, we don't need to make that any worse

#

I wish we could do cheaper/partial physics updates more often instead of running on a fixed interval

crimson jolt
#

sorry to keep coming back to the masked thing

#

are you sure the lag affects interiors other than mineshaft?

#

i agree the findobjectsoftype isn't necessary since he could just use the one cached in roundmanager.instance

#

but "flag" is only true if currentDungeonType == 4 (meaning a mineshaft generated)

#

and isInElevatorStartRoom defaults to false

#

so on any other interior wouldn't flag != isInElevatorStartRoom always be false != false and then the branch would be skipped

crimson jolt
tardy pivot
#

isn't the branch on an or?

crimson jolt
#

oh duh

#

you're right

#

can't believe i walked through all that logic and completely missed that LOL

tardy pivot
#

rip

#

that happens

#

logic from what i read seems to be:
if we're in mineshaft, there is a player inside and the masked just came back from outside
then the masked tries to use the elevator to get back in the facility.
or
if there is no player inside
then try to use the elevator to reach the main entrance

#

the logic for using the elevator seems to be only one so that's probably why the masked tend to get stuck in a loop in the elevator

old sapphire
#

They called him Matty Fix

#

xD

green gust
#

A matty of sorts?

keen ruin
#

Version 2.1.0

  • Fixed a bug that would cause the bracken not to path out of line of sight in some situations.
  • Added presets and options to configure the bug fixes that slightly change behavior from vanilla.
#

also yeah what Matty said

#

I think that logic is:
if the masked has no targetable player (no players in the masked's current area, be it inside or outside)
or if the masked's closest targetable player is in the entrance room and the masked is not, or vice versa
use the elevator

crimson jolt
#

yeah

#

it definitely doesn't work exactly that way in game

#

you can stand in the entrance room and watch masked go up and down the elevators constantly, as long as they don't see you (or maybe even if they see you?)

keen ruin
#

yeah was it you that mentioned the radius is too small? feels like it maybe should be a bounds check

crimson jolt
#

but i think you are right that that is the intent

keen ruin
#

huh, really?

crimson jolt
#

if ramps generate at the bottom of the elevator you can trick the masked into thinking you're in the top room while you are at the bottom of the elevator

keen ruin
#

oh I see

crimson jolt
#

that ought to be fixed

#

i definitely agree with a rectangular bounds check being the approach

keen ruin
#

yeah feels like that definitely should be a small bounds check instead of a big ol sphere

crimson jolt
#

at this point im working on a plugin to fix the masked (since i have a bunch of fixes from butteryfixes i could migrate, plus i want to tackle this eventually)

keen ruin
#

although.. be careful of that one moon that tilts the interior

crimson jolt
#

so i will try to deep dive and figure out what is exactly happening

keen ruin
#

yee

#

sounds nice

green gust
keen ruin
#

I assume you shouldn't need to overwrite my patch to make it not call FindObjectOfType?

crimson jolt
#

oh did you patch that in pathfinding lag fix?

keen ruin
#

not yet

#

soon tm

crimson jolt
#

i was gonna do it myself

keen ruin
#

oh I see

crimson jolt
#

but the way i was gonna write it

keen ruin
#

well we can both do it :^)

crimson jolt
#

it will not crash or throw an error

#

if someone else does it first

keen ruin
#

yee

crimson jolt
#

because my transpiler style is kinda goofy

keen ruin
#

oh? lol

crimson jolt
#

yeah i just iterate through the code instructions with a for loop and do a bunch of operand checks around surrounding indices

#

i still have never figured out codematchers

keen ruin
#

anywho mine are also written similarly, they should all soft fail

crimson jolt
#

lol

keen ruin
#

oh god

#

please do that

#

initially that was what I tried to do, but if you try to do anything remotely complex it becomes unmaintainable

crimson jolt
#

... yeah...

keen ruin
#

CodeMatcher isn't too bad to use but I honestly like having a home grown one

#

CodeMatcher really shouldn't be too hard to figure out, lemme know if you want some help with that

#

or if you wanna use my class teehee

crimson jolt
#

yeah i want to get better at writing transpilers but most of the time i try to avoid them completely if i can

#

and whenever i do write them it's so easy to just fall back on being lazy and doing it the old way

#

but there are definitely some shortcomings that have caused me trouble before

keen ruin
#

I think that style makes it way too easy to make it dependent on code being laid out in a certain way without being able to verify it conveniently

crimson jolt
#

sometimes (i forget exactly what circumstance but it's been an issue before) i can't use accesstools to get the right methodinfo

#

so i've had to just read the method in the operand as a string and do contains

#

and that's pretty ugly and terrible

#

but "functional"

keen ruin
#

oh you'll have to use something like AccessTools or the C# reflection classes even with CodeMatcher

keen ruin
#

oh god

#

yeah generics are tricky

#

I have a helper for that

crimson jolt
#

or maybe it was like... methods with a lot of overloads

#

because sometimes i couldnt just match the parameter types

#

i forget why that was a problem

keen ruin
#

hmm definitely should be able to

crimson jolt
#

not sure if you plan to address this yourself

#

but im also probably just going to prefix and replace the RoundManager.FindMainEntranceScript and RoundManager.FindMainEntrancePosition functions

#

since they each call FindObjectsOfType and Masked call them like 3 times each time they use the entrance doors

#

it might actually provide some small boosts for other enemies like bracken, maneater, etc. that also reference this function in their AI

#

you could just cache EntranceTeleports as they spawn (and worst case, do a FindObjectsByType if the list is empty) and it would probably be identical to 99.9999999999% of vanilla and modded use cases

#

so that is what i am going to do

crimson jolt
crimson jolt
#

@keen ruin @green gust i think i figured something out

#

it looks like masked can't wander around outside if the only players outside are inside the ship and the ship is closed

#

i'm using imperium to free cam above the map and i'm noticing they just constantly go in and out of the building if the ship doors are closed

#

but if the ship door is open, or i am standing off of the ship, they wander around outside freely

#

i think it's probably pretty safe to call this unintentional behavior

#

since it calls GetClosestPlayer with cannotBeInShip and cannotBeNearShip both false

#

but without going back to check v49 i can't say for sure if this is consistent with how masked have always functioned

#

it seems like the problem is just that the logic of EnemyAI.PlayerIsTargetable is wrong

#

because it does this check

(!this.isOutside || !StartOfRound.Instance.hangarDoorsClosed || playerScript.isInHangarShipRoom == this.isInsidePlayerShip)

regardless of if cannotBeInShip is false

#

i am not sure how to go about fixing this

crimson jolt
#

alternatively a special patch could be written specifically for the masked

crimson jolt
#

i did notice that as long as im encouraging them to use the proper behavior (by leaving the ship door open and standing outside the ship somewhere)

#

they will enter the ship and hide just like they used to

crimson jolt
crimson jolt
#

holy shit yeah

#

i optimized all of the functions using FindObjectsOfType<EntranceTeleport>() and assigned the cached elevator in MaskedPlayerEnemy.DoAIInterval()

#

and did a quick test spawning 50 masked inside the building then warping to the surface

crimson jolt
#

but if i disable all the patches it causes horrendous performance

crimson jolt
# crimson jolt

i drop to like, <10 FPS until the masked manage to use the doors (so closestPlayer will stop being null)

#

that elevator search is bad

keen ruin
#

I could probably make a fully accurate caching patch for that by transpiling FindExitPoint

crimson jolt
#

i just did it in a prefix

#

but yes

#

there's no caching

#
static bool EntranceTeleport_Pre_FindExitPoint(EntranceTeleport __instance, ref bool __result)
{
    if (__instance.exitPoint == null || __instance.exitPointAudio == null)
    {
        for (int i = 0; i < entranceTeleports.Count; i++)
        {
            if (entranceTeleports[i] == null)
                continue;

            if (entranceTeleports[i].entranceId == __instance.entranceId && entranceTeleports[i].isEntranceToBuilding != __instance.isEntranceToBuilding)
            {
                __instance.exitPointAudio = entranceTeleports[i].entrancePointAudio;
                __instance.exitPoint = entranceTeleports[i].entrancePoint;
            }
        }
    }

    __result = (__instance.exitPoint != null);
    return false;
}
#

entranceTeleports is a static list i manage (they add themselves in Awake and remove themselves OnDestroy)

#

i believe this is identical to the original function

keen ruin
crimson jolt
#

i did the same for the other two functions i mentioned

crimson jolt
#

it's just a bit of a pain

#

i can probably just do a code diff and know for sure

#

since i'm aware of the function causing the issue now

keen ruin
#

oh ew a prefix cancel

keen ruin
#

prefix cancel is totally incompatible with me making an alternative patch with a transpiler

crimson jolt
#

yeah im only prefixing it on the assumption nobody else cares to touch this

#

but if you intend to handle it yourself i suppose i will need to actually do the work

#

i did want to reach out in case you had plans

keen ruin
#

you would have to detect whether my patch ran and allow the original to run or else we get a situation where my code is unaware that it can't be run and replaces the returned value with null

crimson jolt
#

i normally just check the chainloader on startup and cache a bool

keen ruin
#

I would like to, if that is indeed a costly operation in practice, I'll have to check though

crimson jolt
#

if i need to return true before my custom code

keen ruin
#

hmm

crimson jolt
#

in fairness i can probably just replace the findobjectsoftype call with a reference to my static array using a transpiler

keen ruin
#

you could just postfix it and check if exit point is non null and it has the teleport id you want

crimson jolt
#

i forget if i optimized anything else

crimson jolt
#

there is no branching that happens beforehand

#

that is the case for all 3 functions i mentioned

#

it would require prefix cancel or transpiler

keen ruin
#

in FindExitPoint? it's only called if the exit is not already found

crimson jolt
#
public bool FindExitPoint()
{
    EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>();
keen ruin
#

check where it's called

crimson jolt
#
public void TeleportPlayer()
{
    bool flag = false;
    if (!this.FindExitPoint())
    {
        flag = true;
    }
#

every time the local player uses the teleport it gets called with no check

keen ruin
#

oh huh

crimson jolt
#

it is kind of confusing

#

he has like 3 similarly named functions that all do similar things

crimson jolt
keen ruin
#

that's certainly not ideal but doesn't mean my solution doesn't work

#

feels like fixing that is a job for a different mod

#

it's not that huge a deal

crimson jolt
#

i don't exactly disagree

keen ruin
#

postfixing the method and checking it still works fine

crimson jolt
#

it probably belongs somewhere in like, lethal performance, if it weren't going to be put here (which it sounds like it might be)

keen ruin
#

nah I wouldn't patch that here

crimson jolt
#

the custom logic would have to replace the original function call (either prefix or transpiler) or it will still do FindObjectsOfType immediately when it is called

#

at that point custom logic doesn't matter, since you're trying to avoid the search

#

right?

keen ruin
#

I mean you can set your cached main entrance from a postfix of FindExitPoint and not have to cancel the method and potentially break transpilers

crimson jolt
#

oh

#

im not caching the main entrance

keen ruin
#

wha

crimson jolt
#

im caching a list of main entrances and im substituting the search in all the functions that do a search

#

with an iteration through that cached list

keen ruin
#

that.. uh

#

I mean

#

that's a fine solution but it feels like it's excessive for a masked fix mod

#

that affects a whole lot more than the masked

#

if you put that in your main fixes mod that would make more sense to me

#

but also I still disagree with making it a prefix

crimson jolt
#

well

#

i am sort of making the assumption that nobody else is touching these functions

#

which i think is a fair assumption but it is probably not the best etiquette

#

it's true

keen ruin
#

you shouldn't have told me about the issue then lol

crimson jolt
#

i will double check and see if im doing any other optimizations

#

and if im not i will just transpile and replace the search with a reference to the array

#

i suppose

keen ruin
#

then again I can probably do it with a postfix and not be broken by your changes I guess

crimson jolt
#

i suppose that is fair enough

keen ruin
#

how are you making the array?

crimson jolt
#

oh sorry it's a list not an array

keen ruin
#

ah

#

well you're gonna have to do a little trick then

#

hold on

crimson jolt
#

i create a list with 8 slots (march has 4 entrances, so that covers all vanilla levels without resizing)

#
[HarmonyPatch(typeof(EntranceTeleport), nameof(EntranceTeleport.Awake))]
[HarmonyPostfix]
static void EntranceTeleport_Post_Awake(EntranceTeleport __instance)
{
    if (!entranceTeleports.Contains(__instance))
        entranceTeleports.Add(__instance);
}

[HarmonyPatch(typeof(NetworkBehaviour), nameof(NetworkBehaviour.OnDestroy))]
[HarmonyPostfix]
static void NetworkBehaviour_Post_OnDestroy(NetworkBehaviour __instance)
{
    if (__instance is EntranceTeleport entranceTeleport)
        entranceTeleports.Remove(entranceTeleport);
}
#

and it is managed by this

keen ruin
#

yee that's good enough, although enable/disable would be preferable if those exist

#

this is what I do for tulip snakes to avoid allocating each access

keen ruin
#

(you don't have to add the branches, I'm just doing that so that I can test before/after to ensure nothing changes)

crimson jolt
#

i assume there's no convenient way to like

#

pseudo-patch EntranceTeleport.OnEnable for example

#

i've always just patched the base class's method and had a type check but that feels kind of dirty

#

idk if there's a better way

keen ruin
#

if it doesn't have those methods then I wouldn't bother

#

you can just test the enabled property

crimson jolt
#

yeah it only has awake and update

#

no start even

keen ruin
#

and destroy?

crimson jolt
#
static void NetworkBehaviour_Post_OnDestroy(NetworkBehaviour __instance)
{
    if (__instance is EntranceTeleport entranceTeleport)
keen ruin
#

oh

crimson jolt
#

the other option is clearing the list after a scene unloads which is fine for 100% of vanilla cases

#

but i dont know if that assumption holds true for all custom content

keen ruin
#

someone will break that assumption for sure

crimson jolt
#

yeah i was concerned about that

#

networkbehaviour apparently doesnt even override onenable or ondisable

#

so i'd have to go a step up and patch monobehaviour

#

and i feel like the further up you go, the more processing time you waste on interactions that are executed globally

#

and that nullifies a lot of the benefit

keen ruin
#

yeah

crimson jolt
#

i think it is sacrificing parity with vanilla's return values (potentially breaking modded content) or overstepping into patching base methods

#

without much happy middleground

keen ruin
#

yeah, I'll brainstorm a bit when I'm at my PC in a minute

#

really, I think it's fine for it to call it always and just transpile TeleportPlayer to not call it if the exit point is already found

#

but this all is something that I think is worth suggesting to DiFFoZ, since he has a patcher that can add methods if desired

#

(I believe)

crimson jolt
#

well the only reason i've been doing it myself is because i think he's been on hiatus recently

keen ruin
#

yeah

#

it's not really urgent though, teleport has always been a bit slow tbh

crimson jolt
#

i was also doing vehiclecontroller caching over in butteryfixes because that is "no ETA" on lethalperformance's side

#

although it's still eventually planned i believe

keen ruin
#

bit if you wanted to transpile that to not be called within ButteryFixes or something that would maybe be fine

crimson jolt
#

well

keen ruin
#

I see

crimson jolt
#

i will probably rewrite them to be transpilers

#

at least

#

doing the prefixes was nice because it made it really quick and easy to test

#

and the performance is definitely a boon, for me

#

but i think you are right and i should probably do it the proper way instead of doing it the lazy way

#

and hoping it will last "long enough" beore someone breaks it

#

Lol

keen ruin
#

you find it noticeable when you teleport?

crimson jolt
#

no i don't really care much about the findexitpoint thing

#

that was just easy to fix cuz i was fixing everything else the same way at the same time

crimson jolt
#

and each one is an unskipped FindObjectsOfType call with 0 caching

#

the biggest performance boost was definitely from the elevator caching

#

though

keen ruin
#

right

#

definitely is something I would like to include here since it can be a pure performance patch

crimson jolt
#

yes

keen ruin
#

with no behavior change

crimson jolt
#

i was patching them because atm nobody else is patching them

#

but i think that FindMainEntrancePosition, at least, belongs here, ultimately

#

it's used in pathfinding for multiple enemies

keen ruin
#

yeah

crimson jolt
#

FindMainEntranceScript is only used by the masked

#

and it's just so he can play the sound of the doors opening when they teleport

#

so that one doesnt matter as much

keen ruin
#

it's funny that there are two methods that do almost identical things, just one gets the position on top of that logic to find the entrance

crimson jolt
#

i think i actually transpiled out its call in EnemySoundFixes because it warranted replacement with a custom function

keen ruin
#

huh I see

crimson jolt
keen ruin
#

was it playing the sound on one side regardless of which direction it was going?

crimson jolt
#

but each have different "default" behaviors

#

find position returns Vector3.zero if it doesn't get a valid result

keen ruin
#

ah right

crimson jolt
#

and find script returns whatever is at the front of the array (so whichever has the lowest instance ID)

#

or returns null if the array is empty

#

you could easily hook null & Vector3.zero into each other

#

but the return array[0] thing kind of throws a wrench into chaining them with correct behaviours

#

at least, for my money

keen ruin
#

if I just use a cached field it's fine

crimson jolt
keen ruin
#

but I have to figure out how to get the "first" one if it fails

crimson jolt
#

i forget which way it was, but it was either players make the door open sound on walkie talkies or the masked do

#

and the other didn't

keen ruin
#

not that I think it really matters, but best not to change behavior at all

crimson jolt
#

i just replaced the call in both functions to a shared function that plays audio on both sides of the door, as well as on walkie talkies

keen ruin
#

oh, do players make the sound on both sides too? I haven't really paid attention to that

crimson jolt
#

yeah, players make audio on both sides of the door, masked only make audio on what side they end up

#

and then one or the other plays the audio on nearby radios in addition to that

#

anyways

crimson jolt
#

im tempted to just leave the findmainentrancescript prefix in since it's only used by masked, but i can practically guarantee some custom mod is using it, and maybe another mod is patching it

#

so i think that is laziness speaking over reason

#

i will probably just rewrite all of them to be safe

#

or well

crimson jolt
#

so maybe i will just leave that in someone else's hands if it proves to be an issue with custom content

#

i guess all im actually trying to say is, when you get a chance, look into patching RoundManager.FindMainEntrancePosition

#

i think it is of most interest to you

keen ruin
#

well you shouldn't need to worry about FindMainEntranceScript since I'm planning on patching it

crimson jolt
#

and I think it will be easy to replicate it with caching and still have vanilla paritous behaviour

keen ruin
#

I could probably bust out a transpiler in like an hour once I decide on the best solution

crimson jolt
#

probably

#

it's a very easy function

keen ruin
#

I gotta figure out the best way to ensure that it perfectly matches the vanilla output

crimson jolt
#
public static Vector3 FindMainEntrancePosition(bool getTeleportPosition = false, bool getOutsideEntrance = false)
{
    EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>(false);
    for (int i = 0; i < array.Length; i++)
    {
        if (array[i].entranceId == 0)
        {
            if (!getOutsideEntrance)
            {
                if (!array[i].isEntranceToBuilding)
                {
                    if (getTeleportPosition)
                    {
                        return array[i].entrancePoint.position;
                    }
                    return array[i].transform.position;
                }
            }
            else if (array[i].isEntranceToBuilding)
            {
                if (getTeleportPosition)
                {
                    return array[i].entrancePoint.position;
                }
                return array[i].transform.position;
            }
        }
    }
    Debug.LogError("Main entrance position could not be found. Returning origin.");
    return Vector3.zero;
}
#

you could simplify it down to this

for (EntranceTeleport teleport in cachedTeleports)
{
  if (teleport.entranceID == 0 && getOutsideEntrance == teleport.isEntranceBuilding)
    return getTeleportPosition ? teleport.entrancePoint.position : teleport.transform.position;
}
return Vector3.zero;
#

the fact it compresses so much is one of the reasons it's so tempting to just prefix cancel the original

#

but under the hood it might not actually offer much advantage

#

im not too sure

#

it just looks way cleaner

crimson jolt
#

or you could potentially get minute differences if custom content has multiple entrances tagged with an ID of 0

#

but im pretty certain there would be bigger problems if that was the case, because entrances depend on the ID to match with each other and function as teleports

#

so i doubt that is a tremendously common problem

keen ruin
#

caching just main entrance should also work, if I just only assign it if it's null

#

that would provide the first instance

#

prefix cancel feels like the play for those methods though

crimson jolt
#

you'd either need to cache both of the entrance teleports with ID 0

#

or you'd need to check for both entrance point and exit point (exit point is only selected when the player uses the teleport, so you'd need to find it yourself in this case to be safe)

#

imo it'd probably just be better to cache the entrance and exit but i suppose both would work

#

anyways i have some stuff i need to go do

#

i'd like to release all of this stuff tonight because i am also waiting to release something else

#

but thank you for the chat

#

i will continue to look into the masked behavior since i didn't solve all the mysteries i wanted to

#

the GetClosestPlayer and PlayerIsTargetable thing will be a tricky nut to crack

#

and IMO it probably approaches changes too subjective to be encompassed by pathfinding lag fix

#

but maybe it will be possible to fix their elevator usage without straying too far from vanilla's behavior

#

and the caching will defo help

keen ruin
#

oh I don't plan on doing any changes to their pathing in PathfindingLagFix

#

that's all you

crimson jolt
#

oh

#

maybe i misunderstood what you meant by this

#

but i see

keen ruin
#

ah yeah, I was just suggesting that it was probably a minimal change

#

I think the intention of the code is there, usually bugs like this are small oopsies

crimson jolt
#

i gotcha

keen ruin
#

very often related to optional parameters lol

#

optional parameters are evil

#

(sometimes)

crimson jolt
#

i think i just misread it as "i could probably fix this with minimal changes" but i see what you mean now

crimson jolt
crimson jolt
#

im not sure if you read (i've posted a lot) but part of the problem is that masked don't fetch the "closest" player if they are in the ship with the doors closed

keen ruin
#

also it's looking more like I'm just gonna do the list trick lol caching is more of a pain than I thought since I forgot it had both sides

#

the logic to get the right transform is kinda ugly

crimson jolt
#

because even though GetClosestPlayer says it doesn't care if players are in the ship, it calls PlayerIsTargetable which considers a player untargetable if they are in the ship, the doors are closed, and the enemy doing the search is on the other side of the doors (either inside while the player is outside or vice versa)

#

so if you lock yourself in your ship, the masked won't find any enemies inside and will go outside to search

#

then see no players outside and go back inside to search

#

endlessly, every 3 seconds, which explains the weird behavior people have been reporting regarding that

#

if you make yourself untargetable with imperium you can observe that behavior in plain sight, so i think that's probably clouding a little bit of the debugging process as well

crimson jolt
#

anyways i feel like zeekerss probably just intended that function to call to check "are players on the surface or inside the building" and so i will probably just make it a config option to simplify it to that

#

it deviates from vanilla behavior but i think it's probably closer to intent

keen ruin
crimson jolt
#

and i think it just feels better

crimson jolt
keen ruin
#

ah I suppose that's true

crimson jolt
#

if you have a corpse or a radar booster next to the entrance doors, and have your door closed

#

and imo it's not that tall of an order to have a corpse at the doors and your ship closed up on the moons that are spawning masked

#

so that kinda makes sense to me

keen ruin
#

replacing it with custom code to get the closest player including within the ship is probably fine

#

yeah

crimson jolt
#

anyways not to just dump work into your hands but if you're already planning to patch the main entrance doors

#

i feel like it's pretty likely i will either be doubling up on the work for no tangible benefit (our patches would have the same result) or just causing you problems i'd need to patch out of my mod later

#

so i might just leave it at the elevator caching and wait to see how things go over here before i get into anything else

#

the small lag spikes when they teleport is the lesser of two evils, anyway

keen ruin
#

yeah, up to you as long as your patches can soft fail and don't cause problems for mine 😅 I'll be putting this on the beta branch so you can always test it ahead of time

keen ruin
#

anyone else transpiling those methods would be pretty strange unless they're trying to fix this issue, and since I use postfixes for everything it shouldn't be able to break

crimson jolt
#

lol, i see

#

well that is unfortunate but i definitely cant blame you

#

anyone else transpiling those methods would be pretty strange unless they're trying to fix this issue
this is basically where i am as well

#

but i suppose you never know, in the end

karmic plaza
#

hey zags question, i assume the lag fix applies to any script using SetDestinationToPosition?

keen ruin
#

nono the async pathfinding is to reduce main-thread calls to CalculatePath (on NavMesh or NavMeshAgent)

#

also I just discovered this

#

I am in pain

#

zeekerss please

#

two calls to CalculatePath where one and a variable would suffice

keen ruin
#

also buttery, I'm seeing a masked go in and out with ship doors open on 42313928, might be worth lookin into

#

I'll check and make sure it still does that without my patches tho in a sec

keen ruin
#

oh sorry, on Titan

#

Mineshaft

crimson jolt
#

alrighty

#

i'll check it out

#

are you using imperium?

keen ruin
crimson jolt
#

i wonder if the offmeshlinks break their ability to pathfind to the player

#

but i thought titan's other staircase (the one by the fire exit) connects cleanly to navmesh

#

so idk about that

keen ruin
#

NavMeshAgent.CalculatePath should be totally consistent with SetDestination in that regard and all others

#

so I doubt it

#

unless it's calling NavMesh.CalculatePath and not communicating all agent config

#

yea this dude is just going in and out, no PathfindingLagFix

#

wait

#

did you say doors need to be closed?

crimson jolt
#

the problem is PlayerIsTargetable

#

if that returns false for any reason, they are considered invalid for GetClosestPlayer

#

what i was encountering was that if the ship doors are closed, and you are on the opposite side of the doors from the masked in question, it would not consider you as a target, and would go back inside the building

#

so if your ship doors are open, it could be anything else on that function canceling out your "targetability"

#

for example, if a masked grabs you, all other masked will start ignoring you (so if you were the only one outside, they will go back in the entrance)

#

it probably does a check for that one "inKillAnimationWithEnemy" value or whatever it was called

green gust
#

There's a couple that make you untargetable, but yeah prob

keen ruin
#

yeah it does

#

looks like it's not a problem with that, GetClosestPlayer() is returning me when he is outside

crimson jolt
#

oh

#

im stupid

#

i didnt register the part where you said mineshaft

#

this probably has to do with broken mineshaft logic yeah

keen ruin
#

oh I guess I forget what you said about that

crimson jolt
#

i still have not done a deep dive into that to figure out what is going wrong

#

but

keen ruin
#

ah

crimson jolt
#
if (flag4 && RoundManager.Instance.currentDungeonType == 4 && !this.isOutside)
{
    if (!this.isInElevatorStartRoom)
    {
        flag2 = this.UseElevator(true);
    }
    else
    {
        bool flag5 = false;
        for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
        {
            if (!StartOfRound.Instance.allPlayerScripts[i].isPlayerDead && StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled && StartOfRound.Instance.allPlayerScripts[i].isInsideFactory)
            {
                flag5 = true;
                break;
            }
        }
        if (!flag5)
        {
            flag3 = true;
            flag2 = this.GoTowardsEntrance();
        }
        else if (!flag)
        {
            flag2 = this.UseElevator(false);
        }
    }
}
else
{
    flag3 = true;
    flag2 = this.GoTowardsEntrance();
}
#

there is this giant block of code

green gust
#

Flag hell

keen ruin
#

it must be that else block sending it back

crimson jolt
#

and GoTowardsEntrance() forces them to path to the entrance doors

crimson jolt
#

although it's weird

#

the only thing that should be coming up false here is flag4

#

and flag4 is the "is elevatorScript not null" boolean

green gust
#

What's flag4 again?

#

Ah

crimson jolt
#

so that shouldn't be false

#

because it's a mineshaft

green gust
#

Then doesn't thay just mean that in mineshaft, its just an if else for whether it's inside or outside

crimson jolt
#

honestly it's hard to say

#

this code is an overgrown nightmare

keen ruin
#

it's the masked going back inside, so isOutside == true

#

so !isOutside == false

#

the condition we care about is either further up or completely missing

ashen harbor
keen ruin
#

whut

crimson jolt
green gust
#

I'd assume there'd be prior code to this that should be handling masked not just instantly going back inside

keen ruin
#

path into each other? there's nothing special about that

#

unless it's colliders

crimson jolt
#

it is the biggest difference for me with masked

green gust
crimson jolt
#

i get full frames with 50 masked spawned if i remove the elevator search

ashen harbor
#

Yeah, I know Jade had to reduce the amount that can spawn outside on Rampart due to too many walking into each other sometimes and making the game lag

ashen harbor
crimson jolt
#

probably

#

i am publishing my masked plugin tonight

#

hopefully in a couple minutes or an hour or so

#

and it will cache the elevator script

#

although zaggy will probably implement that into pathfindinglagfix beta soon too

keen ruin
#

lemme just deobfuscate this crap

green gust
#

Lol

ashen harbor
#

Are you also gonna be pushing the update with VehicleController stuff cached soon?

green gust
#

I also saw FindExitPoints was mentioned, was thay a bad function too?

crimson jolt
#

i am releasing 3 things at the same time

ashen harbor
#

Yay

crimson jolt
#

butteryfixes is having masked stuff pulled out of it into the new plugin

#

and that update will include vehiclecontroller caching

#

then the mask plugin

ashen harbor
crimson jolt
#

and then another new plugin that i was gonna release yesterday and delayed because of all of this junk

ashen harbor
#

Should do a ButteryOptimizations mod

crimson jolt
#

i have not tested these as much as i would've liked so i am really hopeful there aren't major issues i have missed

#

but i have smoke tested everything and it works pretty well on my profile, at least, so i am optimistic

ashen harbor
#

Excited

#

I can finally bring the fox back and not have it drag my game down to 15 fps everytime it grabs a player

#

XD

green gust
crimson jolt
#

that's the hope, anyway

crimson jolt
#

i was only doing them because nobody else had done them yet

green gust
#

Ahh ic

crimson jolt
#

they belong more here IMO

#

the only thing left is the FindExitPoint patch

green gust
#

How bad is that one? I use it a decent amount

crimson jolt
#

i added a skip if it exitPoint and exitPointAudio are already cached since there is no reason the vanilla function should be called in that circumstance

crimson jolt
green gust
crimson jolt
#

it opens immediately with a FindObjectsOfType call

#

if all you want is the exit point

keen ruin
#

?????? discord??

#

why is it not indented

crimson jolt
green gust
#

I use it because I need to populate the fireexits ingame ;>

crimson jolt
#

you just shouldn't be calling it actively under almost any circumstance

green gust
#

Iirc it's that function anyway

green gust
crimson jolt
#

but if you are regularly using it over the course of a day it will lag spike

keen ruin
#

looks like the issue is that flag is not equivalent to isInElevatorStartRoom

crimson jolt
#

i so badly want to just throw out the state 0 logic

#

no offense to zeekerss but it sucks

green gust
#

Zeekerss needs to separate his shit into readable functions lol

keen ruin
crimson jolt
#

i feel like it'd make way more sense to split it into a "path to main entrance function" and then that handles all the logic of using the elevator only if it's necessary (for mineshaft interiors)

green gust
#

No state machine should just be... like that bleh

keen ruin
#

ah buttery said that

#

gg

green gust
#

But yeah that's what I'll end up doing

keen ruin
#

generalizing elevator code and making it so that enemies that want to path through them can find a path through any elevators in the level

crimson jolt
#

that's cool

keen ruin
#

also through teleports

crimson jolt
#

and maybe one of these days i can implement it into a customized masked wander state

#

that works less bad than this

#

lol

keen ruin
#

theoretically the masked could just use a custom roaming algorithm that calls through to that API and then it can wander and check all nodes on the map

crimson jolt
#

i would definitely need to make it a config setting because i dont see a great way to make "replacing an entire behavior state on a vanilla enemy" super transpiler-able

#

it'd probably just be a prefix cancel with a config at the top to return true instead

keen ruin
#

yeah it's tricky

#

but thing is

#

I think I have to do it in PathfindingLib itself, because the point is to allow people to use PathfindingLib in their own elevator implementations, so the masked have to know how to make use of that too

#

it's tricky tho

#

well actually I shouldn't say I would put it in PathfindingLib itself, but a dependency of it that people should make a hard dep if they want to use that API for their moon/interior

green gust
keen ruin
#

as long as the state doesn't change before the switch, you can just prefix cancel if state is 0

crimson jolt
#

probably something like

prefix
{
  if (configDisablePrefix)
    return true;

  if (isEnemyDead || currentBehaviourStateIndex != 0)
    return true;

  // custom state 0
  return false;
}
#

is how i'd do it

green gust
#

Oh yeah that makes sense lol

crimson jolt
#

the more i look at this elevator behavior the more i just dont want to use it at all

#

i have them working ok on factory and manor except i need to make their targeting less picky

#

so they dont get stuck entering/exiting the building forever

#

but all of the mineshaft logic just seems rotten

keen ruin
#

yeah it does seem more messed up than I thought

#

trying to figure out the smallest patch to fix this rn

crimson jolt
#

good luck