Pet System Networking

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve?
    Alright so I need to achieve this:
  • Pets are equipped, unequipped by the players
  • All pet creation and movement is handled by clients
  • Each pet should be uniquely identifiable because server might tell client “Pet X is interactive with the environment” or “Pet X picked up Food Y”. So both the client and server should know what Pet X is

Questions:

  • What I’m basically searching for is the best type of networking I should use for this. (Also need players who join the server late to be able to know what they need to display)
  • How should I store the data (How do I uniquely identify each pet, it’s owner, etc)

I don’t want an entire script or a system, I just want to learn about logics of it. Even a link to a good documentary would help. Thank you!

Great, a networking issue. Alright, here we go. It’s not going to be fun.

There are many different ways you could go about this. Personally, I would suggest you learn what an ECS is and use it. ECS will allow you to construct entities with data and replicate them. But if you don’t want to rewrite your codebase or rewire your brain, then we can stick to simple tables/OOP.

At the end of the day, either ECS or OOP/Tables, a pet is effectively a table:
pet = { name, type, color, rarity, position }

I personally believe the best way to do this is by assigning each pet an ID. Then, you can let the client know to create a pet at ID say 200 and value { “bob”, “cat”, Color.RED, “gold”, 0,0,2 }. When you need the server to update something, the server can tell all clients that the pet at id 200 actually is called “bobbie”. Then, clean up pets by telling the clients to remove the pet at id 200.

Without diving into ECS too much, if you decide to use ECS, the E part is called “entity”, effectively just an ID. This simplifies this part of it.

If a player joins late, loop through every pet that is active and tell the player to create the ID with the value.

You can store the data however you want. If you want to be super simple:

array of pets = { [200] = { “bob”, “cat”, Color.RED, “gold”, 0,0,2 }, [182] = { “bobbie”, “dog”, Color.BLUE, “common”, 3,0,1 }

What I want to drive home is to keep server authoritative. The server has the main say in everything, the client MIRRORs the server’s IDs and responds to it.

Pet creation should NOT be handled by clients. When the client wants to equip/unequip a pet, send a remote to the server REQUESTING that to happen. The server decides to allow it or not allow it, and creates the new pet with a new ID.

If you want pet movement to be handled on client (which IS a good idea since pets don’t need to be in the exact same place client and server, and you want to save bandwidth), don’t have a position field. Instead, just have a field like “following = Player”. Then, on the client, have your movement code on how the pet should move to be around the player (like a lerp to ±20 studs radius around the player).

You MIGHT run into some issues with serialization but you will be able to figure that out. StreamingEnabled might also throw some hitches so you might want to disable it or figure a way to not replicate any pets outside the streaming radius.

1 Like

Thank you, this is extremely helpful!

Most of my queries have been answered except how exactly should I communicate the changes to the clients? Firing the whole dictionary with pet data seems inefficient, and should I use RemoteEvents? Would these events be enough:

  • InitiatePets(PetData: {[Entity]: {Components}}) - Fires only when a client loads in to tell the client of all existing pets.
  • UpdatePet(Entity, Component, NewValue) - Update the component of an existing entity.
  • UnequipPet(Entity) - Removes the pet.

@Aawesome10001 (Sorry you may have forgot to check the ping)

yep, i forgot.

Okay, so there are a couple things I recommend.
You CAN use remote events with those, yes. If you plan to extend it later, you can switch to an ECS to work for everything, not just pets. But just for pets, yes those can work.

What I would recommend is two things:
When creating a new entity, you should send over the whole dictionary. Since you won’t be doing so many of those per frame, that won’t be much of a problem. Same for an unequipped pet with an ID.

Now, for updatepet, it gets more complicated.
In my game, I send over a table with overrides. For instance, if the entire pet table is:

{
name = “bob”,
health = 2,
following = Aawesome10001
}

I would send the remote event over ONLY with what changed. For instance, thee remote would send:

{ health = 3 }

Then, when received, loop over every key value pair in the received smaller “overrides” table (or if you want to be really fancy and have a nested table you can recursive loop), and then set the real pet as such:

-- assume data is the replicated data
local petEntity = getPet(data.id)
for key, value in pairs(data.overrides)
    petEntity[key] = value
end

If you plan to be sending LOTS of data every frame like position (which again I stress you shouldn’t need to, but you might want to), consider using a networking library. I personally use ByteNet as its pretty easy to use and gives good bandwidth saving.

One final thing: server entity IDs and client entity IDs may be DIFFERENT. if they are different, you need to make sure to always use the server’s entity ID. Thats only for if you’re using an ECS though.

1 Like

I’ve completed this, and its lots more smoother!

Glad to hear it. Good luck on your journey!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.