#archived-networking
1 messages ยท Page 42 of 1
neither of them use a server generally, and if you do it's only to get the final result of the game out, not for any direct communication with the clients
aight thanks
also because deterministic lockstep generally means sharing more information with your clients than you'd like to
๐
@split crescent hmm.. not sure if I agree
Delta Snapshots suffer from the same issues
In that everyone needs all data
I mean sure you can mask data if you really want to
But honestly it's not a huge deal really
I think the difference is you can do server side culling?
but will admit I'm a little out of my depth there
i second going over Unity's FPS Demo (took a team of guys ~2 years), i spent probably a good week going over it. it's a pretty fun learning experience but also a big eye opener ๐
@weak plinth it's very purpose built
But it's basically a standard delta snapshot
Doesn't detract from it at all, it's very well built
gotcha, i'm speaking more from no experience developing a networking lib and getting a view into how much is really involved, even if it's specifically for your game
it certainly woke me up ๐
Yes it's a great learning resource
@split crescent you can do server side culling, absolutely
I mean it depends on the game if it helps
@jade glacier o/
heyo
I can barely get FPS Demo to open, much less run on my laptop... so can't really poke at the net code they have set up in there
@jade glacier if you don't want to run it just open the code folder in visual studio code or some other smaller text editor which let's you open a folder as a project
I can open the source in VS, and the project already has done its 2 hour load up in the editor... so I can "look" at it... I just cant see it in action
Just makes the detective work a little harder without being able to have a running scene
Honestly I never played it
It doesn't help much TBH
If you want to learn what they did
I mostly need to locate the player object and sort out what classes are on it
The networking folder was full of lower level stuff, I am more interested in their tick engine, and where they handle their simulation
2 sec I'll link it
or just the file names of interest if you happen to remember
There's a client one also
But that's the main loop
Odd seeing Update() ... are they not making use of an update manager for this stuff?
Ahh, so this is acting as the update manager of sorts
Yes
Cool, will have to set aside some time to follow these methods around and see what kind of choices they made
Ping me if you need help with where something is or how it's structured
Will do
I am a little confused about Unity's networking roadmap... since their actual networking code seems to be making little to no progress, but this project has working networking.... are they struggling to staff the actual UNET replacement project or something? @graceful zephyr
I assume FPS Sample is running on their replacement transport code, or is that not the case?
i believe they wrapped the transport (from the new networking alpha) in their SocketTransport class
i kinda recall hearing in a talk on the fps demo that some of the things they did in the fps demo might find its way into the actual networking lib
yeah, thats what I am thinking is likely going to happen. They will be asked to turn their net code into more generalized HLAPI stuff
but yeah i've had the same concerns about the networking lib, since the advice they gave people writing games was to wait if they were releasing post 6 months out mark (i think that was 3 months ago?). but i only see the lowest level and no updates in the repo
Are they talking about yet another HLAPI?
All of the HLAPIs keep looking about the same... all RPC/Syncvar/Message based, and nothing that really focuses on giving developers a solid tick synced frame based HLAPI that can easily be made to work for determinism, input syncing, rewind, resim... etc
Unity doesn't need any more Syncvar and RPC libraries ๐
@jade glacier so... the fps sampel can use both unet transport and the new transport
it doesn't care, it just needs unreliable sends
literally
They abstracted it, yeah... as everything really should be now
Afaik their are not going to do a new HLAPI
but more 'dedicated' solutions
to various game types
most of our libraries as we wait for these things all are coming down to byte[] in and out
but, thats not solving the shortage of a proper state engine starting point for new developers
we have 1000 guys like myself hacking together our own
its incredibly hard to make a generic state engine that is easy to use and flexible enough
true, but some of the stepping stones can be made at the MLAPI level I would think
not the usual RPC Syncvar level crap
rpc/syncvar is just... the worst model imaginable
but a "here are the ticks and here is the byte[]" .... serialize your heart out
or at least the way it was implemented in unet
@jade glacier if you look at the fps sample in detail, you'll see why it's not as easy as just letting people serialize into byte buffers
I know it opens the doors for massive breakage
it needs a lot of meta data around
you can do safety bloat like PUN does
which isn't easily... made generic
but PUN too... NO tick engine concept, just messages
yeah, Bolt is what I still say is the only proper tick engine available
but that library is sealed up tight
yeah, not a slight to you at all, its still stands
as somehow the only fucking tick engine
every one in networking chat is trying to sync inputs and work out how to resimulate....
its super needed
import component CustomComponent;
compressor GameVector3 : Vector3 {
Owner {
}
All {
X {
Min = -1024;
Max = 1024;
Accuracy = 0.01;
}
Y {
Min = -32;
Max = 128;
Accuracy = 0.01;
}
Z {
Min = -1024;
Max = 1024;
Accuracy = 0.01;
}
}
}
component replicated Transform<V, Q> {
Vector3<V> Position(All);
Vector3<V> Velocity(All);
Quaternion<Q> Rotation(All);
}
component replicated Inventory(CanSeeAll, OnlyItemType) {
InventorySlot[20] Slots(CanSeeAll, OnlyItemType);
}
object InventorySlot(CanSeeAll, OnlyItemType) {
Int32 ItemId(CanSeeAll | OnlyItemType);
Int32 ItemCount(CanSeeAll);
}
archetype Player {
use predictable Transform<PlayerVector, PlayerRotation>;
use Inventory(Friendly, Enemy);
}
archetype Chest {
use Transform;
use Inventory(CanSeeContents, None);
}
filter Transform {
has Transform;
}
here's my prototype DSL for specifying state/compression/filters/etc.
it's not finished at all, it needs a lot more work
Out of context, not sure I get most of that
its a 'custom' language
I recognize what they hint to
but not how it fits into anything ๐
it compiles into a .NET DLL
gotcha
so i wrote a custom parser/trans-compiler for it basically... so it can compile into a .net dll
still not decided if i'm gonna emit C# and then run the C# compiler, or emit a DLL directly via Cecil
That's coding and operating at a level above me ๐
the idea is pretty simple
you define components
like transform, inventory, etc.
and then you define entities/archetypes/state (whatever i end up calling them) which are groups of said components
Defined in code I assume, since this isn't inspector based
yeah, define in the DSL i linked
the DSL is then compiled into a .NET DLL via a tiny editor tool
and it will generate code like this into the DLL:
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public unsafe struct Player {
void* _ptr;
public Transform Transform {
get {
Transform transform;
transform.Ptr = (__Transform*)(((Byte*)_ptr) + Maths.RoundToAlignment(sizeof(__Entity)));
transform.EntityState.Entity = (__Entity*)_ptr;
transform.EntityState.ComponentIndex = 0;
return transform;
}
}
public Inventory Inventory {
get {
Inventory inventory;
inventory.Ptr = (__Inventory*)(((Byte*)_ptr) + (Maths.RoundToAlignment(sizeof(__Entity)) + Maths.RoundToAlignment(sizeof(__Transform))));
inventory.EntityState.Entity = (__Entity*)_ptr;
inventory.EntityState.ComponentIndex = 1;
return inventory;
}
}
}
Something I can read finally ๐
which can then be used like this:
Player p = new Player();
var slot = test.Slots[0];
slot.ItemCount = 1;
slot.ItemId = 1;
var transform = p.Transform;
transform.Position = Vector3.one;
transform.Rotation = Quaternion.identity;
p.Transform.SetPosition(Vector3.one);
var slots = p.Inventory.Slots;
for (Int32 i = 0; i < slots.Length; ++i) {
var s = slots[i];
s.ItemCount = i;
s.ItemId = i;
}
Following in a general sense yeah
Still not decided on syntax fully yet for any part
Totally different world than I live in, so mostly looks alien. I never compile anything so that all looks like voodoo
I would like to do it without the dsl and compiler
But it's so many things you'd need to do by hand then
In code
Or you need to trade away executing speed
I don't see my networking skills ever getting past giving objects Serialize() Deserialize() Interpolate() and Rewind() methods, but thsi stuff is fascinating
so if it's a replicated transform type and you do p.Transform.SetPosition the replication is taken care of for you?
@weak plinth yes
oh my god i want it now
yeah, the end result is magical
That's what photon bolt does if you want something like that now
i know you know that @jade glacier that was for @weak plinth
:p
again this is super early, and i'm still changing things all over the place
I own bolt, I just hit walls too quick with it and exits maintenance of it and its docs.
I tell everyone how great it is, I just don't use it LOL
I can't judge an FPS really without actually playing it - since the devils of netcode are in the details of playing
but I assume its rock solid
absolutely
what's the decider between PUN & Bolt?
PUN and BOLT have photon in common, and that is about the end of it
@weak plinth Bolt is aimed at basically a specific target: authoritative fps games, or games in that style... it can be used for other games of course (and it has)
PUN is client to client messaging through a relay
but it has a lot of stuff which you wont find anywhere else, like systems for authoritative movement, lag compensation for shooting, etc.
but bolt has ONE way of doing everything, and you can't deviate from it easily
Bolt is a full on engine
PUN is much more open ended where you just serialize stuff and deal with everything yourself
ahh ok, overkill for my mostly text party game atm :), but i'm gonna make a note of it
Would be more of a hindrance than a help for that kind of game
@jade glacier we're mostly going for mobile fps/tps games with quantum, not trying to do PC fps games.
What the Unity world needs and I am not quite good enough to produce in a timely fashion is a input sync + tick engine that is library agnostic
@graceful zephyr Is there a reason to not make PCs a target? Seems if it works on mobile, it will slay on PC?
@jade glacier PC fps games are built in a certain way, and people expect it to work in a very very specific manner
@graceful zephyr Lot of work, but its also where 90% of Unity new networking projects are mired
mobile fps is easier since it's slower paced, slower aiming, etc.
there are some very very technical/specific considerations which makes quantum a good target for mobile and console fps, but not pc fps ... right now, we're going to solve those also
but initially we target mobile
Ahh, this probably goes back to my previous questions about client prediction in a deterministic game.... seems like its going to be tricker
like the current game plays just FINE on PC, but yeah... some very very technical details we need to figure out to make it rock solid even for PC
The whole reason non deterministic works so well is you can have the players all be in different timeframes and disagree
and very few high end FPSes are built in Unity
for PC
but for mobile... almost all of them are built in Unity
so a much bigger market
heh
is full determinisim really doable for a fast paced FPS ? I can't get my head around how client prediction works when the player locally has to agree with the server 100%, the whole favoring the shooter thing kind of goes out the window no?
@graceful zephyr
sorry, with the "reality" of things
and you can still do favor the shooter
Locally I will be ahead of time though still no?
so my local position in the world isn't the true position
no, you will all be at the same time, but it will be predicted time
but you will all be at the same point in time
so you predict the entire world
yes
gak
and roll back the whole world also
well that explains the missing thing I wasnt getting... but holy dick is that going to be tough to make tight
extrapolation = noise
this video
is one client watching another client
with ~230 ping
full prediction of 13-14 ticks (so 14*16 milliseconds)
0.22 seconds of prediction
The extapolation aspect is why you were saying slower moving tends to be desirable
but there's no extrapolation/prediction errors visible
though it seems the real concern is fast changes in user input
even though the other client is moving erraticaly
watch the video
im moving super erratic, still looks perfect
both clients have 230-240 ping there
Would be helpful to see that with a green ghost showing where it missed the prediction?
There must be some rubber banding happening
absolutely, but the goal here was just to show that we can correct massive prediction errors without any visual errors
this was just a video i recorded for internal showcase thing
And so in this... if you shoot the bad prediction... how does that get passed along as a hit when others will disagree?
it uses the same type of system as battlefield
but instead of the server doing a plausability check, all clients do it
Ahh, gives the client a little more authority to make up for it
not a hack risk giving it that much wiggle?
nah, it also has the benefit of providing pixel accurate shooting for the clients
which games like counter-strike or CoD don't do
so it's a fairly big benefit also, in that shooting always is as accurate as possible
plus we have the ability to do full rewind checks due to how quantum works internally, we can go back in time to say 10 frames ago and shoot there if we need to
But it can't check your shot based on your view angle across the network... it has to accept a "No seriously I shot this guy in the head" as fact across the network if he was pointing in the general direction?
Or is the plausibility test accounting for extrapolation?
and it actually tests objects as they would have extrapolated?
it accounts for the extrapolation, it will send the view angle also, so it's not just that you were facing the general direction
your crosshair has to line up
quantum has a buffer of all states for the past second in the memory, for the entire world
so we can go back in time on all clients, etc.
to check for hits, etc.
didnt realize you were extrapolating for starters, and didn't realize you were giving client that kind of authority with checks based on possible extrapolations
pretty advanced stuff to code, but I get the concept now
it's a lot of technical details, there's other things which are harder to explain without a fairly deep understanding of what quantum does internally in relation to game state, input, etc.
I'm not looking to create anything like it, just couldnt get my head around the prediction model in determinism
hadnt ever considered extrapolation to be viable
it's just not straight up dumb extrapolation either
it doesn't just forward the player based on velocity
or something 'stupid' like that
yeah, I assume you have all kinds of catmull equations, slerping, acceleration lerps etc
no i mean, the extrapolation is much 'bigger' than that
it's the complete game state that is extrapolated
got a meeting now
Ahhh
bbl
u2
Networking is a really hot topic on this server....
it is with you and fholm around ๐ธ
I usually pass my questions to the Photon Server forums though ๐
This is fholm's house though, it's his channel so make sure you leave latency at the door.
don't talk about how you serialize uncompressed values though
they'll bitpack shame you
@last hornet I don't :(
nah that might just be @jade glacier ๐
Lets have a little bet on when Unity's own new networking will be mature enough for a released 16 player FPS title. I'm guessing early 2020.
It's clear by the multi million investments into server infrastructure - the same servers that power pubg and other AAA games, as well as buying the most widely used VOIP solution for AAA games (pubg/fortnite/LoL).
buying all that indicates some degree of seriousness
Either that or Unity has much more money than any of us dare imagine.
The work on FPS Sample will likely help drive that particular goal
@compact bramble well that's more of a hosting and services thing tho
Not multiplayer code
Sure but it implies the code is a priority or Unity just blew millions and someone got fired so hard that they exploded in 0 ms
Cos no code, no cash back.
@compact bramble all of the services so far have explicitly been state that it doesnt rely on their networking code, that it's agnostic
and they get no additional rev just because you run on their networking stack
They can't rely on third party to use their own infrastructure, so they will have to provide their own solution which while will still be optional, will also be pretty much the only way they can monetise, so they have no choice but to roll out a quantum-killer
it will be delta compressed pistols at dawn
or would be if you didn't stand over them as they slept with an axe
@compact bramble well quantum is hardly a generic solution for every game ๐
so posh... I used to think you were a viking. Perhaps I was wrong
hardly a generic solution! only for posh people ๐ โค
avoids an axe
would player auth, BaaS / custom, that sort of thing be out of scope for #archived-networking and more #๐ปโcode-beginner ?
mostly looking for suggestions for a good BaaS that can support friends (not just 1 way, like "following"), a party system (long-polling hopefully for party updates, so i can queue people together and keep groups synced across clients), and good auth w/ social auth. (i tried PlayFab, but that's what got me started writing my own)
If anyone has time to look over a noob, I can't figure out my issue. Using local host I can connect fine, but now when I try to use my ip i cant connect to the server being hosted and i cant figure it out. If anyone could point me in the right direction id appreciate it.
Also fair warning, code is pretty bad cause im testing right now
If you do want to glance at it, in all its horror, here are the key files
Client: https://hastebin.com/ixuxobinen.cpp
Server: https://hastebin.com/ulivegoqan.cs
UnityNetworkHandler: https://hastebin.com/davuqiguyi.cs (This one is preeeetty bad)
NetworkCanvas: https://hastebin.com/okufisewev.cs
Player and PlayerInfo: https://hastebin.com/iloniyoheq.cs
Any recommended compression classes or methods to use? Most of my network messages are small, but wouldn't mind profiling a couple just to see if there's any significant bandwidth gain (and CPU processing)
@jade glacier has a good one on the asset store
@cosmic atlas
Thanks, I'll take a look
The example scenes should make usage pretty clear, of not just ping me @cosmic atlas
Thanks, yeah just skimming the docs between other google searches haha
Probably am interested in serializing byte[] arrays, but could see if there's any optimisations for .PutFloat, .PutUShort kinda methods too, or for strings as well
I don't do any MonoBehaviour/Transform/Component magic syncing
its core is a float compressor
doesn't do strings, but it has a bitpacker in it, its an extension for byte[]
so you can just myByteArray.Write(valueOfAnyType, ref positionPtr, numOfBits);
there are three bitpackers in it actually, one for arrays (like byte[]) one for packing into primitaves like ulong, and a struct type called Bitstream that is a universal adapter between all of those
but the byte[] extension sounds like what you are after
for the float compression though, you want to make use of the Float Crusher
kk ty ๐
morning o/
@warm jungle well you shouldn't be sending strings as the event 'keys;
yes i know that lol, i figured that out and im redoing all my systems cleaner now using enums @graceful zephyr
so there's nothing wrong with your structure technically, it's like a good first thing
but it deals with stuff to.... manually
well... that's not really what im getting at
hold on, i'll show you an example
@warm jungle so like this... i can define an entity like this:
public class Character : EntityAuto {
public VectorProperty Position;
public QuaternionProperty Rotation;
protected override void SetupProperties() {
Position = new VectorProperty(this, nameof(Position));
Rotation = new QuaternionProperty(this, nameof(Rotation));
}
}
Then register it like this: _context.RegisterEntityAuto<Character>();
and create and use it like this:
var character = _context.CreateEntity<Character>();
character.Position.Value = new UnityEngine.Vector3(0, 4, 0);
character.Rotation.Value = UnityEngine.Quaternion.identity;
and it doesn't have a concept of like 'a position update message', etc.
it just deals with the entity as a whole
position and rotation will automatically replicate when they are changed, etc.
no need to send like 'oh i want to update position'
it's too hard to deal with a system that does that
I.. dont quite understand
I should consider switching to interfaces like that rather than derived network classes
Is EntityAuto a monobehavior? is this supposed to go on an obj youre spawning? To track those values? Or is Character a variable inside a MB class to track them or something? Does it somehow do auto syncing? I had some ideas for that. Im just not sure exactly sure what you mean, and by like "Replicate", and how I would do it other than "updateposition" and shit @graceful zephyr
Im going to bed tho, so you can reply tomorrow or tonight and @ me here or in loaf and ill reply or look at it then
its 2am so
@warm jungle lol we can do this when you wake up
dope
For you auto serializing wrappers like vectorProperty, where does the codec end up residing? Does every instance store it's own multiplier and De-multiplier? Our do you have a means for sharing like codecs?
@graceful zephyr
@jade glacier the serializer is only generated once per entity type and shared
Cool, was wondering at a glance where that was happening
@jade glacier it happens inside the constructor of the property types
I HAD to jump through making hacks to make that work for my asset because of the inspector aspect
Major
Christ mobile typing is trash
All this code is outside of unity doesn't even care if unity exists
my new system will use a DSL and code generator/compiler instead
there's too much hoop jumping to make this work from straight C#
I can imagine
i mean it's not tha dbad, i'll show u hold on
public VectorProperty(EntityAuto entity, String name = null) {
_entity = entity;
_offset = entity.ValueCount++;
if (entity.AutoSerializer.PropertySetup) {
entity.AutoSerializer.RegisterSerializer(new VectorPropertySerializer(name, Axes.All, default(FloatCompression), default(FloatCompression), default(FloatCompression)));
}
}
that if case only executes when it creates the first entity of that type
its that simple really
I've actually gone the passcode route with mine
how do you mean
All codecs produce a hash based on settings, so similar codecs result in the same hash
ah
So I see if a hash exists yet for the particular codec... If so what gets used as shared
for the DSL im looking at a syntax like this:
compressor GameVector3 : Vector3 {
Owner {
}
All {
X {
Min = -1024;
Max = 1024;
Accuracy = 0.01;
}
Y {
Min = -32;
Max = 128;
Accuracy = 0.01;
}
Z {
Min = -1024;
Max = 1024;
Accuracy = 0.01;
}
}
}
component Transform<V, Q> {
Vector3<V> Position;
Vector3<V> Velocity;
Quaternion<Q> Rotation;
}
entity Character {
Transform<GameVector3, Default> Transform;
}
Unless it's not a static codec and the seeing can be changed.... Then it's a whole other mess
the generic arguments are the compressors basically
Christ I would love to return to that clean a code
i mean this is a custom language that i have to compile to a .NET DLL by hand
so it's not like this is something C# supports or can be done in C# by default easily
it can also have different compressor clauses based on say which team your on, if you have control of the character, or if you're further away
https://gdl.space/tuxehifiha.cpp
as a reference of how convoluted things have gotten... this is JUST the float compressor
#define WORLD_MIN -1024
#define WORLD_MAX +1024
#define WORLD_MIN_Y -32
#define WORLD_MAX_Y +128
#define POSITION_CLOSE_ACCURACY = 0.01
#define POSITION_FAR_ACCURACY = 0.1
compressor GameVector3 : Vector3 {
Close {
X { Min = WORLD_MIN; Max = WORLD_MAX; Accuracy = POSITION_CLOSE_ACCURACY; }
Y { Min = WORLD_MIN_Y; Max = WORLD_MAX_Y; Accuracy = POSITION_CLOSE_ACCURACY; }
Z { Min = WORLD_MIN; Max = WORLD_MAX; Accuracy = POSITION_CLOSE_ACCURACY; }
}
Far {
X { Min = WORLD_MIN; Max = WORLD_MAX; Accuracy = POSITION_FAR_ACCURACY; }
Y { Min = WORLD_MIN_Y; Max = WORLD_MAX_Y; Accuracy = POSITION_FAR_ACCURACY; }
Z { Min = WORLD_MIN; Max = WORLD_MAX; Accuracy = POSITION_FAR_ACCURACY; }
}
}
You do your level of detail stuff in the cormpressor itself?
so you could do this for example
and it will switch those depending on which flags you set on an entity for a specific connection, etc.
yeah that's a lot of code lol
that used to be my simple base class, looked more like what you have above
but then... the inspector
It could use a housecleaning, but it works so I am afraid to poke at it
i know the feeling ๐
the simulator in quantum is like that... the one that actually does the predict/rollback
it works perfectly
but its like 2000 lines of REALLY complicated C#
and i'm so scared to poke it ๐
yeah, you forget writing most of it
and it was written so quickly it didnt get documented... so you know it works.. but you forget why
i changed it a few months ago and introduced a prediction bug which would cause the simulations to drift... but only like a 1/100000000 chance
that was fun to find
or if you die in train wreck is that whole project boned?
commonly called Buss Factor
i mean my colleague understands most of it i suppose, or at least knows what it does but maybe doesnt have a full understanding of the code itself
hes really good so
We had to have key man insurance on ourselves when we owned our old company for that reason
i have that on myself in my company
lol what is key man insurance?
@weak plinth basically the company cant survive without this person so we're gonna insure him so that we get a payout incase something happens so we get money to rescue the company
insurance for if a key member of a company is lost... that it WILL wreck the company and cost a lot to clean up
holy crap
Pretty common in small companies
yeah
where usually there are a couple of people the whole thing ride on the backs of
how much insurance did you have on yourselves?
million each I thnk
almost same as mine then ye
it was required by some clients I recall
I forget why we did it, but it was required
for me it's more a way to make sure that if osmething happens, wife/kids are okey, since wife is the benefactor to my company
yeah, different benefactor... same concept
and its much cheaper to take a keyman insurance than a private life insurance for that amount
Though if its just the family, can you just do life insurance instead?
I guess you could survive...
i have a private one also, but that's just to cover the house basically
and be alive but not producing
makes sense, key man I would expect to be better for most stuff
since your work = who you are for the most part
as that'd be stupidly expensive
at least here
im trying to figure out a way to override the compression with user code
incase people want to do weird stuff (they always do)
make a standardized compression interface that your compression uses as well?
I don't know your entire structure... so really I got nothing ๐
well so
and nothing I suggest you wont have already though of LOL
so one of the reasons i want to use code generation
is that i can generate serializers like this
public static void Serialize(void* data, DirtyInfo info, Connection connection, BitStream stream) {
// Transform
var transform = GetTransform(data);
if (info.IsDirty(transform->_PositionId)) {
stream.WriteVector3(Transform->Position);
}
if (info.IsDirty(transform->_RotationId)) {
stream.WriteQuaternion(Transform->Rotation);
}
// Inventory
// ... snip
}
and that is so much more efficient
than having some generic loop which checks property types, etc. calls into virtual methods, etc.
yeah, clearly
my old serializer code, which is written in C# which uses the structure form the character entity i showed before
the core loop is this
// write properties into packet
while (_propertyHeap.Count > 0 && written.Count < _propertyPacketCountMax) {
// start position
var s = packet.GetHandle();
// peek property
var p = _propertyHeap.PeekValue();
// gotta hold
Assert.Check(p.Index <= _propertyIndexMax);
// write property index
packet.WriteInt32(p.Index, _propertyIndexBits);
// write property data
_properties[p.Index].SendProperty(connection, entity, entity.Values, packet);
if (packet.Overflow) {
// restore handle (we could not write this property)
packet.RestoreHandle(s);
// break out and dont attempt to write anything else
break;
}
else {
// pop it
_propertyHeap.Pop();
// clear from dirty set
link.Dirty.Clear(p.Index);
// clear out priority
link.Priority[p.Index] = 0;
// add to written list
written.Add(p);
}
}
yeah, that looks more like what I am used to
but the problem is that there's a ton of just... shitty housekeeping to do
because i dont know the properties, etc.
You are trying to sort how to introduce user code/custom serialization into your codegen?
yes
because i've been doing this long enough that i know people are going to want to do weird shit
that i didnt think of
and providing a way for them to do that is necessary
Can it just slip a callback method into that serialize method if they flag it as custom?
even if it's just custom compression
or they want to serialize stuff themselves completely
for various things
yeah, they probably will
also with my new method of doing delta compression
i realized that i can just write the data for an entity once
I recall with bolt that being like a question I had for you 10 mins into it
and then memcpy it to all connections that need the same update for the same entity
so i only need to actually serialize once (in most cases)
Was that not already the case?
no
memcopy requires byte alignment rather than bit correct?
correct, but that can be solved
yeah, the bookends just need some masking is all if I am reading you
even if i need to manually loop over it to insert the bytes, it's still faster than re-doing the serialization by hand
as i can copy it in 8 byte blocks
still slower with everything shifted though no?
yeah, thats what I recall from making my ulong[] parts of my bitstream
not using memcopy, but same concept
its about 2.5x faster using ulong[] than byte[], but even then compared to re-running the whole serialize method
just being able to go into one method, copy all data
is going to beat the serialization even if its in byte[] form
even if i cant use memcpy due to wanting bit instead of byte alignment
I was assuming you were doing that already, wasn't that the point of the two step process?
no all my old libs have done individual serialize calls for each entity for each connection
as they had no easy way of saying "this entity has the exact same update for client a and b"
but the new system does
ahh, that part I missed, the ability to identify entire connections as getting the same everything as another
yeah
seems like that is getting pretty deep into edge cases though?
i mean they needing the same update for a specific entity , not the whole world
i suppose for people that want to overwrite the serializer i could do this (C#):
public static class MyCustomSerializer {
public static void Vector3(Entity* entity, Vector3 position, Connection connection, BitStream stream) {
... write custom serialier code ...
}
}
and then in the DSL:
Vector3<MyCustomSerializer.Vector3> Position;
}```
and how delta frames (culled data frames, not delta like you are talking) get sorted when you aren't sending everything
yeah that'd work
If the code for like Vector3Property is exposed to them, I would think they would make their own variations with their own names?
the properties wont exist, that was the old system
Ooh
I'm not much help here, would really have to use the whole system as a developer to really give you constructive feedback on usability
yeah for sure, im just throwing around ideas
I would just think of it from the workflow perspective is all... like if they were using your system as you designed it.. and then decided they wanted to custom serialize something.... what code would they be looking at already
that's what im trying to figure out, exactly what they would do in the case they want to serialize something completely bespoke
like a fucking Dictionary<String, String> or something
My normal expectation would be I would derive from a class of yours with T being Dictionary<S,S> and fill in the overrides, but that isn't what you are doing
no, also my core network state system only supports primitive types, or structs of primitive types
since it will exist in native memory only
i cant have C# reference types in it
people serializing dicts over the network need a beating anyway ๐
For sure, the Dict example is a good edge case
if you can make that intuitive, you have a winner
Though really not even intuitive, since you are dealing with advanced users there... just doable at all would be good
i'm thinking if you need to do something like that it's gonna be streamed on the side using a separate data channel
I assume people have access to the network stream?
like before or after all of your auto stuff
not decided that yet, and it's not really needed to write into the main stream
As long as raw stream access exists in some form... everything is possible
it would be more like "okey i want to send this big update of string dictionary to this client"
and then it streams that over time to the user
ahh, yeah thats should not be part of the firehose
which would be completely reliable
since dealing with resends, etc. is too annoying in this case
Along those lines, a dict sync really doesn't seem like it would belong on an unreliable entity ever
and then you alter the dictionary before it finishes sending 
@cosmic atlas well it'd be serialized in one go ๐
yea but then having to resend what's changed and track that
don't mind me, just musing as I read lol
yeah there's tons of edge cases that needs handling
im just thinking of the general architecture
of how to deal with when people want to send 'larger' updates
of some random crap binary data
which doesn't fit on the regular game state
I assume there is a concept of ontick and offtick for that kind of stuff?
like loading a level
has no concept of tick
correct, there's the game state goes in sync with the tick
and then whatever-else-crap-you-need which is ... whenever it gets sent/arrives
Can events be flagged that way as well? A tick event/trigger vs just some dumb stuff you want to broadcast?
the events are most likely going to be entities also
as they are 'one shot' entities basically
Seems like just a parallel messaging system for async stuff would cover the rest
ye
the parallel channel would be 100% reliable+ordered
just to simplify for the user, so you can send like "Add this string to this entities string,string dict"
with some metering system that breaks sends up into reasonable bytes per second and such
yes
as this data is not considered time critical, it's fine with full reliable/resend crap
lol
also all of this is being done in a way so that I can squeeze as much single thread performance as possible out of it
i dont need multi core stuff, i will just have 2 threads
unity main thread, and background thread which does delta compression + socket plumbing
compression being the entity self-serializaiton I assume?
ye
Can the stitching also reside on the second thread?
for lack of knowing the real term
packing up all of the connection specific sends
yes
though I guess that would result in a lot of buffers
rather than one reusable in the main thread
it needs to for the server at least, for performance reasons
What do you call the process of the server creating each byte[] for each client?
That I am calling stitching atm
for lack of a term
vs entity serializtion
entity serializes itself
yes
packet collects them
of sorts, this new system probably will work like that
I've labed it as Stitch for now so I don't have a bunch of methods called Serialize
the reason i want to use native memory is that i will have duplicate buffers of the networked state, i can just memcpy a few buffers from the main thread and send to the background thread and the background thread has a completely isolated copy of the game state, for each tick
so I can tell the internal methods for serialization on the entity from the writer to the conn.... but its not a good name
so server will say: "tick 100 done, copy it to background thread which takes care of sending it to clients"
ahh, gotcha
and then server can keep mutating his state for tick 101
its not breaking that into threads, its just one giant send to all conn thread
well it's basically a few memcpy calls to duplicate the whole world state, which it hands of to background thread
I was thinking parallel threads for each conn, but yea... absurd overkill
yeah, hadn't considered copying over the whole connection serialization process... seemed like that would be hefty if there were a lot of entities
it's not, because they are all laid out in a few manually allocated blocks
it takes like 0.001ms to copy all of it, it's nothing
Yeah, I forget you live in the world of aggressive memory management
imagine you have a few byte[] arrays for varying entity types, etc. and you split them up with various indexes+length into the array is each entity, so then to copy the whole world state all you need to do is duplicate the arrays
by copying to another array of the same size
thats very ECS like
Hmm, actually thats not as crazy as I was thinking
you are't aligning all of the fields that make up the entire world state.... ? You are just aligning all of the byte[] buffers used for the entity serialization?
ye
ahh, smart and gives you some ECS like benefit without making an unreadable mess
Though, how do you align buffers like that when entities are created over time, like as players join and such?
Or are they not all aligned into one giant block like that?
I am thinking I am totally reading more into what you said than what it actually is doing
so it uses buffers that are sized and chunked based on entity sizes basically
rounded to some common values
Ah, I think I just got it
it wastes a bit of memory but that's fine
but say all entities smaller than 64 bytes will be in one block of memory, all smaller than 256 will be in one, etc.
Do you pool the buffers themselves then?
rather than have each entity own a byte[] of its own?
the ones that get sent to the background thread? yes
it's a few massive buffers which are split up between entities of the same size
or similar sizes
rather
interesting
so i'll have maybe like 5-6 different size buffers
of like 128 bytes, 512 bytes, 1kb and 4kb maybe
or w/e sizes the entities and up as
makes me want to rethink the way I am doing it, which is each entity has its own byte[]... that really should be pooled or should write into a larger buffer and use pointers
thing is the entities dont write into these buffers, the entities themself LIVE in this buffer
Doesn't that make your unserialized/uncompressed fields intermingle with the serialized data though?
and get in the way of your memcopy?
no, the serialized data is kept in other buffers
ah ok, was mostly talking abou those buffers
and what they are, how they are allocated, and if/how they get aligned if they even do
they are byte* buffers allocated from malloc they can also be splited/chunked like i talked about
but thats less of an issue generally
since they will only live on the background thread anyway, it can pool those itself, etc.
Leads to more questions, but they aren't important ๐
Overall, super intelligent design you have going there
yeah the serialization buffers are less important
they can be handled in a myriad of different ways, that's not complicated, can just do regular ulong[] for those allocated separately
it doesnt affect performance much
At this point I am just implementing the entire concept of pre serialization and unique sends to each connection... NST didn't have that. So just trying to make it so at some point I can modify it to throw the serialization process onto another jobs thread.
i dont see how thats possible when you depend on unitys transforms, etc
as you cant access any unity stuff
from a background thread
at all
I would have to snapshot it first yeah
Not tackling that yet, or maybe ever
just wanted to make it not a massive refactor for myself if I try, so just planning ahead a little
My assets only ever will be for networking newbs who want drag and drop. That kind of performance is probably not in the cards
At this point, I just want to add per connection unique sends
yeah, i dont see you needing that type of performance
and will be done with that
#1 goal right now though is just making a solid tick engine
sounds like a good goal
Hey, is photon pun a good choice for mp in the vein of clash royale?
Oh well, ping me if anyone knows. It'll be super helpful to me thanks.
clash royale is implemented using a lockstep model
you can see it in how they bake the command delay into unit spawning
Nah, i just mean the matchmaking itself is similar to the one in clash royale
a public room with two player, the game itself is a fast paced arcade-y kinda thing
I doubt lockstep would work for that
Sorry for not being exactly clear on that
But what i need is basically just easy skill based matchmaking with real-time input, and it seems photon pun fits the bill, but i just need to know if there are better alternatives
you should generally treat matchmaking as a separate concept/appliance from your core networking implementation
Okay, noted. I am new at this networking stuff
So, is photon pun latency good enough for real time matches with only two players?
I read that it doesn't scale very well, but i only need 2 players in any room at a time
But that may change
So, I'm having confusion on how to setup something to sync positions between an obj on each client. There are two issues I'm running into.
For one, normally if I was to spawn something in, like the players, or a bullet or something, I can send a message to the server to spawn that for all clients and give it the same unique id on each client.
However, if its just a box that exists in the world by default, I cant do that? I can have the boxes request a unique id, but then theyll just be different unique ids cause theyre considered different objs from each client. Any idea on the best way to deal with this? Manually assigning ids doesnt seem very sustainable or good practice.
Aside from that this is how I was currently trying to sync the position https://hastebin.com/ajofuminiq.cs and it doesnt work very well. its laggy and glitchy, and I'm not sure the best way to go about doing this.
@warm jungle frame interpolation for the latter
not sure what you mean about the box that exists in the world by default. If it's part of the scene, then it should have an ID that can sync when clients connect. it's server owned.
I talked with someone on GDL about it and got an idea of what to do for it
for the id
Im not sure what you mean for the frame interpolation - i was under the impression I'm already doing that? I'm doing a MoveTowards on the syncing
essentially instead of rendering each new update. you replay the game a frame behind, and interpolate from the last position to the next one. this way you can still be interpolating while waiting for the next frame to come from the server
I.. don't really understand and don't get why this would really help? If youre just playing the frames but just a frame behind im not sure how youd exactly set that up, or how it would help
because it wouldnt be jittering, you're smoothing between two server approved frames
But am I not already doing this? The client moves, sends an update to the server, the server sends that new position to the client, the client interpolates towards that new point
is the server sending the position back to the client?
and your just setting that?
frame interpolation is for rendering other clients (proxies) smoothly
if you want to respond to updates from the server for your own client position, that is client side prediction
when the client gets an update from the server of his position, that's from some time behind. so you need to accept that, and then replay batched events
When the client moves, it sends its position to the server.
The server then sends that position out to all the clients.
All of those clients set those values to another variable, and then in update i have a transform.position = MoveTowards(transform.position, thatNewPos, Time.deltaTime * speed)
so when you say "sends that position out to all clients", is that including the client that sent it?
yes
Well it shouldnt tho, cause the original client that sent it would already be in that position right? so it would interpolate.. toward where its already at, aka go nowhere
no, cause lag exists
by the time i get the message back from the server, my local instance has moved forward
this is where client side prediction comes into play
Okay, so. Like in that it refers to input right? Player presses a button, and you gotta get all the buttons in the right order to be in the right position.
But in this case I'm not dealing with button presses, but only position updates, so I dont even really care about the entire back catalog of where ive been, just where i should be now
the concept is the same
either by syncing inputs, or by syncing position
by the time the server responds to the originating client with the 'approved / updated' position. the client has already moved past that server tick
you could have the controller client entirely ignore server updates for his entity
Yeah, I thought about that, but I'm not sure how I can detect if this specific client is the one who sent the message
and yeah, so if the server is always late sending back the new position, how can that be fixed or helped? If its always behind it never helps unless i just ignore the client who sent
Also I assume I also want to have objs that are moving due to the server update be ignored, but idk how to detect if its moving based on the server updating it, or if its from something else moving it
you normally would keep a buffer of past positions, and if they send a state update at a certain server frame that doesnt align with your local clients registry, then you know you have diverged from the server and need to reconcile
and you should definitely be able to tell which client is sending you position updates
Also security wise trusting a client is bad unless you don't care about that in your case
The client could just move however it wants or even teleport
yep, never trust the client
@warm jungle what's the issues you're having
@warm jungle look at litenetlib Manager, some guy made and shared it. Does a lot of the stuff you are trying to figure out. Can see how he did it.
https://www.pcgamesn.com/steam-dedicated-servers
Highlights:
Relay servers provided by Valve, free of charge for any game released on Steam (opt-in, price is essentially included in the 30% tax). Developers can either proxy to their own game servers or use Valve-provided dedicated ones (only for Valve-approved developers at the moment).
Servers are "hidden" from the outside world, players can no longer know their IPs and connect directly
Free of charge DDoS protection included as well
All connections are routed through Valve's backbone, which provides lower pings and higher speeds and throughput
Platform-independent account identity support (Xbox Live, Steam, PSN, etc.)
Beta only at the moment. Developers should not use this in the production environment until all the functionality is shipped
with that, this is my main concern Clearly, as with all Steam updates, it comes on Valve time.
still haven't seen Source 2 SDK they promoted years ago being free for developers who at least release on steam
so, without any library/engine SDK on my hands, they can talk as much as they want but it will not change anything ๐
@weak plinth where did you get those highlights from? the article you linked didn't contain all that info
reddit ny bad
I found the reddit thread, no source links there either
yes, that's the one I'm reading, and that's commenting the same link
but the post that put those there doesn't tell where the info is from, so it doesn't look credible at all
like, the part where relay servers provided by valve free of charge part, or the platform independent thing
the article itself links this as the only source https://www.resetera.com/threads/valves-new-multiplayer-api-in-public-beta-vac-for-everyone-dedicated-servers-ip-hiding.96853/
IN BETA We're working on shipping this to the Steam Client and making it available in the Steamworks SDK right now. If you want early access, we have a standalone version of the library you can link with. You can also try out the opensource version.
String encryption and au...
the the free of charge is doubtful
but that's not really going into business details
that person have multiple threads for it even ๐
but yeah, I call BS
I mean, if valve is looking to compete without lowering it's percentage, this is a way to do it
Doesn't seem that far our to me
are the others like discord & epic offering much outside of a place to stick your game? i figured steam had them beat in services pretty badly out of the gate
sure, but hosting dedicated itself couldn't still be totally free or included on that 30%, it would get crazy expensive on some games for them
@weak plinth bit offtopic here but sure, there are other stores too, gog, humblebundle, itch all accept indies
yeah, was just moreso commenting on the fact i don't think they need this to stay competitive even and keep their % the same
atm, there's no real threat
any suggestions on an approach to out of game notifications? initially i was going to do long-polling, but i'm thinking of using websockets for friend invites, party updates, etc. any good websocket libs i could use that you know of? (looking at this: http://sta.github.io/websocket-sharp/)
@weak plinth for which platform?
There's notification APIs for all of them now adays
android / ios is what i'd like to build for if that's what you mean
But it's usually platform specific
Yes, they both have notification APis don't they?
Use those
oh sorry, by out of game i meant like the menu scene, social scene, stuff like that
basically when they're not connected to an online game
http://www.hatebin.com/zftrbecinf Nothing I would rather be doing on a Saturday morning than be adding a zillion callbacks that should have already been there to a dead networking library.
I find pretty much all networking libraries die because it's a fun problem to start but one that never runs out of problems.
Those that survive must be backed by cash or open source.
I guess a solution like Quantum is to be both the problem and the answer. The internet matters less in this case ๐
UNet didn't though fail for much more of a reason than Unity failed to finish and continue to support its growth. I'm glad to see it die though because all of these HLAPIs are based on around some really bad networking concepts (RPCs and Syncvars) and really get developers going down bad paths.
Quantum and Bolt (both being fholms work) are the only two that actually ground up respect AAA methods for networking. They are closed, but there is nothing stopping these open libraries from embracing the same principles... they just don't for whatever reason.
All of the HLAPIs for networking seem to go straight for abstractions with RPCs and syncvars with little or no consideration for the actual important stuff, which is the tick-based syncing up of all of the clients and server, and the bitpacking that you generally do on top of those tics.
UNet was a result of the company having no funding for it and no management.
Now I'm pretty sure there's a decent amount of support behind it, still it's left me burned once so I'll be approaching with caution this time round.
It's strange really that a big company like unity wouldn't put maximum resources behind something, but I guess finding the right staff is also a hard job even with endless cash.
shrugs - it is all guesswork we shouldn't have to even discuss but a failure makes that get discussed because unity's failure is a customer failing too
If Unity tried to maintain an internal game like Epic does with their library, I suspect the engine would have a lot less of this headscratchers built into it.
They are though
for years, Unity's made small internal games to test stuff, and more recently it's been big tech demos and more recently still an entire FPS networked game that you can get from github
@jade glacier the open unet derivatives don't use those techniques because they all want to have this mega generic library which can do everything but also sucks at everything except for the simplest games
Like the way you network different genres of games is massively different
Not just deterministic vs not, but the requirements are just different within one genre like fps/tps where there's widely different implementations used depending on the specific game, etc
Like the way fortnite and cs are networked is just different at it's core even
@compact bramble big difference between small internal games and public facing massive hits like fortnite, unreal tournament etc
I get that in the big scheme of things, but they didn't even make an effort to ground up build layers that branch into ANY trees that are useful.
Nope, because those things are really hard to get right
@graceful zephyr That fact that I and every other dude in these net channels are making tick engine and input syncing says something about that layer ... just missing....
That layer alone branches into 90% of the next layers
You can easily build an architecture which you realize half way through just doesn't work
yeah of course
I think they have been slow to realize that though, because they werent making ANY actual game with UNET
it would have reversed course early on had anyone building it been making it for any type of game
It seems like someone got really excited about weaving all kinds of cool stuff like RPCs and Syncvars...
without asking if they were even the right path
They are 2 layers above what needed to be made first
Anyone with half decent experience in networking could've looked at unet hlapi and said it was a dead end
Literally first thing I said when I looked into the dlls
The weaving was cool, but it was icing on bad cake
Meh, weaving stuff is at best... Almost useful
I wasn't even experienced and 2 weeks in I was trying to get out from under RPCs and Syncvars... not sure how that got designed by someone obviously competent as they were
What is scary is PUN and Forge seem to repeat the same thing
PUN is just a different target tho
Lots of rpc and syncing... but still no foundation in syncing up clients into a common tick
Yeah, but PUN can easily escape this mess. I suspect in fact it could even do a really great job of it
that relay server could be a beast, rather than a dumb mirror
I know why it is what it is
And am not saying anyone did anything wrong
Just that Unity networking is in a sad state because everyone building these things but you seems to understand the fundamental backbone of networking
Quantum and Bolt are still the only two engines I can name that treat the tick like a AAA title would and should
And that bitpack like they should
I feel like a broken record with this stuff, but its a wall that is just right there in the middle of the networking room
but AAA would also never work on closed source libraries where you can't even fix things when they break :p
My issue with UNET HLAPI isn't even that its closed, its just that it skips right over packing states and inputs into ticks... and goes right to messaging
Its like making games using email as the transport LOL
HLAPI though was actually open, though lot of good that really did.
Anyway, to put a pin in my rant... anyone making MLAPI or HLAPI level networking stuff, really need to spend a little time coming up with some good generic tick engines and tick based input/state syncs... or they are just making garbage... imo
@jade glacier quantum doesn't do a lot of actually networking tho
It just sends input but sure
It does a different thing with the ticks
yes sure
but it still must have a rock solid means of getting all of the clients on the same clock and lining things up
Yes
Anyway, not looking to poop on the channel with my ranting over and over about that
Gotta put shitpants to bed
Youre going to need a new name for him once he gets potty trained
I assume you don't say it in English
Oldest is still called nugget because that's the nickname I gave him
Pooperhossen or something I assume ๐
Can't have this one being called shitpants when he's 5
We do say it in English
Me and the wife talk English
With each other
Ah yeah, I forget that swedish wasn't her primary language
Ye, so no he's shitpants, verbatim
Its bizarre being in Portugal, hearing all kinds of accents but most speaking English, since any mixed group that is the default.
I'm always like... why are you speaking English??
Because that one friend.
Kind of a shame English became the dominant language... its not the prettiest or easiest
Yeah, your typing is better than most Americans
I prefer it over swedish
I'm working on Spanish, that seems like the ideal second language after English
It's gotten to the point where my English is better than my swedish and I find myself thinking in English and using English grammar rules when speaking swedish
Talk English at home, work from home and all work is in English, all tv shows are in English, type in English all day etc
Ah ;yeah, you are definitely becoming native English
Anyway, didnt mean to keep you from shitpants
Quick
Yes it is 9 PM here, way past his bedtime
So he was out in a few minutes
Now he is sleeping on my chest
So you put him to bed... on your chest?
๐
Should've been more clear ;p
Just it takes me tops 10 mins to do it if he gets to fall asleep on me, takes like an hour if it's in the crib by himself
baby science
So I walk around in a circle with him and talk crap on discord on my phone
I started on my new idea we talked about a few days back
Just prototyping some stuff, trying to figure out the implementation details
How many days to get a basic enough test happening to see how its working? Though seems like you can predict most of the results.
I'm still trying to make sense of the memory footprint, seems like with a large number of netobjects and a high player count, that would really start to add up?
It's not more than any other solution, it's just that you don't think about the memory when dealing with classes and monobehaviour
The memory footprint is an absolute non issue
True, its already a bloated giant with those anyway
It'll take me.. IDK two weeks maybe for a first prototype
Maybe less since I already figured out a lot of the details in my earlier prototyping, but maybe more if I run into some big issue I have not forseen
Looking forward to hearing
Going to hammer away at it tonight
Soon as I can get out from under mr shitpants
It may happen really quickly
Mostly just dealing with memory layout stuff atm
Like how to structure the data in a way that gives me the least overhead when passing it on to the background thread
And restructuring of the socket hookup as I need to move some stuff around
Due to how the new background serializer will work
all a paygrade above me for sure
We'll see how it goes, still a few question marks to figure out
Your transport is going to be a beast with this many use cases having been applied to it
But nothing too big I'm worried about
The transport layer is as simple as possible
No reliability, only ack/nack
What's your next layer above that called then? I assume that manages the order and reliability?
No abstraction of it, interesting
That's split into two main pieces
The background thread and the unity main thread stuff
conceptually tidy
The socket library itself has an abstraction for plugging in different subsystems like steam, .net sockets, photon cloud, etc
I'm fuzzy on the distinction between the transport and the sockets
Game => net lib main thread => net lib bg thread => transport => socket adapter
Ahh, ok
I never touch the transport and socket - so they were just the same thing to me
"The mailbox" ๐
Difference between transport and socket is a hairline one, but for me the socket is the raw thing I call send on to put stuff on the wire, the transport is the connection abstraction, ack/nack ontop
I see the value of keeping them separate if libraries like Steam and Photon don't make any transport level choices for you
I just assumed their api was that entire pipe
the only thing my transport layer asks of the socket abstraction is two things:
- provide me with some way to identify who im sending/receiving stuff to (ip address, steam id, etc.)
- provide me a way to send unreliable data to them
and basically every socket api in existance does those two things, .net sockets, steam, xbox, psn, switch, etc
they all allow you to do those two things
and then i build the rest of it myself on top
so it can run on any socket layer
if they provide more features, fine... but i dont use those
and yes im on my laptop now as you can tell by my typing speed ๐
I'm jealous of that nice clean abstraction... as I sit here modifying my adapters from UNET to work with PUN.... not at all clean or tidy
You are unleashed
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NetCode.Sockets {
public abstract class SocketImplementation {
public Peer Peer { get; internal set; }
public abstract SocketEndPoint EndPoint { get; }
public abstract Boolean Bound { get; }
public abstract Boolean SupportsPollTimeout { get; }
public abstract Boolean IsEndPointCompatible(SocketEndPoint endpoint);
public abstract void Bind(SocketEndPoint endpoint);
public abstract Boolean Poll(Int32 timeout);
public abstract Int32 Send(Byte[] buffer, Int32 length, SocketEndPoint endpoint);
public abstract Int32 Recv(Byte[] buffer, Int32 length, out SocketEndPoint endpoint);
}
}
that is my base class for the socket abstraction
Nice and short
its obviously modelled on classic raw sockets
but its similar to the systems i've built in the past and it works well, it can be adapted to any networking api ive come across
atm SocketEndPoint is a class, which i want to turn into a struct instead
but thats fine for now doesnt matter
not a pooled class candidate?
nope, and it doenst need to be a class either
i was just lazy as its simpler to do it with a class
ah
its basically
i can either just implement the core idea of how it should work and use plain .net sockets
or i could build the real real thing with needs me to do a whole native plugin and interface with sockets in C
just to get rid of one allocation point during development
which is just... meh, doesnt matter for now
3 hours vs 3 days of work sort of thing
//TODO:
ye
Do you recall if PUN has delegate callbacks for network events, or just the interface methods? I need to make use of callbacks in a static class, but not sure thats doable @graceful zephyr
there is a acallback yes
hell if I can seem to locate them
The derived base class methods I know, and the interface I know... but not finding delegates
its on PhotonNetwork.peer or something
PhotonNetwork.OnEventCall
at least in pun 1.x
digging through the PUN2 migration notes now
PhotonNetwork.OnEventCall is gone. You have two options: use PhotonNetwork.NetworkingClient.EventReceived(EventData) instead. use IOnEventCallback.OnEvent(EventData).
{
PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
}
private static void OnEvent(EventData data)
{
}```
Not puking red at me, so looks like the right track. Thanks @graceful zephyr
np
The docs seem to indicate its a callback like the interface ones, but it only seems to fire for network messages, and not events like OnConnect... oh well. Going to have to change my static to a singleton, which is annoying.
morning o/
Werd
hey
Bad networking
Wasnt able to find a way to get system callbacks with PUN, so just resorted to making my static adapter class into not static, instead a non-MB Singleton... Just so I could put their callback interfaces on it. @graceful zephyr
Annoying, but not the end of the world
And good morning
what do you mean system callbacks?
you mean for connected/diconnected/etc ?
good morning to you too o/
mornin
@graceful zephyr joined room, the whole list of pun events
@jade glacier ah yeah thats only doable with the regular callback interface
@cosmic atlas morning o/
adding a "Refresh Games" button while contemplating if I should just implement some sort of auto matchmaking system ;_;
I do have my tick engine and input syncs working with PUN now so the surgery was a success
nice
@jade glacier i wanna discuss your speed up/slow down tick system for the clients at some point, did you test it with different ping conditions/simulated lag, etc ?
on that topic: you know photon has a builtin lag simulator right?
`Photon Lag Simulation Gui' script
I have to choose how to deal with BIG CHANGES in latency. Right now it triggers a hard realignment
It's not a realistic scenerio...
i would have it use the same system for everything, it gets too messy otherwise
But I want it to be able to survive me turning on 300ms of delay.. and removing it
Right now that cause packets to get fully discarded... Since a rapid catch-up with physx isn't reasonable
yeah it is
I didn't, I use a third party net sister
Distressor
I have to think about how playing with uses time to aggressively will break other things
Though realistically that should never happen
On the flip side... It will extrapolate a bunch... But that's easy
what i would do is that if you want to use the tick system and all of that with your system, basically it's implicit that they need to hand over control of fixed timesteps to your library
It's just on the .. what if I get a crap ton of updates at once
@jade glacier have you seen the overwatch videos on how they deal with this?
Have not, but should so I'm not reinventing this wheel
The system isn't deterministic, so I can toss excessive updates flooding in.. but as long as I am spending the time on this, figure I may as well try to do it so it doesn't do that, and keep it future deterministic friendly
Ok, mobile typing is failing me here
Laptop time
If you want to make it deterministic then running several physics steps to catch up is required
I think you are right about taking over the timestep completely, and having devs make any changes to it through my property
so I can just manhandle the fixedTimeStep duration without fighting them
They really being me when I finally make something with my own networking code
bolt takes full control over the fixed timesteps
I have no idea how often anyone even would want to tinker with the fixedupdate rate in a networked game, but as long as I am writing this I should write in handling for it
and dont evne let the user fuck with it
and it works fin
it will literally override it every frame to make sure its the right value
Right now they could try to change it, but every tick I would just be overwriting their changes
ye
So I could make a property that changes the target rate
if they want to change the timestep
The main question right now is how and if to really make this make sense in PUN
that has to be done from the server
what we do in quantum is that with every update we send out the current timescale of the server for each tick essentially
server auth in PUN isn't really a great idea. I have it doing it... but not sure there is a real point to it
hey guys ๐ธ
o/ yo
All of the players can and generally do talk directly to one another, so nudging to keep locked up with the server does nothing for client to client
morning
or eve
yeah im having an issue with bad latency testing as well
@jade glacier its morning (timezonesarealie)
If its morning in Britain... its morning everywhere.
hosting both my master and game server on my poop adsl wifi at home and testing client thru my laptop on mobile data hotspot for a realistically horrendous connection xD
๐
its 7:50 pm here
haha ๐
That was how I originally tested my net code for mobile.... I would host on my wifi laptop on home cable... and connect my phones over mobile carriers @stuck void Gave a pretty good realistic case of lag and jitter
seems I can have my attacks miss-but-not-miss with a bad connection, so I'm gonna have to build a system to sync em up at the very least so it doesnt look so out of sync visually
What kind of game is it, and what are you syncing stuff up with?
cant do much about actually missing or not missing since its fully server auth
but I'll need something to at least let the client visually know so I dont have a projectile whoosing past but they still take damage
ahh, server auth with user inputs... so some inputs are getting lost?
not quite, I've got an almost-reliable system on top of udp, but the delay in the client receiving the attack message coupled with the input delay can result in close calls that arent in sync
That's pretty common without going deterministic, since the player in his world is actually in a future position relative to the network objects being shown to him
So rockets flying by but actually hitting you in the server report is a pretty common artifact
i spent the weekend designing the memory model for my new networking system to shuffle all the serialization to a background thread, it's looking like it will work out
yeah, I did delay the server attack slightly based on the lowest average latency across all players in the area which helped a fair bit, but its still possible to consistently make them go out of sync with close dodges
well i spent the weekends with the kids, spent the evenings working on the netcode :p
@graceful zephyr Are/Have you considered proposing this entire system to the guys at Exit? Might get backing to finish it out as a bolt replacement?
just want to do it as a hobby thing for now, no idea how to monetize it later
i hate having the pressure of having to deliver something when im inventing new stuff
im thinking I'll just keep track of abilities and projectiles on a list like I do with enemies and players, and let the server tell the client whether or not it hit, so at worst even if it slips by a little bit it'll still play its impact animation and disappear on the client
It will be a quick turnaround if you decide to once you have all of these parts made
like this is probably the 10th iteration of my new system, and i think i finally got it in place
started in late 2017 so :p
Its going to be beastly when you finish it, though these things are never really done... there is always some new tech idea that could be added
You can also consider letting some owner stuff get passed through the server before it becomes server authority states
me or ada?
like enemy weapon fire you might be able to have passed along immediately @stuck void
for the cosmetics of it
ah
Some risk there, but you can shave the server buffer out of the picture with a little client to client trust on the cosmetics