буфера раст что это
Бесстрашная защита. Безопасность памяти в Rust
В прошлом году Mozilla выпустила Quantum CSS для Firefox, который стал кульминацией восьми лет разработки Rust — безопасного для памяти языка системного программирования. Потребовалось более года, чтобы переписать основной компонент браузера на Rust.
До сих пор все основные браузерные движки написаны на C++, в основном по соображениям эффективности. Но с большой производительностью приходит большая ответственность: программисты C++ должны вручную управлять памятью, что открывает ящик Пандоры уязвимостей. Rust не только устраняет такие ошибки, но его методы также предотвращают гонки данных, позволяя программистам более эффективно внедрять параллельный код.
Что такое безопасность памяти
Когда мы говорим о создании безопасных приложений, то часто упоминаем безопасность памяти. Неофициально мы имеем в виду, что ни в каком состоянии программа не может получить доступ к недействительной памяти. Причины нарушений безопасности:
Подобные нарушения могут привести к неожиданному сбою или изменению предполагаемого поведения программы. Потенциальные последствия: утечка информации, выполнение произвольного кода и удалённое выполнение кода.
Управление памятью
Управление памятью имеет решающее значение для производительности и безопасности приложений. В этом разделе рассмотрим базовую модель памяти. Одно из ключевых понятий — указатели. Это переменные, в которых хранятся адреса памяти. Если мы перейдём по этому адресу, то увидим там некоторые данные. Поэтому мы говорим, что указатель является ссылкой на эти данные (или указывает на них). Так же, как домашний адрес говорит людям, где вас найти, адрес памяти показывает программе, где найти данные.
Всё в программе находится по определенным адресам памяти, включая инструкции кода. Неправильное использование указателей может привести к серьёзным уязвимостям, включая утечку информации и выполнение произвольного кода.
Выделение/освобождение
Когда мы создаём переменную, то программа должна выделить достаточно места в памяти для хранения данных этой переменной. Поскольку у каждого процесса ограниченный объём памяти, конечно, нужен способ освобождения ресурсов. Когда память освобождается, то становится доступной для хранения новых данных, но старые данные живут там до тех пор, пока ячейка не будет перезаписана.
Буферы
Буфер — это непрерывная область памяти, в которой хранится несколько экземпляров одного типа данных. Например, фраза «Мой кот — бэтмен» сохранится в 16-байтовый буфер. Буферы определяются начальным адресом и длиной. Чтобы не повредить данные в соседней памяти, важно убедиться, что мы не читаем и не записываем за пределы буфера.
Поток управления
Программы состоят из подпрограмм, которые выполняются в определённом порядке. В конце подпрограммы компьютер переходит к сохранённому указателю на следующую часть кода (который называется адресом возврата). При переходе на адрес возврата происходит одна из трех вещей:
Как языки обеспечивают безопасность памяти
Все языки программирования принадлежат разным частям спектра. С одной стороны спектра — такие языки, как C/C++. Они эффективны, но требуют ручного управления памятью. С другой стороны — интерпретируемые языки с автоматическим управлением памятью (например, подсчёт ссылок и сборка мусора (GC)), но они расплачиваются производительностью. Даже языки с хорошо оптимизированной сборкой мусора не могут сравниться по производительности с языками без GC.
Ручное управление памятью
Некоторые языки (например, C) требуют от программистов вручную управлять памятью: когда и сколько выделять памяти, когда её освобождать. Это даёт программисту полный контроль над тем, как программа использует ресурсы, обеспечивая быстрый и эффективный код. Но такой подход подвержен ошибкам, особенно в сложных кодовых базах.
Ошибки, которые легко сделать:
Подходящая инструкция по безопасности для тех, кто управляет памятью вручную
Умные указатели
Умные указатели снабжены дополнительной информацией, чтобы предотвратить неправильное управление памятью. Они используются для автоматического управления памятью и проверки границ. В отличие от обычного указателя, умный указатель способен самоуничтожиться и не будет ждать, пока программист удалит его вручную.
Есть разные варианты такой конструкции, которая обёртывает исходный указатель в несколько полезных абстракций. Некоторые умные указатели подсчитывают ссылки на каждый объект, а другие реализуют политику определения контекста (scoping policy) для ограничения времени жизни указателя определёнными условиями.
При подсчёте ссылок ресурсы освобождаются при удалении последней ссылки на объект. Базовые реализации подсчёта ссылок страдают от низкой производительности, повышенного потребления памяти и их трудно использовать в многопоточных средах. Если объекты ссылаются друг на друга (циклические ссылки), то подсчёт ссылок для каждого объекта никогда не достигнет нуля, так что требуются более сложные методы.
Сборка мусора
В некоторых языках (например, Java, Go, Python) реализована сборка мусора. Часть среды выполнения, которая называется сборщиком мусора (GC), отслеживает переменные и определяет недоступные ресурсы в графе ссылок между объектами. Как только объект становится недоступен, GC освобождает базовую память для повторного использования в будущем. Любое выделение и освобождение памяти происходит без явной команды программиста.
Хотя GC гарантирует, что память всегда используется корректно, он освобождает память не самым эффективным способом — иногда последнее использование объекта происходит гораздо раньше, чем сборщик мусора освободит память. Издержки производительности бывают непомерно высоки для критически важных приложений: чтобы избежать падения производительности, приходится использовать иногда в 5 раз больше памяти.
Владение
В Rust для обеспечения высокой производительности и безопасности памяти используется концепция владения (ownership). Более формально, это пример аффинной типизации. Весь код Rust следует определённым правилам, которые позволяют компилятору управлять памятью без потери времени выполнения:
Когда переменная выходит за пределы области видимости, Rust освобождает эту память. В следующем примере переменные s1 и s2 выходят за пределы области, обе пытаются освободить одну и ту же память, что приводит к ошибке double-free. Чтобы предотвратить это, при переносе значения из переменной предыдущий владелец становится недействительным. Если затем программист попытается использовать недопустимую переменную, компилятор отклонит код. Этого можно избежать, создав глубокую копию данных или используя ссылки.
Другой набор правил borrow checker’а относится к времени жизни переменных. Rust запрещает использование неинициализированных переменных и висячих указателей на несуществующие объекты. Если скомпилировать код из примера ниже, r будет ссылаться на память, которая освобождается, когда x выходит за пределы области видимости: возникает висячий указатель. Компилятор отслеживает все области и проверяет допустимость всех переносов, иногда требуя от программиста явного указания времени жизни переменной.
Модель владения обеспечивает прочную основу для корректного доступа к памяти, предотвращая неопределённое поведение.
Уязвимости памяти
Основные последствия уязвимой памяти:
В лучшем случае при ошибке памяти приложение аварийно завершит работу. В худшем случае злоумышленник получит контроль над программой через уязвимость (что может привести к дальнейшим атакам).
Злоупотребления освобождённой памятью (use-after-free, double free)
Этот подкласс уязвимостей возникает, когда какой-либо ресурс освобождён, но на его адрес по-прежнему сохранилась ссылка. Это мощный хакерский метод, который может привести к доступу за пределы диапазона, утечке информации, выполнению кода и многому другому.
Языки со сборкой мусора и подсчётом ссылок предотвращают использование недопустимых указателей, уничтожая только недоступные объекты (что может привести к снижению производительности), а языки с ручным управлением подвержены этой уязвимости (особенно в сложных кодовых базах). Инструмент borrow checker в Rust не позволяет уничтожать объекты, пока на него существуют ссылки, так что эти баги устраняются на этапе компиляции.
Неинициализированные переменные
Если переменная используется до инициализации, то в этой памяти могут быть любые данные, включая случайный мусор или ранее отброшенные данные, что приводит к утечке информации (их иногда называют недействительными указателями). Чтобы предотвратить эти проблемы, в языках с управлением памятью часто используется процедура автоматической инициализации после выделения памяти.
Как и в C, большинство переменных в Rust изначально не инициализированы. Но в отличие от C вы не можете их прочитать до инициализации. Следующий код не скомпилируется:
Пример 3: Использование неинициализированной переменной
Нулевые указатели
Когда приложение разыменовывает указатель, который оказывается нулевым, обычно он просто обращается к мусору и вызывает сбой. В некоторых случаях эти уязвимости могут привести к выполнению произвольного кода (1, 2, 3). В Rust есть два типа указателей: ссылки и необработанные указатели (raw pointers). Ссылки безопасны, а вот необработанные указатели могут стать проблемой.
Rust предотвращает разыменование нулевого указателя двумя способами:
Что делать, если нельзя избежать указателей, допускающих нулевое значение (например, при взаимодействии с кодом на другом языке)? Попытайтесь изолировать ущерб. Разыменование необработанных указателей должно происходить в изолированном unsafe-блоке. В нём ослаблены правила Rust и разрешены некоторые операции, которые могут вызвать неопределённое поведение (например, разыменование необработанного указателя).
— Всё, чего касается borrow chekcer… а что насчёт вон того тёмного места?
— Это unsafe-блок. Никогда не ходи туда, Симба
Переполнение буфера
Мы обсудили уязвимости, которых можно избежать, ограничив доступ к неопределённой памяти. Но проблема в том, что переполнение буфера неправильно обращается не к неопределённой, а к легально выделенной памяти. Как и баг use-after-free, такой доступ может стать проблемой, потому что обращается к освобождённой памяти, где по-прежнему содержится конфиденциальная информация, которая уже не должна существовать.
Переполнение буфера просто означает доступ за пределы области (out-of-bounds). Из-за того, как буферы хранятся в памяти, они часто приводят к утечке информации, которая может содержать конфиденциальные данные, в том числе пароли. В более серьёзных случаях возможны уязвимости ACE/RCE путём перезаписи указателя инструкции.
Пример 4: Переполнение буфера (код C)
Простейшая защита от переполнения буфера — всегда при доступе к элементам требовать проверки границ, но это приводит к снижению производительности.
Что делает Rust? Встроенные типы буферов в стандартной библиотеке требуют проверки границ для любого случайного доступа, но также предоставляют интерфейсы API итератора, чтобы ускорить последовательные обращения. Это гарантирует, что чтение и запись за пределами границ для этих типов невозможны. Rust продвигает шаблоны, которые требуют проверки границ только в тех местах, где почти наверняка придётся вручную размещать их в C/C++.
Безопасность памяти — только полдела
Нарушения безопасности приводят к уязвимостям, таким как утечка данных и удалённое выполнение кода. Существуют разные способы защитить память, в том числе умные указатели и сборка мусора. Вы даже можете формально доказать безопасность памяти. Хотя некоторые языки смирились с падением производительности ради безопасности памяти, концепция владения в Rust обеспечивает безопасность и минимизирует накладные расходы.
К сожалению, ошибки памяти — это лишь часть истории, когда мы говорим о написании безопасного кода. В следующей статье рассмотрим потокобезопасность и атаки на параллельный код.
Эксплуатация уязвимостей памяти: дополнительные ресурсы
Как устранять в Rust проблемы с производительностью (лаги, фризы, низкий FPS)
Случаются, как оказалось, в Rust проблемы технического плана, которые, скажем так, несколько мешают красиво «выживать» в мире игры. Речь, разумеется, в первую очередь о проблемах с производительностью, то есть, о тех неприятных моментах, когда Rust сильно лагает, виснет и т.д.
Такого рода «непонятки» в игре случаются довольно часто, потому сейчас попробуем разобраться, откуда они берутся и как их устранять.
когда в Rust проблемы с производительностью возникают сразу
Проще говоря, уже при первом запуске игра явно фризит, лагает и падает FPS. В таком случае начинать стоит с проверки имеющегося в наличии компа на предмет соответствия системным требованиям Rust. Хотя бы «минималке», но лучше — рекомендованным.
Минимальные системные требования у Rust, напомним, следующие:
если с «железом» всё ОК, но в Rust проблемы с производительностью все равно есть
…то далее надо поэкспериментировать с настройками графики самой игры. Rust — прога довольно ресурсоемкая, потому вполне способна «пригрузить» даже комп, соответствующий рекомендованным требованиям.
Следовательно, на таких пиковых уровнях производительности, когда создается повышенная нагрузка на отдельные элементы системы (вплоть до перегрева), игра не только заметно лагает, но и возникает риск, что эти самые «элементы», и прежде всего видеокарта может и не вытянуть. Со всеми вытекающими…
Решение простое: если игра виснет и лагает регулярно, то открываем настройки и понижаем уровень качества графики. Для начала — общего разрешения и качества детализации текстур. В идеале лучше сразу сбросить все и до минимума (в особенности, когда комп не самый топовый по возможностям).
После чего перезапускаем игру и играем немного. Если игра идет нормально, то далее поочередно поднимаем ключевые параметры графики до более высоких. Да, это займет некоторое время, но зато есть шанс сравнительно быстро найти такое сочетание настроек, с которым в Rust проблемы с производительностью мешать больше не будут.
Плюс к этому, запускаем игру сразу в полноэкранном режиме. Оконные режимы в Rust только ухудшают работу, поскольку не дают Windows всецело переключиться на оптимизацию производительность игры.
проблемы в Rust — проверяем сервер
Это на тот случай, когда игра явно лагает даже на компе, возможностей которого с лихвой хватает на все рекомендованные требования. Для начала не лишним будет просто глянуть текущий статус сервера, можно [ЗДЕСЬ], к примеру.
Но помимо этого также учитываем, что у Rust не все серверы и не всегда работают одинаково стабильно. Но зато, когда тормозит один, то можно на время перейти на другой. Само собой, выбирать лучше тот, который расположен поближе и на данный момент загружен меньше. Вариант со сменой сервера, конечно, не самый лучший, а в ряде случаев и вовсе неприемлемый, но хоть поиграть можно будет…
если лагает Rust — оптимизируем «сбор мусора»
Это дело, к слову, настоящие мастера Rust-а рекомендуют наладить как можно раньше. Речь — о корректных настройках автоматического управления памятью в игре (а именно, её поиск и освобождение неиспользуемой памяти — это, собственно, и есть так называемый «сбор мусора» или garbage collection, если в оригинале).
Если в двух словах, то суть басни в том, что в Rust лаги и фризы, как правило, происходят в самом начале цикла «сборки мусора» на сервере. Потому устраняется эта проблема путем изменения частоты этих циклов. Вкратце технология описана в блоге Facepunch Studios (ССЫЛКА), а также ЗДЕСЬ на русском и со всеми подробностями.
Потому повторятся не будем, а отметим только, что метода предусматривает изменение значения переменной gc.buffer на значение, отличное от 256 (значения по умолчанию), при котором игра автоматом будет пытаться очистить память, если загрузка превышает примерно 128 мегабайт.
Таким образом, если у локальной системы (т.е. вашего компа) есть запас оперативной памяти, то можно сократить интервалы сборки мусора, увеличив значение буфера примерно до 2048, и существенно снизить вероятность возникновения лагов и падения FPS. Вот пока как-то так…
Как правильно строить дом новичку в игре Rust
На какой бы вы сервер не зашли, вы всегда будете сталкиваться с такой проблемой, как «рейд». Рейд – это неизбежная ситуация, с которой приходится сталкиваться каждому игроку в игре Rust. Но, если опытные игроки анализируют свои ошибки в постройке, то новички сразу же пытаются покинуть сервер, чтобы «начать с нуля». На самом деле это далеко не правильная позиция, и сейчас я вам детально расскажу, почему я так считаю.
Я начну с нуля на другом сервере и построю крутой дом в игре Rust…
Тебя зарейдили? Ты решил сразу же ливнуть на другой сервер? И? Какой смысл, дружище? Построишь ты опять «коробку», и тебя вновь зарейдят! Хотя ты мог извлечь урок из того рейда, который был на прошлом сервере. Какой? Посмотри на свой дом, и ответь на несколько вопросов:
А теперь посмотри на свой дом, и сам себе ответь на вопрос – вот если бы ты уже знал, что будут рейдить здесь, то, как бы укрепил свой дом? Опа! А тут и решение – сделать так-то и так-то… Если ты уже спалил всю планировку дома, то не советую тебе застраивать этот же дом. Лучше построить другой, пусть и поменьше, но зато более эффективный. Ты уже будешь знать, чем тебя зарейдили, с каких сторон подошли, какие способы рейда использовали. Парень, ты на своих собственных ошибках будешь учиться правильно строить. На самом деле в расте мало построить большую коробку…
Большая коробка или маленький антирейд дом?
Я заметил, что на большинстве серверов, да и большая часть игроков строит большие дома, в основном квадратные коробки. Добраться до лута можно через 3-4 стены. Такие дома не эффективны, зато отнимают у вас много ресурсов. Сейчас на скриншоте ниже я вам покажу примеры «неправильных» и «правильных» домов. Настоятельно советую вам до конца дочитать материал, чтобы построить хороший домик и уже в первые дни игры не потерять его.
Вот как НЕ НАДО строить дома! Это НЕПРАВИЛЬНЫЙ дом в игре Rust
Увидели? На скриншоте выше мы вам показали обычную «КОРОБКУ», которая поддается рейдерству на «раз-два». Причем ломать такие дома можно как с боков, так и сверху, подстроившись к дому. А теперь ниже посмотрите на пример маленького «антирейд» дома, который построен ПРАВИЛЬНО!
Вот так НАДО строить дома. Это ПРАВИЛЬНЫЙ дом в игре Rust!
Самая нужная и надежная вещь в постройке дома – это буферки. Кто не в курсе, буферки –это буферные зоны, которые, чаще всего, не используются, и просто создают дополнительные комнаты и пространства вокруг дома. Один из самых популярных способов выставления буферных зон – это треугольный фундамент и последующее наращивание стен. То есть, вы строите определенный дом, и вокруг его начинаете обустраивать треугольниками, создавая дополнительные стены.
Соответственно, сами понимаете, что вы создаете дополнительную преграду для человека, который собирается рейдить ваш дом. Чем больше у вас буферных зон, тем больше придется потратить рейдеру С4 и ракет. Специально для вас мы создали отдельный раздел схем для игры rust, в котором можно найти просто огромное количество схем антирейдовых домов на все случаи жизни: для соло игроков, для пары игроков, для клана. Все схемы открываются через программу Fortify, которая стоит копейки и привязана к сервису Steam. Обязательно зайдите в этот раздел и посмотрите схемы, которые мы вам предлагаем.
Какой дом строить на сервере в игре Rust?
Все зависит от того, на каком сервере вы играете. Если это классический сервер, то в одиночку построить большой дом у вас не получится. Максимум, на что вы способны – дом 4 на 4 в несколько этажей. Причем вы затратите большое количество времени и усилий. Если же вы играете в команде, то даже на классическом сервере Rust можно построить большой дом с буферными зонами и антирейдом.
Если вы играете на серверах с умножением ресурсов, например, x2-x5, или даже x10, то здесь уже нужно строить большой дом. Благо, для этого у вас все есть, особенно, если вы играете в клане. Но в любом случае мы настоятельно вам рекомендуем строить антирейдовые дома с буферными зонами.
Как правильно поставить шкафы в игре Rust
Построить дом – это одно дело, а вот расставить в нем все ящики и шкафы – это другое, причем не менее важное, чем сам процесс стройки.
Шкаф – это элемент, который блокирует постройку для тех пользователей, которые в нем не авторизованы. То есть, в его радиусе действия смогут строить только те, кто в нем авторизован.
И так, как же правильно расставлять шкафы? Самый простой способ – один шкаф ставится посередине дома. Если вы только начали строить домик, то ставите шкаф и наращиваете стены и этажи.
Как только у вас появится 3, 4 и более этажа, убираете шкаф внизу, и сначала ставите шкаф вверху, тоже посередине дома, а потом через один этаж ставите еще по шкафу. Запомните, что в Rust можно ставить шкафы через один этаж. Даже если рейдер ворвется на первый этаж, сломает стены и авторизуется в вашем шкафу, он не сможет пройти дальше, потому что у вас на 3м этаже отдельный шкаф.
Важно! Обязательно закрывайте шкафы стенами! И не дверями, а стенами! Один раз авторизовались, и замуровали его намертво.
Только обязательно впишите туда всех своих друзей и соклановцев, кто с вами живет. На классике стены и любые строительные элементы можно ремувнуть в течении нескольких минут, если вдруг нужно будет вписать кого-то или поменять расположение. На модифицированных же серверах есть команда /remove, которая позволит вам в любой момент киянкой сломать любые объекты, если ранее вы их ставили.
Правильная расстановка шкафов вокруг дома в игре Rust
Поставить шкафы в доме – это одно! А вот защитить территорию вокруг – это уже другое дело. Вам необходимо взять лист постройки и отойти от дома на такое расстояние, чтобы Building привилегия от шкафа внутри дома исчезла. Как только исчезнет – можете ставить треугольный фундамент, на него шкаф, авторизоваться в нем и все замуровывать. Обязательно Все апгрейдите хотя бы до каменного, чтобы никто не сломал.
Так вам нужно сделать вокруг всего своего дома. Если он у вас прямоугольный, то обычно хватает 4 шкафа вокруг дома по всем направлениям, то есть: сзади дома, спереди дома, слева и справа. Если же дом круглый, то приходится ставить больше шкафов. Обычно где-то 6-8 штук.
Зачем ставить шкафы вокруг дома в Rust? Это делается для того, чтобы к вам не смогли подстроиться другие игроки и прыгнуть на крышу с большой вышки. Обычно это происходит так: игрок построил дом с буферками вокруг дома, но совсем забыл про крышу. Рейдеры подстраиваются с вышкой около дома максимально близко, прыгают на крышу дома и долбят в середину. Несколько этажей вниз – и вот она уже лутовая, шкафы, открытые комнаты и многие другие интересные помещения! Чтобы защитить свой дом – обязательно ставьте вокруг шкафы, и замуровывайте их примерно так же, как на скриншоте ниже.
В этих буферках (треугольниках» стоят шкафы. И они зашиты! Никто не сможет подстроиться к дому
На скриншоте выше показан пример шкафов, которые стоят вокруг дома. Все они закрыты в металлических треугольниках, что обеспечивает защиту вашему дому и блокирует «подстройку» и рейд через крышу. Ниже на скриншоте показаны «усиленные» закупоренные шкафы вокруг дома.
Пример «укрепленной» буферки с шкафами. Так делать можно, когда есть лишние ресурсы.
Как правильно ставить стены в игре Rust
Как же правильно ставить стены? Во-первых, запомните, что стены ставятся внутренней стороной к вам. То есть, стоите вы с листом постройки и ставите стенку. Сторона, которая повернута к вам – это внутренняя сторона, и она ломается быстрее, чем внешняя.
Поэтому когда строите дом – стойте внутри дома, и стройте стены. Если вы стоите за домом и ставите стены, то сразу поворачивайте их.
Как повернуть стенку в Rust? Для этого нажмите на стене, которую нужно повернуть киянкой, и выберите пункт «Повернуть».
Как отличить сторону стены? У внешней стороны поверхность более грубая, чем у внутренней стороны. Это очень хорошо видно на примере каменных стенок. У внешней стороны она темноватая, а у внутренней – светлая, белая. Так вот, белая сторона ломается быстрее, и если вы ее поставите неправильно, то вам быстро выдолбят стены и залезут в дом.
Пример внешней и внутренней стороны стенки каменной в игре Rust
Какие двери лучше ставить в доме в Rust
Одна из распространенных ошибок игроков – это входные двери! Очень часто они ставят деревянные или железные.
Деревянные двери можно вынести патронами, огнеметом, продолбить кирками и топорами. Причем времени на это уйдет очень мало! Как только появится возможность, меняйте дверь и ставьте кодовый замок! Не ключ, а кодовый замок.
Совет! Если все-таки используете ключи, то всегда оставляйте одну копию дома в ящике. Может быть так, что вас «сожрет» медведь или убьют далеко от дома. Вам нужно будет быстро выбежать, а вы не сможете, так как у вас нет ключа. А на его создание может и не быть ресурсов. Вот так проблемка, не правда ли?
Железные двери можно вынести с 4х бобовых С4 или с разрывных патронов. Скрафтить разрывных патронов или бобовых С4 – не проблема!
Поэтому, как только соберете шестеренки для арморной двери, сразу же ставьте ее. Не обязательно по всему дому, но на вход точно. Так вы уже отсеете половину рейдеров, которые в первые дни после вайпа бегают с бобовыми С4 и рейдят небольшие дома.
Как правильно ставить окна в игре Rust
Еще одна наболевшая тема для новичков, которые только начали играть в Rust Experimental. Очень часто вас выносят, потому что вы ставите окна на 1,2 этажах. На первый этаж может зайти любой игрок через окошко, даже если там стоят ставни.
На второй этаж рейдера может подсадить «дружок», и он все равно попадет к вам в дом. Как вылезти – они уж точно придумают.
Если уж вы решили делать окна, то обязательно ставьте решетки и ставни с внутренней стороны дома, чтобы их нельзя было просто так открыть и «спалить» планировку вашего дома. Наиболее оптимальный вариант – установка окошек на верних этажах, начиная с третьего. Рекомендую вам поставить за окном стены, чтобы игроки с улицы не смогли увидеть планировку вашего дома.
Совет! Обязательно смотрите, чтобы не было уступов и гор около вашего дома и окон, иначе можно оттуда подпрыгнуть и залезть в окно.
Это далеко не все, но основные советы для новичков, которые только начали играть в Rust Experimental. Читайте наши другие гайды, следите за обновлениями, и мы научим вас играть «красиво» в Rust и выбиться в топ!