def Server_Snapshot_Update(client, networker, game, event):
    # Copy the current game state, and replace it with everything the server knows
    packet_time = round(struct.unpack_from(">f", event.bytestr)[0], 3)
    event.bytestr= event.bytestr[4:]
    if len(game.old_states) > 0:
        tmp = game.old_states
        tmp.sort(key=lambda x: x.time)
        #if tmp != game.old_states:
        #    print([s.time for s in game.old_states])
        old_state_times = [old_state.time for old_state in game.old_states]
        if max(old_state_times) > packet_time:
            if packet_time in old_state_times:
                # The packet time miraculously is equal one of the stored states
                state = game.old_states[old_state_times.index(packet_time)]
            else:
                # it isn't, we gotta interpolate between the two nearest
                sorted_times = old_state_times
                sorted_times.sort(key=lambda state_time: abs(state_time - packet_time))
                state_1 = game.old_states[old_state_times.index(sorted_times[0])]
                state_2 = game.old_states[old_state_times.index(sorted_times[1])]
                state = state_1.copy()
                state.interpolate(state_1, state_2, (packet_time - sorted_times[0]) / (sorted_times[1] - sorted_times[0]))
        else:
            state = game.current_state
        # Delete all the old states, they are useless. Remember that list is chronologically ordered
        while len(game.old_states) > 0:
            if game.old_states[0].time <= packet_time:
                game.old_states.pop(0)
            else:
                break
        # Also delete those too far ahead
        server_current_time = packet_time + networker.estimated_ping
        while len(game.old_states) > 0:
            if game.old_states[-1].time >= packet_time + min(networker.estimated_ping, constants.MAX_EXTRAPOLATION):
                game.old_states.pop(-1)
            else:
                break
    else:
        state = game.current_state
    if state.time < packet_time:
        state.update_all_objects(game, packet_time-state.time)
    #try:
    #    print("game.old_states: {}\n".format([s.time for s in game.old_states]), "{0} < {1} < {2}\n".format(state_1.time, state.time, state_2.time), "packet time:{}\n".format(packet_time), "server time:{}\n".format(packet_time+networker.estimated_ping))
    #except:
    #    print("game.old_states: {}\n".format([s.time for s in game.old_states]), "state.time:{0}\n".format(state.time),"current_state.time:{}\n".format(game.current_state.time), "state.time-current_state.time:{}\n".format(state.time - game.current_state.time), "packet time:{}\n".format(packet_time), "server time:{}\n".format(packet_time+networker.estimated_ping))
    # State should now be exactly what the client thinks should happen at packet_time. Now let the server correct that assumption
    for player in state.players.values():
        length = player.deserialize_input(event.bytestr)
        event.bytestr = event.bytestr[length:]
        try:
            character = state.entities[player.character_id]
            length = character.deserialize(state, event.bytestr)
            event.bytestr = event.bytestr[length:]
        except KeyError:
            # Character is dead; continue
            pass
    # Now we have exactly what happened on the server at packet_time, update it to packet_time+ping (which also happens to be the length of all old_states)
    #state.update_all_objects(game, networker.estimated_ping)
    # Update this state with all the input information that appeared in the meantime
    for old_state in game.old_states:
        state.update_synced_objects(game, min(constants.PHYSICS_TIMESTEP, old_state.time - state.time))
        old_player = old_state.players[client.our_player_id]
        input = old_player.serialize_input()
        player = state.players[client.our_player_id]
        player.deserialize_input(input)
    game.current_state = state
NAGN, where should I push this? It pretty much works, aka I think the client emulates what's happening on the server pretty well, although I couldn't do a long-range hosting test yet. Also, it's totally not smooth, there's warping (which is supposed to be there), so I'll have to take a look at buffering stuff and using it for the interpolation.