#plugins-dev-chat

1 messages · Page 17 of 1

teal junco
#

memorystreams can have bytes written to them, then the bytes can be added to a filestream where i can add that to the end of a file?

grand flower
#

bingo

teal junco
#

What do you mean?

grand flower
#

pre: spawn players that need spawning, setup things for that snapshot
update: move players
post: do stuff after executing the snapshot, like idk despawning something, player hp etc

teal junco
#

Oh okay

#

yeah, that makes sense

grand flower
#

good luck!

teal junco
#

Thanks

#

This is all very interesting, hopefully wont be a pain in the ass to figure out

grand flower
#

You'll definitely bump into edge cases or special setups for certain entities

#

but I don't see why it wouldn't be feasible

teal junco
#

I could create snapshot sets with record and playback functionality for each entity in SL right

#

I don't think I'll write this for LabAPI unfortunately because I'm more familiar with the Exiled wrappers and I don't want to dive too deep into unfamiliar territory.

grand flower
#

You'd probably write different snapshot handlers for different entity types

#

I'd write it "event" based

grand flower
#

Pre: SpawnPlayerEvent(Name: SomePlayer, Id: SomeId), Update: MoveEntity(Type: Player, Entity: SomeId, Eventdata), Post: UpdatePlayerData(Id: SomeId, Data: {HP: Value, Role: SomeRole})

#

SpawnItem etc etc

#

Basically create as many events as you'd need to be able to replay a round

teal junco
grand flower
#

When I say snapshot I mean a capture of everything that happened between last captured frame and current captured frame

#

Easiest would be to capture at server tickrate

#

If between the last captured frame and current captured frame a door opened/closed, record that

#

record the new state of players (position, rotation, hp, role, etc)

#

record items spawning, despawning

#

so on and so on

teal junco
#

okay, I think I see, so the pre- in this case would be the player spawning if he didnt already exist, move entity being an update to transform if his data changed, and post being the player data changing

grand flower
#

yep

#

hmm technically "update" wouldn't exist in the snapshot data

#

it'd be the steps you would take when replaying a recording

#

I don't even think you'd need pre/post in that case. It'd be like "pre" to setup stuff needed for this frame (spawning/despawning) and then comparing the data from the previous captured snapshot to the current snapshot to determine changes/interpolate

teal junco
#

Okay, so an event would have the state of the relevant object saved, and when reading it runs the update code

grand flower
#

You'd look for the entities in the current snapshot inside the previous one, and if they exist you interpolate to the current state from the previous one

#

yeah

#

Events for entity spawning/despawning and the rest is just a dump of the recorded state of all entities

#

That'll probably work fine, you can despawn entities in the next capture snapshot's setup phase

#

you'll have to think up a clever way to detect stuff like shooting, throwing items, picking up etc

#

that's probably gonna be one of the hardest parts

teal junco
grand flower
#

Basically your list of changes are determined on a per-entity basis.
if an entity just got spawned this snapshot, skip them.
If they exist in the previous snapshot, you interpolate between the state of the previous one to the state of the new snapshot.
As such, you only need to record the state of the entities you wish to replay (position, rotation, hp, etc)

teal junco
grand flower
#

I wouldn't try to record event handlers

#

In the end those event handlers are just going to change entity states

#

Which you're already recording

teal junco
#

certain things I dont think can be saved as states, like firing a gun or using an item/interactible

teal junco
grand flower
#

You'll want to record them but you won't be able to interpolate

#

You'll spawn them, set their values

teal junco
#

yeah that makes sense

grand flower
#

it's an event that happened in the snapshot

#

You could save their equipped gun, and the amount of bullets fired with that gun

#

Then when you interpolate you know how many shots to simulate

teal junco
#

I would use a postfix event handler for that right

#

like ShotEvent

grand flower
#

sounds about right

teal junco
#

and I can simulate gunshots by telling the dummy to pull the trigger on a gun theyre holding, is that right? I probably have to come up with a special protocol for playbacking certain events anyways

grand flower
#

Yep

#

You're gonna be recording the player's items in the snapshots anyway

#

So for guns you'll know how much ammo they have in the mag

#

You can set that, then simulate a shot when playing back

teal junco
#

and for safety I should give the players godmode so they dont accidentally kill each other slightly earlier or later than theyre suoposed to right

grand flower
#

I would make an abstract SnapshotHandler<T> class, and you make specializations for every type of entity you want to record. Could have a RecordData method, PlaybackData(Snapshot previous, Snapshot current)

grand flower
#

Then you can just simulate damage by changing their HP since it'll change in the next snapshot anyway

teal junco
grand flower
#

you definitely should

#

Will make maintaining and adding more supported entities a lot easier

teal junco
#

So I would have like a PlayerSnapshotHandler : SnapshotHandler ?

grand flower
#

probably something like PlayerSnapshotHandler : SnapshotHandler<Player>

#

bonus with this is you can make your replay plugin support other plugins

#

if you make it public

#

They just have to implement their own handlers

teal junco
#

yeah i wanted to add a system to support other snapshots

grand flower
#

ay, makes it easy that way

teal junco
#

Should I compartmentalize snapshots, so have a different one for players base stats like hp, transform, role, and another one for item states within that player and etc

grand flower
#

That'll be up to you to find out haha

#

I can't think that far ahead

teal junco
#

I have done a total of zero projects of this kind of scale

grand flower
#

Oh I just remembered, it's not a bad idea it's just very low level and the work to do that from a plugin would be kinda huge.
However: it is how Unreal Engine's replay system works. It captures net events and replays them IIRC.

teal junco
#

Thats essentially fully lying to the client

worthy rune
#

yeah it would require patching to work, last time i thought about it, my initial goal was to make it work well with other plugins

teal junco
#

it would be nice as hell but also hard to make and maintain

grand flower
#

on Unreal though you just download the recording and replay it locally

#

You don't have a server sending you as the data as a client

#

You're just replaying what the server did

worthy rune
#

matinance should be better i would hope as new stuff should "just work"

#

obv recordings would break between updates

grand flower
#

You can definitely write your own binary format to handle updates

#

It's a lot of work ofc but Unreal has versioned saves for stuff like that

#

You'll need to like, save the version of the replay within it and "port" the data to the latest format before replaying it

worthy rune
#

i dont think mirror is so forgiving, if theres new data required in a packet it expects it, or the client soft locks immediately

grand flower
#

oh right yeah if you go the net packet route

#

I meant the simpler state capturing on the server

worthy rune
#

ahh

grand flower
#

i don't think Unreal handles that either for its demo net driver

teal junco
#

I thought I could use NPC motor and mouselook but it might desync

#

I wonder if players being constantly teleported would be able to play walking animations and footsteps

grand flower
#

I'd just interpolate towards the captured position/rotation

#

dunno about sounds though

worthy rune
#

sounds like footsteps are produced client side from player movement so should work without any extra code

teal junco
grand flower
#

nvm Unreal does support different versions with its demo net driver

grand flower
#

it just records the version of the recording and sets it when (de)serializing data

#

just gotta make sure you handle that in your game code if you have custom serialization

#

smart

upper vapor
restive turret
#

So you know what to deser

upper vapor
#

I mean if you sniff the outgoing packets then you'd know exactly what type of message it is

grand flower
#

It would work but it'd be a lot more work than just capturing entity states into snapshots directly and replaying them, because you're doing it from a plugin not with low level access

#

It's how Unreal does it and it has a custom net driver class (handles processing packets) just for it, directly in the engine

upper vapor
grand flower
#

Depends on how knowledgeable you are on that kind of thing

#

If you don't know how the net side works you'll probably spend more time trying to understand and learn it

#

compared to the other approach which is a little simpler to wrap your head around

restive turret
#

Eh, really depends on the person who writing it

upper vapor
#

Let's make both implementations and see how many things do we break toomuchtrolling

restive turret
#

Million

upper vapor
#

Labillion

restive turret
#

Grenade calculation would be that

upper vapor
#

Uh oh

grand flower
#

If you managed to replay the net packets deterministically and properly, yeah you'll probably end up with a better result

#

But the other solution is probably going to look fine too with some tinkering

upper vapor
#

The snapshot and replay one

grand flower
#

The downside is that it'd be hard to replay demos of other versions with the net stuff

restive turret
#

Ye no shit

grand flower
#

It's feasible but like, from a plugin ehhhhhhh

restive turret
#

In r6s it is exact same

grand flower
#

you'll bash your head in

#

it's the simpler option DogKek

#

Unreal supports it but only if you handle it in your game and well, nobody does that

restive turret
#

You can't really upgrade or downgrade demos

grand flower
#

You can but it's assuming you don't remove stuff from the game

#

and well, don't change behaviour either

#

which atp yeah nah

restive turret
#

If you rewrite fully some things will

grand flower
#

dunno why Unreal supports it tbh

#

I can't think of any game that implemented demos w/ versioning support

#

all of them just tell you to eat dirt if you want to watch a replay from an older version

upper vapor
#

Challenge: write custom network message serializers and deserializers with versioning and make deserialization backwards-compatible toomuchtrolling

restive turret
#

You can just ultimately write a version in header or smth and show error when try to replay

grand flower
#

doesn't matter if you support different versions of net messages

#

the issue is if the functions those net messages call changed between versions, you'll end up with different results

#

best case scenario your players are now stuck walking in walls or something, or not doing the actions they should be doing

#

worst case scenario you just crash

restive turret
#

That's why nobody doing it really

grand flower
#

oh, reminds me

#

@teal junco you'll need to save the seed of the map in your replay data

upper vapor
#

ViaVersion but for SL

grand flower
#

since you'll want the exact same map

restive turret
#

Would be funny going tru walls

grand flower
#

You probably wouldnt

#

Assuming the dummy colliders will stop you from doing that

#

Idk

#

Would be funny though

upper vapor
#

Not if you give them noclip

restive turret
#

Well have fun with either of those options

#

ClassDPlushie best of luck or smth

worthy rune
#

would be the least of your problems if the seed is incorrect due to the relative positioning system people will just teleport between random rooms when they walk between them

upper vapor
#

Lmao

grand flower
#

Relative positioning system?

upper vapor
#

Hold up

grand flower
#

I'm in bed cant turn on the sound, can you give me a tldr?

#

I'll watch it fully tomorrow tho ty

#

Okay I think I got the gist of it

#

Now the real question: why though

#

Like why is it relative to a room and not just world coordinates

static osprey
#

did you get to check it out?

worthy rune
#

the reason for moving elevators i think was to make effects where you can see players through wall work with them i.e. you dont just see the players disapear when the elevator teleports them

grand flower
#

I'd get having based movement for elevators but don't really get why the bandwidth reduction was needed that bad for the rest

unique crane
worthy rune
#

bandwidth was a nice side effect i think and wasnt the main reason

static osprey
upper vapor
static osprey
upper vapor
#

So it's a significant improvement for larger servers

static osprey
#

im banning myself to test

grand flower
#

I don't think it would matter tbh considering the game and the player counts you target

unique crane
static osprey
grand flower
#

Unreal uses double precision floats for everything nowadays and it's not that bad bandwidth wise. Could just strip down the precision if required heh

#

I think SL's biggest issue is just processing for large player counts

#

Dies pretty fast

worthy rune
#

true

upper vapor
upper vapor
grand flower
#

Oh yeah it'd do that but ehhhh in all honesty does seem like it adds a lot of complexity for rather small benefits/results

#

Could just do parent-based relative movement in some scenarios, like elevators (p much the only scenario in SL)

unique crane
upper vapor
#

Easy touse

worthy rune
grand flower
#

Hey if it's all done and working nowadays that's cool, mostly meant when it was originally thought of and implemented heh

grand flower
#

Kinda wish the spawn waves had intros

#

Would be cool

unique crane
#

Pro tip: get the PumpActionModule and set NumberOfBarrels to 16

worthy rune
#

yeah setting the parent and sending local positions could of worked too

upper vapor
grand flower
#

Idk why moving platforms made me think of that

#

Being able to see yourself in the MTF heli

static osprey
grand flower
#

Or driving as CI

static osprey
upper vapor
grand flower
upper vapor
#

That would be cool indeed

#

I guess you could use the ensnared effect and 0 gravity and position overrides

grand flower
#

Doubt it'd look good at all unless NW did it themselves

white matrix
#

Tyty I'll look into it

static osprey
#

@worthy rune@unique crane it works on other people, thanks though SteamHappy

unique crane
#

Thats truly interesting

upper vapor
restive turret
#

Lmao

upper vapor
#

i wanna get ntf working too, for some reason the offset is improperly set on the server (or i'm using the wrong transform)

soft depot
upper vapor
#

if only

icy knoll
#

does anyone know how to reset someone's snake game score to 0?

#

i know you can send data for snake over, i just dont know about how to do it and how to reset the score

#

just to tip off those people who just camp spawn 😭

upper vapor
#

Use the reset message type I guess

white matrix
#

In the new beta, does Specialist spawn with an E11 now?

#

did they change that or am I tripping and is a plugin changing this

hearty shard
#

Specialist and Sergeant are the same really

#

Specialist is just given when you escape thats the only difference

#

i think ?

upper pike
#

If only there was a plugin that gave specialists extra loot as a reward for escaping ClassDTroll

hearty shard
#

nuh uh

#

fuck specialist

#

remove it!!!

upper pike
#

But they have a cooler role colour

white matrix
#

anyways

brazen dune
#

@unique crane if there would be another round of events add microhid & jailbird ones

upper pike
white matrix
#

Any way to get the client-logs? I'm trying to find the cause of a friend's crash

restive turret
#

log,bat

upper vapor
#

What slejm said

white matrix
#

because their game keeps crashing after verifying

fresh zenith
static osprey
#

how would one set door state?

hearty shard
#

door.IsOpen = true

#

= false

#

i believe

#

or smth

#

idk what labapi has it as

static osprey
static osprey
celest verge
#

you can also trigger it with doorevents using the door's network target state

#

though door.IsOpen is easier to use

teal junco
#

Can I begin a LabAPI project by just referencing everything in the Server dlls?

unique crane
#

Yeah

#

All you need it the LabAPI dll and Assembly-Csharp

brazen dune
hearty shard
#

unless thats not decompiled

terse bone
#

snake players hate this simple trick

[HarmonyPatch(typeof(ChaosKeycardItem), nameof(ChaosKeycardItem.ServerSendMessage))]
internal static class SnakePatch
{
    private static void Postfix(ChaosKeycardItem __instance, SnakeNetworkMessage msg)
    {
        if (!PluginEntryPoint.Instance.Config.EnableSnakeExplosion)
            return;

        if (!msg.Flags.HasFlag(SnakeNetworkMessage.SyncFlags.HasNewFood))
            return;

        if (!ChaosKeycardItem.SnakeSessions.TryGetValue(__instance.ItemSerial, out SnakeEngine engine))
            return;

        if (engine.Score < 20)
            return;

        if (UnityEngine.Random.Range(0, 10) is not 0)
            return;

        Player player = Player.Get(__instance.Owner);

        player.RemoveItem(__instance);
        ExplosionUtils.ServerExplode(__instance.Owner, ExplosionType.PinkCandy);

        Logger.Info($"Player {player.LogName} exploded. Reason: played SNAKE too much");
    }
}
true cedar
#

DoorAction action = door.TargetState ? doorAction.Open : DoorAction.Closed;
DoorEvents.TriggerAction(door, action, ply);

hearty shard
grand flower
#

ServerEventType.PlayerDamage is now PlayerHurting right

#

or PlayerHurt?

restive turret
#

I don't know about labapi only custom roles, exiled has those.
And I also did make a custom items.
Logger.Debug has a second parameter as a bool, I use something like
Main.Instance.Config.Debug to can change to print or not

teal junco
#

 ÿÿÿÿ  ADemoSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null !DemoSystem.Snapshots.TestSnapshot <Name>k__BackingField  Firstnm Lastnm
@grand flower does this look like a proper serialized?

grand flower
#

no clue

#

never looked at serialized data

teal junco
#

Damn

upper vapor
#

Otherwise it would be

#

Let's say, a bit unpleasant for the ears

teal junco
#

At least the mtf will get a good warning

upper vapor
#

True

upper vapor
unique crane
#

Any firearm-specific events yall would like to see?

upper vapor
#

no cancellation ofc

worthy rune
#

isnt that already a thing?

upper vapor
#

oh

unique crane
#

Brainstorming time

upper vapor
#

i didn't think of "aiming" lol

restive turret
#

or with -ing too

#

i guess

unique crane
#

My limitation is cancelling events which are triggered client-side no matter what

#

such as firing

restive turret
#

maybe MicroHidChangeing state

upper vapor
upper vapor
#

whar

unique crane
upper vapor
unique crane
#

Reloading, Unloading

upper vapor
#

why didn't i think of searching for that word

#

then

#

cocking weapon event

#

desync? probably

restive turret
#

well, only thing I would appriciate is Jailbird Damage hander parse the "IsCharged" can yo do that? SteamHappy

hearty shard
#

no!

upper vapor
unique crane
#

Hmmm

upper vapor
#

would 127 events be their own category?
like

  • Scp127ReactingToSpawnWave
  • Scp127SayingHello
  • Scp127SayingGoodbye
  • Scp127LosingFriend
    why did i name the last one that 😭
unique crane
#

He is sad when you die

unique crane
#

Each one has unique identifier enum for translations so you can tell which one it is

upper vapor
#

maybe Scp127LevelingUp

icy knoll
#

yeah i imagine people would want that

restive turret
#

also events for MicroHID and Jailbird

pallid shell
#

ehm, i need help

#

what do I have to click?

restive turret
#

there is no nuget

#

use one that shipped with the game

pallid shell
restive turret
#

from the dedicated server files

pallid shell
#

yeah but what file

#

what .dll

#

there are a lot of them

restive turret
#

LabApi.dll ?

pallid shell
#

oh

#

thanks

restive turret
#

and probably Assembly-CSharp. dll too

hearty shard
#

@unique crane hi buddyyyy

#

im here to complain

#

jk i want RAUtils.ProcessPlayerIdOrNamesList

unique crane
#

Haiiii

hearty shard
#

whats the actual source for that

#

mines broken

#

idk what changed in 14.1 in it for it to break

unique crane
#
public static List<ReferenceHub> ProcessPlayerIdOrNamesList(ArraySegment<string> args, int startindex, out string[] newargs, bool keepEmptyEntries = false)
{
    try
    {
        string argString = FormatArguments(args, startindex);
        List<ReferenceHub> players = ListPool<ReferenceHub>.Shared.Rent();

        /*
         * If the list starts with an "@" we will be looking for a list of player names rather than ID's
         * Tab autocomplete will format names like: @Thomasjosif or @"Thomas josif"
        */
        if (argString.StartsWith('@'))
        {
            Regex rg = new Regex(PlayerNameRegex);

            MatchCollection mc = rg.Matches(argString);

            foreach (Match match in mc)
            {
                // We need to remove the player from the arraysegment because if it contains spaces it ends up screwing up the segmentation
                argString = ReplaceFirst(argString, match.Value, "");

                // Remove our formatting
                string name = match.Value.Substring(1).Replace("\"", "").Replace(".", "");

                List<ReferenceHub> found = ReferenceHub.AllHubs.Where(ply => ply.nicknameSync.MyNick.Equals(name)).ToList();
                if (found.Count == 1 && !players.Contains(found[0]))
                    players.Add(found[0]);
            }

            newargs = argString.Split(' ', (keepEmptyEntries ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries));
            return players;
        }

        if (args.At(startindex).Length > 0)
        {
            // If the list of players to set nickname for is a set of ID's (i.e.: 1.2.3)
            if (char.IsDigit(args.At(startindex)[0]))
            {
                //Regular playerID processing. See the Misc.ProcessRaPlayersList util.
                string[] sar = args.At(startindex).Split('.');

                // Go through all strings in the split arguments above
                foreach (string s in sar)
                {
                    if (!int.TryParse(s, out int i) || !ReferenceHub.TryGetHub(i, out ReferenceHub hub))
                        continue;

                    if (!players.Contains(hub))
                        players.Add(hub);
                }
                    
            }

            // If the list of players to set nickname for is a set of names (i.e.: SoNearSonar.Beryl.Masonic)
            else if (char.IsLetter(args.At(startindex)[0]))
            {
                string[] sar = args.At(startindex).Split('.');

                foreach (string s in sar)
                {
                    foreach (ReferenceHub hub in ReferenceHub.AllHubs)
                    {
                        if (!hub.nicknameSync.MyNick.Equals(s))
                            continue;

                        if (!players.Contains(hub))
                            players.Add(hub);
                    }
                }
            }
        }

        newargs = args.Count > 1 ? FormatArguments(args, startindex + 1).Split(' ', keepEmptyEntries ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries) : null;
        return players;
    }
    catch (Exception e)
    {
        Debug.LogException(e);
        newargs = null;
        return null;
    }
}
hearty shard
#

than youuuu

unique crane
#

Wait

#

Why does it create new regex each player process

#

😭

hearty shard
#

oh yeah

#

that truly is special

#

me when

#

also

#

just realized ur code makes it so you cant have both player num + a player name

#

like 2.david.eve.5.6

#

wont work

#

only 2, 5, 6 will be processed guh

unique crane
#

Not that big of a deal

hearty shard
restive turret
#

Make a pr eve

hearty shard
unique crane
restive turret
hearty shard
#

good point h

unique crane
#

If you make something better, just DM it to me.. ill make PR and take the money

hearty shard
#

however

unique crane
restive turret
hearty shard
#

yeah

#

see

#

david doesnt deserve money

#

so we kill him

#

put him on a stake

unique crane
restive turret
#

A rare or very done steak?

hearty shard
#

something aint right here...

unique crane
#

Make the lambdas static

#

(micro nano optimalization)

teal junco
hearty shard
#

is there an easy way to get the local offset of a room ur in ?

upper vapor
hearty shard
#

yeah but

#

is there anything ingame currently

#

for it

#

otherwise i gotta make command 💔

upper vapor
#

Right uh

#

Yeah you gotta make a command

hearty shard
#

💔

#

@unique crane add to basegame ly

#

thankss

unique crane
#

Cant you just player.position - room.position?

hearty shard
#

idk

#

but still

unique crane
#

That gives you vector with offset from room and the player

hearty shard
#

basegame should have a nice way of it

#

@upper vapor am i stupid

#

this should be fine right

upper vapor
#

Yup

hearty shard
#

coolll

upper vapor
#

You can save some nanoseconds by putting player.Room into a local variable

hearty shard
#

nuh uh

#

so it should work

#

oh this doesnt spawn the item does it..

worthy rune
#

currenty you need to network spawn it yourself, this will probably change in future updates tho

hearty shard
#

it should have a bool spawn parameter

worthy rune
#

yeah

hearty shard
#

pls add

#

but yeah

#

that looks like the issue all along

unique crane
grand flower
#

Unable to test so resorting to asking here: does damage applied by cardiac arrest have 049 as the attacker if it was the one to touch you and give it to you

hearty shard
#

honestly

#

i wish 106 did that

#

when dying in pocket dimension

grand flower
#

Is it the case for 049 then or nah

#

Would be nice if it was

upper vapor
upper vapor
terse bone
upper vapor
#

Um

#

Maybe

#

Idk lemme check

hearty shard
upper vapor
hearty shard
#

im 99% sure it doesnt

upper vapor
#

It didn't

#

Doesn't

hearty shard
#

yep

#

so

#

thats what i want

upper vapor
#

David go implement

hearty shard
#

also when you leave pd to know the 106 that sent them in

#

cuz like

#

solves all my problems

grand flower
grand flower
#

Scp173AddedObserverEventArgs: is Player 173 or is it Target?

#

(kinda wish this was a little more documented)

unique crane
#

That is not enough?

#

Oh wait we dont ship the xml docs yet

#

@grand flower

grand flower
#

Ahhhh yeah that'll do it haha

#

ty

grand flower
#

Is there any player event for when they shoot an obstacle? Other than OnPlayerPlacedBulletHole. That event does have the position but not the damage info of the shot.

icy knoll
grand flower
#

I know, but I still want to get the potential damage that would've been inflicted with the weapon

#

I suppose I could get the player's current weapon and use OnPlayerPlacedBulletHole though

icy knoll
#

that may give dmg

grand flower
#

it does but no position

icy knoll
#

shooting doesnt give damage

grand flower
#

oh

icy knoll
grand flower
#

of the hit

#

hmmm

icy knoll
#

make sure you check if Hurt is from a gun

grand flower
#

Firearm._modules would have the hitreg module right

icy knoll
#

idk

grand flower
#

guess we'll see

#

in theory it should work but that'll be fun to find out

teal junco
#

What happens if you parent a player to another NI

#

?

grand flower
#

Probably bad things

#

They'll likely rubberband like crazy

teal junco
#

youre probably not a network identity on your own machine so yeah

crimson nova
#

Why I cannot reload while having different size?

grand flower
#

Is 096's head detection clientside or serverside

teal junco
#

server side im 99% sure

#

i have a salt clip of myself looking down, and 096s face goes where i was looking 0.1 seconds ago and he aggros on me

#

maybe its also both,

grand flower
#

yeah that explains it, a little disappointing if so

teal junco
#

so the client catches whatever the server doesnt

grand flower
#

the false positives are annoying

teal junco
#

Oh yeah

#

but i guess its like

#

an anti cheat measure

#

SL already bans for any form of game modification so i dont see that its necessary

#

and they already made tesla gates client side to avoid this exact problem

#

and tesla gates are way more common than 096

grand flower
#

you don't have to make it fully clientside, just with a margin of error

#

cause rn any amount of server lag or ping from 096 or you and you'll end up "looking at it" without seeing it on your screen

#

if they gave you a grace margin where until the server disagrees on the fact you haven't seen 096 X times in a short period it forces it

#

would be a lot more enjoyable for players

teal junco
#

so for like

#

0.5 seconds

#

if the client insists it doesnr see 096 face, server lets it slide

grand flower
#

that or it could just accumulate error until it goes over a threshold

#

slowly reduce the accumulated error over time so for normal players it works fine

#

cheaters who don't tell the server they've seen 096 would have it be forced fast enough

teal junco
#

and every tick they agree it deducts a point?

grand flower
#

each tick the server thinks the player saw 096's face without receiving the client's acknowledgement

#

I would make it deduct points slower than gaining them

#

bit of trial and error and they'd probably end up with thresholds that most players like

#

I get why it's not clientside/fully clientside but ouch

teal junco
#

and the client can say it saw 096 face without the server agreeing?

#

well actually that might open up problems too

grand flower
#

of players cheating to trigger 096

teal junco
#

096 remote enragement hacks

grand flower
#

yeah

#

can have the threshold go both ways, with some sanity checks

#

LOS, etc

#

that "hack" would be simpler to prevent

teal junco
#

when youre playing 096 and a CI who just spawned triggers you

grand flower
#

and again they have an AC so w/e on that part

teal junco
grand flower
#

line of sight

teal junco
#

oh

grand flower
#

if the client tells the server they've seen 096 they can just do sanity checks to make sure it was possible

#

that's not as much of a problem as the server doing false positives, player enjoyment wise

teal junco
#

so if theres like no good ray between 096 and player then it wont work

teal junco
#

negativez*

grand flower
#

and like, a player shooting 096 triggers it anyway so not like 096 would feel much of an issue that way

#

I don't think 096 would see the difference if something like this was implemented

#

Mostly players getting less false positives

teal junco
#

the interaction is a lot more intimate on the victims side than 096s side

grand flower
#

yeah, cause generally you assume they're looking down or away or something

#

yup

teal junco
#

it should favor the human

#

a little

grand flower
#

the threshold stuff would very likely help with that

teal junco
#

obviously in a perfect world we have instant transmission and theres 0ms ping

grand flower
#

dunno if I can suggest that somewhere DogKek

#

yeah but multiplayer's never perfect

#

unless you're doing a LAN party and even then

teal junco
#

just build a backlog of these suggestions somewhere and pay 5 bucks for a month of tier 2

#

and then send a bunch peridoically to get feedback and get staff to read it

#

this implementatjon is probably a bit hard but its worth a shot asking nw to add it

mild ice
#

!forums

regal lakeBOT
grand flower
#

Ehhh I don't wanna make a public post, if the devs see the idea here they're free to use it

teal junco
#

networking seems really hard to me

#

i dont understand how people can understand that shit

grand flower
#

made it my field for games, love it

#

it is complex but ever so satisfying when things end up working

teal junco
#

if i wanted to ever work with netcode whats a good place to start learning it

grand flower
grand flower
#

Can you block a player from aiming a weapon?

#

there's no OnPlayerAimingWeapon that I can see

#

right, clientside

#

i feel like that was possible in the past but eh

upper pike
#

Maybe try looking into the firearm modules

#

I think they cover aimining

grand flower
#

Mostly wondering why that's a nono when stuff like OnPlayerReloadingWeapon exists. Unless that's not predicted?

grand flower
upper pike
#

Damn

#

Might not be possible then. Maybe try checking the docs

upper vapor
#

you can't cancel ads, that's client-side behavior
imagine having to wait 240ms for the server to approve your toggle request

grand flower
#

Doesn't mean you can't predict it and get told off by the server

upper vapor
#

that would also be weird for players

#

i guess they could add a sync var or some other way to stop a specific firearm from adsing

grand flower
#

I found some sync data so I'm just tapping into that

#

will find out if it works later

#

But "it looks weird" is a little silly imo

#

It'll look weirder for players with high latency which, i'll be honest, I'm not trying to make it look good for them. You play on a server with high latency, expect some breakage

#

For low latency, maybe a little but in my scenario they'll understand why they can't aim anyway

#

If the previous API had it, they already had that weirdness anyway

restive turret
grand flower
#

oh

#

okay that explains things

#

I forget it's not complete

#

scratch everything i've said then, i'll just put a todo

upper vapor
#

what if you send the ads rpc to the owner of the firearm toomuchtrolling

#

probably won't work but maybe it's worth a try

grand flower
#

I don't think I have access to it

#

Seems like they use SyncData for ADS not an RPC, so that's what I tinkered with in the meantime

#

OnPlayerAimingWeapon probably ends up doing the same thing anyway

#

LinearAdsModule.AdsData.AdsTarget

upper vapor
restive turret
#

Event

upper vapor
#

use Aimed

grand flower
#

I know

#

It's what I did in the meantime

upper vapor
#

right

restive turret
#

Left

upper pike
#

Would being able to directly change weapon stats like damage and fire rate be implemented in the future?

restive turret
#

FR is not synced.
About dmg? Idk

#

Would be cool ye

grand flower
#

Damage you can already do serverside with OnPlayerHurting

restive turret
#

I think you can also current the ammo type but not entirely sure if works

upper pike
upper vapor
#

you can change penetration
it's in the base stats i believe

restive turret
#

Burn dmg is inside the module

#

It's a field so you can edit it with publicized one

upper pike
upper vapor
#

nothing's protected if you publicize shrug

upper pike
#

... ngl i forgot publicising was a thing

upper pike
#

Won't let me publicise Assembly-CSharp

#

Its the one file that doesn't want to work

upper vapor
#

use BepinEx.AssemblyPublicizer from NuGet

upper pike
#

Wait got it working somehow

#

Hell did i do?

crimson nova
#

Is there a way to fix weapon reload as differently scaled player?

upper vapor
brazen dune
marsh minnow
#

How can I install LabAPI dependecy?

worthy rune
#

In you server files under \SCPSL_Data\Managed you should see the LabAPI dll

#

you should also reference Assembly-CSharp.dll while your there

marsh minnow
#

Yeah I know but how to setup Visual Studio

worthy rune
#

under the solution explorer tab right click dependencies and click add project reference

marsh minnow
#

There are no dependecies

#

Only refernces and Properties

worthy rune
#

hmm, can you show a screen shot

marsh minnow
#

Just a photo screenshots don't work for some reason

worthy rune
#

right click this

#

when you reference a dll you are creating a dependency if that what you were wondering

marsh minnow
#

It shows
Add refernce
Add Service Refernce
Add Analyzer
Manage NuGet Package
Collapse All Dependencies
Scope to This
New Solution Explorer view

worthy rune
#

yeah

#

although you should really add assembly C# too

#

Assembly-CSharp.dll

marsh minnow
#

Where can I find that?

worthy rune
#

same folder as LabAPI.dll

marsh minnow
#

It says that plugin could not be found

#

i added Assembly Csharp.dll but it is still there

restive turret
#

because it is LabApi.Loader.Features.Plugins

marsh minnow
#

For some reason i cannot define RequiredApiVersion

icy knoll
marsh minnow
#

Feature target type object creation IS not avalaible in C# 7.3. Please use language version 9.0 or greater

upper vapor
# marsh minnow

for this you need to modify your .csproj file to include <LangVersion>12</LangVersion> in a property group
you can use any C# version basically, as long as you have the SDK installed

marsh minnow
#

Where Can i find csproj file?

icy knoll
restive turret
#

Cant find the meme for the screenshot button

upper pike
#

Looking for it as well

restive turret
worthy rune
#

my new keyboard doesnt have a print screen button

upper vapor
#

at least you have win+shift+s

worthy rune
#

i have to do fn + f7 to activate it

hearty shard
#

ive never used print screen button

upper vapor
hearty shard
#

im gonna be honest

#

😭

upper vapor
#

must be an easy life

hearty shard
#

you just said

#

the other way to screenshot

worthy rune
upper vapor
worthy rune
#

hate it for how slow it is, even if you get to choose the area you want

upper vapor
#

windows moment

upper vapor
#

use Player.ReadyList instead of Player.List

hearty shard
#

yes

worthy rune
#

i thought that was scaling related, weird

hearty shard
#

so when you send a spawn msg to dedicated server

#

it fucks it all server sided

upper vapor
#

regardless of use case if you respawn the player object then 💥

#

what eve said

hearty shard
#

its how i fixed my skeleton being invisible

restive turret
#

Skill issue

worthy rune
#

yeah trouble told me about it

restive turret
#

(did the same)

worthy rune
hearty shard
#

wahhhh

worthy rune
#

yeah i kind forgor

upper vapor
#

that's not in the current build

#

we have unauthenticated list

worthy rune
#

should hopefully make it into the next build

#

also hopefully IEnumerable<Player> GetAll(bool includePlayers = true, bool? isPlayerReady = true, bool includeNpcs = true, bool? isNpcDummy = true, bool includeHost = false) will be there too

upper vapor
#

me when discord shows the sob emoji when i search for steamhappy

marsh minnow
worthy rune
#

should be the folder of your project

#

or the solution if you specified it too in the setup

restive turret
worthy rune
#

by default it returns Player.ReadyList

restive turret
#

I meant as bool?

hearty shard
#

yeah whys it nullable

worthy rune
#
/// <summary>
/// Gets a filtered set of players from the <see cref="List"/>.
/// </summary>
/// <param name="includePlayers">Whether to include real players, see <see cref="IsPlayer"/>.</param>
/// <param name="isPlayerReady">
/// Whether to filter real players by their authentication status, see <see cref="IsReady"/>.
/// Use <see langword="null"/> to get both unauthenticated and authenticated players.
/// </param>
/// <param name="includeNpcs">Whether to include non playable characters (NPCs), see <see cref="IsNpc"/>.</param>
/// <param name="isNpcDummy">
/// Whether to filter non playable characters (NPCs) by whether they are a <see cref="IsDummy"/> or not.
/// Use <see langword="null"/> to get both dummy NPCs and non dummy NPCs.
/// </param>
/// <param name="includeHost">Whether to include the host player or not, see <see cref="IsHost"/>.</param>
/// <returns>The set of all players that meet the criteria.</returns>
/// <remarks>
/// By default it returns the same set of players as <see cref="ReadyList"/>.
/// <para>
/// Filtering is done on 3 groups of players separately.
/// If a player meets the criteria for 1 of the 3 groups it is included in the list.
/// The 3 groups are <paramref name="includePlayers"/>, <paramref name="includeNpcs"/>, and <paramref name="includeHost"/>.
/// Further filtering per group is specified by <paramref name="isPlayerReady"/> and <paramref name="isNpcDummy"/> respectively.
/// If <see langword="null"/> the filter is not applied, thus includes all players for that group.
/// </para>
/// </remarks>
public static IEnumerable<Player> GetAll(bool includePlayers = true, bool? isPlayerReady = true, bool includeNpcs = true, bool? isNpcDummy = true, bool includeHost = false)
#
{
    foreach(var player in List)
    {
        if ((includePlayers && player.IsPlayer && (!isPlayerReady.HasValue || isPlayerReady == player.IsReady)) ||
            (includeNpcs && player.IsNpc && (!isNpcDummy.HasValue || isNpcDummy == player.IsDummy)) ||
            (includeHost && player.IsHost))
            yield return player;
    }
}
upper vapor
#

null would be no filter

hearty shard
#

holy yap

upper vapor
#

or skip check

restive turret
#

Ah now i get it why

hearty shard
#

var 💔

worthy rune
#

oh lmao, i actually better change that they dont like it when im using var

restive turret
#

There is no var here

#

Nvm

hearty shard
#

ur blind

restive turret
#

Ye i don't have glasses on

restive turret
#

The compiler already knows what type will be there

worthy rune
#

i dont think its being used

upper vapor
#

bruh

#

vs should be yelling at you!!1!1!1!1!!!

unique crane
#

Only valid reason to use var is when you are working with linq's IOrderedEnumerable with 5 billiion generic params, groupings and whatever you make up

#

in my opinion

marsh minnow
#

So it now works

worthy rune
#

something wrong, its not merged yet so i can still make changes

true cedar
#

yea

#

the existence of that method

#

rather than have a "do everything" player list method just have people use linq

terse bone
#

Well, in my opinion Player.List is a beginner trap rn, cause' it does not contain players only
Better approach would be to return only real players, no dummies, no host and have separate properties for that
Then Player.List would be truly a List of Players

#

Like all the way from MP2 i had to have this defined (Of course it was constantly changing, it went through Exiled, NW API and now it's on LabAPI)

terse bone
#

well, this one has dummies in it

worthy rune
#

true, im going to add a Player.AuthenticatedList which is prety much just ready players

#

prefect for sending network messages too

terse bone
worthy rune
#

yeah thats good you did that

worthy rune
#

I agree about the using linq methods over the "do everything" one and i expect experienced devs to do their own filtering when needed. The GetAll method is mostly targeted towards new devs as a nice catch all case that doesnt hide the nuances of getting all the players. This is why i decided to keep Player.List containing all the players including the host otherwise it would have to be made for a specific use case e.g. only real players or real players and dummies. The downside being that new devs are unlikely to understand that there are certain groups of players that must be treated differently. The consequences of which are pretty bad, usualy soft locking players and crashing servers. So Player.List remains as the option for experienced devs to do their own filtering and Player.GetAll() is a good option for beginners.

#

imo one of the main issues atm is that no one has docs so none of this is apparent, hopefully the situation improves once a nuget package has been made

lucid oxide
worthy rune
#

what im trying to say is that i didnt want to hide very important details in the API by providing some "catch all" use case which is technically impossible todo. What mattered was new devs understanding that they shouldnt just be using a single set of players blindly.

worthy rune
# lucid oxide What's possible usecase of processing host equally with real players?

we could remove host, and players would be able to use Player.List without issues about 90% of the time, the issue now is that the list contains unauthenticates players and NPCs, which usually causes players to become softlocked if interacted with incorrectly. i want to avoid this essentially as i remember it being one of the main issues plugin devs ran into, and an especially hard one for a new dev to figure out

lucid oxide
worthy rune
#

thats true

lucid oxide
terse bone
#

Will there be an event that allows modification of round end conditions?

worthy rune
#

i think theres an event like that already

unique crane
#

Set the IsAllowed

terse bone
#

Isn't it only fired when round's about to end?

unique crane
#

Yes?

worthy rune
#

yeah it might be by the looks

unique crane
#

When else would you expect it to run?

#

If you set it to false, it wont end

#

And try again in 2,5 seconds

#

OH

#

I get it..

terse bone
#

Writing while in a bus is kinda hard

unique crane
#

Let me see its implementation

worthy rune
terse bone
#

I just want to have some players excluded from round end conditions

#

Because i need to use an scp role for players as it allows them to see in the dark

#

But they interfere with those conditions and you can't easly (without making custom coroutine) modify them

unique crane
#

Alright its executed when the round is about to end yea..

#

Well

worthy rune
unique crane
unique crane
#

Like NV status effect

terse bone
teal junco
#

cant you patch the scp target getter at least

terse bone
teal junco
#

a fix i had for NV was spawning a light only one player could see and parenting it to the player

terse bone
#

But i can't look at code rn

terse bone
teal junco
#

one seocnd

#

well actually mine is an exiled and barely works so

worthy rune
teal junco
#

wait how do i hide embed

upper vapor
#

surround it with <> or click the small x

teal junco
#

thank you

#

i dont like posting links and then it makes a huge image in the convo

#

it feels like an interuption

icy knoll
#

top right

teal junco
#

i dont have such an X on mobile so the <> works fine

#

If you had to implement client side parent rpc in such a way that armature bones were supported how would you do it. Short of making the bones NIs.

marsh minnow
#

Hello so I have two questions. First how can I make script execute at start of round and how to get player location.

static osprey
worthy rune
static osprey
#

embed success

marsh minnow
#

yeah but how can I know which using LabAPI.something to use?

lucid oxide
unique crane
unique crane
marsh minnow
#

It doesn't work for some reason

#

Also how can I use Unity?

worthy rune
#

wdym

teal junco
#

and u cant use the editor you have to interact with the scene thru code

terse bone
teal junco
#

uh

#

weird

teal junco
#

i want you to look at my code. Its under Omni-CustomItems/Equipment/Goggles/NightVision or something. it shows how you can just do light.trans.parent = player.transform

#

wait did i maybe modify the light source

#

fuck one second

#

Yeah it miggt have to do with smoothing or some shit

terse bone
#

Oh, i parented to a player using that new method

teal junco
#

what new method

worthy rune
#

oh the RPC?

terse bone
#

Yep

teal junco
#

the rpc triggers no matter how you parent right

#

this plugin is for 14.0 and it still triggers the rpc

worthy rune
#

yeah that doesnt work as you would expect, what you want todo is parent it directly instead

teal junco
#

yeah

#

if you wanna hide shit from everyone else

true cedar
#

as you said

#

new devs probably won't know what all of this means

#

so it's just gonna be extremely confusing

#

secondly, new devs aren't gonna understand how to properly use the method. you're not supposed to do Player.GetAll(true, null, false, true) etc, you're supposed to do Player.GetAll(isReadyPlayer: false)

worthy rune
true cedar
#

that's something i think will trip a lot of new devs up

worthy rune
#

maybe, im not sure how to solve that

true cedar
#

don't have the method be like that?

#

when you have 5 optional parameters, three of which are bool?, i think it's clear that something is wrong

#

if you really want a "GetAll", make it take a SearchSetting struct or something

#

and extract the parameters out to the struct

#

it'll take up more lines, but then you don't need to worry about beginners using it wrog

teal junco
#

does labApi have javadocs

#

or whatever thats claled

true cedar
#

no need for Player.AuthenticatedList, just Player.GetAll(SearchSetting.Authenticated)

worthy rune
#
public struct SearhFilter
{
    public static SearhFilter Ready => new();

    public static SearhFilter Authenticated => new() { IncludeNpcs = false };

    public bool IncludePlayers = true;

    public bool? IsPlayerReady = true;

    public bool IncludeNpcs = true;

    public bool? IsNpcDummy = true;

    public bool IncludeHost = false;

    public SearhFilter() { }
}

something like this?

worthy rune
#

clos enough

icy knoll
#

if you dont put the c in i will cry 😭

terse bone
#

Maybe search flags?

terse bone
#

Or, if you combine some search (flags )options and put them in a static class called SearchOptions then maybe it would make sense

hearty shard
#

have it be more clear

upper vapor
terse bone
terse bone
#

You can also make "presets" from these flags if you want

#

As i said

upper vapor
#

those could also be included in the enums

#

like AuthenticatedAndDummies = AuthenticatedPlayers | Dummies

terse bone
#

Ohh i forgot you could do that

#

Yeah that would be nice

worthy rune
#

yeah i believe thats the way to go, would be much easier to explain

hearty shard
#

yes

worthy rune
#

not actual docs, just showing how everything is divided up. still would like a better name for RegularNpcs currently no name is given anywhere else for non dummy NPCs

[Flags]
public enum PlayerSearhFlags
{
    None = 0,
    AuthenticatedPlayers = 1, // IsPlayer && IsReady
    UnthenticatedPlayers = 2, // IsPlayer && !IsReady
    DummyNpcs = 4, // IsNpc && IsDummy
    RegularNpcs = 8, // IsNpc && !IsDummy
    Host = 16, // IsHost
}
upper vapor
#

what would a non-dummy npc be

hearty shard
worthy rune
#

all dummies are NPCs, think of any NPC before dummies were added

hearty shard
#

i still gotta fix this having the name as null and showing in tab

worthy rune
#

dummies are primarily used testing so they are coded to act more like players which can be problematic let say if you want to hide them on the player list or RA

#

also dummies are expected to be visible to plugins like players would, while non dummy NPCs are not

marsh minnow
#

Hello so I want to try example plugin HelloWorld but it doesn't load

#

I have it in LabAPI/plugins do i have to put it into global or 7777 folder?

worthy rune
marsh minnow
#

I tried but it doesn't work

upper vapor
#

the wiki may be outdated

marsh minnow
#

So I should but it into global folder?

hearty shard
#

[port (eg 7777)] will only load for that port

worthy rune
marsh minnow
#

In february last update of readme I saw

marsh minnow
plush walrus
#

Gotta ask, (this is a repost from Exiled)

Why is the default gravity for a player 0, -19.60, 0? (The 0, -12.60, 0 is just me testing around with gravity)

Wouldn't it make more sense if it was 0, 1, 0 or 1, 1, 1?

ashen hornet
teal junco
#

thats what i assume

teal junco
plush walrus
#

although if its passed through an exponent shouldn't it be positive and not negative?

teal junco
#

wait

ashen hornet
teal junco
#

What is the exponent for though

teal junco
#

I think.

plush walrus
teal junco
#

imo

#

its like the vector3 added to your position when gravity is applied

upper vapor
#

since Y is up in the coordinate system, applying a negative force would make the object go down
sure, the naming isn't the best but it does mean upwards force

teal junco
#

The gravity value is the vectoe applied

#

I think its intuitive naming

plush walrus
#

Eh, either way, not a big deal

#

Just a generalist question I had

teal junco
#

When will SCP SL fix the jump

upper vapor
#

because "earth" gravity wouldn't be sufficient

#

for the game at least

plush walrus
#

Double it trolling

teal junco
#

hubert had to artificially make them fatter

unique crane
#

Unity's units are interesting

plush walrus
#

Although this did come up with an idea for like an event. Reversed Gravity

#

I dont want to think about it too hard now or the implications of it on Surface

unique crane
plush walrus
#

Otherwise I will try to make it a real thing lmao

unique crane
#

Just like in australia

teal junco
unique crane
#

so you dont fall into outter space

plush walrus
teal junco
#

Im not sure whether SL uses meters or what.

unique crane
#

Uhhh

#

Surely not meters

#

Just unity's units

plush walrus
#

Meters I thought

#

It used to be not the case way back in the day but iirc now days 1 unity unit in game = 1 meter

teal junco
#

I think so?

unique crane
teal junco
#

then they slightly adjusted all scales

unique crane
#

It could be scaled on LabAPI side yea but too late for that

plush walrus
restive turret
restive turret
restive turret
#

Also if you like you can choose earths gravity i guess

unique crane
#

If you want

#

latest version

#

Put it alongside your labapi dll where you reference it

grand flower
#

Does the OnPlayerInteractedDoor event fire even if the player wasn't allowed to open/close it?

restive turret
#

I love this

#

OnUsed run after it runs OnRemoved

#

😭

teal junco
#

its usually a postfix or something right

grand flower
terse bone
#

Is ChaosKeycardItem not registered as KeycardItem in LabAPI?
A few days ago i had this code and after that check it swaps original keycard to a custom one, but it didn't swap for chaos keycard only

#

that's what i got from wrappers list ig

grand flower
#

but I think I see how I can handle stuff so no biggie

grand flower
#

yeah no but there's an issue

#

I switched ev.IsAllowed to ev.CanOpen

#

if CanOpen is false it still doesn't fire OnPlayerInteractedDoor

unique crane
#

Yep

grand flower
#

and honestly it probably should?

grand flower
#

I get stopping it for IsAllowed but the player still interacted with the door even if they couldn't open it

#

if that remains it kinda makes InteractedDoor useless for cases where I want a handler to potentially block the interaction in a certain scenario and another to blow it up if nothing blocked the interaction

#

I'd have to put both of these in InteractingDoor and pray one runs before the other so I can check ev.IsAllowed

celest thorn
#

Im having an issue really stupid with doors, im making my own editor and the doors for some reason aren't loading in the correct position

The door will always spawn in heavy all of the types in the position where they should be but on heavy and Relative positioning will be messed up so badly, i spawn them in surface for example and they will be in the void working fine but messing up everything else like movement etc...

grand flower
marsh minnow
#

Hello so how can I print player position at start of round? I tried defining as a Vector3 position = Player.Position but it says that An object reference is required for non-static field,method, or property 'HelloWorldPlugin.Player'

grand flower
#

@unique crane should I open an issue for the above or is that... normal? nvm was an issue with my IDE or binaries idk

terse bone
#

ahh discord

#

can't have AV1 on discord too

#

i guess it still kinda flickers, but it's better than before

#

practically unnoticeable because of compression

unique crane
#

It may be the compression yea

#

but I dont see any issue with that

#

Like if you parent it to the player

#

you cant get it smoother

terse bone
#

this is what i did

#

but if i disable movement smoothing then it flickers horribly

grand flower
#

the worst thing is, looking at LabAPI's code I feel like that's the case

#

so idk why it's not running the event

upper vapor
grand flower
#

only IsAllowed prevents it

celest thorn
celest thorn
celest thorn
#

but for example lockers

#

don't spawn in the correct

grand flower
upper vapor
celest thorn
celest thorn
#

honestly i didn't

upper vapor
#

Weird stuff