#plugins-dev-chat

1 messages Β· Page 25 of 1

hearty shard
#

smth with locker probably

chilly verge
#

Locker seems to be the normal lockers that spawn loot, at least from how the classes look like

unique crane
#

It is still a locker

#

Pretty sure

hearty shard
#

thats basegame

#

labapi wrapper is PedestalLocker

random scaffold
#

this it?

#

which class

hearty shard
chilly verge
#

thanks

#

didnt check subclasses tbh

hearty shard
#

@restive turret im bored

#

give me smth new

#

what does sl need for apis

restive turret
#

Custom effects

#

A bunch of

#

Idk

hearty shard
#

literally did that api

restive turret
#

oh apis uhh

#

custom dummy AI

hearty shard
#

guh

#

cuz its close to exiled

restive turret
#

merge deez

hearty shard
#

no!

hearty shard
#

you...

restive turret
#

haha gottem

hearty shard
#

evil..

#

slejm

#

wat do u do

restive turret
#
  1. Custom Networking like mirror to learn how it works
  2. Waiting for ja** uni review time
hearty shard
#

smh

restive turret
#

help me with custom tiems idk

hearty shard
#

damn

#

idk how i wanna do this

unique crane
#

Why you do that in a first place

hearty shard
#

you mean have player prefab?

unique crane
#

yea

hearty shard
#

its nicer to have ig

#
Transform playerEffectsStore = PrefabStore<ReferenceHub>.Prefab.playerEffectsController.effectsGameObject.transform;

Transform playerEffectsManager = PrefabManager.PlayerPrefab.playerEffectsController.effectsGameObject.transform;

Transform playerEffectsBaseGame = NetworkManager.singleton.playerPrefab.GetComponent<PlayerEffectsController>().effectsGameObject.transform.transform;
unique crane
#

why

hearty shard
#

wdym why

#

😭

#

i dont like the third

unique crane
#

Like whats that for xd

hearty shard
#

oh thats the custom effect thing

#

but still

#

player prefab is used for stuff sometimes

#

so having it in a more obvious spot than NetworkManager.singleton might help some ppl

hearty shard
#

there was a third use case i forgot

hearty shard
icy knoll
#

Is it possible to block specific keybinds from being used on a Keybind Setting?

hearty shard
#

no

#

why

icy knoll
#

want to make it so people can't set the keybinds to their mouse

upper vapor
hearty shard
#

@icy knoll you..

#

idk if i like it

#

but you said smth about wanting this

hearty shard
#

πŸ’”

wheat flower
#

true

#

im only joking

#

but what is that

icy knoll
hearty shard
#

damn

hearty shard
#

its sigma

#

trust

icy knoll
hearty shard
#

SSSS wrapper is actually goated

icy knoll
#

makes ur life a lot better trust me

#

especially with SSSS

hearty shard
#

when nw ssss wrapper that isnt terrible

wheat flower
#

sss should really be reworked imo

icy knoll
#

saves you an arm and a leg when trying to deal with settings only being visible to certain people and stuff

hearty shard
#

sort of

#

:3

icy knoll
#

atleast we now have SSKeybindHintParameter

wheat flower
#

im sorry hubert, but the way it works serverside is just annoying πŸ’€

wheat flower
hearty shard
#
public class ExampleKeybindSetting : CustomKeybindSetting
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ExampleKeybindSetting"/> class.
        /// </summary>
        public ExampleKeybindSetting()
            : base(900, "Example Kill Button", KeyCode.G)
        {
        }

        /// <inheritdoc />
        public override CustomHeader Header { get; } = CustomHeader.Examples;

        /// <inheritdoc />
        protected override CustomSetting CreateDuplicate() => new ExampleKeybindSetting();

        /// <inheritdoc />
        protected override void HandleSettingUpdate(Player player)
        {
            player.Kill();
        }
    }
#

this is goated

#

kill keybind trolling

wheat flower
#

epic

icy knoll
icy knoll
#

:c

hearty shard
#

public SettingThing(int)

#

now it doesnt work

#

and breaks

#

which is why it is how it is

icy knoll
#

ahhh

#

makes sense actually

#

just

#

wish there was a way to remove it when no params

hearty shard
#

its a duplicate of my private source

hearty shard
icy knoll
hearty shard
#

what

icy knoll
#

emma

hearty shard
#

how is this

icy knoll
#

modded mc player

hearty shard
#

brainrot

#

😭

icy knoll
#

yes

#

they love brainrot

wheat flower
#

who tf is moddedmc

#

(ik dont worry)

icy knoll
#

everyone knows who modded is

hearty shard
#

no

#

not the mentally healthy people

wheat flower
#

i dont know anything other than the fact they annoying

wheat flower
#

(but they are also based too so i guess it cancels)

buoyant oyster
#

is it just me missing something or does RoundStarting not exist

hearty shard
#

errr

#

it does

buoyant oyster
hearty shard
#

its not a player event

#

its a server event

buoyant oyster
#

so i am stupid

#

mb

buoyant oyster
#

tanks

hearty shard
#

tank it

buoyant oyster
#

i just woke up

unique crane
#

But you have reccomended keybind option. And if client puts your keybind to.. idk.. capslock

#

I think thats their problem

icy knoll
#

no they set it to mouse to make it easier for them to use

#

can i raise this as a feature request in the labapi issues or will it get declined?

unique crane
hearty shard
icy knoll
icy knoll
unique crane
#

Add cooldown to it

wheat flower
#

nah

#

mouse is cool

unique crane
#

Done

wheat flower
#

also that

icy knoll
wheat flower
#

then do it with dictionary?

unique crane
#

There are many ways to do it

icy knoll
unique crane
#

depending on how you handle the thingy

#

Do you have handler for the ability for each player?

hearty shard
#

it

unique crane
#

or is it all in one

icy knoll
#

also, sometimes as well people will click so fast that there isnt even enough time to add to the dictionary

hearty shard
#

you dont need a dictionary i dont think

teal junco
icy knoll
hearty shard
unique crane
#

Game loop first processes all messages, dispatches then and then in next iteration it proceses the new messages that arrived meanwhile

#

Not in between

wheat flower
#

No matter how you do it, you need a way to have a cooldown for each player individually

#

Dictionary works just fine

hearty shard
#
private static void OnSettingsUpdated(ReferenceHub hub, ServerSpecificSettingBase settingBase)
        {
            if (hub.IsHost)
                return;

            Player player = Player.Get(hub);

            CustomSetting? setting = CustomSettings.FirstOrDefault(s => s.Base.SettingId == settingBase.SettingId);
            if (setting == null || !setting.CanView(player))
                return;

            CustomSetting newSettingPlayer = EnsurePlayerSpecificSetting(player, setting);

            NetworkWriter entryWriter = new();
            NetworkWriter valueWriter = new();
            settingBase.SerializeEntry(entryWriter);
            settingBase.SerializeValue(valueWriter);
            newSettingPlayer.Base.DeserializeEntry(new NetworkReader(entryWriter.buffer));
            newSettingPlayer.Base.DeserializeValue(new NetworkReader(valueWriter.buffer));
            newSettingPlayer.HandleSettingUpdate(player);
        }
#

new setting is per player

unique crane
#

If you have handler object for eeach object then I suggest using either:

#

StaticUnityMethods.OnUpdate and decerase the timer every time.deltatime

#

orrr

#

Use Stopwatch

#

Thats how its done base game usually

icy knoll
hearty shard
#

this prevents it

#
public class ExampleKeybindSetting : CustomKeybindSetting
    {
        private AbilityCooldown cooldown = new();

        /// <summary>
        /// Initializes a new instance of the <see cref="ExampleKeybindSetting"/> class.
        /// </summary>
        public ExampleKeybindSetting()
            : base(900, "Example Kill Button", KeyCode.G)
        {
        }

        /// <inheritdoc />
        public override CustomHeader Header { get; } = CustomHeader.Examples;

        /// <inheritdoc />
        protected override CustomSetting CreateDuplicate() => new ExampleKeybindSetting();

        /// <inheritdoc />
        protected override void HandleSettingUpdate(Player player)
        {
            if (!cooldown.IsReady)
                return;

            cooldown.Trigger(5);
            player.Kill();
        }
    }
icy knoll
hearty shard
#

should work

icy knoll
#

ill bookmark this

#

thanks eve

hearty shard
#

its rly just this

#

basegame does the same

#

i believe

#

its required to have the settings be synced properly

#

also for TryGetSetting of a player

#

i could do breaking change to add Owner property

#

would be nullable tho

#

idk if thats the way for it

icy knoll
#

and make it so owner isn’t nullable lol

hearty shard
#

Owner has to be nullable πŸ’€

icy knoll
#

grr

hearty shard
#

default base you register

royal mica
#

Also people can just bind the keybind on their mouse, bypassing the "no mouse" solution

hearty shard
#

has to have null owner or Server.Host

icy knoll
#

null!

teal junco
#

how do i impart force on a ragdoll or kill the player so their ragdoll goes flying? preferably in such a way as to avoid being hazardous to other players

static meteor
#

I know the amount of damage done with atleast jailbirds will affect the ragdoll velocity

teal junco
#

so jailbird damage handler maybe.
but what about direction?

unique crane
#

@icy knoll You can post it as suggestion

#

Worst case is that beryl or ced says no

static meteor
frank flicker
hearty shard
#

yuck

teal junco
#

I'll try this.

wheat flower
teal junco
frank flicker
hearty shard
#

but still

teal junco
hearty shard
#

😭

frank flicker
wheat flower
#

publicizing? nah
raw assembly? HELL YEAH

teal junco
#

What is the jailbird death text again?

hearty shard
#

smth smth

#

yk yk

frank flicker
hearty shard
#

its rly easy

#

and then itll work as if its public

wheat flower
#

and enable unsafe code in your project properties

hearty shard
#

ya

wheat flower
#

so it doesnt throw an error KEK

hearty shard
#
<PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.2" PrivateAssets="all" />

<Reference Include="Assembly-CSharp" HintPath="$(SL_REFERENCES)\Assembly-CSharp.dll" Publicize="true" />
frank flicker
wheat flower
#

crazy

hearty shard
#

rly cool

static meteor
#

I just used Exileds publicizer Β―_(ツ)_/Β―

frank flicker
#

And would this still work on servers by just uploading the plugin dll? Or would the server have to do additional things on their end?

static meteor
#

No modifications needed for the server

unique crane
#

You dont need to change the publicized dll on the server

#

only locally for your programming purposes

frank flicker
#

sweet

hearty shard
#

DAVIDDDDDD

unique crane
#

EVEEEEE

#

hai

hearty shard
#

hi!

frank flicker
#

Yep, its part of code for a ragdoll launcher. I've used that line before, I just copied it from a friends code

frank flicker
wheat flower
#

well reflection is costly in runtime performance

#

other than that nothing truly bad about it

#

reflection has to look through metadata, etc to search for things

frank flicker
#

makes sense

wheat flower
#

(nothing broken tho lol)

hearty shard
#

performance my beloved

wheat flower
#
/// <summary>
/// Patches the <see cref="ServerSpecificSettingsSync.ServerPrevalidateClientResponse"/> to allow our custom settings. This allows us to ignore DefinedSettings nonsense.
/// </summary>
[HarmonyPostfix]
[HarmonyPatch(typeof(ServerSpecificSettingsSync), nameof(ServerSpecificSettingsSync.ServerPrevalidateClientResponse))]
private static void ServerSpecificSettingsSync_ServerPrevalidateClientResponse(SSSClientResponse msg, ref bool __result)
{
    if (__result)
        return;

    __result = _ourSettings.Contains((msg.Id, msg.SettingType));
}
hearty shard
#

gj

wheat flower
#

i hate defined settings!i hate defined settings!

hearty shard
#
/// <summary>
    /// Fixes validation for <see cref="CustomSetting"/>.
    /// </summary>
    [HarmonyPatchCategory(nameof(CustomSetting))]
    [HarmonyPatch(typeof(ServerSpecificSettingsSync), nameof(ServerSpecificSettingsSync.ServerPrevalidateClientResponse))]
    internal static class SettingsSyncValidateFix
    {
#pragma warning disable SA1313
        private static void Postfix(SSSClientResponse msg, ref bool __result)
#pragma warning restore SA1313
        {
            if (__result)
                return;

            __result = CustomSetting.Get(msg.SettingType, msg.Id) != null;
        }
    }
#

mine is that

wheat flower
#

customsetting.get

#

truly peak

hearty shard
#

yse!

#

yes!

wheat flower
#

in my case im not making an api

#

its a personal plugin for server

#

trol

hearty shard
#

this is a copy paste of my private plugin

#

xd

wheat flower
#

W

#

FirstOrDefault is peak

hearty shard
#

obviously

wheat flower
#

i love hashset though (less performance on less items)

hearty shard
#

xd

restive turret
#

use ReadOnlySpan

hearty shard
#

Spawn

wheat flower
#

wut

#

nahhhhh

#

ReadOnlySpawn

hearty shard
#

zereth

#

do you use any public apis

#

other than labapi

wheat flower
#

i used* exiled

#

now i dont

#

kek

#

but nothing else afaik

hearty shard
#

me when ruei & MER for me πŸ’”

wheat flower
#

i used like ruei

#

once

#

and never again

#

and mer

hearty shard
#

whyy

wheat flower
#

i barely touch on

wheat flower
hearty shard
#

fair enough

wheat flower
#

decided to try ruei

#

it works well

#

but i never tried using it elsewhere

#

simply because im not making any crazy menus

#

if i end up doing that, then ill use it

hearty shard
#

i use it for displaying player info

#

like current scp stats

wheat flower
#

yeah i think we had a plugin doin that

hearty shard
#

me when

wheat flower
#

i dont have any custom roles or items atm

#

me when

hearty shard
#

i removed my API thing

#

now its all together in an SL sort of style

wheat flower
hearty shard
#

also love labapi having 0 docs

#

with nuget

wheat flower
#

true

#

nw, please fix

hearty shard
#

i thought they added it

wheat flower
#

im not even using the nuget

#

i find it easier to download a branch

#

then reference it how i want

#

than switching versions n shit

hearty shard
#

i was only going to cuz of docs

wheat flower
#

if they include in branch

#

then W move

hearty shard
#

oh nvm

#

rider was just stupid

#

it works

wheat flower
#

oh

#

nice

#

i have upped the level of antics

#

ignore type completely

hearty shard
#

zereth

#

helppp

#

i forgot what its called

#

like

#

theres Action

wheat flower
#

u need help

#

from me?

#

impossible

hearty shard
#

but whats the one for one that returns a value

wheat flower
#

Func

hearty shard
#

thanksss

upper vapor
upper vapor
#

xddd

#

peak

random scaffold
#

how i can remove regeneration from painkiller?

wheat flower
#

patch

#

probably

hearty shard
#

patch it

wheat flower
#

hold om

#

let me uhh

#

give a sec

upper vapor
#

isn't there an useditem handler for that?

wheat flower
#

maybe

hearty shard
#
private static Dictionary<RoleTypeId, Func<List<RoleTypeId>, float>> handlers = new()
        {
            { RoleTypeId.Scp3114, roles => roles.IsEmpty() ? 0 : 0.5f },
        };

        private static bool Prefix(ref RoleTypeId __result)
        {
            float maxInclusive = 0.0f;
            int length = ScpSpawner.SpawnableScps.Length;
            for (int index = 0; index < length; ++index)
            {
                PlayerRoleBase spawnableScp = ScpSpawner.SpawnableScps[index];
                if (ScpSpawner.EnqueuedScps.Contains(spawnableScp.RoleTypeId))
                {
                    ScpSpawner._chancesArray[index] = 0.0f;
                }
                else
                {
                    // consider that it might not be ISpawnableScp
                    float num = Mathf.Max(
                        ScpSpawner.SpawnableScps[index] is ISpawnableScp spawnScp
                            ? spawnScp.GetSpawnChance(ScpSpawner.EnqueuedScps)
                            : handlers.TryGetValue(ScpSpawner.SpawnableScps[index].RoleTypeId, out Func<List<RoleTypeId>, float>? handler)
                        ? handler.Invoke(ScpSpawner.EnqueuedScps) : 0,
                        0);
                    maxInclusive += num;
                    ScpSpawner._chancesArray[index] = num;
                }
            }

            if (maxInclusive == 0.0)
            {
                __result = ScpSpawner.RandomLeastFrequentScp;
                return false;
            }

            float num1 = Random.Range(0.0f, maxInclusive);
            for (int index = 0; index < length; ++index)
            {
                num1 -= ScpSpawner._chancesArray[index];
                if (num1 < 0.0)
                {
                    __result = ScpSpawner.SpawnableScps[index].RoleTypeId;
                    return false;
                }
            }
        }
#

me when i

#

this sucks ass

#

😭

unique crane
wheat flower
#

what r u trying to do

#

make role chances?

hearty shard
#

its my code for allowing 3114 spawn

#

just reworked to use dictionary

wheat flower
#

ngl

#

its cooked

#

i agree

hearty shard
#

yes!!!

#

but it works

upper vapor
#

should've written a transpiler

#

smh

hearty shard
#

i would

#

but i dont know

#

so

#

:D

upper vapor
#

perfect opportunity to learn

hearty shard
#

literally the only code i need to modify is

else
                {
                    // consider that it might not be ISpawnableScp
                    float num = Mathf.Max(
                        ScpSpawner.SpawnableScps[index] is ISpawnableScp spawnScp
                            ? spawnScp.GetSpawnChance(ScpSpawner.EnqueuedScps)
                            : Handlers.TryGetValue(ScpSpawner.SpawnableScps[index].RoleTypeId, out Func<List<RoleTypeId>, float>? handler)
                        ? handler.Invoke(ScpSpawner.EnqueuedScps)
                        : 0,
                        0);
                    maxInclusive += num;
                    ScpSpawner._chancesArray[index] = num;
                }
#

to consider ISpawnableScp can be gone

#

cuz 3114 doesnt have it

#

cuz

#

someone didnt add it

wheat flower
#

probably beause it doesnt spawn anymore

#

but yeah i guess thats kinda goofy

#

tell me what u need

#

i can make transpiler (trust)

hearty shard
#
public static RoleTypeId NextScp
    {
      [OriginalAttributes(MethodAttributes.Private)] get
      {
        float maxInclusive = 0.0f;
        int length = ScpSpawner.SpawnableScps.Length;
        for (int index = 0; index < length; ++index)
        {
          PlayerRoleBase spawnableScp = ScpSpawner.SpawnableScps[index];
          if (ScpSpawner.EnqueuedScps.Contains(spawnableScp.RoleTypeId))
          {
            ScpSpawner._chancesArray[index] = 0.0f;
          }
          else
          {
            float num = Mathf.Max((ScpSpawner.SpawnableScps[index] as ISpawnableScp).GetSpawnChance(ScpSpawner.EnqueuedScps), 0.0f);
            maxInclusive += num;
            ScpSpawner._chancesArray[index] = num;
          }
        }
        if ((double) maxInclusive == 0.0)
          return ScpSpawner.RandomLeastFrequentScp;
        float num1 = Random.Range(0.0f, maxInclusive);
        for (int index = 0; index < length; ++index)
        {
          num1 -= ScpSpawner._chancesArray[index];
          if ((double) num1 < 0.0)
            return ScpSpawner.SpawnableScps[index].RoleTypeId;
        }
        return ScpSpawner.SpawnableScps[length - 1].RoleTypeId;
      }
    }
#

this is basegame

#

im changing the else for the chance getting

upper vapor
#

you could just replace the castclass code with a method call that returns ISpawnableScp

hearty shard
#

theres also this

wheat flower
#

i didnt think of that

hearty shard
#

wdym

upper vapor
upper vapor
#

that's why

wheat flower
hearty shard
#

damn

upper vapor
#
public sealed record CustomSpawnableScp(float Chance) : ISpawnableScp
{
    public float GetSpawnChance(whatever) => Chance;
}
#

in the method you do a type check, and a dictionary lookup if the type check fails

icy knoll
#

saves the hassle of ?

upper vapor
unique crane
hearty shard
#

it fixed itself

unique crane
#

gg

hearty shard
#

also gotta love

restive turret
#

99

#

ulong.MaxValue

hearty shard
restive turret
#

skill issue

hearty shard
#

otherwise cedmod ruins my day

#

cedmod changed his priority to high instead of medium

#

😭

#

i need my patches before cedmod does

restive turret
#

F for u

#

just patch cedmod to not patch it

hearty shard
#

😭

wheat flower
#

best code ever

upper vapor
#

0.000000

#

could be written as F6

wheat flower
#

i just forgor

grand flower
#

Tf is this person's problem

hearty shard
#

😭

grand flower
#

No seriously

teal junco
#

Oh nevermind he doesnt actually care

hearty shard
#

he just hates

#

xd

teal junco
#

Hes just trolling lol

teal junco
#

i wanna read the full original post

grand flower
teal junco
#

does label mean the arrow will have custom text underneath?

#

also, i dont recall whether the arrows are colored or just white

grand flower
#

They're red

teal junco
#

they should be colorable

#

but idk that might be a lot of work

teal junco
upper vapor
#

no

#

you don't

#

period

young phoenix
#

guys I have a question, how do setup the project correctly? The wiki doesn't tell anything about loading the labapi dll with visual studio (as I believe is what I'm supposed to do), and thus the plugin class doesn't exist for me.

teal junco
hearty shard
unique crane
#

or that

teal junco
#

and look up LabAPI

young phoenix
teal junco
#

No find LabAPI

#

from Northwood

upper vapor
#

Northwood.LabAPI

young phoenix
#

got it

upper vapor
#

-# david

unique crane
#

Northwood.LabApi

unique crane
young phoenix
#

thanks guys

teal junco
#

Northwood.LabApi

teal junco
#

youre welcome

upper vapor
# teal junco ?

basically what they were commenting is "nooo you can't have feedback!!1!1"

#

imagine suggesting something to be added that can actually be useful for some people

teal junco
#

Custom Scips and monetization are garbage but That doesnt mean we shouldnt add dev tools

unique crane
#

what

#

And what is that essay from him about custom Scps?

icy knoll
#

just block them

#

they are just fuckin annoying it seems

teal junco
# unique crane And what is that essay from him about custom Scps?

All custom SCPs are garbage, terrible. They abuse their custom functions, such as having the appearance of SCP-049-2, but attaching human models, and being able to pick up weapons and shoot. Especially tutorial characters are abused by them for custom SCPs. Players cannot distinguish whether this character with a human model is an enemy or a friend. They even use this function to sell VIPs, widening the gap between ordinary players and VIP players. Now back to your problem, I don't think we can increase it at all

upper vapor
upper vapor
#

they're thinking on a level beyond us

teal junco
#

anyways I think that custom SCP player info distance should be like 1000

#

just to be fair

#

079 map getting custom markers would be nice tho

upper vapor
hearty shard
upper vapor
#

idk i didn't pay attention while writing that xd

upper vapor
icy knoll
#

Would having an ability cooldown of 0.1 disconnect people from the server whilst spamming? lol

wheat flower
#

uhh if you are using the base game thing that kicks

#

otherwise no

icy knoll
#

loads of my members have been spamming a server specific keybind and i put an ability cooldown to counter it and loads are crashing

wheat flower
#

crashing, you mean dcing?

#

cuz a crash is a nw thing

icy knoll
#

yeah

#

dcing

hearty shard
#

check LA errors

icy knoll
#

ill have to check logs as console has no errors

teal junco
teal junco
icy knoll
#

oh yeah

#

LA log error :3

teal junco
#

you might need to add some null and index checks somewhere

icy knoll
#

NRE is throwing...

#

what the fuck

#

i wish it would tell me what is null

hearty shard
#

😭

#

show code

#

and stacktrace

icy knoll
#
[2025-05-20 16:45:32.493 +00:00] [STDOUT]   at SillySCP.API.Features.StruggleSetting.HandleSettingUpdate (LabApi.Features.Wrappers.Player player) [0x0002d] in <ac6d1520c08d4f2b8a5382060632f1a6>:0
[2025-05-20 16:45:32.493 +00:00] [STDOUT]   at SecretAPI.Features.UserSettings.CustomSetting.OnSettingsUpdated (ReferenceHub hub, UserSettings.ServerSpecific.ServerSpecificSettingBase settingBase) [0x000a5] in <f66e80861ab541ef806784a2419e5920>:0
[2025-05-20 16:45:32.493 +00:00] [STDOUT]   at (wrapper delegate-invoke) System.Action`2[ReferenceHub,UserSettings.ServerSpecific.ServerSpecificSettingBase].invoke_void_T1_T2(ReferenceHub,UserSettings.ServerSpecific.ServerSpecificSettingBase)
[2025-05-20 16:45:32.493 +00:00] [STDOUT]   at UserSettings.ServerSpecific.ServerSpecificSettingsSync.ServerDeserializeClientResponse (ReferenceHub sender, UserSettings.ServerSpecific.ServerSpecificSettingBase setting, Mirror.NetworkReaderPooled reader) [0x00018] in <8db1ca0fe9a6484084cda320b139932c>:0
[2025-05-20 16:45:32.493 +00:00] [STDOUT]   at UserSettings.ServerSpecific.ServerSpecificSettingsSync.ServerProcessClientResponseMsg (Mirror.NetworkConnection conn, UserSettings.ServerSpecific.SSSClientResponse msg) [0x00062] in <8db1ca0fe9a6484084cda320b139932c>:0
[2025-05-20 16:45:32.493 +00:00] [STDOUT]   at (wrapper delegate-invoke) System.Action`2[Mirror.NetworkConnectionToClient,UserSettings.ServerSpecific.SSSClientResponse].invoke_void_T1_T2(Mirror.NetworkConnectionToClient,UserSettings.ServerSpecific.SSSClientResponse)
[2025-05-20 16:45:32.493 +00:00] [STDOUT]   at Mirror.NetworkMessages+<>c__DisplayClass9_0`2[T,C].<WrapHandler>g__Wrapped|0 (C conn, T msg, System.Int32 _) [0x00000] in <1d7cfb83986b400084ab2287d18f3359>:0
[2025-05-20 16:45:32.493 +00:00] [STDOUT]   at Mirror.NetworkMessages+<>c__DisplayClass8_0`2[T,C].<WrapHandler>b__0 (Mirror.NetworkConnection conn, Mirror.NetworkReader reader, System.Int32 channelId) [0x0007a] in <1d7cfb83986b400084ab2287d18f3359>:0```
teal junco
teal junco
icy knoll
teal junco
icy knoll
#

how do i do it again in rider 😭

teal junco
young phoenix
#

guys it's giving me this error, how can I switch the language version?

teal junco
#

show code also

#

of the method

upper vapor
icy knoll
young phoenix
upper vapor
#

nope, some C# features are framework-agnostic

#

you need to have the new .NET SDK installed though

#

.NET 8 for C# 12, .NET 9 for 13

young phoenix
#

I do have that

upper vapor
#

alright then setting the language version should do the trick

hearty shard
young phoenix
#

does it matter in which propertygroup I put it?

upper vapor
young phoenix
#

alr thnx

upper vapor
#

personal preference but i put it somewhere in the first block

random scaffold
#

who can show me where in Assembly-CSharp called any event of LabAPI

#

lol

grand flower
#

Just look for usages of LabAPI's event args

static meteor
#

I've seen it but couldn't tell you where

grand flower
#

It'll show you

#

I've seen them multiple times, helps to know what's going on when debugging

upper vapor
terse bone
#

is there a way of spawning doors with custom buttons? (i want to use KeycardButtons for it)

wheat flower
#

the buttons are included in their respective door prefab

#

not separate

tulip kiln
upper vapor
tribal dagger
#

why is LabAPI not a dependency?

tulip kiln
terse bone
#

lmao

upper vapor
#

in SCPSL_Data/Managed

#

dependencies would be ones that you copy to the labapi dependencies directory

hearty shard
wheat flower
hearty shard
#

but yeah its apart of the game files

wheat flower
#

You cant change them

tribal dagger
#

ig ill just use GetCallingAssembly

#

if that will work

upper vapor
#

typeof(PluginLoader).Assembly

hearty shard
#

yeah

tribal dagger
#

fair enough

upper vapor
#

also, what would be your use-case of finding events from the LabAPI assembly?

hearty shard
#

maybe idk

upper vapor
#

hmm

tribal dagger
#

connecting events to a script requires reflection from my assessment

upper vapor
#

i see

grand flower
#

Could also just postfix them

upper vapor
hearty shard
fresh zenith
#

does OnServerRoundStarting get executed before or after the players recieve their roles?

hearty shard
#

its when round tries to start

fresh zenith
#

and Started prob after right?

hearty shard
#

RoundStarted is also before roles are received

grand flower
#

Patch the functions that fire the event

upper vapor
hearty shard
#

roles being given are done on the RoundStarted event (so itll be slightly after)

fresh zenith
hearty shard
#

i mean that roles are given slightly after round start

#

because it uses round start event to trigger role give

fresh zenith
#

oh.

wheat flower
#

timing.calldelayed(0, yourfunchere) in roundstart event will work

#

run it next frame

hearty shard
#

isnt there one for next frame

wheat flower
#

idk you check

static meteor
#

Yes

wheat flower
#

im pretty sure no

static meteor
#

Atleast for coroutines

yield return Timing.WaitForOneFrame;
wheat flower
#

yeah coroutines only tho

upper vapor
wheat flower
#

trust me

#

(i made one and it works perfectly)

upper vapor
#

grrr

#

source generators are cool

wheat flower
#

but its tedious

wheat flower
upper vapor
#

i wanna obsolete my library that i took years to make xd

#

okay not really obsolete it but

#

source-generated commands

wheat flower
#

if you make a source generator for it

#

then you will have gained my trust

upper vapor
#

:3

tribal dagger
upper vapor
#

i hate the boilerplate of ICommand

wheat flower
tribal dagger
#

i need to get the event name itself when its executed somehow

wheat flower
#

maybe i should try making a generator for it

tribal dagger
#

probably stacktrace

wheat flower
#

idk what the specifics would be tho

upper vapor
#

also, there are methods in the PlayerEvents, ServerEvents classes and such which contain the methods that invoke the events

tribal dagger
#

yeah that will work for argumented

#

but RoundStarted doesnt have eventargs

#

e.g.

wheat flower
#

stacktrace probably easiest

upper vapor
#

just use a different delegate for events without arguments

tribal dagger
#

yeah thats what im doing

upper vapor
#

you can use the event name

#

instead of the type

upper vapor
tribal dagger
#

idk about the performance tho

upper vapor
#

yeah about that

#

not very good

tribal dagger
#

but i dont think stackframe is that slow

#

for it to matter

upper vapor
#

when you're iterating through the events you can just capture the event's name

tribal dagger
#

how exactly iterating?

upper vapor
#

do you manually declare all events?

tribal dagger
#

nope
i get all events using reflection into a list of EventInfo, once i want to connect e.g. WaitingForPlayers, i just find it, get the subscribe method and generic type of that method

#

if generic is null, its non argumented

#

then i just use that subscribe method with the required delegate

#

the problem is when that method is called, i know that some event is attached to that method

#

i dont have a way to mark an event when its invoked

upper vapor
tribal dagger
#

but it must match the subscribe method

fresh zenith
tribal dagger
upper vapor
tribal dagger
#

idk how youd the name of that event there

tribal dagger
upper vapor
#

i'm interested in the loop

tribal dagger
upper vapor
#

ye

tribal dagger
upper vapor
#

how do you go through them

tribal dagger
upper vapor
#

do you... manually specify the event names..?

#

ouch

#

oh wait nvm

tribal dagger
#

well the point is that i connect only to the events i need

upper vapor
#

right

tribal dagger
#

or rather, the user needs

upper vapor
#

why not pass it the event name and add a parameter to your handler method

#

oh wait

#

you can just create a LabEventHandler at runtime

#

(the non-generic one)

#

okay maybe the stacktrace thing is easier

buoyant oyster
#

how would I get the room a generator is active in after the ActivatedGenerator event fires?

buoyant oyster
#

didnt see that

#

ffs

#

ty

icy knoll
#

lol

#

@hearty shard why did you do Get(Type type, int id) and not Get<T>(int id) for CustomSetting?

icy knoll
hearty shard
#

oh its public

#

i forgot

icy knoll
#

LOL

hearty shard
#

i use it internally

icy knoll
#

i need that method to be public anyway

#

about to make a patch

hearty shard
#

<T> doesnt work for my use

icy knoll
hearty shard
#

then pr it

icy knoll
#

can you implement pleaseeeee

#

grrr

#

ok

hearty shard
#

wtf do u need it for 😭

icy knoll
#

im making a patch which requires me to modify a property inside of the setting

hearty shard
#

im ngl i forgot to commit some things back when i made them πŸ’€

#

like GetPlayerSetting

#

πŸ’€

icy knoll
#

yup...

#

ill add them all

#

i think

#

ah crap

#

no owner here

#

LOL

young phoenix
#

should I drag plugins to LabApi/plugins or LabApi/plugins/global?

hearty shard
icy knoll
#

yeah

#

that's the plan

restive turret
#

Easier to manange

young phoenix
#

thnx

icy knoll
hearty shard
#

@icy knoll can see is checked before a new instance is created for a specific player

hearty shard
#

also just Get(typeof(T), id) as T

icy knoll
#

you check type on base

#

LOL

hearty shard
#

oh yeah

#

like that

#

ok

young phoenix
#

where can I find a list of all the methods and events?

icy knoll
#

on the github repo

hearty shard
#

where T : CustomSetting => CustomSettings.FirstOrDefault(s => s.Base.SettingId == id && s.GetType() == typeof(T) && s.Owner == player) as T;

#

btw

#

i think theres

hearty shard
#

an easier way

#

public static IReadOnlyDictionary<Player, List<CustomSetting>> PlayerSettings => ReceivedPlayerSettings;

#

that gets the settings a player has

icy knoll
#

oh yeah

#

ill make a commit

#

2s

hearty shard
#

so PlayerSettings.TryGetValue(player, out List<>) ? list.FirstOrDefault() : null

icy knoll
#

pushing

#

check

hearty shard
#

idek if i like the Owner property

#

it makes sense but

icy knoll
#

your choice

hearty shard
#

itd make more sense if i reworked it so CanView would use Owner

#

but then it creates one for ppl without perms

icy knoll
#

yeah

#

why not make it static?

hearty shard
#

which one

icy knoll
#

or can you not make static overrides

icy knoll
hearty shard
#

u cant

icy knoll
#

damn

hearty shard
#

i likely wont merge the owner property

icy knoll
#

fair

#

i can change my branch then

#

as I didn't know about that dict

hearty shard
#

yea

icy knoll
#

dev or master?

hearty shard
#

dev

icy knoll
#

now i have to edit the code to remove ur changes

#

grr

young phoenix
#

is there any good introduction for labapi, the github wiki lacks and seems outdated?

icy knoll
hearty shard
icy knoll
icy knoll
#

yippie

unique crane
#

Is there anything you would like pure labapi-wise?

#

No base game changes

icy knoll
unique crane
#

Whole

hearty shard
#

david

#

can i ask

#

why

#

whys there 3 methods

icy knoll
#

SpeakerToy::Play(AudioMessage)
SpeakerToy::Play(VoiceMessage) << also for this one make it so you can actually use the raw data though so that a voice message doesn't need to be made if you just have the data and stuff

unique crane
#

microoptimalizations yea

chilly verge
#

Are there any events/possibilities related to getting the score of the snake minigame?

chilly verge
#

I just want to give players a flashlight when hitting 80 points :D

static meteor
#

Isn't snake pretty much all client side?

icy knoll
chilly verge
#

I don't know, but I know that it is at least somehow broadcasted to the other clients, since you can watch the other players playing it in spectator and when looking over their shoulders

deft yarrow
chilly verge
#

so the server has to have at least some kind of information.

fresh zenith
#

quick question. how can i "generate" and load configs from another folder in the plugin config folder via LoadConfigs() ? or is there any way?

unique crane
#

I wouldnt call that unreadable

deft yarrow
#

Idk, it's a weird decision to do it that way

terse bone
teal junco
#

I think you can do that with remote admin but the less remote admin executed from code the better

unique crane
#

Alright thats good idea

#

Anything else?

teal junco
#

is there an scp 127 wrapper yet

tulip kiln
#

Ok so

tulip kiln
unique crane
#

Yeah there arent

tulip kiln
#

Things like Charging, Shooting, EnergyModified (or smth)

terse bone
#

I would also like to see CustomHandlersManager.CheckEvent() as public method

#

because i have implemented CustomEventHandler with additional events

#

and i use that method for registering events

teal junco
unique crane
#

Wdym?

teal junco
#

is there an enum firearmstate or something similar who i can watch

teal junco
unique crane
#

There is method

#

in PumpActionModule

#

like

#

schedule pump

teal junco
#

so if i patch that I will know when it happens?

#

thank you

hearty shard
#

😭

tulip kiln
#

Also, has anyone noticed a small problem with SpeakerToys? I have a lot of speakers and queue audio to them in a loop at the same time. In-game however, there seems to be a bit of desync (Unless I move away, since loaded speakers work fine apparently).

#

And loaded speakers aren't always in sync, just usually

grand flower
#

is that the case

#

Don't have any issues with multiple speakers keeping audio in sync here

unique crane
#

^

tulip kiln
#

ahh

#

thought they all have to have unique ids

#

gonna check in a moment

grand flower
#

No, it's just that they'll play the exact same audio if they have the same id

unique crane
#

Id is just where to send the audio yea

grand flower
#

Which is big 🧠 moment from NW

#

It works so well

#

You might have to manually encode and transmit audio data through AudioMessage, unsure if the game handles that otherwise for speakers having the same id?

#

Did that here, works with zero issues

unique crane
#

and the parameter delays the pump by 0.5 seconds

#

Its for single shot and double shot pumps

#

as double shot pumps have bigger delay

buoyant oyster
#

new pipes room is listed as "unnamed"

grand flower
#

a few rooms are

#

including the waterfall room

upper pike
buoyant oyster
#

its the only unnamed room a gen can spawn in afaik

worthy rune
#

shouldnt be

grand flower
#

Waterfall & pipe rooms have no name

warped prairie
#

is there a way to disable the snake game on the chaos card?

#

wayyy too many people just camping and stalling to play some random snake game

teal junco
#

one SN api please!

warped prairie
#

lmao

soft depot
#

I made EXILED plugin exactly for this!

teal junco
#

oh wait is exiled?

#

damn it

warped prairie
#

ah is exiled

#

ultra sad

soft depot
#

if you're in the EXILED discord, just look up SNAPI in TinybrainSanctum

soft depot
warped prairie
#

i mean ill take code and port it

teal junco
warped prairie
#

ill look it up ther

soft depot
#

99% changing references and enablind code

#

lemme check it's transpiler for EXILED code

#

it's all using Call so you'll get errors for stuff needing to be changed

#

I'd do it, but I feel like I'd get the itch to make it #if #else based and uhh.... that sounds hellish

#

is it me or are voice messages quieter in the 14.1?

devout terrace
#

the later

#

they reduced voice reverb

soft depot
#

there's still some reverb though when you destroy the object making the audio tho lol

#

wait it's actually just far away stuff has hella reverb

#

that's kinda sick

buoyant oyster
#

ive literally never seen that happen with like 230 hours ingame 😭

grand flower
#

It probably should

teal junco
#

no red underline text either way

teal junco
devout terrace
#

yo what the f

worthy rune
#

are you sure player velocity is not zero?

devout terrace
#

negative time left

limpid fjord
#

ez

teal junco
worthy rune
#

anything in localadmin logs

teal junco
worthy rune
#

SCP Secret Laboratory\LocalAdminLogs

teal junco
# worthy rune anything in localadmin logs

NRE

[2025-05-20 21:30:38.982 -05:00] [STDOUT]   at CompoundV24.Powers.Superpowers.RobinKillComponent+<>c__DisplayClass10_0.<OnTriggerEnter>b__0 () [0x00045] in <9f21b4d243a544eb96e9d26da3a0b41a>:0
[2025-05-20 21:30:38.982 -05:00] [STDOUT]   at MEC.Timing+<_DelayedCall>d__310.MoveNext () [0x00056] in <857a4408504f4deea6b81470f00f71dd>:0
[2025-05-20 21:30:38.982 -05:00] [STDOUT]   at MEC.Timing.Update () [0x0043c] in <857a4408504f4deea6b81470f00f71dd>:0```
worthy rune
# teal junco

is CompoundV24.Powers.Superpowers.RobinKillComponent the enclosing namespace for this?

teal junco
#

RobinKillComponent is the mono behavior that holds this code

worthy rune
#

do you have the current code for that

teal junco
#

i can send the entire thing

#

it had minimum changes from an hour ago

#
    public class RobinKillComponent : MonoBehaviour
    {
        /// <summary>
        /// Gets or sets the <see cref="ControllableSuperspeed"/> instance to use.
        /// </summary>
        public ControllableSuperspeed SuperspeedInstance { get; set; }

        public Player Player { get; set; }

        internal void Init()
        {
            BoxCollider trigger = gameObject.GetComponent<BoxCollider>();
            trigger.isTrigger = true;
            Log.Debug($"initialized robinkillcomponent {trigger is null} && {trigger.isTrigger}");
        }

        private void OnDestroyed()
        {
            if (gameObject.TryGetComponent(out BoxCollider trigger))
            {
                Destroy(trigger);
            }
        }

        private void OnTriggerEnter(Collider other)
        {
            Player victim = Player.Get(other);
            if (victim is null || victim == Player || victim.IsGodModeEnabled || !SuperspeedInstance.PlayerHasPowerEnabled(Player) || Player.Velocity == Vector3.zero)
            {
                // Log.Debug($"Failed checks velocity: {Player.Velocity == Vector3.zero} player speed: {!SuperspeedInstance.PlayerHasSpeedEnabled(Player)}");
                return;
            }

            Player.ShowHitMarker();
            SoundHelper.PlaySound(victim.Position, "gore");
            Timing.CallDelayed(0.01f, () =>
            {
                var h = new CustomReasonDamageHandler("Liquification suggests that subject was struck by high speed object.", 150);

                // typeof(StandardDamageHandler).GetField("StartVelocity").SetValue(h, Player.Velocity * 10);

                // h.StartVelocity = Player.Transform.forward * 50;
                victim.ReferenceHub.playerStats.DealDamage(h);
            });
          /*Timing.CallDelayed(0.01f, () =>
            {
                victim.Hurt(150);
            });*/
        }
    }```
worthy rune
#

not sure where the NRE came from

teal junco
worthy rune
#

it might, although sometimes that doest work

teal junco
#

also Player is null should prevent NREs originating from non existent players right

#

otherwise i may have just picked out a useless log

teal junco
#

i just dont know why it wont let me modify that field

teal junco
#

StartingVelocity

#

thats the piece of code that seems to cause exceptions

worthy rune
#

in your example its commented out

heady turret
#

@unique crane why scps cant use keycards?

worthy rune
brisk matrix
heady turret
#

it would be great if it is possible to allow scps using keycards

worthy rune
#

you are unlikely to get an answer for the first, since that was likely implemented by someone else

buoyant oyster
#

I want to modify the firing behavior of a weapon, for example making the ak shoot particle disruptor lazers, where would I start with that?

teal junco
#

sorry i meant to clarify that at that time that code was not commented out

#

they should effectively be the same anyway

worthy rune
#

well both use Player which i dont see set anywhere

teal junco
#

and again if i comment it out it works fine

worthy rune
teal junco
#

Sorry

#

In OnTriggerEnter

#

under the Timing.CallDelayed

#

Theres two codes commented out

#

I tried both but not at the same time

worthy rune
#

just
// typeof(StandardDamageHandler).GetField("StartVelocity").SetValue(h, Player.Velocity * 10);

            // h.StartVelocity = Player.Transform.forward * 50;

and nothing else yeah

teal junco
#

they should do the same thing but actually cause issues

worthy rune
#

ok thats much clearer

teal junco
upper vapor
#

NonPublic and Instance

teal junco
upper vapor
#

Oh

#

Um

worthy rune
#

thats your answer

upper vapor
#

That's uh

teal junco
#

I didnt know the binding flags could be so important considering theres only one field named that.

upper vapor
#

Also, if you publicize the assembly, that's for development only

#

Since you don't change it in the server's assemblies, the field is still private

teal junco
#

i assumed that since i publicized it it just gave me access i wouldnt otherwise have

#

So I will consider using the binding flags, thank you

upper vapor
#

So when you publicize the assembly, you change the visibility for development. However, in the server assembly, the field is still private or protected. Therefore, using reflection with no binding flags. Will look for public fields, so you can't find them if you were to change the server. Assembly to make that field public. That and you could use reflection, but at that point you might as well just assign it with direct access.

#

Don't change the assembly to a publicized in the server , though because it will just not work

fresh zenith
#

question how can i "create" an folder in the config folder of my plugin for extra configs?

#

anyone got an small example?

upper vapor
random scaffold
#

how i can get room / roomType from BreakableWindow?

fresh zenith
heady turret
#

is that possible to change this base answer? Like i want to change color and other

grand flower
#

Question to NW are data stores persisting when a player leaves or round restarts normal?

#

The amount of bugs I've just linked to this is staggering, writing my own logic to prevent that but the current logic seems a bit odd

jaunty trail
#

does permissions always doing icomsender to player not cause issues

#

aka some cases not being handled properly

#

haven't done sl in a bit just wondering cause am updating something

random scaffold
icy knoll
random scaffold
#

no

#

doesnt exists

upper vapor
#

position.TryGetRoom

random scaffold
unique crane
#

You have that as a property of the Room

random scaffold
#

name

#

why enum named as name

#

why not type

#

um

unique crane
#

Erm yes

random scaffold
#

why enum is name

#

not type

upper vapor
# random scaffold no

just do if (position.TryGetRoom(out var room) && room.RoomName == RoomName.Whatever)

icy knoll
upper vapor
#

i tried to mirror the RoomName enums as much as possible