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.