Первое, что я бы сказал, это то, что ваш код выглядит наизнанку. Почему у вас есть логическая функция высокого уровня, которая должна выполнять основную работу по проверке того, какие клиенты вошли в систему и во всем мире? Все эти сетевые вещи должны быть удалены из игровой логики, чтобы это было сделано на более высоком уровне, и внутриигровая логика должна обрабатывать только игроков, которые в настоящее время играют и в мире. Это оставляет вас с простым вопросом: достаточно ли близки эти два игрока друг к другу? Здесь достаточно простой проверки расстояния, как у вас уже есть.
Следующая вещь - уменьшить количество циклов, которые вы делаете. Расстояние, как правило, является коммутативным свойством, поэтому вам не нужно проверять расстояние между A и B, а также между B и A. Чтобы сделать это, в то время как ваш первый цикл проходит через всех клиентов, второй цикл должен только перебирать все клиенты, которые приходят после первого. Это вдвое уменьшает количество итераций, которые вам нужно сделать.
Вам также не нужно делать это постоянно, как вы заявляете. Нужно просто делать это достаточно часто, чтобы игра шла гладко. Если скорость движения не так высока, вам может потребоваться делать это каждые несколько секунд, чтобы она была достаточно хорошей.
Если это все еще недостаточно для вас, то какая-то система пространственного хеширования, описанная ianh, является хорошим способом уменьшения количества запросов, которые вы делаете. Сетка является самой простой, но какая-то древовидная структура (в идеале самобалансирующаяся) является еще одним вариантом.