#plugins-dev-chat

1 messages · Page 150 of 1

upper vapor
#

Not for 1.1.3

slate flume
icy knoll
#

why wasn’t that announced? is it not on live?

upper vapor
#

It's on early server build

slate flume
hearty shard
restive turret
#

someone forgot to push early-server-build int olive

icy knoll
slate flume
#

So apparently the plugin devs don't need to know about it GoodOne

upper vapor
#

Cuz idk

slate flume
#

This is fucking insane to me

icy knoll
#

what was even added in it bruh

slate flume
#

Ts pmo

hearty shard
#

@limber silo ^^

#

Problem solved

slate flume
#

I never fucking heard about it because I DIDN'T GET AN ANNOUNCEMENT

hearty shard
#

honestly im surprised your server owner never updated

#

That or your transpiler just didnt error

slate flume
hearty shard
#

Damn

upper vapor
icy knoll
#

tbh i didn’t know about this either and im an api maintainer 😭

slate flume
#

One has medical issues and the other is moving into an apartment

restive turret
upper vapor
slate flume
#

WHAT ARE WE DOING BRO

#

COME ON

hearty shard
#

i knew Trol

slate flume
#

I'm trying to hold this shit together

upper vapor
limber silo
#

ah right I forgot to make the announcement lol, had an exam at the time

limber silo
hearty shard
upper vapor
hearty shard
#

No one ever told jesus 💀

icy knoll
slate flume
#

I'm crashing out

#

I'm actively losing my mind

restive turret
#

just dont

slate flume
#

I've been trying to figure out what happened in this piece of code to cause players to stop taking damage from firearms

hearty shard
slate flume
#

I have no idea what the hell is causing it

royal mica
#

Why is this a problem, you already publicize everything xdx

restive turret
hearty shard
slate flume
royal mica
#

yeah it is a serious issue, just wanted to meme about publicizing

hearty shard
# restive turret

Ya but announcements about labapi could say that yk... Theres a version available

upper vapor
royal mica
#

time to represent

upper vapor
#

Omfg

upper vapor
#

I'm representing
NativeAOT which will break everything

hearty shard
#

Well actually idk

slate flume
upper vapor
slate flume
#

^^^^

#

Yes

limber silo
#

this was our biggest release

upper vapor
#

Not on steam I don't think

limber silo
slate flume
#

I don't even think it's in master

upper vapor
restive turret
slate flume
upper vapor
#

Oh well

slate flume
#

Cause fuck me

#

I guess

upper vapor
#

I think now y'all are gonna wait for 14.2

limber silo
restive turret
#

ye

hearty shard
limber silo
#

I thought I got it into master

hearty shard
#

i mean it might be in master on GitHub

slate flume
#

Are we so fucking for real right now

#

I hate this place

hearty shard
limber silo
#

it is on nuget correctly

#

huh

#

whatever

slate flume
limber silo
restive turret
limber silo
#

biggest release in labapi story

restive turret
#

or xml

limber silo
slate flume
hearty shard
#

Or no?

slate flume
hearty shard
#

David said it was fixed

limber silo
#

not in labapi

#

in master

slate flume
#

It's entirely in a LabAPI wrapper

#

You guys are making me go insane

hearty shard
#

Yip yip horray!

slate flume
#

So was it fixed or not?

hearty shard
#

Idk

#

David said it was

limber silo
#

that file hasnt been touched in 2 months

#

what was the issue

slate flume
#

@upper vapor oh so you're just a big fucking liar

hearty shard
#

He gave you a link to david saying it was fixed in 1.1.3

hearty shard
upper vapor
hearty shard
#

I swear he said the labapi version

slate flume
#

No it wasn't fixed

restive turret
limber silo
#

"We will be pushing it to live in around 24 hours if no other issues are found." wait wasnt it pushed

hearty shard
#

Damn

upper vapor
hearty shard
#

Fault

limber silo
#

ah that makes sense

hearty shard
#

How dare you

slate flume
# limber silo what was the issue

So TimedGrenadeProjectile::SpawnActive spawns grenades that instantly explode because you guys forgot to check if the timeOverride was less than zero

hearty shard
#

Stinky liar

#

Poopyhead even

upper vapor
hearty shard
#

Uh oh

upper vapor
#

You're going to cishet land

hearty shard
#

guh....

limber silo
#

cant you just set the timer manually for now

hearty shard
slate flume
#

I just transpiler patched it

limber silo
#

alright...

slate flume
#
[HarmonyPatch(typeof(TimedGrenadeProjectile), nameof(TimedGrenadeProjectile.SpawnActive))]
public class TimedGrenadeFix
{
    // Currently, SpawnActive has an issue where the default timeOverride (-1) is always being set to be the remaining time
    // This causes any grenade spawned to instantly explode if you don't specify an override, which is not intended behavior
    // This patch fixes that problem by preventing the RemainingTime from being set if timeOverride is less than 0
    public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
    {
        var codeMatcher = new CodeMatcher(instructions, generator);

        codeMatcher.MatchStartForward(
                CodeMatch.Calls(AccessTools.PropertySetter(typeof(TimedGrenadeProjectile),
                    nameof(TimedGrenadeProjectile.RemainingTime))))
            .ThrowIfInvalid("Couldn't find RemainingTime setter call");

        codeMatcher.MatchStartForward(CodeMatch.WithOpcodes([OpCodes.Ret])).ThrowIfInvalid("Couldn't find return");;
        codeMatcher.CreateLabel(out Label returnLabel);
        
        codeMatcher.MatchStartBackwards(CodeMatch.WithOpcodes([OpCodes.Dup]));
        codeMatcher.Insert(
            CodeInstruction.LoadArgument(3),
            new CodeInstruction(OpCodes.Ldc_R8, 0d),
            new CodeInstruction(OpCodes.Blt_S, returnLabel));

        return codeMatcher.Instructions();
    }
}
#

It was an easy patch

#

It's just weird that I had to patch ts in the first place

limber silo
#

well you didnt

slate flume
#

Wdym

hearty shard
#

specifying time Trol

slate flume
#

Wdym I didn't patch it?

limber silo
#

you could just timeOverride:

slate flume
#

I patched it right there

slate flume
#

Do you?

hearty shard
slate flume
#

I've got no fucking clue what the default grenade fuse time is

restive turret
slate flume
#

Why are you flaming me about this

#

I legit don't know

hearty shard
restive turret
#

I think all of them are diff

#

lemme check

limber silo
slate flume
#

Well it doesn't matter anymore cause I already patched it

limber silo
#

you can get it multiple ways tho, or feel free to ask me

#

if it happens again

restive turret
#

Frag: 3.5
Flash: 2.8
Scp018: 80
Scp2176: 10

slate flume
#

I apologize I'm just pressed rn

limber silo
#

no worries

#

we are working on a big update right now and we are really focused into it

#

so if there are issues like this feel free to ping me

slate flume
#

TimedGrenadeProjectile::SpawnActive spawns grenades that instantly explode
I brought this up to SlejmUr who asked me to open a GitHub issue
I opened the GitHub issue, to which it was closed out by Axwabo claiming the issue was already fixed and that I need to update to 1.1.3
I then found out there have been no announcements made about the release of 1.1.3
I then also find out that, no, the issue hasn't been fixed

I just wanted one line of code changed 😭

upper vapor
#

I didn't claim it was fixed

#

I just marked it as duplicate

#

All I said was "why aren't you on 1.1.3 though"

hearty shard
#

ya

#

David said it was fixed

slate flume
limber silo
hearty shard
#

Ax linked to davids comment

slate flume
#

Sorry for reading into the issue you posted

#

I'm losing it

#

It's fine I'm just tired

#

It's hard to even get a straight and simple answer about basic things sometimes

slate flume
upper vapor
#

So yeah it was fixed (apparently) but it didn't get merged

slate flume
#

Well praise be

upper vapor
#

Firing David rn

slate flume
#

I think I'm gonna go eat some food before I lose it some more

upper vapor
#

Yeah go do that

#

Godot

restive turret
restive turret
slate flume
#

I don't mean any hate or disrespect or anything else to anyone with any of my earlier comments I'm just very frustrated with a bunch of stuff right now and this was another log to the fire

#

Was not expecting so much shit to come from inquiring about a one line change in the code

restive turret
#

3 lines actually (because of stylecop)

upper vapor
slate flume
slate flume
upper vapor
#

Don't let some analyzer tell you that you need trailing commas in multiline statements

restive turret
slate flume
restive turret
#

and as I saw ax too lol

slate flume
#

I dislike a lot of forced coding styles and preferences and shit

upper vapor
restive turret
#

real

upper vapor
#

É

slate flume
#

I've only had bad experience with police officers

#

Except for my school's SRO

#

He was chill

restive turret
slate flume
#

I've never written XML docs

restive turret
#

despite my lack of knowledge of english words

#

and bad phrasing

upper vapor
restive turret
#

🔥

slate flume
#

You're much more articulate than most non-primary English speakers I've met

#

You probably know more English words than some Americans

#

And all they know is English lmao

slate flume
#

Hard truth

#

But people are stupid as hell

upper vapor
#

Wtf is a kilometer

restive turret
#

the fact that is i can write english good because i have time editing what i was gonna say but i usually just ghasping what i was gonna try to say

#

because my mind is always faster than what i say so i just skip words or required context sometimes

slate flume
#

It urks me how long it takes some people to get the the fucking point of whatever they're saying

#

Like dude spit it out

restive turret
#

and because i can just quickly switch between topics sometimes people just say "what?"

#

happens in hungarian too

restive turret
slate flume
#

It doesn't help that he's also like half-deaf

restive turret
#

i just mumble most of the times

upper vapor
slate flume
#

People just need to keep up honestly

upper vapor
royal mica
upper vapor
#

One time I had an interview and I had to ask the interviewer a total of 5 times to repeat what they said

#

Blud was just

#

Logicering the words

#

Minigun

upper vapor
restive turret
#

I usually rephrase the question so i know i understood it correctly

restive turret
#

ty

#

SlejmGPT

upper vapor
#

😭

upper vapor
#

Right I need a higher clock speed

#

And better ears

slate flume
#

🗣️ 🔥

#

Skill issue

warped prairie
soft depot
#

Why did yall decide to release this 1 month after last commit 😭

spare zodiac
#

@limber silo talk!

main zenith
#

Thank u so much

icy knoll
#

forgot to do the usual stuff

unique crane
#

Idk who uses labapi from github

#

you need dedicated server anyways

celest thorn
unique crane
#

false

celest thorn
unique crane
#

You sent the trollface emoji after it

celest thorn
#

nah im joking i use it for searching methods

restive turret
#

Search deez

celest thorn
sweet flax
#

do you guys use an assembly publicizer?

static meteor
#

Yes

icy knoll
restive turret
restive turret
celest thorn
celest thorn
icy knoll
restive turret
#

Oh

#

I through like

#

Bepin as yknow

#

Mod loader

icy knoll
#

no bepinex assembly publiciser

#

smh

restive turret
#

smb

icy knoll
#

smb?

restive turret
#

Shaking my bytes

restive turret
#

Wait no it should he shocking my bytes

sweet flax
restive turret
#

In their site ye

warped prairie
#

Bep when he enters x or something idk never read the book

limber silo
#

hey

celest thorn
#

This chat is dead

bright vine
cyan crown
bright vine
#

is there a method that automatically gets a random room? or do i have to randomize the list

icy knoll
#

unless added recently?

celest thorn
worthy rune
#

i think the RandomItem extension is from the base-game

celest thorn
#

it has been since forever

celest thorn
#

itself

icy knoll
#

there isn't a reference to c# having that method

hearty shard
#

On List<T>

worthy rune
#

ahh

hearty shard
#

Actually

worthy rune
#

well Room.List is a IReadOnlyCollection so i dont think it works

hearty shard
#

It might be array yall did that on

#

Yea

worthy rune
#

we could probably make an extension for IReadOnlyCollection

celest thorn
#

nah it works

worthy rune
hearty shard
#

well

#

If it does exist then basegame, secretapi and exiled dont need one

#

However all 3 have extensions related to random item (basegame for array/list, secretapi/exiled both do for IEnumerable afaik)

#

None of them would be needed if C# had it built in

worthy rune
#

IEnumerable isnt ideal as you have to enumerate over all items to count the length(which is requires if you want to get a random item)

#

min interface that fits is IReadonlyCollection

hearty shard
worthy rune
#

thats still enumerating the items

bright vine
hearty shard
#

But it does work for all, which was the point when i made it originally

bright vine
#

you’re welcome folks the chat has been revived

#

all thanks to one simple request

worthy rune
#

btw i think Enumerable.Count casts to IReadonlyCollection in the implementation if it can(could be wrong)

hearty shard
#

Its .Count((

#

()

#

Method

#

Rather than property

#

Might be wrong

worthy rune
#

same thing

hearty shard
#

Close enough

#

Afaik it enumerates them all

#

All elements

#

Rather than cast

warped prairie
#

When she enumerate my element and I’m epic

hearty shard
#

what..

grand flower
#

I know Rider warns you about this, at the very least

#

So you can just ToList() before getting a random item

#

I'd still implement it as IEnumerable just for flexibility

worthy rune
worthy rune
hearty shard
#

checked keyword prevents it looping back to negative right

worthy rune
#

yeah

#

i think it thows?

#

it does

grand flower
#

heh

#

I remember the one time I had to use unchecked because Rider couldn't figure out my logic wouldn't ever overflow

upper vapor
#

const ushort

grand flower
#
public static byte? GetAvailableIdentifier()
{
    // Unchecked because we can't overflow a byte with values between 0 - 255
    // Two less instructions, yippee.
    unchecked
    {
        var available = Enumerable.Range(byte.MinValue, byte.MaxValue)
            .Except(GetOccupiedIdentifiers());

        // Won't cause issues in this case - we know what we're enumerating.
        // ReSharper disable PossibleMultipleEnumeration
        if (available.Any())
        {
            return (byte?)available.First();
        }
        // ReSharper restore PossibleMultipleEnumeration

        return null;
    }
}
#

that was before we could change the volume of speaker toys

#

we'd just spawn multiple with the same controller id to increase the volume

upper vapor
#

amplify your input (if possible)

grand flower
slow grotto
#

Feel free to fork/fix/rename it, I'm unsure how far I'll take it

static meteor
#

As long as cloudflare doesn't force a check I imagine it would be fine

slow grotto
#

Good point

upper vapor
#

1000000th plugin updater toomuchtrolling

slow grotto
#

IK IK

#

I felt like I was missing out

upper vapor
#

ah

#

this is

#

you're doing synchronous async...

slow grotto
#

I know how lazy I am with integrating with other plugins, so figured I'd see if there was a way to do it without needing to do anything

#

Yeah probably

#

Just hope you have fast internet

upper vapor
#

😭

slow grotto
#

More of a meme plugin at the moment I guess

grand flower
#

💀

upper vapor
#

newtonsoft.json :((

slow grotto
#

Do you have a prefered one?

upper vapor
#

system.text.json

grand flower
#

and System.Text.Json

upper vapor
#

much better

#

yep

static meteor
grand flower
upper vapor
#

are y'all not using system.text.json? 😭

grand flower
#

I am for my own stuff

slow grotto
grand flower
#

outside of SL, don't think I needed json in SL

upper vapor
grand flower
#

tbh System.Text.Json is a bit more finnicky

upper vapor
#

why

grand flower
#

but mostly because JSON.NET breaks JSON standards iirc

upper vapor
grand flower
#

It's like, less lenient about the JSON you give it compared to JSON.NET

#

but once you fix it a little it's fine

#

For one of my side projects I had to pause I used System.Text.Json's NativeAOT stuff

#

it's cool

upper vapor
grand flower
#

I don't remember exactly

upper vapor
#

or whih oart

grand flower
#

I think for one it doesn't like ints with decimals

#

1.0 wouldn't parse to an int for example

#

even though it's perfectly round

upper vapor
#

☠️

grand flower
#

that pissed me off for a while

#

had to ask the sole Garry's Mod maintainer to fix the JSON functions LOL

#

thankfully he did pretty much the next day so I love that guy

grand flower
upper vapor
#

i guess you could've made a custom converter but yeah replace works ig

#

now do it with spans toomuchtrolling

grand flower
upper vapor
#

right

#

you'd need to add the serializer options to every call

#

ugh

grand flower
#

y u p

upper vapor
#

kinda sad how you can't change the defaults

grand flower
#

that's why I just did the bandaid solution on the gmod lua side and then removed it when the maintainer fixed it

#

but I'll just have to remember about this issue for my project when I expose JSON to Luau

upper vapor
grand flower
#

wrote some funky C++ to detect recursion in userdata parents

#

so like if you had a userdata A that had userdata B as a parent, but B has A as a parent

#

The compiler already catches that but the error was a bit hard to read, so I made my own detection to get a nicer one

upper vapor
upper vapor
grand flower
#

better than what the compiler used to say

#

This just tells you that the constraints of not having a recursive base isn't satisfied

#

Which should be enough for you to go "oh fuck I have a circular base"

ashen hound
#

imagine if anyone uses livestream thing which I made for audio player api lol

celest thorn
slate flume
slate flume
#

I wonder if this was ever fixed

#

Also I need to get into LabAPI support cause I'm about to crash out trying to figure out what's going wrong

grand flower
#

don't think so

#

I think Bright's still having the issue

#

I'd have to check logs later

celest thorn
#

i could try helping you

slate flume
# celest thorn whats the issue

I'm spawning a primitive and a dummy when a player dies and for some reason this makes it so when the player spawns back in, they take no damage from firearms

#

I get no errors in the console, no errors in the LocalAdminLogs

sweet flax
#

can you show the code

slate flume
sinful bronze
#

can you go to touch grass

royal mica
#

Random thought: Would a Dummy be damaged if you spawn it behind the Player and shoot the player?

slate flume
#

I can test

#

Bullet holes were going right through the player

royal mica
#

That rules out hitbox issues possibly

slate flume
#

The raycasts just aren't hitting

royal mica
#

if so, then possibly the hitbox is lost somewhere

slate flume
#

I know it's in this section of code because when I removed it the problem was fixed

grand flower
#

which section of code

slate flume
grand flower
#

code

celest thorn
#

code

slate flume
#

The problem is in a component I made

plain gazelle
#

All of our discord webhooks are broken qwq
HttpClient.GetAsync("example.com") works totally fine, but anything going out to discord.com times out :c
Is this a Discord issue, Terabit issue or skill issue on our side

slate flume
# grand flower code
public class GhostAnimation : MonoBehaviour
{
    private FirstPersonMovementModule FPMM;
    private Fade Fade;
    private ushort Frames;
    private const ushort DisappearStart = 90;
    private const ushort MaxFrames = 150;
    private Vector3 DeltaPos;
    private float FadeIntensity;
    private float FadeIntensityIncreasePerFrame;
    
    public void Init(ReferenceHub ghost, Vector3 endPosition)
    {
        FPMM = ((IFpcRole)ghost.roleManager.CurrentRole).FpcModule;
        Frames = 0;
        DeltaPos = (endPosition - FPMM.Position) / MaxFrames;
        Fade = ghost.playerEffectsController.GetEffect<Fade>();
        ghost.characterClassManager.GodMode = true;
        FadeIntensity = Fade.Intensity = 120;
        FadeIntensityIncreasePerFrame = (255 - FadeIntensity) / (MaxFrames - DisappearStart);
        FPMM.Motor.GravityController.Gravity = Vector3.zero;
    }
    public void Update()
    {
        if (Frames++ >= MaxFrames)
        {
            Destroy(gameObject);
            return;
        }

        FPMM.Position += DeltaPos;
        if (Frames >= DisappearStart)
        {
            FadeIntensity += FadeIntensityIncreasePerFrame;
            Fade.DisableEffect();
            Fade.Intensity = (byte)Math.Round(FadeIntensity);
        }

    }
}

Also this code kind of sucks right now

grand flower
#

what piece of code fixes it?

slate flume
grand flower
#

just check for exceptions in local admin logs

slate flume
#
public override void OnPlayerDeath(PlayerDeathEventArgs ev)
{
    if (ReferenceEquals(ev.Player?.ReferenceHub, null))
        return;
    if (!Physics.Raycast(ev.OldPosition, Vector3.down, out RaycastHit hit, 10, ~LayerMask.GetMask("Ragdoll")))
        return;
    Vector3 up = hit.normal;
    Vector3 floor = hit.point;
    if (Vector3.Dot(Vector3.up, up) < 0.7)
        return;
    float height = 0.7f;
    float length = 0.2f;
    Quaternion rotation = Quaternion.FromToRotation(Vector3.up, up) * new Quaternion(0, 1, 0 ,0) * RemovePitchFast(ev.OldCameraRotation);
    Vector3 position = floor + up * height / 2;
    var gravestone = PrimitiveObjectToy.Create(position, rotation, networkSpawn: false);
    gravestone.Type = PrimitiveType.Cube;
    gravestone.Color = new Color(0.15f, 0.15f, 0.15f);
    gravestone.Flags = PrimitiveFlags.Visible;
    gravestone.Scale = new Vector3(0.5f, height, length);
    gravestone.Spawn();
    var text = TextToy.Create(floor + up * height * 0.7f - rotation * Vector3.forward * (length / 2 + 0.001f), rotation, networkSpawn: false);
    text.Scale = new Vector3(0.5f, height, length);
    text.DisplaySize = new (100f, 100f);
    text.TextFormat = "<align=center><size=35%><b>RIP";
    text.Spawn();
    ReferenceHub ghost = DummyUtils.SpawnDummy("Apparition");
    Timing.CallDelayed(Timing.WaitForOneFrame, () =>
    {
        ghost.roleManager.ServerSetRole(ev.OldRole, RoleChangeReason.None, RoleSpawnFlags.None);
        ghost.TryOverrideRotation(QuaternionToPitchYaw(ev.OldCameraRotation));
        //ghost.playerStats.GetModule<AdminFlagsStat>().SetFlag(AdminFlags.Noclip, true);
        ghost.TryOverridePosition(ev.OldPosition);
        ghost.gameObject.AddComponent<GhostAnimation>().Init(ghost, ev.OldPosition + Vector3.up * 2);
    });
}
slate flume
#

That's why I'm baffled

grand flower
#

before initializing the component

slate flume
grand flower
#

try a second

#

if that fixes it try 1 frame or 2 frames

celest thorn
grand flower
#

we love delay based fixes

slate flume
grand flower
#

-_-

slate flume
#

Yeah so a delay didn't do anything

grand flower
#

did you try doing the rotation & position override after the delay too

slate flume
#

I took everything after setting the role and delayed it by a second

#

And it fixed nothing

celest thorn
#

so from where you think the problem starts?

slate flume
grand flower
#

just comment out code until it starts working

slate flume
grand flower
#

inside the component

slate flume
#

Sure

celest thorn
#

Wait

#

you forgot to add the effect

#

the effect is never enabled

slate flume
celest thorn
#

oh forgot about that

#

my bad

slate flume
#

Also what layermask are items on?

#

I want to exclude them from my raycasts

grand flower
#

i think

slate flume
grand flower
#

don't remember

#

can't you use the number anyway

slate flume
#

~LayerMask.GetMask("Ragdoll")

grand flower
#

LayerMask.LayerToName(9)

slate flume
#

I could but it's inconvenient as shit with what I already have

teal junco
slate flume
#

It's InteractableNoPlayerCollision

#

I commented out the code that runs in the update cycle and the problem disappeared

#

What the hell

celest thorn
slate flume
celest thorn
#

maybe then the FPCC.Position?

slate flume
#

Hey look I fixed it

#
public class GhostAnimation : MonoBehaviour
{
    private FirstPersonMovementModule FPMM = null!;
    private Fade Fade = null!;
    private ushort Frames;
    private const ushort DisappearStart = 90;
    private const ushort MaxFrames = 150;
    private Vector3 DeltaPos;
    private float FadeIntensity;
    private float FadeIntensityIncreasePerFrame;
    
    public void Init(ReferenceHub ghost, Vector3 endPosition)
    {
        FPMM = ((IFpcRole)ghost.roleManager.CurrentRole).FpcModule;
        Frames = 0;
        DeltaPos = (endPosition - FPMM.Position) / MaxFrames;
        Fade = ghost.playerEffectsController.GetEffect<Fade>();
        ghost.characterClassManager.GodMode = true;
        FadeIntensity = Fade.Intensity = 120;
        FadeIntensityIncreasePerFrame = (255 - FadeIntensity) / (MaxFrames - DisappearStart);
        FPMM.Motor.GravityController.Gravity = Vector3.zero;
    }
    public void Update()
    {
        if (Frames++ >= MaxFrames)
        {
            NetworkServer.Destroy(gameObject);
            return;
        }

        FPMM.Position += DeltaPos;
        if (Frames >= DisappearStart)
        {
            FadeIntensity += FadeIntensityIncreasePerFrame;
            Fade.DisableEffect();
            Fade.Intensity = (byte)Math.Round(FadeIntensity);
        }

    }
}

Spot the difference

grand flower
#

missing networkserver.destroy?

slate flume
grand flower
#

but also why are you using networkserver.destroy

slate flume
grand flower
#

ah

#

ok

slate flume
#

This was actually awful

celest thorn
#

oh so that

#

lol

slate flume
#

Idk why UnityEngine.Object.Destroy on a dummy caused a seemingly unrelated player to stop registering damage from firearms

grand flower
#

i love not dealing with unity bs

slate flume
#

Idek how tf that happens

#

Is there any easy way to remove the Dummy badge from a dummy?

#

Wait nvm

#

I'm just gonna edit the PlayerDisplayInfo

hearty shard
grand flower
#

You can hide them from the player list

#

But yeah it'll always have a dummy badge in-game

slate flume
#

Cause hiding the badge from playerdisplayinfo isn't working for some reason

#

Which API maintainer should I @ about this new bug I found

#

Not the one I found with Destroy

#

It's a different one

#

Well actually I'm not sure if it's NW or LabAPI

hearty shard
#

well

#

is it basegame or labapi.dll

slate flume
#

Base game

#

But it's with dummies

hearty shard
#

@hubert Trol

slate flume
#

And I'm not sure if dummies consitutes base-game territory

#

Or if that's something that should go to LabAPI

static meteor
slate flume
#

It's pretty easy actually

static meteor
#

I think i just set the text to string.Empty

slate flume
#

And that's not what I want

teal junco
#

tfw only 32k dummies

slate flume
hearty shard
#

Lmao

slate flume
#

This is ultimate programmer humor memorialized in a bug report

#

I need 2.1 billion more dummies

teal junco
#

I need 32 thousand more speakertoy channels

#

you guys will never understand how it feels

slate flume
#

So are capped at 256 unique SpeakerToys

teal junco
#

but like

#

itd be nice

#

yk

slate flume
#

Yk

#

Replace CASSIE

teal junco
#

But I understand

slate flume
#

Nice

teal junco
#

theres gonna be a point where a lot of plugins use audio

#

It might happen soon. But that kinda builds up

slate flume
#

Yeah I mean there's no way there's not a use case where someone is using more than 256 unique SpeakerToys

teal junco
#

But ideally you wouldnt need to do all these tricks lol

slate flume
#

I want to write unoptimized code

teal junco
#

Also, some plugins (like Amert) are user oriented, not programmer, and when you play a sound through it, each individual one takes up a controllerID

#

A server host who cannot program might end up with a situation where 256+ Amert sound effects are playing at once for whatever reason, and on top of other plugins with their own audio channels, it will cause issues

#

its super edge case though, and maybe eventually I will have saved enough bytes worth of internet transmissions through the controller ID being a byte instead of ushort to buy a coffee

slate flume
#

SCP prox chat

#

That's another few controller IDs used up

teal junco
#

Yeah

#

I think Northwood should have a basegame controllerID pool or something for plugin devs to use

#

because I am sick of two plugins who arent aware of each other's existence (like scp prox chat and AudioPlayerApi) sending different sounds thru the same channel

#

And I literally cant be fucked to modify it so they do

grand flower
#

you can always check what ids are available

#

just gotta have competent plugin devs

teal junco
grand flower
#

but basegame would be nice yeah

slate flume
teal junco
# grand flower you can always check what ids are available

Honestly I have no idea how to do this. Like for audioplayerapi it may be simple enough, but if youre using AudioTransmitter from LabApi, or someone is using basegame or directly using LabApi wrappers for speakers, I dont think that gets properly registered in any way

slate flume
#
public static byte[] UsedControllerIds => SpeakerToy.List
    .Where(toy => !toy.IsDestroyed)
    .Select(toy => toy.ControllerId)
    .ToArray();

public static byte NextAvailableControllerId
{
    get
    {
        var used = new HashSet<byte>(SpeakerToy.UsedControllerIds);
        for (byte i = 0; i < byte.MaxValue; i++)
        {
            if (!used.Contains(i))
                return i;
        }
        
        if (!used.Contains(byte.MaxValue))
            return byte.MaxValue;

        throw new InvalidOperationException("No available controller IDs remaining.");
    }
}

public void AssignNextAvailableControllerId() => speakerToy.ControllerId = SpeakerToy.NextAvailableControllerId;
grand flower
#

I have a better one sec

grand flower
#
/// <summary>
/// Gets an enumerable which contains all occupied identifiers for audio components.
/// </summary>
public static IEnumerable<int> GetOccupiedIdentifiers() => SpeakerToy.List
    .Select(s => s.IsDestroyed ? -1 : s.ControllerId);

/// <summary>
/// Returns the first available controller id that can be used for audio components, or null if none are available.
/// </summary>
public static byte? GetAvailableIdentifier()
{
    // Unchecked because we can't overflow a byte with values between 0 - 255
    // Two less instructions, yippee.
    unchecked
    {
        var available = Enumerable.Range(byte.MinValue, byte.MaxValue + 1)
            .Except(GetOccupiedIdentifiers());

        // Won't cause issues in this case - we know what we're enumerating.
        // ReSharper disable PossibleMultipleEnumeration
        if (available.Any())
        {
            return (byte?)available.First();
        }
        // ReSharper restore PossibleMultipleEnumeration

        return null;
    }
}
slate flume
#

You're working with ints instead of bytes directly

#

And it also doesn't early return when it finds a non-occupied member

grand flower
#

you initialize a new hashset

slate flume
grand flower
#

not enough to matter compared to using a hashset

slate flume
grand flower
#

might be able to optimize it a tiny bit but like, this isn't gonna be used in a hot path anyway

slate flume
#

I use HashSet for O(1) lookups

grand flower
#

also

#

they're enumerables

#

they're lazily evaluated in this case, so Any() returns true immediately because there's an element

#

and we return the first one that isn't excepted (GetOccupiedIdentifiers())

#

afaik

slate flume
#

So you're checking 255 controllerIDs, not 256

slate flume
grand flower
#

not a lot less optimized, but probably a bit slower?

grand flower
slate flume
grand flower
#

why

slate flume
grand flower
#

it's on the stack

slate flume
#
public static byte NextAvailableControllerId
{
    get
    {
        var snapshot = SpeakerToy.List.ToArray();
        var present = new bool[256];

        foreach (var t in snapshot)
            if (!t.IsDestroyed)
                present[t.ControllerId] = true;

        for (ushort i = 0; i <= byte.MaxValue; i++)
            if (!present[i])
                return (byte)i;

        throw new InvalidOperationException("No available controller IDs remaining.");
    }
}
grand flower
#

I have no memory allocation pretty much

#

nothing that will be GC'd at least

slate flume
grand flower
#

new

#

you're allocating 256 bytes of memory

slate flume
#

Oh true

#

I'll stackalloc it

grand flower
#

Enumerable solution is cleaner DogKek

#

You also do ToArray() so that's another allocation

slate flume
#

So just

#
public static byte GetNextAvailableControllerId_StackAlloc()
{
    var snapshot = SpeakerToy.List.ToArray();
    Span<bool> present = stackalloc bool[256];

    foreach (var t in snapshot)
        if (!t.IsDestroyed)
            present[t.ControllerId] = true;

    for (ushort i = 0; i <= byte.MaxValue; i++)
        if (!present[i])
            return (byte)i;

    throw new InvalidOperationException("No available controller IDs remaining.");
}

public static byte NextAvailableControllerId => GetNextAvailableControllerId_StackAlloc();
#

Probably the least overhead

#

Well

#

Toarray still isn't pretty

#

So

#
public static byte GetNextAvailableControllerId_StackAlloc()
{
    Span<bool> present = stackalloc bool[256];

    foreach (var t in SpeakerToy.List)
        if (!t.IsDestroyed)
            present[t.ControllerId] = true;

    for (ushort i = 0; i <= byte.MaxValue; i++)
        if (!present[i])
            return (byte)i;

    throw new InvalidOperationException("No available controller IDs remaining.");
}
#

Put that in the getter

#
public static byte NextAvailableControllerId
{
    get
    {
        Span<bool> present = stackalloc bool[256];

        foreach (var t in SpeakerToy.List)
            if (!t.IsDestroyed)
                present[t.ControllerId] = true;

        for (ushort i = 0; i <= byte.MaxValue; i++)
            if (!present[i])
                return (byte)i;

        throw new InvalidOperationException("No available controller IDs remaining.");
    }
}
spare zodiac
slate flume
spare zodiac
#

makes sense

grand flower
slate flume
#
public static byte NextAvailableControllerId
{
    get
    {
        Span<bool> present = stackalloc bool[256];

        foreach (var t in SpeakerToy.List)
            if (!t.IsDestroyed)
                present[t.ControllerId] = true;

        for (byte n = 0; n < byte.MaxValue; n++)
            if (!present[n])
                return n;
        
        if (!present[byte.MaxValue])
            return byte.MaxValue;

        throw new InvalidOperationException("No available controller IDs remaining.");
    }
}

Is probably the best it gets

grand flower
#

You're pretty much doing the same just a little more janky? When C#'s providing you exactly what you need

#

You're also adding another branch with the if (!present[byte.MaxValue])

slate flume
grand flower
#

would have to see the IL

#

but again, I wouldn't worry about using ints

hearty shard
#

i mean

grand flower
#

The way it's done is on the stack, there's no GC pressure

hearty shard
slate flume
#

Yeah you're probably right

grand flower
#

Keep in mind the compiler is also smart

slate flume
#

Probably the best optimization without sacrificing readability

teal junco
#

Just write it in assembly atp

slate flume
#

Should I make a bit manipulation version? TechnoScheme

grand flower
#

I'd shoot you if you worked on my codebase

#

You're not calling this 10000 times a second

#

And even if you were it probably wouldn't be expensive anyway

slate flume
#

Hyper-optimizing one controllerID lookup

hearty shard
#

hyper optimize it all

slate flume
#

To me it just feels better than the Enumerable

hearty shard
#

Or or

#

Patch it all

#

OnDestroy and Awake or wtv

#

or ig the id setterM

#

Idk

grand flower
#

Enumerable's probably the cleaner solution

#

just from a readability perspective

hearty shard
grand flower
#

Yours might be a bit more performant, a bit less performant, idk

hearty shard
#

Whats the point of C# if not optimizing to the maximum

slate flume
#

I'm making a bit manipulation version

#

Fuck it

hearty shard
#

we need assembly in C#

#

or just C++.....

#

Or C

slate flume
hearty shard
#

Get out.

slate flume
#

I'm gonna optimize the fuck out of this loopup

restive turret
#

loopop

slate flume
#

I'm gonna steal so much code off of stack overflow

restive turret
#

Can't wait for it to you to crash out on it

true cedar
slate flume
#

I think?

warped prairie
#

hope we are all doing well

slate flume
warped prairie
#

indeed, hope things go better today

true cedar
#

present.IndexOf(false) is likely faster

slate flume
#

Not sure how tf this works but I stole it from stack overflow

// de Bruijn lookup table for 64-bit trailing-zero.
private static readonly int[] DeBruijnIdx64 = new int[64]
{
     0, 1, 48, 2, 57, 49, 28, 3,
     61, 58, 50, 42, 38, 29, 17, 4,
     62, 55, 59, 36, 53, 51, 43, 22,
     45, 39, 33, 30, 24, 18, 12, 5,
     63, 47, 56, 27, 60, 41, 37, 16,
     54, 35, 52, 21, 44, 32, 23, 11,
     46, 26, 40, 15, 34, 20, 31, 10,
     25, 14, 19, 9, 13, 8, 7, 6
};

// Trailing-zero count (returns 0..63), or 64 if v == 0
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int TrailingZeroCount64(ulong v)
{
    if (v == 0) return 64;
    // isolate lowest set bit
    ulong isolated = v & (ulong)-(long)v;
    // multiply by de Bruijn and shift
    int idx = (int)((isolated * 0x03F79D71B4CB0A89UL) >> 58);
    return DeBruijnIdx64[idx & 0x3F];
}
true cedar
#

what the fuc

#

k

slate flume
#

Exactly

true cedar
#

why

slate flume
#

It's an efficient way to get the number of trailing zeros in a ulong

#

Apparently

grand flower
#

me when im in an overengineering competition and my opponent is ThatGuy

restive turret
#

Lol

slate flume
#

Okay I might have gotten it?

#

I've never done a lot of bit manipulation shit before

hearty shard
#

only paws and thatguy would do this

hearty shard
#

holy macaroni

true cedar
#

prob

grand flower
#

Remind me to blacklist every single one of you sinners from my codebases

#

my poor babies are going to be violated

soft depot
#

I don't do it in invidual methods (unless peformance critical), but I do overengineer my features

slate flume
#
Span<ulong> words = stackalloc ulong[4];
words.Clear();

// Build bitset: 1 = used
foreach (var t in SpeakerToy.List)
{
    if (t.IsDestroyed) continue;
    int id = t.ControllerId;
    int wi = id >> 6; // id / 64
    int bit = id & 0x3F; // id % 64
    words[wi] |= 1UL << bit;
}

// Scan words for first zero bit (free spot)
for (int wi = 0; wi < words.Length; wi++)
{
    ulong freeBits = ~words[wi];
    if (freeBits == 0) continue;

    int tz = TrailingZeroCount64(freeBits); // 0..63
    int candidate = (wi << 6) + tz;
    if (candidate <= byte.MaxValue)
        return (byte)candidate;
}

throw new InvalidOperationException("No available controller IDs remaining.");

I think this works?

#

What the fuck am I writing

true cedar
#

meh

grand flower
#

please get some help

soft depot
true cedar
#

you could just treat it as a Span<ulong> and rely on simd

#

or Span<int>

#

something like that

#

hashsets/maps usually do that

slate flume
#

Small arrays it doesn't really matter

true cedar
#

no

#

afaik

soft depot
true cedar
#

its still one instruction

soft depot
slate flume
#

We're not operating on a bitset, we're scanning a bitset

true cedar
#

swiss maps do it

slate flume
#

It depends on the size of the bitset

#

This bitmap is small

#

And also I suspect it allocates shit too

#

Bad

true cedar
#

what u do is probably fine is and is effectively SWAR

#

but actual simd might be work better

grand flower
#

All this effort, just for SL to negate it all in one movement tick

soft depot
#

also, like why are we foreaching every speaker toy then for ing over whatever that span is, just foreach every speaker, & by the ~ of the id, then for each byte for a non-zero value

#

like what are we even doing

true cedar
#

although yeah you could literally just keep track of the smallest value

soft depot
#

the span idea is cool n all for less memory usage, but I think the fastest method should be only one iteration over every speaker toy

slate flume
soft depot
#

no more fors or whatnot

#

I think tracking every value at once, then &ing by the ~ is the best way tho cuz you track all values at once, then you just find a non-zero value

slate flume
soft depot
true cedar
soft depot
#

I didn't know bit manipulation was so inefficient

true cedar
#

the "overhead" they're referring to afaik is because you need to fit simd data within lanes

slate flume
true cedar
#

but you have what is either a supported lane count or can easily be divided into one

slate flume
#

We find the place in memory and shift the corresponding bit

true cedar
#

but why not just

soft depot
#

bruh

true cedar
#

loop once keep track of the smallest value

soft depot
#

do I gotta draw this out

soft depot
true cedar
#

the only advantage i can think of is fewer branches

soft depot
#

we can use 0, 1, 2, 3 etc... but not 255

#

and then what

#

0's used up, what do we do

#

it's the smallet value

true cedar
#

yea

#

get the smallest unused value i mean

#

oh wait ic

soft depot
#

alr now you get it

#

you gotta track every possible value

slate flume
#

I'm confused

slate flume
restive turret
#

Hi confused

soft depot
slate flume
true cedar
#

no i get why he's doing that

slate flume
#

Then use an efficient method to find the first non-zero

true cedar
#

also don't use a for loop in this case

slate flume
#

ulong freeBits = ~words[wi];

soft depot
true cedar
#

unroll the loop

slate flume
soft depot
#

just check if the value is greater than 0 if you're checking for non-zero values 😭

slate flume
#

Otherwise I don't get an id

#

My words count is 4 ulongs

slate flume
soft depot
#

then use a for loop

slate flume
#

Foreach is faster

slate flume
#

On the words

#

Then I find the non-zero in the fastest way

true cedar
#

unless jit does it for u

#

it might idk

slate flume
true cedar
#

yea

slate flume
#

That's crazy but interesting

#

Cause it's technically faster

true cedar
#

its what compilers often do

#

im guessing that the jit can do it

slate flume
#

I mean yeah it's probably doing that already

#

Compilers are smart

true cedar
#

but you might want to explicitly specify the count

#

to make it far more likely

true cedar
#

AOT compilers are

true cedar
#

unchecked code is also faster iirc

#

so u can try adding that

#

god i love micro optimizing

slate flume
#

I wanted to hear a little about the shit I stole

#

In combinatorial mathematics, a de Bruijn sequence of order n on a size-k alphabet A is a cyclic sequence in which every possible length-n string on A occurs exactly once as a substring (i.e., as a contiguous subsequence). Such a sequence is denoted by B(k, n) and has length kn, which is also the number of distinct strings of length n on A. Each...

#

What

#

Okay boss

restive turret
#

Omg a number

slate flume
#

It's all starting to make sense

teal junco
#

urm wtf

stable cipher
teal junco
#

im not trippin right

#

yall see this

stable cipher
#

both of us

#

yup

teal junco
#

rip

restive turret
#

Lmao

true cedar
#

um

#

what

#

did i miss

teal junco
#

idfk

true cedar
#

why is he a deleted user now wtf

true cedar
true cedar
burnt hearth
#

where

teal junco
#

the dude deleted himself

burnt hearth
#

who

true cedar
#

im psure it takes like

burnt hearth
#

oh shit i see now

#

who was the person?

true cedar
#

a week for someone to delete their account

#

and during that time you can't use it

#

wtf did he do

burnt hearth
#

HUH WHAT HAPPEND TO TECH

#

NOOOO

grand flower
#

Discord bug

#

wait

#

no???

burnt hearth
#

wait no

#

that isn't tech

grand flower
#

ThatGuy

true cedar
#

lmfao he actually went poof

teal junco
#

@slate flume

grand flower
#

But like I see him as normal and Deleted User at the same time

#

wtf

static meteor
teal junco
#

he exists?

burnt hearth
#

WTF?

#

huhhh

teal junco
#

but he also doesnt

#

may be a discord bug

grand flower
#

probably

true cedar
#

@slate flume

#

wait wtf

grand flower
#

I restarted and now it's deleted

#

welp

true cedar
#

oh i did

#

too

#

jesus

grand flower
#

except in dms still looks fine

burnt hearth
grand flower
#

odd

#

yeah

#

probs discord bug

true cedar
#

they 86'd him

soft depot
#

def discord moment

true cedar
#

i think he actually got deleted

restive turret
#

Or he force deleted himself

true cedar
#

only in plugin chat istg

grand flower
#

odd

mild ice
#

!getuserinfo 434572461011501067

regal lakeBOT
soft depot
grand flower
#

odd

soft depot
#

only the pfp of the dm is fine

#

anyways, he probably learned too much

grand flower
#

i can still dm

#

weird

soft depot
#

actually the server he devs for, in general somebody said his acc got disabled by discord

#

so I guess it was intentional?

grand flower
#

weird

restive turret
#

If you violate ToS or eual or smth ye you get no time for it

#

You get immediate action

teal junco
#

what did my boy do

restive turret
#

Idk

#

Math?

burnt hearth
restive turret
#

He probably crashing out because of that

burnt hearth
#

😭

true cedar
soft depot
#

aint no chat like a plugin chat

restive turret
soft depot
#

in java for sure

grand flower
#

!getuserinfo 434572461011501067

regal lakeBOT
agile tartan
#

I heard spawn queue numbers (4013...) have a bug now. Is there any way to change it via plugin?

teal junco
#

i might add support for event-based animations

#

i want sans to do his aura empty eyes whenever the player he's attached to pulls out a gun or something

soft depot
# teal junco

You better be using the arguments SyncList for this
If you aren't I'll make Exiled steal your house Trolley

warped prairie
teal junco
# teal junco

PS if anyone has high quality back facing versions of sans battle sprites please lmk

#

rn his back just says "sans; front on other side"

soft depot
teal junco
#

is it just determining who gets sent this info?

soft depot
#

What wrapper do you use?

teal junco
soft depot
soft depot
teal junco
#

just for instance

soft depot
#

Add a white pixel and a black pixel, then every pixel can be {0} or {1}

#

So less networking

teal junco
#

Oh I see

#

Yeah I used a script to make it, but I might consider finding another way

soft depot
#

I’ve done a lot of shenanigans with text toys lol

teal junco
#

at runtime or whatever

soft depot
#

I did this with primitives, but I can now do it with text toys

teal junco
#

What is the limit of synclist

#

can I put like 100 elements in it?

#

then I have hyper optimized 100 color images

soft depot
#

No limit, though it has to sync when new clients join

teal junco
#

Yeah

#

Luckily I dont worry myself about optimization

#

As long as I can't tell the TPS is dropping without checking I'm usually happy enough.

celest thorn
#

The biggest problem i've ever had is doing TextToys client side, I know its possible

#

but SyncList don't allow me and they are just a pain in the ass

upper vapor
celest thorn
upper vapor
spare zodiac
tepid sluice
#

hi chat

#

bye chat