#LC_API

1 messages · Page 2 of 1

jagged trout
#

I'll actually just rename it to ReceivedNetworkMessage and have NetworkMessage be the attribute

#

unless you have any other ideas

main minnow
#

it's a tricky one

#

I think those are good names

jagged trout
#

I could make the signature always just ulong, T maybe?

#

Lemme see

main minnow
jagged trout
main minnow
#

True. that's definitely better

jagged trout
#

but docs

#

we will rely on docs

main minnow
jagged trout
#

readthedocs

#

Ok it does still work as ulong, T

#

future me's problem when people ask questions

main minnow
#

You could put the doc comment on the abstract method if you implement it as class annotation rather than method annotation

#

people can still whack a class definition anywhere

#
[NetworkMessage("MyActionName")]
public class MyAction : BaseAction<Vector3>
{
    public override Handle(ulong senderId, Vector3 payload) {
    { 
        ...
    }
}
jagged trout
main minnow
#

if you ever want people to be able to customise their handlers more than just the callback

#

you can add extra stuff to the class

#

if you're just decorating a method, that's making a huge assumption that users will never want more control than the callback

jagged trout
#

Well there's nothing else to control really

main minnow
#

that's what we think for now

jagged trout
#

I wanted them to be able to access private properties in a class

main minnow
#

😂

#

you ... still can

#

can't you?

#

ah yeah, private instance props

#

I see what you're getting at

#

but shouldn't a network message handler always have static context

jagged trout
#

I meant private statics lol

#

but yeah static always

main minnow
#

oh yeah then no issue

#

classes can access private static members from enclosing classes

jagged trout
#

I personally just didn't want to make a class for every network message Iw anted

#

I think it's just a lot of unnecessary classes tbh

main minnow
#

but they're not gonna be in the root namespace so why does it matter

#

i could say the way you're proposing is a lot of unnecessary functions

#

Best of both worlds

#

just do both

jagged trout
#

I also see no future case for having it in a class

#

as you do everything in the handler itself

main minnow
#

what about metadata like who is allowed to send the message

jagged trout
#

that would be defined in the attribute itself

#

like it is with rpcs

main minnow
#

I'm not entirely convinced, but that's just how I am

#

Go for the method attribute syntax

jagged trout
#

I've actually tried both and it seems incredibly difficult because of the generic

#

Since I need to register it with the generic and an Action<ulong, T>

#

idek how to actually get a generic attribute off of a type

#

since you can't GetAttribute(Attribute<T>)

#

Action action = method.CreateDelegate(typeof(Action).MakeGenericType(typeof(ulong), method.GetGenericArguments()[0])) as Action; no idea if this will work, but even if it does, this is cursed.

main minnow
#
interface IAction<out T> where T : class
{
    public void Register(string uniqueName);
}

abstract class BaseAction<T> : IAction<T> where T : class
{
    public abstract void Handle(ulong senderId, T payload);
    
    public void Register(string uniqueName)
    {
        Networking.RegisterMessage<T>(uniqueName, Handle);
    }
}
#

Does that do the trick?

#

Then wherever you're collecting the attribute you can

#
IAction<object> whatever = ...;
whatever.Register();
#

even tho the calling scope only knows it's containing an object type, the instance will know its actual T so will call the right thing

#

@jagged trout Thoughts?

jagged trout
#
[NetworkMessage(typeof(TestClass), "TEST_THING")]
internal static void Test(ulong senderId, TestClass thing)
{
    Log.LogInfo("GOT TEST MESSAGE");
    Log.LogInfo(thing.value);
}

[NetworkMessage(typeof(TestClass), "TEST_THING2")]
internal class BigTest : NetworkMessageHandler<TestClass>
{
    public override void Handler(ulong sender, TestClass message)
    {
        Log.LogInfo("GOT TEST MESSAGE");
        Log.LogInfo(message.value);
    }
}

I got both of these working

#

I had to define the message type in the attribute

#

I will probably make it the 2nd argument if I don't find a way around it

#

getting those generics was very odd

#

Apparently c# attributes don't support generics as expected I don't think

#

I did try a register method on the attribute class, but I couldn't get it working

#

I'll see if I can pull the type from the params though

#

but tomorrow

#

it's 2:30 am and I'm tired

#

gn

main minnow
main minnow
grave saffron
#

What is this?

jagged trout
#

Seems like somehow your broadcast happened before HudManager.Instance was set @grave saffron

#

as that's the only thing that could be null

#

I've never seen that happen before though

jagged trout
# jagged trout ```cs [NetworkMessage(typeof(TestClass), "TEST_THING")] internal static void Tes...

Continuing this, I got it to work with just this, too:

[NetworkMessage("TEST_THING")]
internal static void Test(ulong senderId, TestClass thing)
{
    Log.LogInfo("GOT TEST MESSAGE");
    Log.LogInfo(thing.value);
}

[NetworkMessage("TEST_THING2")]
internal class BigTest : NetworkMessageHandler<TestClass>
{
    public override void Handler(ulong sender, TestClass message)
    {
        Log.LogInfo("GOT TEST MESSAGE 2");
        Log.LogInfo(message.value);
    }
}
#

by extracting the types from the method and from the generic base class

jagged trout
#

well now that it works, I'll focus on making it backward compatible...

jagged trout
#

actually

#

after thinking about it more, this is basically impossible to make backwards compatible

#

with the new system messages have to actually be registered on the network handler

#

ngo will just ignore ones that aren't, and since the old ones just use Broadcast and add to a delegate invoke list, there's no real efficient way to dynamically register them

#

I can invoke the old delegates for properly registered messages, but I can't really register any of the ones that aren't registered

main minnow
jagged trout
#

this is basically just to mimic RPC's with no params

#

And I wanted a way to send a message to clients to tell them to send their mod list, but that message doesn't require any body since we know what handler we're in

main minnow
#

what'd you need the client modlists for?

#
  • why not have clients send them when they join, then cache the results?
jagged trout
main minnow
#

like, that might be something worth re-jigging in the future

jagged trout
#

Apparently people are having issues on 3.1.0 that I just can't seem to reproduce

#

I think most of the issues are caused by outdated mods and people not knowing what the point of a major version is

#

Though someone said LC API is causing godmode? Which I quickly tested and was not able to reproduce

#

I also find it somewhat funny when people report bugs for manually downloading when 99% of the time that means they pirated the game lol

jagged trout
#

@main minnow are you able to help me test like a 2 minute bug that someone is apparently having?

#

only asking since I saw you online

main minnow
#

i'm watching dr who but what's up

#

?

jagged trout
#

apparently someone can't pull the lever, and I tested with one person and then they said it only works with someone else in the lobby

#

¯_(ツ)_/¯

#

If you are able, 018ca6d1-941f-4d75-40fd-9f3323f0b479 this just has bepinex and lc api

main minnow
#

when the only one that can pull the lever is the host

jagged trout
#

they said it was mid game

main minnow
#

are they using late company

jagged trout
#

me and my friends have been having this problem where when we leave a planet, the game gets stuck and doesn't let us go to another planet (the lever that you pull to land just gets stuck on "Waiting for ship to land." and the game also doesn't auto save because of this) and i believe it to be an issue with the game thinking that it's still on a planet even after leaving (for god knows why).

i made sure that this is an issue with LC API because after disabling LC API, the issue didn't happen anymore (no other mods i have use LC API so it was safe to disable it)

This was the whole post

#

they said disabling lc api made it work

#

idk why they have it if they don't need it

main minnow
#

lmao

#

okay

jagged trout
#

but I'd like to test it with more players regardless

#

just to make sure I didn't miss anything

main minnow
#

yeah sure - lemme finish this dr who episode if that's ok? 30mins tops

jagged trout
#

sure

#

Which episode 👀

main minnow
#

this year's Christmas one!

#

my family got home too late to watch it yesterday

main minnow
#

aye okay

jagged trout
main minnow
#

aye i've used it

jagged trout
#

I'll also need your steam friend code

main minnow
#

sure

jagged trout
#

actually your account is linked

main minnow
#

ah good 😂 i was struggling to find the code

#

167473533

jagged trout
#

I sent you a fr

main minnow
#

aye got it

jagged trout
#

alright, we're literally just gonna go to 2 moons lol

main minnow
#

cheeky game crashed

jagged trout
#

Did you need a new invite?

jagged trout
#

@main minnow does the dll not go to Release\net46 anymore on your PR?

#

Hm

#

also

#

Building with minver sets the version as 1.0.0 for the bepinex plugin, even though it builds the dll as 3.2.1

#

that'll have to be fixed before I can merge this

#

I'm not sure minver and the bepinex plugin info are compatible

#

and also netcode weave doesn't seem to work

#

even though it says it did

#

On your PR vs on main

#

I think the issue may be in part that it isn't going to Release/net46

#

and is instead just in bin

#

since there's no _original file, either

#

for some reason it also freezes the version in decomp to 3.0.0.0

Here's mine, vs yours, not sure what's going on there

main minnow
#

I don't know why the convention is that way

main minnow
jagged trout
#

as long as the bepinex version is right

jagged trout
main minnow
#

Aye, I think that'll be because MinVer is setting the Version attr too late for Bepin

#

I'll just need to enforce the right order of the build tasks

main minnow
#

It's hacky but I think making an empty target with Aftertargets=minver and BeforeTargets=BepIn will do the trick 😂

jagged trout
#

I have not yet released 3.2.0 as I'm waiting for your PR, but this will apply then

#

Gonna work on the other pages in the meantime

main minnow
#

awesome!

jagged trout
#

I'm most likely gonna switch to a github pages and have the xml docs auto generate most of it

main minnow
#

@jagged trout I found out why MinVer does what it does:

Assembly version

The assembly version is what the CLR uses at run time to select which version of an assembly to load. Selecting an assembly using versioning only applies to assemblies with a strong name.

<AssemblyVersion>1.0.0.0</AssemblyVersion>

The .NET Framework CLR demands an exact match to load a strong-named assembly. For example, Library1, Version=1.0.0.0 was compiled with a reference to Newtonsoft.Json, Version=11.0.0.0. .NET Framework will only load that exact version 11.0.0.0. To load a different version at run time, a binding redirect must be added to the .NET application's config file.

#

so assuming we adhere to semver, the assembly version being set that way makes sense

main minnow
#

@jagged trout I've updated the PR, take a look when you can

jagged trout
#

Ok

#

I must be using the wrong file

#

where is the actual completed dll going?

#

because the one in bin/ is not netcode patched

#

the only _original file I have in in bin/Release/net46, but it's old

main minnow
#

have you pulled changes?

#

Because for me, the DLL is going to bin/ and there is also an original in that folder

jagged trout
main minnow
#

😂😂😂😂

jagged trout
#

seems to work

main minnow
#

I should double check it works within actions

jagged trout
#

Well I've already merged, so lemme know if it doesn't

#

I won't be making any github releases until 2018 can get the nuget setup as well

#

Where can I get a thunderstore api key?

#

as far as I can tell they just use basic auth

main minnow
jagged trout
#

yeah

main minnow
#

im not sure you'll have high enough privileges to add service accounts

jagged trout
#

I'm not

main minnow
#

when you create a service account, it gives you an API key scoped to the team the account is for

main minnow
#

@jagged trout I borked the build badge 😭

#

give me a sec

#

PR opened

#

ah yes you can experience the glory of PR checks!

#

it brings a tear to my eye

#

🥹

jagged trout
#

@main minnow I haven't actually tested that the networking works on other clients, so do you think you could join me with a custom build?

main minnow
jagged trout
#

actually

#

that won't work

main minnow
#

can I pull your branch and build it myself?

jagged trout
#

no, I have specific test changes that won't be pushed

main minnow
#

👍

jagged trout
#

that one should work

main minnow
#

is this malware steven

#

do I need to be running in a VM

jagged trout
#

If you want lol

#

but you can decomp it

main minnow
#

@jagged trout i've just noticed youre using net46 which doesnt support netstandard2.0

jagged trout
#

I didn't use net46

main minnow
#

in the restructure is it ok if I target netstandard2.0

main minnow
jagged trout
#

As long as it doesn't break anything

main minnow
#

I'll make sure everything still builds correctly 👍

#

Loading LC with your DLL

jagged trout
#

👍

#

ideally we should get the mod list popup then I'll get some console logs after 10 seconds

#

wait

#

I never called the test method lol

#

oh well, the mod list should work

#

also for some reason my vs didn't like that minver so it did this

#

¯_(ツ)_/¯

#

config mismatch

#

hm

main minnow
#

what the fuck? 😂

main minnow
jagged trout
#

I didn't commit it

main minnow
#

oh okay

#

bing chilling

jagged trout
#

it also doesn't let me build if I change it

main minnow
#

you what

jagged trout
#

but it's the same version

main minnow
#

unload project -> edit -> reload?

jagged trout
#

and it seems to work on my end still

#

I don't think this should really make a difference anyways

#

as far as I can tell it's still working

#

hm

main minnow
#

yeah but it's using the expanded view for no reason

#

i'll set the IncludeAssets attr on the restructure branch

jagged trout
#

Let's try this

#

idk why we got config mismatch

#

wait

#

this won't work

main minnow
#

I'll delete my config file so i get a clean one

jagged trout
#

hmmmmmmmmmmmmmmmmmmm

main minnow
#

kek

jagged trout
#

it's the like network prefabs and stuff

#

🤞

#

hmmmmmmmm

#

not good

main minnow
#

wassup

jagged trout
#

I'm assuming unity ngo requires all net messages registered with RegisterNamedMessageHandler to be synced, but with mod mismatches that will almost never be the case, and for mods without lc api, would never work. I'm not sure why we can't connect, however, since we have the same mods

#

I'm gonna remove all the network messages just to see if we can connect

#

This could be a major problem

#

I may have to switch to unnamed messages and just make my own message handler

#

But first lets see if removing the messages allows you to connect

#

The docs don't really mention that they need to be synced anyways

#

in fact it just says that they should be registered in OnNetworkSpawn

#

so it would be impossible for them to be synced on join

#

You do have the networking asset bundle though, right?

#

Your file structure should look like this and inside that Bundles folder should be networking

main minnow
#

I did not

#

I'm sorry about that, let me sort it

#

did you add the Bundles dir with assetbundles to Git?

#

you want me to download from TS?

jagged trout
#

so it'll upload with it

main minnow
#

okay

jagged trout
#

Also, I'm assuming that's the problem, so let's try this lmao

main minnow
#
[Info   :Lethal Company API] Broadcasting
[Error  : Unity Log] NotServerException: ConnectedClientIds should only be accessed on server.
Stack trace:
Unity.Netcode.NetworkManager.get_ConnectedClientsIds () (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
Unity.Netcode.CustomMessagingManager.SendNamedMessageToAll (System.String messageName, Unity.Netcode.FastBufferWriter messageStream, Unity.Netcode.NetworkDelivery networkDelivery) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
LC_API.Networking.NetworkMessageFinalizer.Send () (at <55ac7c31d7b34564b0b94f24f0a6a794>:0)
LC_API.Networking.Network.Broadcast (System.String uniqueName) (at <55ac7c31d7b34564b0b94f24f0a6a794>:0)
LC_API.Plugin+<TestSendMessage>d__14.MoveNext () (at <55ac7c31d7b34564b0b94f24f0a6a794>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <e27997765c1848b09d8073e5d642717a>:0)
jagged trout
#

hm

#

sender id is pretty much useless if I make this an rpc

#

not sure what to do

#

guess I'll also have to make it a relay...

#

Which means I'll need to wrap the type into a new class that has the actual sender and unpack it when received

main minnow
#

have fun!! 😂

#

AUGHHHHHH

#

EVAIIIISAAAAA

#

why couldnt she just make netcodeweaver a clever thing

#

i'm actually going to have to write a javascript action

#

to make the netcode weaver setup action

#

i swear to fucking god

#

see you in a few hours

jagged trout
#

@main minnow think you could test with me again?

#

I think I got this wrapped relay done

#

it works sending to self as host, but gotta test clients as well

#

I actually didn't need to add anything to the bundle either

#

thank god

jagged trout
#

lmk when you're able to test

main minnow
#

@jagged trout sorry about that, whenever

jagged trout
#

is now good?

jagged trout
#

Guess not lol

main minnow
#

I really should take my meds

#

@jagged trout yes, now is good

jagged trout
#

lol that file should still be good

#

alright so we're hoping for it to say broadcasting in your console then in mine I'll see a bunch of network messages

main minnow
#

aye aye

jagged trout
#

anything?

main minnow
#
[Info   :Lethal Company API] Broadcasting
[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
LC_API.Networking.NetworkMessageFinalizer.Send () (at <1be4b194ad4840899e4c16396a912452>:0)
LC_API.Networking.Network.Broadcast (System.String uniqueName) (at <1be4b194ad4840899e4c16396a912452>:0)
LC_API.Plugin+<TestSendMessage>d__14.MoveNext () (at <1be4b194ad4840899e4c16396a912452>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <e27997765c1848b09d8073e5d642717a>:0)
#
[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
LC_API.Networking.NetworkMessageFinalizer.Read (System.UInt64 fakeSender, Unity.Netcode.FastBufferReader reader) (at <1be4b194ad4840899e4c16396a912452>:0)
Unity.Netcode.CustomMessagingManager.InvokeNamedMessage (System.UInt64 hash, System.UInt64 sender, Unity.Netcode.FastBufferReader reader, System.Int32 serializedHeaderSize) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
Unity.Netcode.NamedMessage.Handle (Unity.Netcode.NetworkContext& context) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
Unity.Netcode.NetworkMessageManager.ReceiveMessage[T] (Unity.Netcode.FastBufferReader reader, Unity.Netcode.NetworkContext& context, Unity.Netcode.NetworkMessageManager manager) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
Unity.Netcode.NetworkMessageManager.HandleMessage (Unity.Netcode.NetworkMessageHeader& header, Unity.Netcode.FastBufferReader reader, System.UInt64 senderId, System.Single timestamp, System.Int32 serializedHeaderSize) (at <1b23ec5fcbfc4fbca0db70afcdb9b715>:0)
UnityEngine.Debug:LogException(Exception)
Unity.Netcode.NetworkMessageManager:HandleMessage(NetworkMessageHeader&, FastBufferReader, UInt64, Single, Int32)
Unity.Netcode.NetworkMessageManager:ProcessIncomingMessageQueue()
Unity.Netcode.NetworkManager:NetworkUpdate(NetworkUpdateStage)
Unity.Netcode.NetworkUpdateLoop:RunNetworkUpdateStage(NetworkUpdateStage)
Unity.Netcode.<>c:<CreateLoopSystem>b__0_0()
jagged trout
#

my pain is immeasurable

#

I wonder if Player.HostPlayer is null for you for some reason

#

Yeah it seems like for you HostPlayer and LocalPlayer are null

main minnow
#

that doesn't make any sense

#

maybe i just fucked up the assetbundle

jagged trout
#

nah wasn't you

#

syncing the custom players is finnickey

#

especially with timing and ping

#

it's a nightmare

jagged trout
#

if you're able to help test again lmk

main minnow
#

Yep

#

@jagged trout

#

omw

jagged trout
#

👍

#

@main minnow before you continue your restructure, I'd pull main

#

after your restructure, I'm going to freeze main for releases and we'll work from a dev branch

main minnow
#

Will do. Thankyou for letting me know

zealous beacon
# jagged trout

speaking of this feature can I have a config to turn it off :)

jagged trout
zealous beacon
#

wait is this not the same LC_API that spams hud elements for 5 minutes at the start of every game with cutoff lists of mods?

jagged trout
#

I completely rewrote networking

#

it uses ngo custom messages now

#

so it won't use chat anymore

#

so you can send whatever you want as long as it's serializable and all you gotta do is add that attribute, LC API will handle the rest

swift halo
#

Is it automatic? I assumed it was something you had to implement yourself

jagged trout
swift halo
#

Yeah the other messages just loaded for me. Wi-Fi cut out

jagged trout
#

then you just do

Network.Broadcast("Name", T obj)
swift halo
#

Nice that it doesn't just chat

jagged trout
#

Yeah that was an interesting implementation

swift halo
#

Ouf the string tho 😔

jagged trout
#

But it just uses named messages under the hood

swift halo
#

Oh so it doesn't send the string?

jagged trout
#

the name being what you see in the attribute

#

No

#

you can send anything you want that's serializable

swift halo
#

Cool then

jagged trout
#

the wiki shows an example

swift halo
#

What are you using to serialize the objects?

jagged trout
#
internal static byte[] ToBytes(this object @object)
{
    if (@object == null) return null;

    BinaryFormatter binaryFormatter = new BinaryFormatter();
    MemoryStream memoryStream = new MemoryStream();

    binaryFormatter.Serialize(memoryStream, @object);

    return memoryStream.ToArray();
}

internal static T ToObject<T>(this byte[] bytes) where T : class
{
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    MemoryStream memoryStream = new MemoryStream();

    memoryStream.Write(bytes, 0, bytes.Length);
    memoryStream.Seek(0, SeekOrigin.Begin);

    return binaryFormatter.Deserialize(memoryStream) as T;
}
#

it's just a byte array

swift halo
#

Doesn't binaryformatter have security issues? See: the Raft incident

jagged trout
#

raft incident?

jagged trout
#

hm

#

The data type is defined by the devs using it

#

lemme see tho

swift halo
#

Yes, but any dev could use the remote code exploit on anyone else using LC api

#

Having the mod installed would be a liability

jagged trout
#

Trying to think of a solution

swift halo
#

Don't use binary formatter

jagged trout
#

Well yeah

#

that's not a solution

swift halo
#

It is the only solution...

jagged trout
#

a solution to this problem is replacing it with something else

#

"remove it" is not helpful

swift halo
#

Yeah that's what I mean

#

Or ig implied

jagged trout
#

Yes, removing it will be a part of the solution, but it isn't the solution entirely

#

I can see if json serialization will work I guess

swift halo
#

That would bloat message sizes more than BF

jagged trout
#

Yeah, but alternative is RCE

#

and I'm not about to write a custom binary serializer because I would introduce more security problems than binary formatter

swift halo
#

That's what I did

#

Gaffer on games has a good implementation of a custom binary serializer

#

The issue is it's too low level for your target audience

jagged trout
#

Well I'm not presenting any serialization to the user, I would like them to just be able to send whatever type they want and the api will serialize it for them

#

For more advanced users maybe

#

but it's not useful for most users to have to write their own serialization

swift halo
#

Yep

main minnow
#

@jagged trout since LCAPI is lethal company specific, you could just use Newtonsoft JSON

swift halo
#

I mean then we're back to bloated strings over the network

main minnow
#

i think

#

I actually can't tell if that namespace is part of the newtonsoft package

#

which is apparently the solution that Raft employed

#

Would have to distribute the DLL tho

swift halo
#

From some cursory googling, BSON is not smaller in size

jagged trout
#

easy networking will come with tradeoffs, and we're talking in the megabyte range over the entire game session

#

people can always write their own to optimize for their objects if needed

swift halo
#

Sounds like json would fit your standards then

jagged trout
main minnow
#

how do RPCs serialize then?

#

FastBufferReader/FastBufferWriter? are those marked as internal?

swift halo
#

INetworkSerializable can be used

jagged trout
#

They use INetworkSerializable

#

but that would require people to know how to serialize their objects by hand

#

It's not too difficult though

main minnow
#

aye. Maybe we could use INetworkSerializable's serialization/deserialization when available and fallback to JSON?

#

That would keep overheads minimal for primitives like string, vectors, etc

jagged trout
#

Since they are defined by c# and unity themselves

#

ngo couldn't add that interface to them

main minnow
#

NC4GO implements serializers/deserializers for primitives, yes

jagged trout
#

Yeah what I'm saying is how I can automatically detect whether or not it can be serialized like that

#

I can't just use is INetworkSerializable for those types

#

I can use that for custom classes

swift halo
#

Type check ig

main minnow
#

let me open the nc4go dll

#

no, I have an idea

jagged trout
#

I mean at that point they can probably just make their own custom messages anyways lol

#

ideally it should remain a simple solution for users who just want quick networking

swift halo
#

Odin serializer didn't look half bad

#

Open source too

main minnow
#

although I don't think theres many mods wanting to do this kinda thing

swift halo
#

Sounds like a good idea

main minnow
swift halo
#

I'm not familiar

main minnow
#

You can use it commercially (earn money from derived works)

jagged trout
#

Basically all I would need to care for is distribution with license

#

which I should be able to do with apache

swift halo
main minnow
main minnow
#

I would probably go with that

#

or newtonsoft

jagged trout
#

I wonder if I need to wrap primitive types

main minnow
swift halo
#

Not with Odin I doubt

jagged trout
#

Since right now it's limited to reference types as well

#

but I'm not too bothered

#

Does odin have a nuget package I wonder

#

they don't seem to

#

well I'd have to distribute it anyways

#

They don't make downloading this easy lmao

#

It seems to be a unity package

#

not just a dll

swift halo
#

Betting the unity package just has a dll in it lol

jagged trout
#

Yeah I'm gonna see

#

their little download tool makes you give it a custom namespace lmao

main minnow
#

If you intend to include OdinSerializer in one of your own product distributions, you should modify all source files using a tool like search and replace to move the OdinSerializer namespace into an appropriate namespace for your project, and rename the .dll's that are built. This is to avoid namespace and assembly conflicts in the cases where multiple different assets in the same project all use possibly differing versions of OdinSerializer. For example, you might globally rename "OdinSerializer" to "MyProject.Internal.OdinSerializer", and also have the .dll's renamed to "MyProject.Internal.OdinSerializer.dll".

#

so could write an MSBuild task to download source code from their GitHub, fix the namespaces, etc

#

hmm

jagged trout
#

It's a bunch of C# files

main minnow
#

once I've finished the NetCode weave action and done the restructure

#

I can make an automatic thing for generating a thunderstore package, but not sure what to do about referencing that in project

#

Oh yeah we can just do it in our repo

jagged trout
#

I mean I could just copy the unitypackage's cs files into the repo since I gave them the LC_API namespace lol

#

I'm actually not sure if apache allows that specifically

#

or just redistributing the binaries

#

but they don't actually provide binaries

#

technically the unitypackage would just be compiled in the assembly csharp

main minnow
#

I would use the cs files from their GitHub if possible

#

not sure if they'll be different

jagged trout
#

Oh it's just odin serializer?

main minnow
#

Yeah

jagged trout
#

I wonder if I can build the project on github into its own dll and just use that

main minnow
#

you can, but that can cause namespace issues if other people do the same thing

jagged trout
#

Regardless I do have it working with newtonsoft atm

jagged trout
main minnow
jagged trout
#

which is what their download tool did for me I think

swift halo
jagged trout
#

It pains me that there has to be a security vulnerability in creating a byte array from what is literally just a bunch of bytes 😢

#

Just let me mem copy the entire thing

main minnow
#

jesus christ that was an ordeal

#

@jagged trout it is done

#

but anyway, it works

jagged trout
main minnow
#

No idea why

jagged trout
#

interesting

jagged trout
#

Should I make the network messages need to be manually registered like harmony patches?

It'd be static though so you could just like Network.RegisterAll() and there'd also be the one for registering messages inside a specific type like: Network.RegisterAll(type) to mirror harmony's PatchAll

main minnow
#

Ideally with the same API as harmony

#

Actually, that's only really valid if it's possible to 'unregister' network messages

main minnow
#

okay, then yeah

#

it would be good to let people unregister their messages as a 'teardown' thing

#

of course adoption would be low (almost no one implements teardown) but its a shame because implementing teardown allows hot-reloading

cyan trout
#

cant wait for this 🙏

main minnow
#

@jagged trout it brings a tear to my eye

jagged trout
#

From this point on main will be frozen to releases/release candidates

main minnow
#

Hang on, before you do that

jagged trout
#

all future PRs should target dev

main minnow
#

let me fix the Thunderstore folder

jagged trout
main minnow
#

ah never mind then

#

i'll target that on dev

#

👍

jagged trout
#

well I haven't done any releasing yet

#

the dev branch is still synced

#

where were you gonna put it?

main minnow
#

I'm going to remove the unnecessary duplicated assets (README) and make the paths nicer because tcli does the path remapping for us

jagged trout
#

ok

#

The pain of getting my local fork to sync with this

main minnow
#

Rebase

#

It might be easier

jagged trout
#

didn't seem to do anything

#

I'll probably just reclone

#

actually the sync button on github might work

#

yeah cool, that worked

main minnow
#

yeah @jagged trout there are a few options for that

  • keeping your main branch clean on your fork so it can always sync
  • git remote add upstream ... and then git pull upstream main
jagged trout
#

yeah I have upstream, for some reason updating it kept my local files plus your changes

#

but syncing on github then pulling seemed to work

main minnow
#

That might be a git.config issue to do with preventing the possibility of all local copies being purged

#

if a remote repo gets compromised

#

FYI if you set this in your csproj.user then dotnet build will automatically build the mod zip, provided you have tcli installed

#
<PACK_THUNDERSTORE>true</PACK_THUNDERSTORE>
#

dotnet tool install -g tcli

jagged trout
#

so where's the thunderstore readme at now?

main minnow
#

It gets copied from the repo readme

jagged trout
#

hm

main minnow
#

Oh, were they different?

jagged trout
#

they're different

#

yeah

#

not something I did

main minnow
#

that's ok, I'll bring it back

#

...we could just make it the repo one

#

😂

jagged trout
#

we also need the network bundle

main minnow
#

I tested that

jagged trout
#

where's it at?

main minnow
#

assets/bundles/networking

#

it gets copied to the correct path in the ZIP

jagged trout
main minnow
#

because of the rule in assets/thunderstore.toml

jagged trout
#

didn't seem to be committed

#

oh wait

#

I see it

main minnow
jagged trout
#

can you move the "versions" stuff from the thunderstore readme to CHANGELOG.md and include that in the thunderstore?

#

since thunderstore has a changelog page

#

if it's there

main minnow
#

Yeah, that sounds like a good solution. Then we don't need two separate readmes, rght?

jagged trout
#

yeah

#

I'm gonna see what other diffs there were

main minnow
#

I'll use the Keep A Changelog format if that's ok

main minnow
# jagged trout I'm gonna see what other diffs there were

just this:

# Features
AssetBundle loading - Put asset bundles in BepInEx > Bundles and load them using BundleAPI.BundleLoader.GetLoadedAsset

ServerAPI - Utilities relating to the network and server. This includes:

ModdedServer - Automatically alerts other users when you host a server that your server is modded. 
It also lets mod authors make their mods put users in special matchmaking where they can only play with other modded users

Networking - Easily send data across the network to sync data between clients
jagged trout
#

That's kinda outdated

#

I'd just remove it

main minnow
#

Aye, in that case the root readme has parity

jagged trout
#

Yeah then just get the versions into changelog.md and I'm gonna reformat it then I can merge

main minnow
#

I'm pretty sure we have the same idea

jagged trout
#

I would like new versions to be at the top

main minnow
#

already done

jagged trout
#

since that's what you'll first see

#

yeah

#

other than that I don't really mind

main minnow
jagged trout
#

yeah that's what I use mainly

main minnow
#

networking bundle is at BepInEx/plugins/Bundles/networking

#

Changes pushed

jagged trout
#

as long as Bundles folder resides next to the dll when r2modman unpacks it, I'm cool with it

main minnow
jagged trout
#

though I would potentially consider moving the dll to the plugins folder just for those manual installers that drag and drop the BepinEx folder

#

I've had like 8 issues opened about manual installation because none of them know how to set it up

#

so I made it as easy as possible

main minnow
#

oh for fucks sakes

#

yeah I'll do that too

jagged trout
#

#32, #42, #45, #46, #48, #51

#

all of these issues were because people just dragged and dropped files and expected it to work

#

lmao

main minnow
#

and then complain when filename collisions mean that nothing works right

jagged trout
#

so in the next version I have it just look exactly where the dll is for the Bundles folder

main minnow
#

or that they didn't copy the right file in the first place, like this situ

jagged trout
#

Nah the issue was I was looking specifically for 2018-LC_API

#

which manual installation doesn't have

main minnow
#

ahhhhhhhhhhhh

#

I see

jagged trout
#

I didn't know PluginInfo.Location existed

#

so I was going off of Paths.PluginPath

#

¯_(ツ)_/¯

#

it's "fixed" in the next version though

main minnow
#

Paths.PluginPath should be accurate

#

the problem is people installing manually and not using BepInEx correctly

jagged trout
#

Nah that's BepinEx/plugins

main minnow
#

ah sorry, you're right

jagged trout
#

PluginInfo.Location is the literal location of the dll of the plugin lol

#

Now I just do Path.Combine(Plugin.Instance.Info.Location.Substring(0, Plugin.Instance.Info.Location.LastIndexOf(Path.DirectorySeparatorChar)), "Bundles", "networking")

main minnow
#

sorry 😅

#

if you're within the plugin class, that is

#

otherwise

unique sluice
#

wdym transpilers @jagged trout ?

main minnow
#

Path.GetDirectoryName(Plugin.Instance.Info.Location)

jagged trout
#

I was looking for that method

#

I didn't know what it was called

main minnow
#

of course, I confused myself a few times -

main minnow
#

GetDirectoryName("foo/bar/abc") returns "foo/bar" which is obvious, but if abc is a directory you wouldn't initially think to do GetFileName to get the abc part

unique sluice
main minnow
#

hello

jagged trout
#

I was just about to test it

main minnow
#

hehe sorry

jagged trout
#

I mean not that there's much to test

main minnow
#

true

#

You can also click on the checkmark and get a download of the Thunderstore mod .zip generated by the build action

#

I think

jagged trout
#

I don't see it in there

#

regardless

#

seems to be fine

main minnow
#

the lc-api.version.zip will be inside that somewhere

#

It might be that only 2018 can

jagged trout
main minnow
#

yeah

#

we don't have the permissions

#

Oh wait there it is

#

Right at the bottom

jagged trout
#

amazing version

main minnow
#

lmao

#

Because it's on a PR branch

#

there's no tags

jagged trout
#

yeah

main minnow
#

the main branch ones will be more sane

jagged trout
#

well aparently there's an alpha

#

0.0.0-alpha.0.73

main minnow
unique sluice
#

transpiling w/ bepinex was bad 2 years ago, I wonder if it's better now? like some opcodes just didn't show right and not always matching what dnspy showed for example?

main minnow
unique sluice
main minnow
#

so if the commit is tagged 3.2.1 the version will be 3.2.1
if the 3rd commit back is tagged 3.2.1 the version will be 3.2.1-alpha.3

jagged trout
#

you'll see it in my patches for the hurting and dying event

main minnow
#

not sure why it's 0.73 though and not just 73

jagged trout
#

I just prefer events to be implemented with transpilers as they are the most compatible

#

some make sense as a prefix/postfix as well

#

but most need to go mid code

jagged trout
main minnow
jagged trout
#

they aren't thinking of compatibility usually

#

just "need my mod to work"

unique sluice
#

Does this look like a reasonable overhead for "no netcode patching" RPCs?

main minnow
#

I don't know 🤔

#

what I do know is netcode patching isn't difficult to configure

#

but i do understand it's really annoying

unique sluice
#

I got it to patch but it wouldn't send the messages ;~;

#

Probs something I did

main minnow
#

I'm not sure whether unpatched RPCs can work at all

#

are you imitating what the patcher inserts in ValidateRPCExecution?

main minnow
#

oooof

#

well if it works

#

power to you

unique sluice
#

its something

#

I just dont know if it makes sense

#

to someone else

main minnow
#

if you're trying to make it a library

#

you could use harmony to runtime patch their RPCs

#

and add your validateRPCExecution automatically

unique sluice
#

O.o

#

oooo

#

u smart

main minnow
#

then your thing would be identical to netcode for gameobjects RPCs, right?

unique sluice
#

right

main minnow
#

you would need to write a way for other mods to ask your mod 'Hey, please patch my RPCs!!'

#

so that you don't start runtime patching methods that have already been patched by Netcode weaver

unique sluice
#

How would I get assembly references to other loaded mods w/o them passing me an Assembly.GetExecutingAssembly()?

main minnow
#

what do you need them for?

unique sluice
#

Cuz I culd just do a single attribute like [Nyetwork] applied ot the NetworkBehaviour

main minnow
#

oh

unique sluice
#

Then just patch all those

main minnow
#

I wouldn't do it that way

#

if you look in Harmony's sourcecode

#

You can see the implementations for patch discovery

#

You're basically trying to do the same thing as that

#

It's a lot of code

#

I would probably do something like PatchMyNetworkBehaviour<NetworkBehaviour>();

#
public static void PatchMyThing<T>() where T : NetworkBehaviour
{
  
}
#

which users would call in their Plugin.Awake()

#

@jagged trout I have a bone to pick with you

#
public IEnumerator PlaylistCoroutine()
{
  PrepareNextSongInPlaylist();
  while (Boombox.boomboxAudio.isPlaying) yield return new WaitForSeconds(1);
  IncrementPlaylistIndex();
}
#

what the fuck is that

jagged trout
#

that's not in LC API, is it?

#

that boombox mod is very rudimentary

main minnow
main minnow
jagged trout
#

I use that to detect when the song is over to play the next song

main minnow
#

Yes

#

My plan is to delete that whole boombox controller

#

and let 'sound pack' creators add tracks using JSON files

#

which are downloaded when the game opens

#

no more copyright problems

#

it can download the audio straight to (other) Steven's boombox tracks folder

jagged trout
#

Yeah I want to make the ui for yt boombox better at some point

#

but I haven't worked on it in a while

main minnow
#

yeah I've already removed the UI from the fork 😅 since I'm going for config-only

jagged trout
#

I also suck at UI design.

main minnow
#

Lmaoo that's ok

#

Same

#

I love working with people that actually enjoy/know graphic design

#

I helped make that iteration of the website, I did most of the splash area

#

but jesus I could never have designed it

jagged trout
#

Harmony might be the most cursed C# project tbh

main minnow
#

😂😂😂😂

jagged trout
#

using a stack trace to get the calling assembly lmao idk any other way so I just used that

main minnow
#

ExecutingAssembly

#

wouldn't work?

jagged trout
#

I don't think so

#

well not always

#

that would get the current assembly

#

We need to get the one that called the method

main minnow
#

oh

main minnow
jagged trout
#

I needed the exact same thing to search all their types for NetworkMessage annotations lol

unique sluice
#

weird

jagged trout
#

If only there was some sorta guide on manual installation for the current version

#

lmao

#

Also

#

I think I'm gonna release 3.2.0 today so that this issue can go away and we can get the networking out

#

I'll just keep my events for the next version

#

Now time to find what my changes are so I can update the changelog

#

Wait I think it was literally just networking and your project restructure right @main minnow ?

main minnow
#

yes

#

and CI

jagged trout
#

should I even put that in the changelog?

main minnow
#

I would

#

'notable changes'

#

but it's up to you

jagged trout
#

it just probably wouldn't matter to devs/users I don't think since they won't usually be interacting with it at all other than seeing the build checks

#

hm

#

idek what I'd put in there for it lmao

lavish parcel
#

This mod causes issues joining into regular servers

jagged trout
#

LC API will prevent you from joining regular servers at another mod's request

#

it will not prevent you from joining regular servers without another mod telling it to do so

lavish parcel
#

alright well, I want to use the Coroner mod but thats with LC API

jagged trout
#

@main minnow you wouldn't happen to know how to merge tags from a fork would you?

main minnow
jagged trout
#

I can't push directly to the remote though

#

I don't think

main minnow
jagged trout
#

I can push them to my fork

main minnow
#

that's the only way to do it

jagged trout
#

but I can't get them to the actual main repo

main minnow
#

we should just start working out of your fork lmao

#

(no, 2018 just needs to give you the right permissions ...)

jagged trout
#

Well I don't want to take the project from them

main minnow
#

They quite literally don't want it

#

There's a reason for this:

#

@balmy rover

#

it was previously '2018 HATES lethal company modding'

#

it would be best if they handed over the Thunderstore team to you so we can keep using the front-page project

jagged trout
#

The main issue is if we were to move it to a different team, we probably wouldn't ever get recognized because LC API is the most downloaded mod... It would be seen as a knockoff or potentially even as malware. I also think the thunderstore mods would delete it for being a "copy"

#

So moving it to a new team is basically out of the question

main minnow
#

People do not care if the GitHub repo moves or whatever

#

and NuGet doesn't exist yet

#

So the only thing that would need to happen is that ^^

#

I think all they have to do is set you as 'owner'

#

@jagged trout

#

I mean, all we actually need is an API key for the team

jagged trout
#

Yeah

main minnow
#

It would be preferable if you were able to generate those yourself

#

but Shruge

jagged trout
#

wait

#

lmao one sec

#

nvm lmao

#

I thought I had accidentally bypassed the security somehow

main minnow
#

😂

jagged trout
main minnow
#

kek

jagged trout
#

and it had the menu, but when I tried to add it, it just ignored it

main minnow
#

ye i would message 2018 and ask if you can be set as owner

#

if no, just a service account would be perfect

balmy rover
#

ill probably come back at some point so i just added them as a service account
gamedev requires 100% of my time so once i eventually finish this project i might start working on mods for a little while again
(and its not like i dont want this project, just other stuff is getting in the way of me working on this (and i got burnt out from working on mods all the time))
letrollface

main minnow
jagged trout
#

Thanks to @main minnow after a few versions of testing (sorry) we now have publish workflow that will auto upload the package to thunderstore and nuget

#

This should streamline development as well as provide the XML docs for you when you use it while I work on actual documentation (eventually™️)

unique sluice
#

That's some high tech stuff O.o

small merlin
#

I've been receiving issue reports that LC_API makes their clients no longer work with vanilla clients. I don't know if this is a known issue or can be resolved but whenever I try to make LC_API a dependency I get numerous calls to remove it.

grave saffron
lavish parcel
#

Oh i just got the one where it said it doesnt use lc api lol

jagged trout
#

Yeah I believe it's due to the player networking bundle causing network configs to be out of sync

#

I'm thinking of ways around it, but since the player class needs to be networked I'm not entirely sure what I can do at the moment

main minnow
#

I don't really get the appeal of playing with different modlists?

jagged trout
#

considering LC API provides both client and server sided things I'm not sure it's even feasible to provide the ability to use it without everyone in the lobby needing it

#

same with any other mod that needs a custom network prefab

cyan trout
#

@jagged trout i could be doing this wrong but it seems broadcasting a message is host only even tho it says ANYONE can send them

cyan trout
#

or atleast very inconsistent if it sends it or not

jagged trout
#

@main minnow and I have tested clients sending and it seemed to have worked, can you show me your code?

#

and are there any errors?

#

@cyan trout ^

jagged trout
#

Also, my Internet just got turned off, so this might have to wait a few days

#

Depends on if I can convince Xfinity to turn it back on until my next paycheck

cyan trout
# jagged trout <@263412118257139713> ^
        public class ReviveMessage
        {
            public int PlayerId { get; set; }
        }
        public static void BroadcastRevive(int playerId)
        {
            Debug.LogWarning("BroadcastRevive");
            Debug.LogWarning(playerId);
            Network.Broadcast("VIVIKO_REVIVE", new ReviveMessage() { PlayerId = playerId });
        }

        [NetworkMessage("VIVIKO_REVIVE", true)]
        public static void ReviveHandler(ulong sender, ReviveMessage message)
        {
            Debug.LogWarning("ReviveHandler");
            Debug.LogWarning(message);
            Debug.LogWarning(message.PlayerId);
        }```
#

serveral time i tested this and 90% of the time when the non host triggers the broadcast it doesnt send ot the host/everyone else

jagged trout
#

There were no errors or anything?

#

Also, if the host sends it, does it work?

cyan trout
#

host sending it works 100%

#

non host = 10%

jagged trout
#

I'll test it on LAN since I don't have internet atm

#

Yeah I just sent 100 and received 100

#

Exact same code

#

Hm

#

It's sent with ReliableSequnced, so unity netcode should be ensuring it sends

#

I wonder if the issue is on the receiving relay

#

Did you happen to leave and join multiple games?

#

Specifically whoever was hosting

#

Since the host serves the relay

#

The only thing I could think of is somehow the host isn't relaying the message

cyan trout
#

testing:
match 1:
host kills client and triggers this - works
client kills host- works
match 2:
client kills host - doesnt work

jagged trout
#

What do you mean by "match 2" like second day?

#

Or quitting out of the server and making a new one

cyan trout
#

quit that match and hosted another

main minnow
jagged trout
#

That is weird

#

I do have to unregister the relay and all messages when the server is exited because the network is off, but I did ensure messages were re-registered when a new server was started. I'll have to check that the relay is, too.

#

It's weird that it'd work sometimes though

#

Because that would lead me to assume everything is properly registered

sharp compass
#

Seems like hes still gone…

main minnow
#

?

main minnow
#

@jagged trout are u about?

jagged trout
#

My Internet is still off

#

So I can't do much

main minnow
#

Could u merge a PR and make a release?

#

The nuget package is auto referencing gamelibs which is annoying for my dev workflow

jagged trout
#

Hi

#

internet back

#

I can do that

main minnow
jagged trout
#

wait

#

build failed somehow

main minnow
#

interesting

#

I'll have a look

jagged trout
#

builds in vs just fine

main minnow
#

oh it's a race condition

#

in MSBuild

#

where NetcodePatcher is being executed twice at the same time

#

rerun the task

jagged trout
#

seems to be working

main minnow
#

basically when we MSBuild it uses only 1 process

jagged trout
#

yeah

#

seems to worked

main minnow
#

but Github actions runners set a higher process count by default

#

Which means sometimes it's running NetCode weaver 2x in parallel

#

and that would be fine except it means they are both accessing the same logfile

jagged trout
#

apparently there's an issue with large network messages where it goes beyond buffer size and needs to be fragmented

main minnow
#

oh crikey

jagged trout
#

I need to ensure the fragmented channel doesn't interfere with anything

#

unity has built in fragmentation transport, but I need to make sure the relay doesn't mess up

main minnow
#

Did you have a chance to investigate network messages originating from clients working intermittently?

jagged trout
#

Not just yet

#

I'll create an issue so that I don't forget

#

Also I was kept at work for an extra 2 hours today so I am absolutely out of energy

main minnow
#

Good plan

jagged trout
#

so I will probably not be able to get to these until either tonight or sometime tomorrow

jagged trout
main minnow
#

mm

#

Where do you register the relay?

#

(s)

jagged trout
#

I planned to move them to their own methods

#

so I could unregister the event handler for hot reloading

#

but atm that's a far in the future plan

#

but basically, since the network manager turns off when leaving a game, you have to unregister all the messages

#

then keep re-register them when a new game is joined or (if you're the host) also the relay

#

wait

#

I know exactly why

#

when I unregister them I remove the handler

#

so it doesn't re-register on new game join

#

pain

main minnow
#

Create an issue so you don't forget!

#

🤣

#

Rubber ducky method always works

jagged trout
#

well it was an easy fix

#

just added a param for whether or not to actually fully remove it

#

and with that I'm dead for about 2-3 hours

#

I'll test it then

jagged trout
#

alright

#

just tested main and my local changes on dev

#

didn't work on main, worked on dev

#

pretty sure that's fixed

#

now to see if fragmented has problems

main minnow
jagged trout
#

Ok and fragmented sequenced seems to just work drag and drop

#

tested it before and after with 1000 randomly generated random length strings

#

failed on reliablesequenced, worked on reliablefragmentedsequenced

main minnow
#

noice

jagged trout
#

Also I added a vanilla support config option, however, it disables the entire player and item class

#

including related events

#

which makes the API generally useless

#

it would have its Networking still since those don't require synchronization, except the host requires the mod to relay

#

the message would just be ignored on clients that don't have LC API

#

So I'm debating whether or not we should even have it

#

because technically if one player has LC API, the rest are gonna need it for the API to even work

#

So I'm heavily debating whether or not I should even add vanilla support

#

LC API is just a server sided mod now basically

main minnow
#

right I see what you're saying

#

what about asset bundle loading?

#

since thats what basically all of these clientside mods were using lc api for

main minnow
#

@paper flare are you using Day's runtime netcode patcher?

#

oh what

paper flare
#

Nope, using netcode weaver

main minnow
#

what the fuck

paper flare
#

hi

#

xD

main minnow
#

but you're

#

you're doing it at runtime

paper flare
#

me?

#

what

main minnow
#

i'm so confused

#

ohhh

#

never mind

#

i understand

#

okay i need to add csproj tasks for netcode weaving then...

#

muh

paper flare
#

hwuheehhe

main minnow
#

you're lucky i've done this before

main minnow
#

woops that was wrong channel

#

@jagged trout are you alive

main minnow
#

well, when you're back

jagged trout
#

@main minnow your PR build fails

main minnow
#

It doesn't

#

it's the same problem as before

#

Rerun the task

jagged trout
#

What is the difference anyways?

main minnow
#

I renamed the action

#

The old one doesn't exist

jagged trout
#

works

#

Did this need a release?

main minnow
#

No

#

It's purely a workflow change

jagged trout
#

ok

#

I was gonna go to bed

#

When I wake up tomorrow I'm gonna test the dev branch make sure there's no problems then release

#

but I am very tired

main minnow
#

Get yourself some good rest brother

#

no rush on the release

jagged trout
#

You know

#

I could technically set up the Player behaviour to use custom network messages...

#

seems very silly, though

#

since they work in a static context, I'll have to pass the player id along the message and get the actual player out on the receiving end

#

I do lose the ability to use NetworkVariables, though

#

Which I currently use to set the player's network id from the host to ensure they sync with clients and that all clients have proper IDs

proven terrace
#

Who is maintaining this now? I thought Bobbie took it for a while but I'm not sure

jagged trout
#

I am

#

I am the only other person with access to the team

proven terrace
#

Okay, thanks

uncut raptor
#

I think LC API is breaking my game

edgy orbit
#

I removed it and never had a problem since