Synchronization in multiplayer


#21

I think yes. It’s not as difficult as 3d multiplayer.


#22

sim-eth-es example or in general the sim-eth examples. That’s what I try to tell you. really these examples show you the right way.


#23

Also send an sha512 checksum for every position packet just to be sure it doesn’t get corrupt :frog: /s

client-server is fine. Only the local player has an active character control, the others are kinematic rigid bodies, the client computes the inputs and forces for the local player and sends only the position and rotation to the server, the server retrasmit them to the other players. This is the easy part, then you’ll have to do lag compensation.


#24

It’s already done.

How? Examples?

I have problem:

  1. I move 2min with local character - bot at another computer - Is in another place.
    He is behind.

#25

There are examples of the organization of logic. Thank you try to apply. Read


#26

Guys, I’ll put you in the developers in the credits.


#27

:sweat_smile: :sweat_smile: :sweat_smile: :sweat_smile: :sweat_smile: :sweat_smile:

/s is for sarcasm.

Too long for a reply, search it on google, there is a lot of documentation.

No, thx


#28

If only there was an efficient fully working networking example already posted a 100 times…

…and if only it used some library that would make efficient network syncing easy…

…or, you can do everything from scratch the slow way like you are doing it. It’s easy because you will never have to get it perfect because no one will ever play it. Double win.


#29

My speech in the “government”


#30

Okay.

Apparently the problem in my network part: I think it could be the loss of packages or the interpretation is not in that order.

I think about using torrent architecture.

When I look thank you.


#31

This is VERY HEIGHT LEVEL.

I assume. that this is your level of understanding.
I propose you to read next article series, to improve your feeling about multiplayer.
http://www.gabrielgambetta.com/client-server-game-architecture.html

second step - is Paul’s libs. These are well documented multiplayer game starting points.


#32

Thanks i read this yesterday.


#33

If someone is interested in the problems I have encountered:

  1. The difference between low-level libraries on different operating systems.
  2. Different data rates
  3. Different speed of code execution on different computers
  4. Excessive amount of data - do not send the packet if the model has not changed. Message queue overflow.
  5. Messages were played in the wrong order

#34

I’m flabbergasted. Everyone is pointing to a clear, concise, efficient, simple example of a fully working networked game. And you wont even comment on it. It has source code, code comments and more - its the best tutoring of a networked game ever made.

I’ll try pointing as well:


#35

#36

I did about the same thing.

This is a general concept:

  1. The server stores the state of objects between sessions.
  2. incapsulation, polymorphism inheritance,.
  3. client server design templates (session,dao,active,record,state,MVC,etc)

Bottleneck in the system:

  1. Scaling partitioning opportunity
  2. Database - always use Cache
  3. Shut down hook for correct close TCP/UDP/Database.
  4. Disconnect clients when server shut down

if we use p2p - Load is shared between customers

My cache for session (which stored in database)

/*
 * jsock framework https://github.com/nnpa/jsock open source
 * Each line should be prefixed with  * 
 */
package jsock.core;

import java.util.HashMap;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

/**
 * public static class GenericCache<K, V>
 * @author nn
 * @param <K>
 * @param <V>
 */
public class JCache<K, V> {
      
    public static JCache instance;

    public  Map<K, V> cache = new ConcurrentHashMap<K, V>();  

    public static Map<String,Integer> expiries = new ConcurrentHashMap<String,Integer>();

    public static int checkTime = 30000;
    
    public static java.util.Timer timer;
    
    public JCache(){
        
    }
    
    public synchronized void set(K key, V value,int time){  
        
        instance.cache.put(key, value);  
        
        long currentTime = System.currentTimeMillis();
        
        int lifeTime     =   (int) (currentTime + time);
        
        instance.expiries.put((String) key, lifeTime);

    }  
  
     //Generic method  
     public synchronized V get(K key){  
         return cache.get(key);  
     }
     
     /**
     * 
     * @return 
     */
    public static synchronized JCache getInstance() {
        if (instance == null) {
            instance = new JCache();
        }
        return instance;
    }
    
    public static void runTimer(){
        
        instance.timer   =   new java.util.Timer();
        
        instance.timer.schedule(new TimerTask() {
            @Override
            public void run() {
                for (String key : instance.expiries.keySet()) {
                    int time         = instance.expiries.get(key);
                    long currentTime = System.currentTimeMillis();

                    if(time < currentTime){
                        instance.expiries.remove(key);
                        instance.remove(key);
                    }
                }
            }
        },instance.checkTime);
    }
    
    /**
     * remove cache
     * @param key 
     */
    public synchronized void remove(K key){
        instance.cache.remove(key);
        instance.expiries.remove(key);
    }

}

Load user before action in controller:

 public void loadUser(){
        String token    = message.json.get("auth_token").toString();
        
        JCache cache = JCache.getInstance();
        Users obj = (Users) cache.get(token);
        
        
        if(obj == null){
            
            Session session = new Session();
            session.findByToken(token);

            Users user = new Users();
            user.byId(session.user_id);
            
            webUser = user;
            
            int time = 120000;
            
            cache.set(token,user,time);
         
       }else {
            webUser = obj;
       }
    }

#37

So is cheating. It’s great. Plus the game will always run as poorly as the worst connection. Also great.

But anyway, your game is going to be slow and unplayable passing everything is giant oversized JSON packets. So no worries about cheating, I guess.

Seriously, though, a proper peer-to-peer architecture for anything but a toy game is a huge undertaking and you don’t have the skills necessary. Otherwise, it’s only “scalable” in the sense that anybody can run a server. Having thousands of players in a single game isn’t going to work with poorly implemented P2P.


#38

Make p2p easy
Troubles:

  1. cheat - if first client use cheat 2-3 client - сan disagree with him (сomparison of data)

I saved the number of packages 3 times:
The package is not sent if the player has not rolled over.

public void messageKeysToServer(){
                
        if(isChange()){
           
           JSONObject playerJson    = toJson();


           String outMessage        =  "{\"task\":\"JGameTask\",\"user_id\":\""+ JConfig.user_id +"\",\"auth_token\":\""+JConfig.token +"\",\"scenario\":\"send_keys\",\"data\":"+ playerJson.toJSONString() +"}";

           JOutMessages outMessages = new JOutMessages(JConfig.server_ip,outMessage);

           outMessages.insert();

        }
    }

Question what is the alternative json for transferring arrays and objects?


#39

The issue with now doing comparison across several clients is instead of a message stream like this:

Cheating Client --> Server that validates the move --> Other clients with validated safe move

You’d have this.

Cheating Client --> Normal Client 1 --> Validate message and send result to Client 2 --> Receive confirmation
–> Normal Client 2 --> Validate message and send result to Client 1 --> Receive confirmation

THEN both client 1 and 2 would send back to cheating client who might disagree.

So instead of simple central validation everyone has to validate everyone on every turn.

And don’t even start on what happens if you have 2 clients that are using different types of cheats.


#40

Example:

public void updateBot() {
   if(updateCount >= physicsUpdateStep){
            characterControl.setPhysicsLocation(physicsLocation);
            
            physicsUpdateStep += 80;
   }
   updateCount++;
}

every 80 updates (bot is synchronized with real client)
there is a movement of several millimeters - every 3-4 seconds.

If this is not done at different customers get different results