You would have to decide whether you want the server or clients to manage the creation of cars. Here are some options for this scenario:
1) [This is the most authoritative way] The server manages the creation and translation of cars. The server keeps track of player positions and spawns cars near them and removes cars that are far away. The server then sends the position, type, rotation, etc. data to the clients.
2) [This is the least authoritative way] The clients manage the creation and translation of cars. A client creates cars near itself and then tells the server to inform the other clients that a car has been created. When a car is far from the client, the client tells the server to tell the other clients that a car has been removed. Extra logic could be added so that clients too far away from the new car don't receive the creation message.
With client-server networking you must choose whether you want certain logic to be done on the client-side or the server-side. Typically games choose a middle-ground where the client makes predictions about what the server is going to do, but the server has the final say for whether other clients see that happen.
Here is some pseudo-code for one of the simplest client-server networking implementations. This code deals with players, but the same concept would apply to cars. Again, this is just one way of many. This implementation below has several flaws, but hopefully it makes sense.
// CLIENT
let players = [];
let loop = new GameLoop(60);
let conn = new Connection(127.0.0.1:8080, "tcp");
conn.onMessage(function(message) {
// go through all sent players from server
for (player in message.players) {
// create new players
if (!players[player.id]) players.add(new Player());
// set the positions from the server
players[player.id].position = player.position;
}
});
loop.onTick(function() {
// gather input
let input = {
moveLeft: Engine.keyDown("a"),
moveForward: Engine.keyDown("w"),
...
};
// send input
conn.send(input);
});
// SERVER
let players = [];
let loop = new GameLoop(60);
let server = new ConnectionReceiver(8080, "tcp");
server.onConnect(function(conn) {
// recognize new player joined
players.add(new ServerPlayer(conn));
});
server.onInputMessage(function(input, id) {
players[id].useInput(input); // makes changes to stored server data
});
loop.onTick(function() {
// send players to clients
for (player in players) {
player.conn.send({
players
});
}
});