#plugins-dev-chat

1 messages ยท Page 153 of 1

royal mica
#

wait what

slate flume
#

Because NW sucks at their job or smthn

royal mica
#

you throw the keycard and it doesn't wokr?

slate flume
#

You know KeycardPickups don't store the permission levels?

#

That's fucked up

royal mica
#

ngl I want to apply to NW and create an automated testing system dogkek

slate flume
#

Idk who designed it that way

#

In order to test levels for collisions they have to get a template

#

That's why it doesn't work

upper vapor
#

Easier, shorter to use
You don't need to put everything in the same class

royal mica
upper vapor
slate flume
upper vapor
slate flume
#

I wrote a baller patch for it

royal mica
upper vapor
#

Pretty much nothing in this game follows SRP
But you don't need to bloat classes with methods that don't belong there

slate flume
#

It hooks after the component.Target is DoorVariant target and then overrides handling if it's a custom keycard using CustomPermDetails

royal mica
slate flume
#

Facts

upper vapor
#

I didn't write it ๐Ÿ˜ญ

royal mica
#

I'm not saying it is your fault

upper vapor
#

I would definitely use many many extension classes but

royal mica
#

if I were I would be much harsher xdx

upper vapor
#

Nw isn't me

#

If only we had extension members in Unity

royal mica
#
class MouseLook : ... { }

extension(MouseLook) {
  public static UpdateRotation() { ... }
}

dis you?

celest thorn
#

Bruh my autobus stopped and the driver is having a fight with a dude

slate flume
#

Okay yo what the hell

upper vapor
royal mica
upper vapor
royal mica
#

everything is extension now ๐Ÿ—ฃ๏ธ ๐Ÿ—ฃ๏ธ ๐Ÿ—ฃ๏ธ ๐Ÿ—ฃ๏ธ

upper vapor
#

Use pointers

slate flume
#

How does that happen

royal mica
#

Cache

upper vapor
royal mica
#

hi

slate flume
#

Like

upper vapor
slate flume
#

No! I literally just closed and reopened my LocalAdmin

#

And then

#

Bang

#

?

upper vapor
upper vapor
celest thorn
#

20 minutes of fight bro

flat vine
#

I see that Spawner has been removed from SCP-3114's code and it now uses the same ISpawnableScp interface as other SCPs. Will SCP-3114 get a separate slider for setting spawn preferences?

upper vapor
celest thorn
#

Yea

slate flume
royal mica
upper vapor
#

We'll find out sometime

upper vapor
slate flume
#

Settings aren't going to stay in the game for a halloween-exclusive SCP

slate flume
#

NW spawn code is ass

royal mica
#

someone should create a plugin xdx

celest thorn
#

Remember SSSS gave us grate power

slate flume
#

I hate the role assigning code

royal mica
flat vine
royal mica
#

Especially if people already got used to it

slate flume
slate flume
#

They take like 4 patches and are held together by scotch tape and prayers

royal mica
flat vine
# royal mica then tbh don't change it

It would just be weird if there was a slider from the game itself and a slider in the ServerSpecific settings. That's why I wanted to clarify this point.

hearty shard
#

__result = true;

#

i used to have 2 patches since i was using basegame spawn and i had to fix since 3114 wasnt spawnable interface so

royal mica
#

just have to patch this

  private static PlayerRoleBase[] SpawnableScps
  {
    get
    {
      if (ScpSpawner._cacheSet)
        return ScpSpawner._cachedSpawnableScps;
      List<PlayerRoleBase> playerRoleBaseList = new List<PlayerRoleBase>();
      foreach (KeyValuePair<RoleTypeId, PlayerRoleBase> allRole in PlayerRoleLoader.AllRoles)
      {
        if (allRole.Value is ISpawnableScp)
          playerRoleBaseList.Add(allRole.Value);
      }
      ScpSpawner._cacheSet = true;
      ScpSpawner._chancesArray = new float[playerRoleBaseList.Count];
      return ScpSpawner._cachedSpawnableScps = playerRoleBaseList.ToArray();
    }
  }
royal mica
#

what the fuck are they doing ICANT

slate flume
hearty shard
#
[HarmonyPatch(typeof(Scp3114Role), nameof(Scp3114Role.EnableSpawning), MethodType.Getter)]
    internal static class PreventDefault3114SpawnPatch
    {
        private static bool Prefix(ref bool __result)
        {
            __result = true;
            return false;
        }
    }
slate flume
#

We get it halloween is coming up and they changed the code

hearty shard
#

yes...

#

thats why im saying its easier....

slate flume
hearty shard
#

this requires an scp to inherit ISpawnableScp anyway

#

which 3114 did in fact not

slate flume
royal mica
#

that is why you patch the getter

ashen hound
#

you will see more power when [REDACTED] gets released

royal mica
#

ooh role spawn rework

#

nice

#

cannot wait to fuck around for 4 hours to prevent spawning again

hearty shard
slate flume
#

Can we just fix the spawn code?

royal mica
celest thorn
slate flume
hearty shard
#

its why i did another patch to make it create ISpawnableScp for ones that dont have it

#

fake it Trol

#
  • a patch to remove ragdoll spawning
royal mica
#

at this point we should just create an open source server impl xdx

hearty shard
#

(couldve been an event but yk...)

#

i refused to

slate flume
#

Is it possible to convert a ragdoll to bones without an SCP-3114?

#

Does this other shit matter?

flat vine
slate flume
hearty shard
#

Scp3114RagdollToBonesConverter.ConvertExisting(BasicRagdoll)

#

try it

#

its static

hearty shard
#

i wish 314spawner still had it

#

cuz that one had the ragdoll spawn code

#

for round start

marble cobalt
royal mica
#

Can you please PLEASE confirm the ragdoll serial bug is fixed

slate flume
hearty shard
#

so it is just not done yet and not an intended change

marble cobalt
#

Correct

marble cobalt
#

It's just the public branch being incomplete atm

slate flume
royal mica
#

Currently

hearty shard
slate flume
#

LMAO based

marble cobalt
#

Haven't seen that one getting reported

hearty shard
#

but its low priority

royal mica
#

It is on the public git even

#

lemme search it

hearty shard
#

ive never actually used ragdoll serial

marble cobalt
royal mica
hearty shard
#

beryl can you make me programer and ill go put = null

#

and then i will resign

royal mica
#

I just assume this is a merge bug

marble cobalt
slate flume
hearty shard
marble cobalt
royal mica
#

well then the patches stay

#

thank fuck harmony can just ignore everything and update readonly field

#

I assume then the RagdollData class that is in the preview branch is the same as it'll be used in 14.2

slate flume
magic gate
slate flume
royal mica
#

okay thank you!

hearty shard
#

well

#

tbf

#

just wait 2 days

slate flume
hearty shard
#

if ragdoll spawn code for 3114 getting refactored

#

then yk

#

just use that

slate flume
#

I don't want to spawn ragdolls, I want to convert them to skeletons
I'm unsure if that part is actually getting refactored

hearty shard
#

Oh

#

then yeah prob uhh

#

what i said

#

but

#

yk

#

not working for some reason?

#

bug?

slate flume
#

Despite the weird naming

hearty shard
#

oh wait

slate flume
#

But idk

hearty shard
#

maybe thats the client side code for making the bones?

#

rather than ragdoll to 3114 ragdoll

slate flume
#

That's just fucked up

hearty shard
#

well

#

spawning the bones prob would be

#

but normal ragdoll to 3114 is doable

#

i mean basegame does it

slate flume
hearty shard
#

i will try............

#

to figure out..

slate flume
#

Nice bones

hearty shard
#

oh

#

it does

#

Scp3114RagdollToBonesConverter.ServerConvertNew(this.CastRole, curRagdoll);

#

to disguise

#

lel

#
  public static void ServerConvertNew(Scp3114Role scp, DynamicRagdoll ragdoll)
  {
    Scp3114RagdollToBonesConverter subroutine;
    if (!scp.SubroutineModule.TryGetSubroutine<Scp3114RagdollToBonesConverter>(out subroutine))
      return;
    RagdollData info = ragdoll.Info;
    ragdoll.NetworkInfo = new RagdollData(info.OwnerHub, (DamageHandlerBase) new Scp3114DamageHandler((BasicRagdoll) ragdoll, false), info.RoleType, info.StartRelativePosition, info.StartRelativeRotation, info.Nickname, info.CreationTime);
    subroutine._syncRagdoll = ragdoll;
    subroutine.ServerSendRpc(true);
  }
slate flume
hearty shard
#

yea idk tbh

#

it might need the rpc

#

to tell clients to spawn bones

slate flume
#

So spawn a dummy 3114

hearty shard
#

yes

#

also

#

yea its client side the first i gave you

#

although this is used too in damagehandler

slate flume
slate flume
hearty shard
#

tbf

#

it might become easier with the new update?

#

@marble cobalt

#

will converting normal ragdoll to 3114 or is there like a solution u have

slate flume
hearty shard
#

admin toys

slate flume
#

That's very

#

Un-northwood-esque

#

Well I got it

hearty shard
#

oh

#

what was it

slate flume
#
if (ev.Ragdoll.Base is not DynamicRagdoll ragdoll)
    throw new InvalidOperationException("SCP-049-2 consumed a ragdoll that is not a DynamicRagdoll");
ReferenceHub dummy = DummyUtils.SpawnDummy("3114");
PlayerRoleManager roleManager = dummy.roleManager;
roleManager.ServerSetRole(RoleTypeId.Scp3114, RoleChangeReason.None, RoleSpawnFlags.None);
var role = (Scp3114Role)roleManager.CurrentRole;
Scp3114RagdollToBonesConverter.ServerConvertNew(role, ragdoll);
#

Dummy player

#

I wonder

#

If I can get away without the dummy

marble cobalt
#

we're not refactoring 3114, we just changed the spawner script

slate flume
#

Called that shit

celest thorn
#

Wait why the fake model got update gingerbread maybe work with new models???

upper vapor
ashen hound
#

thats some schizo text outgoing

upper vapor
worn gull
#

Hi! Is it possible to destroy or open fully the new SCP-096 door?

icy knoll
#

havent had a chance to look at it yet

#

but why?

celest thorn
worn gull
restive turret
upper vapor
hearty shard
#

and it needs the 3114 to put sync ragdoll

#

but idk

restive turret
#

well the bones for the ragdoll (?) can has a dummy component i guess and you call once to get all children

hearty shard
#

bro

#

what is with players and going "ez" after losing horrifically and only getting out on chance

#

๐Ÿ’€

true cedar
#

what is it with eve and being stupid

hearty shard
#

ur just rude

true cedar
#

nuh uh

hearty shard
#

ur a STINKER

restive turret
#

ServerCreateRagdoll is setting serial 0 even if can be null

#

but that thing isnt used

royal mica
#

It is used when creating a ragdoll

restive turret
#

ah ye figured

royal mica
#

If you check, every function defalt params to 0

restive turret
#

ya

worn gull
lusty reef
royal mica
#

howtf did you post here without the role

restive turret
#

you dont need a role to view here

royal mica
#

Wait you dont?

restive turret
#

nah

royal mica
#

wtf I thought this was behind the plugin dev role

restive turret
#

after release it got opened to everyone

royal mica
#

aww dang it

true cedar
#

close the gates

restive turret
#

@slate flume
https://github.com/northwood-studios/LabAPI/issues/288
In here if you make it minus in any way in the code of
ExtractWaypointData (check screenshot) the check will be going downward so any new point has to be a smaller than before will be picked, so any negative priority would be the most of it?
Is that what you intend?

worthy rune
worthy rune
restive turret
#

negative should prioritize the waypoint more as I read tru it

worthy rune
soft depot
soft depot
#

It lowers the given squared distance making the waypoint more appealing

#

But if negative priority worked, I could fake the priority, then have clients never use a waypoint cuz they think itโ€™s 1000000 meters away

restive turret
#

or fake the position?

#

you can i think

soft depot
#

Thatโ€™s stupid

worthy rune
#

defeates the purpose as everything inside also gets moved

soft depot
#

Cuz thatโ€™ll make ppl go to brazil

restive turret
#

the waypoinst already make me go there

worthy rune
soft depot
true cedar
#

i still dont know what waypoints are im ngl

restive turret
#

yknow what would be cool

#

if its parenting to it

worthy rune
#

wha

restive turret
#

whaz

limber silo
#

But we are focusing on a big labapi update for 15.0 currently

hearty shard
#

2.0 incoming

restive turret
#

we so good it will be 3.0

#

joke

upper vapor
icy knoll
#

already such a bad update

#

/j

sinful bronze
unique crane
#

no

upper vapor
sinful bronze
#

Devs dont know what is sex

upper vapor
#

And it might be for the better if we stop that conversation

rare wolf
#

is there any labpapi event for Exileds ChoosingStartTeamQueueEventArgs

unique crane
#

Choosing which players to spawn in wave?

rare wolf
#

no no like

#

when the round first starts

#

its fired when the server starts deciding the dclass, scp, facility guards etc

unique crane
#

Nop

#

you can edit the queue itself tho

rare wolf
#

nahh not what i need..

#

it has to be a event thats called when the round starts but BEFORE any player role is set

unique crane
#

ah so you want to edit who spawns as what

rare wolf
#

looking through the github i dotn know if i see anything

restive turret
#

oh i throught it was for waves

#

ye there isnt such a thuing

rare wolf
#

RoundStartingEventArgs maybe?

unique crane
#

Yeah

#

that one should be before any round things are run

rare wolf
#

ok sweet

warped prairie
#

ye theres RoundStarting and RoundStarted which call before and after that stuff happens

obtuse spruce
#

Why all my plugins config was broken with the 14.2 server build SA_dies

warped prairie
#

Will be fixed trust

obtuse spruce
#

I just deleted the properties.yml and it work SkullClownRainbow

hearty shard
#

itll be fixed for full 14.2 releaes prob

rare wolf
#

oml

#

the new nuke voicelines and music

#

so peak

#

this has to be one of my fav additions to SL in a long time

restive turret
#

make sure you are on latest experimental

hearty shard
#

blah blah blah

restive turret
#

14.2.0-deploy-d8abecba

sinful bronze
restive turret
#

lmao

fathom charm
#

Why do I need to call a delayed call to give the player an effect, for example, in the OnPlayerSpawned event?

grand flower
#

northwood moment

#

mostly stuff isn't fully setup when that event is called

#

one or two frames should be fine

upper vapor
fathom charm
#

ok

upper vapor
#

PlayerSpawned is called after the position is changed, effects are reset after that, but before the PlayerChangedRole

grand flower
#

even then you'll want to delay

upper vapor
#

why

#

oh cuz

#

client resets it?

grand flower
#

idk but it doesn't work without a delay

upper vapor
#

copium

grand flower
#

might be outdated info though

#

fix it northwood

upper vapor
fathom charm
#

with call delay will work

upper vapor
#

cyn was right then

#

wright

#

bright

grand flower
#

Trust me

#

Every single unnecessary delay in Bright's codebase was removed

#

Refactored a ton of it

#

So we only have the strict necessary ones and it's generally for role changed/spawned

glad pagoda
#

well in SL we have a few waits cuz of how Unity works lol

upper vapor
#

we love script execution order

glad pagoda
#

a lot of stuff that needs to touch UI has to have waits

glad pagoda
upper vapor
#

like tmpro at least

#

has a priority of -100 iirc

#

-# by default

grand flower
#

unity moment

#

But

#

In this scenario you could just delay the LabAPI event itself

#

Only call it when the player is fully ready

#

Might skip intermediate states but whatever

icy knoll
#

should add a utility method which calls a coroutine

#

Player::WaitUntilReady(() => smth to do when player is ready);

upper vapor
#

awaitables when

grand flower
#

Plugin devs shouldn't have to do that

upper vapor
#

why

grand flower
#

Why do plugin devs have to wait until the player is ready in an event fired by the game

#

The game/LabAPI should wait to fire the event

slender depot
#

When making plugins, you kinda learn how to fix SL's and API's mistakes

#

it's the fun part

#

or sometimes it's not so fun, but most of the time it's fun

upper vapor
#

when a local index changes

hearty shard
#

afaik it does

#

ive never had issues

grand flower
#

someone tried and said no so idk

celest thorn
#
    /// <inheritdoc />
    public override void OnPlayerHurting(PlayerHurtingEventArgs ev)
    {
        if (ev.Attacker == null)
            return;
        if (ev.Attacker.IsSCP)
            return;
        if (ev.DamageHandler is not StandardDamageHandler handler)
            return;

        if (ev.Attacker.DoNotTrack)
            return;

        StatsDatastore store = StatsDatastore.Get(ev.Attacker);
        store.Damage += handler.TotalDamageDealt;

        base.OnPlayerHurting(ev);
    }

Why is this doesn't work? like the damage is always 0

restive turret
#

Totaldamagedealth runs after hurting

celest thorn
blissful pike
#

wanted to show this off. I program custom roles for my server.

#

This is my new "Spartan" role, made the audio from four different sound effects that i found online and edited together in premiere pro.

#

The whole idea of it is when you die, you enter "The Last Stand" where you get another chance at 300hp rapidly decreasing.

#

have a bunch of other roles I've made that I can show hehe

grand flower
#

nice

blissful pike
#

thank u cryingkitten

#

I also made this

#

Ekko, the ability to rewind time (restores health to what it was before too). 90 second cooldown

upper vapor
#

ooooo

#

-# you have duplicate sound in the recording

blissful pike
#

There are 32 teleports everytime the ability is used lol

blissful pike
#

DO YOU GUYS LIKE DO YOU GUYS LIKE

#

TOOK VERY LONG TIME

#

and there are a lot more of these unique roles ๐Ÿ’€

restive turret
#

Good one

blissful pike
#

ITS YOU

#

YOU MADE SCR

#

THIS IS BASED ON YOUR PLUGIN LOL

#

this is all made on top of your plugin

restive turret
#

This 2 role is so good man, good job!

blissful pike
#

thank uuu

restive turret
#

In Calamiy we have some but most of them made by Kadava himself. I just occasionally help the plugin that builds top on scr

blissful pike
#

because my special ability roles depend on you

restive turret
#

I plan to update cus new labapi events

blissful pike
#

oooh wait where do u see the new labapi events

#

are they released yet?

restive turret
#

I make them & in 14.2 labapi dll

#

Not yet released

#

Release date is tomorrow so

static meteor
#

Whoops

restive turret
#

Lol

worn burrow
#

Is there a damagehandler for scp207 or is there only UniversalDamageHandler?

static meteor
#

Whatever the one effects use

worn burrow
static meteor
#

Its uses UniversalDamageHandler

#
    public override void OnTick()
    {
        if (NetworkServer.active && !Vitality.CheckPlayer(base.Hub))
        {
            float damage = base.CurrentStack.DamageAmount * GetMovementStateMultiplier();
            base.Hub.playerStats.DealDamage(new UniversalDamageHandler(damage, DeathTranslations.Scp207));
        }
    }
worn burrow
#

ok

worn burrow
static meteor
#

check if the Scp207 effect is active?

worn burrow
static meteor
#

And this too probably

            Scp207 scp207 = ev.Player.GetEffect<Scp207>();
            if (damage == scp207.CurrentStack.DamageAmount * scp207.GetMovementStateMultiplier())
worn burrow
#

Okay

static meteor
#

Or you could harmony patch it if you have harmony in your project

    [HarmonyPatch(typeof(Scp207), nameof(Scp207.OnTick))]
    public static class Scp207OnTickPrefix
    {
        [HarmonyPrefix]
        public static void Prefix(Scp207 __instance)
        {
            if (NetworkServer.active && !Vitality.CheckPlayer(__instance.Hub))
            {
                float damage = __instance.CurrentStack.DamageAmount * __instance.GetMovementStateMultiplier();
                Player player = Player.Get(__instance.Hub);
                Logger.Info($"207 is dealing {damage:F2} damage to {player.DisplayName}");
            }
        }
    }
worn burrow
#

okay

worn burrow
static meteor
#

Your trying to modify the damage done?

worn burrow
static meteor
#

Harmony patch should be

    [HarmonyPatch(typeof(Scp207), nameof(Scp207.OnTick))]
    public static class Scp207OnTickPrefix
    {
        [HarmonyPrefix]
        public static bool Prefix(Scp207 __instance)
        {
            if (NetworkServer.active && !Vitality.CheckPlayer(__instance.Hub))
            {
                // Modify the damage to how you want it to be calculated here
                float damage = __instance.CurrentStack.DamageAmount * __instance.GetMovementStateMultiplier();

                Player player = Player.Get(__instance.Hub);
                player.ReferenceHub.playerStats.DealDamage(new UniversalDamageHandler(damage, DeathTranslations.Scp207));
                Logger.Info($"207 is dealing {damage:F2} damage to {player.DisplayName}");
                return false;
            }

            return true;
        }
    }
worn burrow
#

okay

static meteor
worn burrow
# static meteor Harmony patch should be ```cs [HarmonyPatch(typeof(Scp207), nameof(Scp207.On...

bruh [2025-10-23 00:17:07.820 +00:00] [STDOUT] at CustomPlayerEffects.TickingEffectBase.OnEffectUpdate () [0x00039] in <895ff7c21fbe46748fde1d20cfb514c1>:0
[2025-10-23 00:17:07.820 +00:00] [STDOUT] at CustomPlayerEffects.CokeBase1[TStack].OnEffectUpdate () [0x00000] in <895ff7c21fbe46748fde1d20cfb514c1>:0 [2025-10-23 00:17:07.820 +00:00] [STDOUT] at CustomPlayerEffects.StatusEffectBase.Update () [0x0000f] in <895ff7c21fbe46748fde1d20cfb514c1>:0 [2025-10-23 00:17:08.819 +00:00] [STDOUT] MethodAccessException: Method CustomPlayerEffects.CokeBase1[CustomPlayerEffects.Scp207Stack].get_CurrentStack()' is inaccessible from method Soyako_NoRP.Features.Patch.Scp207OnTickPrefix.Prefix(CustomPlayerEffects.Scp207)'
[2025-10-23 00:17:08.819 +00:00] [STDOUT] at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_throw_method_access(intptr,intptr)
[2025-10-23 00:17:08.819 +00:00] [STDOUT] at Soyako_NoRP.Features.Patch.Scp207OnTickPrefix.Prefix (CustomPlayerEffects.Scp207 __instance) [0x00014] in C:\Users\maell\RiderProjects\Soyako-NoRP\Soyako-NoRP\Features\Patch\Scp207Patch.cs:21

#

i love harmonypatch

static meteor
#

enable unsafe code in your project

worn burrow
#

okay

#

thanks @static meteor

slate flume
#

@worn burrow

#

Don't

#

Harmony patch is unnecessary here

#

It's excessive and I don't recommend it

slate flume
#

Recommending a harmony patch for this is crazy work

#

Istg sometimes I have to peruse these forums so people don't recommend wild shit to new devs

slate flume
# worn burrow thanks <@617462103938302098>

Don't have an over-reliance on Harmony patches, generally you should use the pre-existing implements as much as possible
In this case, it's also much cleaner to use LabAPI events instead of Harmony
Just do:

public override void OnPlayerHurting(PlayerHurtingEventArgs ev)
{
  if (ev.DamageHandler is UniversalDamageHandler handler && handler.TranslationId == DeathTranslations.Scp207.Id)
    handler.Damage *= 0.5f;
}
#

You can replace the damage change with whatever you want the damage to be changed to for each tick

slate flume
cosmic echo
#

if I player.Ban someone for 292 billion years do you guys think anything will break

static meteor
#

player.Ban(long.MaxValue) Trolley

cosmic echo
slate flume
#

Why the fuck does it allow you to ban people for negative amounts of time

static meteor
slate flume
slate flume
#

@worthy rune Remember the character controller bug?

ReferenceHub dummy = DummyUtils.SpawnDummy("Bones");
PlayerRoleManager roleManager = dummy.roleManager;
roleManager.ServerSetRole(RoleTypeId.Scp3114, RoleChangeReason.None, RoleSpawnFlags.None);
var role = (Scp3114Role)roleManager.CurrentRole;
DamageHandlerBase handler = ragdoll.NetworkInfo.Handler;
Scp3114RagdollToBonesConverter.ServerConvertNew(role, ragdoll);
ragdoll.NetworkInfo = SetHandler(ragdoll.NetworkInfo, handler);
NetworkServer.Destroy(dummy.gameObject);

This causes almost the exact same issue

#

I think it's something with creating/destroying a player on the same frame

soft depot
#

been trying to learn how 2 do that forever

celest thorn
#

Yo has anyone ever created the library of babel in SL?

slate flume
soft depot
#

awww I wanted headless player ๐Ÿ˜”

celest thorn
soft depot
#

No, just funny bug Iโ€™ve seen before but idk how to recreate

grand flower
#

Debug.Log = nil
LogLuauVM: Error: [ServerVM] [string "RunString"]:1: attempt to modify a readonly table
[string "RunString"]:1
pog

#

got error handling done for my Luau plugin (unrelated to SL but I talked a lot about it here kek)

slate flume
#

I made a series of patches that'll prevent the game from shitting itself if this happens

#

Now considering this has happened to people in the past I'm going to show the changes I made to fix it

#
[HarmonyPatch]
public class NullPlayerFixes
{
    [HarmonyPrefix]
    [HarmonyPatch(typeof(CharacterModel), nameof(CharacterModel.OnPlayerMove))]
    public static bool OnPlayerMove(CharacterModel __instance) => __instance._ownerTr != null;
    
    [HarmonyPrefix]
    [HarmonyPatch(typeof(FpcMouseLook), nameof(FpcMouseLook.UpdateRotation))]
    public static bool UpdateRotation(FpcMouseLook __instance) => __instance._hub != null;
    
    [HarmonyTranspiler]
    [HarmonyPatch(typeof(FpcMotor), nameof(FpcMotor.UpdatePosition))]
    public static IEnumerable<CodeInstruction> UpdatePosition(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
    {
        var codeMatcher = new CodeMatcher(instructions, generator);

        codeMatcher.MatchStartForward(CodeMatch.Calls(AccessTools.PropertyGetter(typeof(FirstPersonMovementModule),
                nameof(FirstPersonMovementModule.CharController))))
            .Advance();
        int characterControllerIndex = codeMatcher.Instruction.LocalIndex();
        codeMatcher.Advance();

        codeMatcher.CreateLabel(out Label normalPathLabel);
        codeMatcher.Insert(
            new CodeInstruction(OpCodes.Ldnull),
            CodeInstruction.LoadLocal(characterControllerIndex),
            CodeInstruction.Call(typeof(UnityEngine.Object), "CompareBaseObjects"),
            new CodeInstruction(OpCodes.Brfalse_S, normalPathLabel),
            new CodeInstruction(OpCodes.Ret)
        );
        
        return codeMatcher.Instructions();
    }
}
#

Now, this doesn't prevent errors from showing up
In my case I still got a few when the event happened
But it does prevent the server from shitting the bed when it does happen

#

Players appear to still be able to move around, interact with things, the whole nine yards

#

And I figure people might wanna know when something's gone wrong, these patches silently fix the problem and don't broadcast it, because the problem occurs every frame

#

Now it might be better to run some destroy code to destroy the faulty modules, so I think I might work on doing that next

grand flower
#

dang so that's why

#

nice find

#

had the same issue with our pets, couldn't figure out why

#

added a one-frame delay to destroying our dummies

slate flume
# grand flower nice find

It was a bitch
We were having seemingly random freezing on the server and after like 5 hours it was narrowed down to "It's happening when a zombie consumes a corpse" and that meant the issue was with spawning the dummy
Added one frame delays and the problem was solved
Now I'm trying to root it out

grand flower
#

we patched so much of the fpc stuff

#

(โ•ฏยฐโ–กยฐ)โ•ฏ๏ธต โ”ปโ”โ”ป

slate flume
#

I'm currently just fucking obliterating every faulty module when it tries to pull some game-breaking BS

grand flower
#

gl

celest thorn
#

I don't remember but does anyone know if SSSS as like a setting dropdown that you can select multiple elements?

static meteor
#

I dont believe so

celest thorn
slate flume
celest thorn
#

I meant a dropdown that allows for multiple not only one

#

i know dropdowns exist

slate flume
#

A dropdown with a bunch of like checkmarks and stuff

#

?

#

This feels like a really obscure UI element

#

What is this for?

celest thorn
slate flume
celest thorn
#

and its not a problem

slate flume
celest thorn
#

waht

slate flume
#

Why not just have like
Head Cosmetic: (dropdown)
Trail: (dropdown)
...

#

That prevents conflicts and is user-friendly

celest thorn
#

i just want players to be able to select more cosmetics from the same dropdown

slate flume
#

If you select two cosmetics in the same category then they conflict

#

Why would you want that

celest thorn
#

they don't

#

i've built a system for that bruh

slate flume
#

Does that mean you automatically force some cosmetics to disable if they conflict?

#

Does that mean you stack them in a non-conflicting way?

#

What are we talking about dude

celest thorn
#

im stacking them in a non conflicting way

#

i just need to know a simple thing can i do with one dropdown mutliple selection.

slate flume
#

Select item, press button to toggle it

celest thorn
#

hmm yea thats the best

static meteor
#

why not something like this?

celest thorn
slate flume
slate flume
# slate flume ```c# [HarmonyPatch] public class NullPlayerFixes { [HarmonyPrefix] [Har...

Update @worthy rune sorry for pinging you so much just you were the person I was talking to about this before so I figured you'd wanna know
I boiled the fix down to less than a dozen lines of code by rooting out the inciting problem

[HarmonyPatch(typeof(FirstPersonMovementModule), nameof(FirstPersonMovementModule.UpdateMovement))]
public class NullFpmmFix
{
    public static bool Prefix(FirstPersonMovementModule __instance)
    {
        if (__instance.Hub != null) return true;
        __instance.ResetObject();
        Logger.Info("Disabled FirstPersonMovementModule with a null ReferenceHub");
        return false;
    }
}
slate flume
#

There's some larger unexplained problem

upper vapor
slate flume
#

If you spawn a dummy, set their role, and disconnect them on the same frame, you don't get a disconnect message because the OnDestroy never properly completes

slate flume
#

If you have 100 head cosmetics that's gonna get fucked up

#

But it's your perogative

celest thorn
slate flume
#

It'll still look weird

upper vapor
celest thorn
#

btw axwabo if i release a plugin based on the theorem of the Library of babel, will it be liked Trolley

https://libraryofbabel.info/

upper vapor
# celest thorn i left the idea

Then keep the dropdown and tell the player that the settings are shit if they choose a bad combination
Your can do two dropdowns for the two torso settings, don't even need a warning tbh

slate flume
#

Something there is producing an NRE before the log is added

slate flume
celest thorn
upper vapor
celest thorn
#

but still a theory if something like that should exist

#

how it would behave

slate flume
slate flume
upper vapor
#

Yeah that yeah
Hub isn't set until start is called which would happen next drake

#

Frame

celest thorn
#

labapi exist in the library Trolley

upper vapor
#

Iirc multiple components do that

hearty shard
upper vapor
#

Get the hub in start

#

Which is just stupid

slate flume
upper vapor
#

Ah

#

Mb

#

Now that's interesting

slate flume
#

Right?!

upper vapor
#

Might be something with pooling or the role manager

slate flume
#

I'm pretty sure rogue FPMM modules are what causes the occasional server movement freezing issue
It's possible if a player joins and gets assigned a role, and then disconnects in the same frame somehow, it causes issues

slate flume
slate flume
upper vapor
#

๐Ÿ˜ญ

#

Timing based attack

slate flume
#

I can already imagine what the masses would do if they got their hands on the ability to take down servers just by connecting and disconnecting in the same frame

#

Someone would make a script and absolutely terrorize

celest thorn
#

you gave them an idea

#

Hello creators of the middle of the night not cheat client

upper vapor
#

Maybe we should add component.destroyCancellationToken.IsCancellationRequested in some places

slate flume
#

The lucky thing is it's an easy fix

#

Just call ResetObject on the FPMM if the Hub is null

slate flume
#

Should I add this to the bug tracker?

#

And if so, is it LabAPI or base-game?

upper vapor
#

Uh good question

celest thorn
slate flume
celest thorn
#

Thats why

slate flume
#

Well fire

celest thorn
#

If it doesnโ€™t then they will discard it instantly

teal junco
#

Create the cheat that crashes a server yourself and send it directly to LabApi

celest thorn
#

If the AC didnโ€™t already gban you

teal junco
#

Certainly coding cheats isnt gbannable

#

as long as you dont use them

#

It's just a proof that there is an issue to be solved

celest thorn
teal junco
# celest thorn Yes it is

That would be stupid lol, I can code as many cheats as I want, and Northwood will not ban me until I try to run it in online mode

celest thorn
teal junco
#

A. Why?
B. How?

celest thorn
#

This is what i got told i donโ€™t know the specific

teal junco
#

so you can mod or cheat without any problem

celest thorn
#

But i got told this and honestly risking my entire career for developing an AC against the Clan is not a good idea

#

As much as i like trolling them

teal junco
celest thorn
#

So i wouldnโ€™t risk it

teal junco
#

Unless they have a literal magic AC, which we all know Northwood does not

celest thorn
#

So

teal junco
celest thorn
#

And arc raiders ac has a cheat

teal junco
#

also did i not just say there is a program that disables the AC and auth

celest thorn
# teal junco wtf is yuzu hack

Yuzu is an emulator for Nintendo Switch and hacks are just lines of code that you modify for example if i did that for Xc2 1080p hack it crashed the game for debugging

static meteor
#

14.2 tomorrow SteamHappy

celest thorn
#

Knife scp

upper vapor
celest thorn
upper vapor
upper vapor
celest thorn
# upper vapor Okay maybe you're right

I know because iโ€™ve asked ced and maro asked someone working on the AC because we hate the clan so badly we wanted to make an AC specifically tuned for them

static meteor
#

obelisk

celest thorn
#

A tortures them for fun Trolley

slate flume
static meteor
static meteor
celest thorn
#

Oh hey look at that its me

static meteor
#

My discord keeps crashing ever since the Halloween stuff got activated

static meteor
slate flume
static meteor
#

Crazy

celest thorn
tulip kiln
sinful bronze
upper vapor
#

again, eula 10

sinful bronze
#

or version have cutted AntiCheat

sinful bronze
#

wait

#

HWID?

#

Isn't it removed in 13.5.x

tulip kiln
sinful bronze
#

im so lazy to check it

sinful bronze
#

is reports work during offline mod?

upper vapor
#

idk ask the anticheat ppl

sinful bronze
#

or server owner/server mod can report dude when server only in offline mode...

sinful bronze
sinful bronze
upper vapor
#

human ๐Ÿ˜ญ

icy knoll
#

ax is NOT human

sinful bronze
#

okay

#

anticheat furry

#

like me

#

but im not anti

#

and cheat

spare zodiac
#

๐Ÿšก

sinful bronze
#

!rep

regal lakeBOT
#

You can give a rep!

sinful bronze
#

!rep @upper vapor

regal lakeBOT
#

You have just given @upper vapor a reputation point!

sinful bronze
celest thorn
unique crane
celest thorn
#

only if not proven that is not poisonous but considering the furry aesthetic then most likely no

upper vapor
#

do you like eating

#

metal

unique crane
#

hes all wires and metal

upper vapor
#

and nanites

unique crane
#

and ram

upper vapor
slate flume
unique crane
#

Fish fursona

#

๐Ÿ’€

slate flume
upper vapor
#

scalie

celest thorn
#

I swear im gonna make it once again the banana

celest thorn
#

and nothing else

slate flume
unique crane
#

femboy

celest thorn
#

to even say it

upper vapor
#

you're a closeted ||person||

celest thorn
#

i swear the last thing in my list is furry and egirl

slate flume
celest thorn
#

neither i would give them to strangers lol

slate flume
celest thorn
#

but i don't fall in the category of egirl

upper vapor
#

if you define egirl as online girl then it applies
but usually egirls do some weird shit

slate flume
#

๐Ÿ’€

upper vapor
#

xd

slate flume
#

You're talking to an SL dev

celest thorn
#

if you mean that then YES

upper vapor
#

๐Ÿ˜ญ

celest thorn
#

but if you mean

#

anything else no

#

i know im crazy and any attribute you wanna put me on

#

but im not that degenerate or that low

upper vapor
celest thorn
static meteor
upper vapor
upper vapor
#

google earth can tell you

celest thorn
#

oh you mean NOT me corrisponding to that

upper vapor
#

elevation

upper vapor
celest thorn
#

if you count where i live probably alot

#

my height then not much

upper vapor
static meteor
celest thorn
#

and i just found out that there are a total of 200 people living here

upper vapor
#

geoguesser time

celest thorn
#

im not even surprised

#

its not even in the maps

upper vapor
celest thorn
#

That IS not my city

#

i don't live near enough Trapani

#

and its a ghost city

#

i went visit it

upper vapor
#

don't let the urbex youtubers discover that information

celest thorn
#

the city can be walked

#

and checked

#

its not bad

#

when i went visit it

celest thorn
#

so you need to search from nearby cities Trolley

upper vapor
#

@hearty shard you need to up the intensity of night vision for it to work
-# not sure if you've figured it out yet

hearty shard
upper vapor
#

oh

hearty shard
#

๐Ÿฅ€

upper vapor
#

๐Ÿ˜ญ

hearty shard
#

Holy slowpoke

worn gull
#

Which damage handler is the bulkhead door?

upper vapor
#

same as pitdeath i think

#

universal with id crushed

worn gull
#

thanks

upper vapor
#

np

worn gull
# upper vapor np

So with this the player should not get damaged from the bulkhead

        if (ev.DamageHandler is UniversalDamageHandler dh && dh.TranslationId == DeathTranslations.Crushed.Id)
            ev.IsAllowed = false;```
upper vapor
#

yes

#

correct

blissful pike
#

how do i spawn and control a dummy through plugin code?

#

struggling to find a way

hearty shard
#

well

#

what r u trying to control

blissful pike
#

movement, look direction

hearty shard
#

.Position

#

same as player

#

.Rotation

#

too

blissful pike
#

.position is to teleport it tho, no?

#

i want it to walk

hearty shard
#

ah you want to fake that

blissful pike
#

var dummy = DummyUtils.Spawndummy()

#

and then as for movement? ๐Ÿ˜ญ

celest thorn
#

Or something like that

blissful pike
#

you're gonna need to dumb down these abbreviations for me

celest thorn
#

Let me send you code

#

Far easier

blissful pike
#

okie

hearty shard
#
if (player.RoleBase is not IFpcRole fpcRole)
                return;
            
            fpcRole.FpcModule.Motor.ReceivedPosition = 
#

ReceivedPosition = new RelativePosition(this.Position + this.Hub.PlayerCameraReference.TransformDirection(dir).NormalizeIgnoreY() * distance);

#

this is what basegame does for dummies

blissful pike
#

๐Ÿ˜ญ

hearty shard
#

use a coroutine to have it move

celest thorn
# blissful pike okie
        if (ev.Player.RoleBase is not IFpcRole fpc)
            return;

        fpc.FpcModule.Motor.ReceivedPosition = Position;
hearty shard
#

or a component

restive turret
#

or just stole the code from dummyfollower

hearty shard
#

there is a PlayerFollower component script you can do

#

ya

celest thorn
#

which is far unreadable than this

#

because of decomp

blissful pike
#

how can I get the player from their referencehub?

unique crane
#

Player.Get(hub)

blissful pike
#

thank uu

upper vapor
blissful pike
#

๐Ÿ’€

#

silly me

#

bro like can i not control a dummy the way i do in RA panel

#

like with the "move forward 1m" or "look right 90 degrees" buttons

#

what's the labapi way ๐Ÿ˜ญ

hearty shard
#

that is what the RA panel does

#

with direction and distance being based on your input

pallid summit
#

Hi, questin, is there a way to hide the red and SCP079 indicator?
I want 079 to be able to talk over MTF radio but this makes it a little too obvious

hearty shard
#

rather than scp

#

could maybe?

#

but well

#

its an scp so i think it gets forced to be there

pallid summit
#
public override void OnPlayerSendingVoiceMessage(PlayerSendingVoiceMessageEventArgs ev)
{
    if (ev.Player.Role == RoleTypeId.Scp079 && ev.Message.Channel == VoiceChatChannel.Proximity)
    {
        if (!Active.Contains(ev.Player.ReferenceHub))
            return;
        var radioMessage = new VoiceMessage(ev.Message.Speaker, VoiceChatChannel.Radio, ev.Message.Data, ev.Message.DataLength, true);
        foreach (var player in Player.ReadyList)
        {
            if (player.IsDummy || player == ev.Player)
                continue;

            // Don't send it to 079, it's not much fun hearing your own voice.
            if (CanReceiveRadio(player, ev.Player.ReferenceHub))
            {
                player.Connection.Send(radioMessage, 0);
            }
        }
    }
}

Already using it

pallid summit
hearty shard
#

btw you dont need to create a new voice message

#

ev.Message.Channel =

pallid summit
#

oh well, lore wise it isn't too unrealistic to immediatly know that 079 is speaking

hearty shard
#

erm

#

yeaaa

#

create an npc for it

pallid summit
#

ohh, like an invisible guard or NTF that takes the name of the speaker and sends it through them

hearty shard
#

or tutorial...

pallid summit
#

or that yea

restive turret
#

any alive noon scp role should work

hearty shard
#

well tutorial doesnt count as a scp target etc

#

where as guard and such do

pallid summit
#

true

#

gotta figure out how that works, thanks tho!

pallid summit
celest thorn
static meteor
#

What did i just watch

pallid summit
icy knoll
pallid summit
#

I uhh, no proper guard for dummy spawning

#

the only reason it didn't go higher is because the server crashed ๐Ÿ˜ญ

hearty shard
#

oh!

pallid summit
#

OK, dummy spawned correctly but doesn't seem to want to send the radio message

#

excuse the overly bright screenshot, my HDR is acting up

pallid summit
celest thorn
#

change that

pallid summit
celest thorn
pallid summit
#

so the proxy would need a radio right?

celest thorn
#

or else

#

idk

#

you can't do much

#

other than that

pallid summit
#

I'll try it, thanks!

celest thorn
#

on the item

#

via radio.Base._rangeId = (byte)RadioRangeLevel.UltraRange;

pallid summit
#

otherwise I may have to put the receivers referencehub as the sender, then hide their tag

celest thorn
pallid summit
#

I am trying to do this without any dependencies but I'll keep it in mind

#

cuz battery is also a problem with the radios

celest thorn
celest thorn
pallid summit
#

Give SCP079 the ability to hijack NTF radio without his portrait showing up as the speaker

celest thorn
#
if(item is RadioItem radio) {
   radio.Base._rangeId = (byte)RadioRangeLevel.UltraRange
   RadioRangeMode mode = radio.Base.Ranges[RadioRangeLevel.UltraRange];
   mode.MaximumRange = int.MaxValue
   mode.MinuteCostWhenTalking = 0;
   mode.MinuteCostWhenIdle= 0;
}
celest thorn
#

hmmm

#

then redirect voice messages

#

from the player

#

using

#

PlayerSendingVoiceMessageEventArgs

#

Change the ev.VoiceMessage.Channel = VoiceChatChannel.Radio

pallid summit
#

oop

#

that was longer than I thought

#

Anyways, lemme try the radio method

bright vine
#

or does that not work

pallid summit
#

it seemed to work for SCP079 but maybe that works differently for SCP's

bright vine
#

And the range.. still exists?

pallid summit
#

for SCP the range is infinite but when using a Tutorial dummy (or any human class for that matter) the range is reduced to a few rooms at most (I tested roughly 2 to 3 rooms before audio cut off)

hearty shard
#

scps get put on global

#

always

#

thats why

hearty shard
pallid summit
#

yeah that makes sense

worthy rune
# slate flume Update <@1068368908530229280> sorry for pinging you so much just you were the pe...

all good, no need to apologies about pinging. im pretty interested about how this happens and all the info provided is great. the destroy on the same frame thing looks like it could be caused by unity not calling OnStart/OnEnabled (which is expected). but the OnDestroy/Unpooling code wasnt expecting the "unsetup" objects. i guess this could happen on a vanilla server if a player is created on the same frame the server restarts? although seems like that would be rare. ill look into it myself at a later time so it can be fixed base-game, thanks for the info.

#

oh i see it requires a role to be set in the same frame, probably wouldnt happen base-game then

#

still would be good to fix it for plugin devs tho

pallid summit
hearty shard
#

idk

#

radios are silly

pallid summit
#

ah

#

so the range of the dummy is roughly halfway through entrance zone and it has it wether it has a radio or not

#

strange

bright vine
#

With setting the voice channel to radio for 079

pallid summit
#

their portrait will show up

bright vine
#

Ohh

pallid summit
#

which I do not want

bright vine
#

If the portrait is client sided youโ€™re fucked

#

Probably going to have to use a dummy

pallid summit
#

yeah, that's why I am trying to use a dummy to do it

#

but the dummy has weird range limits and that is whether it has a radio or not

pallid summit
celest thorn
pallid summit
#

what do you mean?

#

I can't publicize a property in a decompiled script afaik

restive turret
#

its a field

pallid summit
#

huh, I can't seem to find it

restive turret
#

cus its private

pallid summit
#

How do I publicize it?

restive turret
#
<PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.2" PrivateAssets="all" ExcludeAssets="runtime" ReferenceOutputAssembly="false" Private="true" />
<Reference Include="Assembly-CSharp" Publicize="true" Private="false" />
#

you have to have a new sdk style csproj

#

otherwise it doesnt work

#

you can do the same publicize stuff in others

pallid summit
restive turret
#

no

pallid summit
#

sorry, I have never done this before so I am struggling allot

restive turret
#

if your .csproj file is not made or updated to newest sdk you have to upgrade into newest sdk style

pallid summit
#

it's probably using the old one but no idea how I would upgrade and google isn't helping either

restive turret
#

to make your life easier, create a new .net6 or net8 project and edit the .csproj to be <TargetFramework>net48</TargetFramework> isntead

#

you have to readd your references and stuff so

pallid summit
#

yeah, tho that's not the hardest part. I just followed the documentation (the little there is) when I created this project

restive turret
#

what IDE you using? rider or vs?

pallid summit
#

VS

restive turret
#

send your csproj here i send back one and replace with yours

#

(you will have to unload or close your VS until you paste it back)

pallid summit
restive turret
#

it might download older yaml.net (since labapi using 11.0.1)

pallid summit
#

Hey, now it recognizes _rangeId!

#

only got a warning from Assembly-CSharp

#

something about Processor missmatch

upper vapor
pallid summit
#

that seemed to work, thanks!

upper vapor
#

Np

pallid summit
# restive turret should be good

Also thanks for being patient with me, I am used to regular Unity stuff so modding for the first time is a whole task to learn ๐Ÿ˜ญ

restive turret
#

no worry

#

u good, everyone have to learn

spare zodiac
pallid summit
#

true, tho I have been swimming in the deep end all day ๐Ÿ˜ญ

#

wondering why my proxy dummy refuses to have infinite range

sinful bronze
#

I love to check game code for fun

#

And to know what i can patch