Comments 7
Может с "режимом наблюдателя" таки?
Это хорошее замечание. Когда я думал над названием, у меня был такой вариант. Но то ли из-за профессиональной деформации то ли еще по какой причине, когда я читаю "наблюдатель", первым в голову приходит слово observer. И паттерн наблюдателя. Я хотел чтобы название сразу было понятно людям. Потому решил взять слово "спектатор". Возможно, я не прав.
Возможно Вы правы.
Что, по-вашему, не так со словом "спектатор"? Это постоянно используемый игровой сленг
Чрезмерное, неоправданное, афонетичное(нелепое на слух) использование заимствований, в данном случае англицизмов. Послушайте, я не борюсь за чистоту русс яза, я лишь озвучил в данном конкретном случае, то что мне показалось излишним и нелепым. Я не вмду смыла бороться с импортными словами: банкрот, шлагбаум и тд, но в конкретном случае мой мозг зацепился. Я не могу сказать, что это плохо, но этот выглядит вульгарно, как кальки некотрых русских рэп исполнителей, где они бездарно и бездумно вставляют импортные слова. Бывают случаи обратные, где англицизмы очень органично вписываются в текст русской песни. Поэтому я обратил внимание в данном конкретном случае. Даже слово mode, давно импортировано в русс яз, как модификация и тд, оно фонетичеси звучит нелепо в сравнение со словом "режим", описывающем работу системы в определенной модификации.
Мой вопрос нёс под собой консультативную подаплеку, рекоментадетльную, а не категоричную и к чему обязывающую. Я спосил: может так лучше?..
Мне кажется, качество этой статьи невысокое. Она учит лишь умению бездумно копипастить код. Потому, что вы не аргументируете принятые решения, не объясняете ничего, а просто говорите: "скопируй этот код". Вы не учите.
Ну например, вы используете библиотеку tonic, но не объясняете даже, что она делает, а уж тем более, почему она выбрана из десятков других библиотек. А я не поленился и погуглил: это HTTP/2 сервер. Такую важную вещь вы не упомянули. А просто предложили бездумно ее использовать, не зная, что она делает.
Пойдем дальше. Почему вы выбрали протокол HTTP/2 для игры? Какие преимущества он дает? На мой взгляд, это плохой выбор, так как он использует TCP, а тот при потере пакета может подвиснуть на десятки секунд. В играх обычно используют UDP, и используют такой протокол, который выдерживает потерю пакетов.
Так как правильно использовать UDP, и с ним у нас возможна потеря пакетов, то посылать на сервер надо не события вроде "кнопка вверх нажата", а "ракетка переместилась в позицию Y". Иначе при потере пакета все рассинхронизируется.
Или, например, возьмем другой пример кода из первой части статьи:
[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>>
В статье нет объяснения, ни что значит первая аннотация, ни почему у main такой сложный тип возврата, что значит Box и что значит dyn. Ваша статья для новичков? Тогда надо объяснить. Или она для профессионалов, которые все это наизусть знают? Им она вряд ли нужна.
Кстати, странно, что main вообще что-то возвращает. Это же главная функция программы, и непонятно, кто будет обрабатывать этот dyn Box после ее завершения.
Или, например, вы пишете:
Оба поля обернуты в Arc<Mutex<>> потому что обращение к этим структурам будет многопоточным.
Зачем мьютекс в многопоточности — это понятно. Но зачем тут Arc (атомарно изменяющийся счетчик ссылок)? Опять же, объяснений нету.
Или, опять же, приведен сложный код без малейших объяснений:
let world = Arc::clone(&self.world).lock().unwrap().as_ref().unwrap().clone();
А точно так много функций нужно вызывать? И что они делают?
Далее, вы в клиенте и в сервере вы скопировали структуру Entity. Почему вы используете копипаст, а не вынесли общую часть в отдельный файл? Нелогично.
Далее, очищать весь экран каждый кадр, по моему, неэффективно, только для того, чтобы сдвинуть ракетки и мяч. Огромное количество пикселей перерисовывается зря.
Далее, вы исходите из того, что ваш код будет вызываться ровно 60 раз в секунду. Но кто вам такое гарантировал в многозадачной ОС? Код может вызываться произвольное число раз в секунду и должен это учитывать. Например, если с момента предыдущего вызова прошло 2 кадра, то и ракетку надо сдвинуть не на 1, а на две позиции вверх. Опять же, ваш сетевой протокол такого просто не поддерживает.
И в заключение. Вы тут пытаетесь создать у не разбирающихся людей впечатление, что Раст — простой и удобный язык, и любой новичок, прочтя вашу статью, легко сможет написать игру. Как бы не так. Раст — сложный язык для профессионалов, а не для новичков. Если вы не знаете Си, Си++ (и всех его тонкостей с RAII, шаблонами, умными указателями), основ ассемблера, то лучше не лезьте в Раст. Раст рассчитан на опытных Си++ программистов, а не на новичков. Документация Раста очень многие вещи не объясняет или объясняет вскользь, рассчитывая что вы их уже знаете из опыта работы с Си++. Например, вы не найдете в документации нормального объяснения "умных указателей" для начинающих — ожидается, что вы знакомы с этой вещью, прежде чем браться за Раст.
Если вы новичок, вам больше подойдет Питон или Яваскрипт. Даже Го (который тоже не для новичков) будет проще Раста.
Также хочу воспользоваться возможностью, чтобы отметить, что документация Раста очень не полна, не логична и не дает ответов на самые простые вопросы. Например, попробуйте найти ответ в документации, что такое str (не &str, а просто str без амперсанда)?
Страница говорит:
The str type, also called a ‘string slice’,...
Из этого можно только понять, что str — это некий тип, который по какой-то непонятной причине называют "string slice", хотя тут написано:
The slice type is written as [T]
Вот это я понять не могу. Если слайс обозначается как [T], то почему str — это слайс? Я не вижу в str квадратных скобок. Две документации просто противоречат друг другу. Одна утверждает, что у слайса есть квадратные скобки, другая — что str без квадратных скобок это тоже слайс. Как такое возможно?
Далее:
It is usually seen in its borrowed form, &str
Обычно str используется с амперсандом. А что будет, если мы используем его без амперсанда? Слово "обычно" подразумевает, что возможен и такой вариант. Где найти ответ?
Читаем далее:
A &str is made up of two components: a pointer to some bytes, and a length.
Хорошо, &str состоит из двух частей. Это понятно. А из чего состоит и что такое просто str? Где искать ответ на этот вопрос?
Или вернемся к обычным слайсам. Документация говорит:
Slice types are generally used through pointer types.
&[T]
Box<[T]>
В общем случае слайсы используются с указателями. А что будет, если использовать его без амперсанда? Слово "в общем случае" подразумевает, что возможны и частные случаи, когда мы используем его без амперсанда.
&[T] это тип слайса. А что обозначает [T] без амперсанда? Это слайс или нет? Ответа нету.
Аналогично, документация не объясняет, почему в Box<[T]> амперсанда нету. Получается, что в каких-то случаях амперсанд нужен, а в каких-то нет, но какие тут действуют правила — непонятно.
Или возьмем тот же амперсанд. Сколько у него разных значений, и нигде это толком не объясняется. Например:
- &a — берет указатель и иммутабельно "одалживает" значение a
- &T — обозначает тип указателя на определенный тип
- &str — обозначает отнюдь не указатель на тип str, а специальную структуру из указателя и длины
- &[T] — это я сам не понимаю, что такое: тип-слайс или тип указателя на слайс? В документации написано "'shared slice', often just called a 'slice'". Непонятно.
- &[1, 2, 3] — это то ли указатель на массив, то ли слайс, я так и не понял. Знаю только, что его можно передать туда, где требуется &[T]
Надеюсь, эти примеры доказывают, что Раст не для новичков. Новичок, очевидно, не сможет разобраться, что значит str без амперсанда, и не сможет осознанно писать код с его использованием. Максимум бездумно копипастить куски кода из Интернета, не понимая, что в них значит str и почему слайс иногда используется с амперсандом, а иногда без. Раст это очень сложный язык, и документация не описывает даже основы.
Большое спасибо за развернутый комментарий. Я хочу показать интересующимся людям что изучать что-то сложное, например, язык программирования rust - легко, создавая что-то свое. Потому что это интересно. Пусть там есть неясные моменты. Объяснять каждый шаг - медвежья услуга. Люди должны заинтересоваться. Я не пишу в этом гайде ААА игру и указываю что есть баги и разные подходы к сетевому коду.
Мультиплеерная игра на Rust + gRPC со спектатор модом. Часть 2