Избранное Все заметки Главная

Блог юного Game Developer'а

Полезные материалы,туториалы,кодинг и различные лайфхаки.

S.T.A.L.K.E.R 2 в 2010-2011 г.

Уже прошло солидное кол-во времени с официального анонса Григоровича,а интернет всё никак не утихнет, «блогерам» дали лишний повод поднять свой рейтинг,выдвинуться в топ за счет инфы по S.T.AL.K.E.R 2,но есть одно но — нет никакой инфы на данный момент. Я сразу предупрежу вас о том,что всё,что представлено ниже — являлось правдивой информацией на момент 2010-2011 г. С тех пор утекло много воды и нет никаких гарантий,что представленные ниже материалы будут использоваться в разработке текущей версии S.T.A.L.K.E.R

Диздок — http://s.gameru.net/stalker/cop/some_docs.7z
Глобальная карта — https://radikal.ru/lfp/s019.radikal.ru/i627/1506/97/c6614117b415.jpg/htm
Исходные коды Xray2 (но это не точно) — https://yadi.sk/d/bd0u9AKAfv8jF

Дизайн NPC

Модели

link : http://yastalker.com/album.php?user=Sitro&album_id=26084

Мутанты

link : http://yastalker.com/album.php?user=Sitro&album_id=26083

Дизайн локаций

link : http://yastalker.com/album.php?user=Sitro&album_id=26082

Видео-материалы

Предполагаемое лого

11 июня  

Roadmap или что нужно знать,чтобы программировать в Unity

Если ты горишь желанием писать игры и уже выбрал в качестве движка Unity ,то не спеши собирать команду директоров. Поверь , то время,которое ты потратишь на обучение сейчас станет лучшей твоей «инвестицией» в своё будущее.

Для чего эта статья?

Видишь ли,статья сэкономит тебе целую кучу времени,ведь тебе не придется ничего искать,вот оно,лежит уже прямо перед тобой,остается только сесть и начать работать.

Знаешь на что похоже обучение в целом? — Изначально, это поездка из города A в город E . Мы понимаем где хотим оказаться в конце путешествия,но если не знать,что для поездки в город N , нам нужно будет пересечь города B ,C и D — мы можем заблудиться. Так откуда же тогда узнать про B , C и D ,если мы путешествуем впервые?
Правильно! Нужно спросить у опытных путешественников.

«Не стесняйтесь задавать вопросы. Это утоляет жажду любопытства, рождает новые мысли, помогает творить».
Анина О.

Водички налили,теперь по-делу:

Это ровно то,что небходимо знать любому .NET программисту.
Тебя не должно пугать «C# Professional» . Это не то,о чем ты подумал.
Те курсы,которые обозначены * — не обязательны для прохождения,но желательны.

Теперь разумный вопрос — «Где мне проходить все эти курсы?»
Здесь — https://itvdn.com/ru/specialities/net-developer . Месячная подписка стоит очень дешёво,а если ты студент,то ещё и купон дадут (нужно будет предъявить студ-билет) . P.S : если ты совсем бедняк,как и большинство Россиян (20!8) ,то напиши в лс Сообщества,помогу

Пока писал эту статью,вспомнил разговор с одним человеком,так вот, оказывается, некоторые люди думают,что C# в Unity и C# вне Unity  — разный,мол нужно проходить отдельные курсы «Скриптинг c# в unity». Нет,черт возьми),C# он и в Африке C#.

Небольшая справка : Версия C#,которая используется в unity может отличаться от последней(актуальной на сей день) , но сути это не меняет, язык тот же, версии -разные.

Теперь напоследок,резюмируя всё написанное ответим на вопрос — «Какие курсы мне нужно пройти,чтобы самостоятельно писать скрипты в Unity? (а не скачивать готовое с unity3ddd)» :

  •  
  • C# Стартовый
  • SQL Essential
  • C# Базовый (ООП)
  • Алгоритмы и структуры данных
  • C# Профессиональный
  • Рефакторинг .NET приложений

После прохождения курсов приступаем к чтению** :

https://www.ozon.ru/context/detail/id/140399774/
https://www.ozon.ru/context/detail/id/34792570/

Литература была прочитана мной и рекомендована не случайно.

** Да-да,именно в такой последовательности — сначала смотрим курсы,затем закрепляем книжками.

4 июня  

Photon,Unet и больше ничего?

Всем привет, статья написана исключительно для того,чтобы поделиться своими впечатлениями о сервисе N,который так упорно почему -то не замечают почти все разработчики продающие свои исходники на AssetStore.
Давайте перечислим самые популярные сорцы на AS:

MFPS, UnitZ , UFPS , EZFPS , FPSME . Все эти сорцы используют либо Unet ,либо Photon (с ограничением в 10 CCU).
Это заставляет новичков думать,что кроме Photon и Unet ничего нет,либо есть,но разбираться в этом долго не хочется.
Photon конечно удобен для быстрого deploy, но позвольте предложить вам кое-что по-лучше.

PlayerIO

site: http://playerio.com

PlayerIO — это быстрый, легкий, масштабируемый и надежный путь к созданию онлайн игр. Такие функции, как BigDB, GameFS, Sitebox и Multiplayer, позволяют создавать крупные сложные онлайн-игры без размещения отдельного сервера самостоятельно.

Очевидные плюсы этого сервиса:

1) Разберется даже ребёнок
2) Возможность строить свою серверную часть на основе playerIO либы и загружать получившуюся dll прямо на сайт.
3) Примерчики для разных платформ*

Лимиты

1) 500 CCU на бесплатном тарифе. За 20 петрушек в месяц можно взять другой тариф — 5000 CCU.
2) 45 одновременных игроков в комнате. Обычно больше и не нужно
3) 20 гб трафика в месяц

Для любителей туториалов вот подборочка :

https://devby.ru/blog/playerio/ (Вообще хороший блог,найдете много интересного для себя)
https://www.youtube.com/user/1NovaCorpGame1/featured
http://forum.boolean.name/showthread.php?t=18008
http://www.ant-karlov.ru/PlayerIO-osnovi-ili-pervaya-onlayn-igra.html

*Для лентяев есть даже небольшой примерчик для Unity.

2 июня  

Unity API из другого потока (can only be called from the main thread)

Наверняка многие из вас пытались вызывать методы из api юньки или обращаться к объектам из другого потока.
Если ещё не пробывали — попробуйте, компилятор заорёт примерно такой ошибкой — can only be called from the main thread
Вообщем-то погуглив я понял,что не я один с этим встречался,поэтому на будущее оставлю решение здесь,может кому пригодится. Совет нашел на SO,но ссылку привести не смогу,утерял.

Условие простое, хотим работать с unity api — проворачиваем свои делишки только в главном потоке,иначе никак.
Поскольку метод Update крутится в главном потоке,проверку будем производить там. Поехали...
Итак, допустим я в дополнительном потоке получаю сообщения от сервера. Мне необходимо каждое сообщение добавлять в Text UI. Если попытаюсь из дополнительного потока поработать с UI,то получу ошибку,исправляется следующим образом:

Для начала объявим в нашем скрипте очередь из делегатов и некоторые промежуточные переменные

private Queue<Action> mainThread = new Queue<Action>(); 
private string data = null;

Теперь для примера напишем метод,который будет взаимодействовать с UI.

private void OnWriteMessageChat()
    {
        if (data != null)
        {
            chatfield.text += data + "\n";
            data = null;
        }
    }

А это пускай будет тот самый метод,который принимает от сервера сообщения :

private void Communication()
                        {
data = "msg from server";
// бла бла , допустим мы уже получили сообщение от сервера и храним её в переменной data ,которую изначально объявили в теле класса.

                                mainThread.Enqueue(new Action(OnWriteMessageChat));
                                Debug.Log("Делегат добавлен в очередь");

                            }

У mainThread есть метод Enqueue,которые добавляет наши делегаты в очередь.
Остается только достать из очереди делегат и вызвать Invoke(). Для этого пригодится Update (я уже упоминал его в начале,не забыли?)

private void Update()
    {
        if(mainThread.Count > 0)
        {
            mainThread.Dequeue().Invoke();
        }

    }

Вот и всё,статья получилось довольно сжатой,но, думаю , смысл понятен.

Кастомные кнопки в инспекторе

Если пользовались различными редакторами,скриптами с AS и наверняка вы заметили,что многие программисты выносят кнопки,переключатели,ползунки в инспектор для вашего удобства.Пробовали когда-нибудь написать что-то подобное?
Впрочем,если у вас нет времени разбираться с UnityEditor,но очень хочется сделать нечто подобное —

То это готовое решение для вас — https://cloud.mail.ru/public/HjXJ/Ut6LGGwE3

Пример кода:

using UnityEngine;

namespace EasyButtons
{
    public class CustomEditorButtonsExample : MonoBehaviour
    {
        [Button("Custom Editor Example")]
        private void SayHello()
        {
            Debug.Log("Hello from custom editor");
        }
    }
}

Источник — https://github.com/madsbangh

8 мая  

Убираем лимит 30 CCU у NetDrone Engine Free

Всем привет,решил ,что такого рода статьи не отберут у меня много времени,но зато будут интересны некоторым читателям.

Предыстория:
Гулял на днях по AssetStore (далее AS), копался в категории Scripting/Network и набрел на один с виду хороший ассет — NetDrone Engine. Разумеется, я сразу забрал его к себе домой и стал декомпрессить. Поигрался со сценами и в итоге обнаружил для себя следующие фичи:

1) Надежный UDP, т.е надстройка над обычным UDP : проверка доставки сообщения,гарантия правильной последовательности и т.д

2) Каналы , комнаты , обработки всех возможных ситуаций (например отключение игрока от сервера) уже предусмотрены.

3) В комплекте сервер , написанный на 2 языках (C++,C#)

Затем начался разглядывать серверный код, и наткнулся на тот самый лимит в 30 одновременных коннектов.

Переменная iMaxUser отвечает как раз установление максимального кол-ва юзеров.

Метод Initialize вызывается из библиотеки libnetdroneunity_nocrypt_ccu30.dll

Если заглянем внутрь dll (используя дизассемблер dnSpy) ,то поймем,что со своей стороны мы можем лишь уменьшить это значение, но никак не увеличить

На этом можно было бы закончить статью, казалось бы,нужно лишь отредактировать код в dnSpy и заменить оригинальную dll на нашу (модифицированную), но нет, при компиляции нас ждёт нечто подобное:

И чтобы не парить себе мозг,исправляя эти ошибки мы пойдем иным путём,

Погнали
Задействуем ildasm (Дизассемблер) и ilasm (Ассемблер). Две эти утилиты уже присутствуют на вашем ПК (если вы устанавливали Visual Studio)

Воспользуйтесь поиском на вашем ПК,чтобы отыскать ildasm.exe и ilasm.exe

Теперь запускаем ildasm.exe и кидаем в открывшееся окошко нашу dll. В опциях выбираем Дамп, и ничего не меняя сохраняем в произвольную папку. На выходе получим 2 файла : имя.il , имя.res

Теперь открываем имя.il с помощью блокнота и ищем интересующую нас переменную

Заменяем на своё значение и сохраняем.

Теперь, если вы нашли вторую утилиту ilasm.exe ,то скопируйте путь до папки, в которой она лежит и выполните команду в cmd

Команда : cd <путь до папки>

Ну и последний штрих — запускаем ilasm с параметрами, вот так — ilasm /dll C:\StudyServer\newIL\code.il /output=C:\StudyServer\newIL\code.dll

где C:\StudyServer\newIL\code.il — путь к нашему il файлу иC:\StudyServer\newIL\code.dll — путь к dll файлу,который создастся после отработки ilasm .

Если всё прошло ОК , то вы должны увидеть такое сообщение:

Такое ощущение,что разраб специально не стал усложнять нам жизнь (за это ему и респект),а ведь можно было,как минимум, обфусцировать всю dll , и хранить хэши оригинальной dll для выявления подмены.

На этом всё,всем спасибо за внимание,надеюсь статья окажется некоторым полезной!

UPD: Забыл написать,что в ConfigEx.cs на 98 строке также необходимо поменять значение аргумента у метода SetMaxConnection(30) на своё

UPD: если вы криворукий балван,то вот ссылка на модифицированную dll — https://cloud.mail.ru/public/D4L2/UhtYbhi2j

Архитектура сессионных(комнатных) сетевых игр

Сессионные игры — игры,в которых каждый отдельно взятый игрок может создать своё лобби,пригласить или подождать подключения других игроков и начать играть с подключенными к лобби игроками.

Вопрос:
Пишу небольшую мультиплеерную настольную игру. Каждый «стол» игры планируется в отдельном потоке. Возник вопрос по организации приема данных от клиентов (соединение UDP): Все потоки слушают 1 порт и каждый ловит из общей массы нужную для стола инфу или же назначать порт для каждого отдельного стола избавляя от функции сортировки данных?

Ответ:
Порты и потоки — это очень ценный и ограниченный ресурс. Портов всего 65536 (и не все из них можно юзать), а потоков вообще нежелательно иметь больше чем процессорных ядер (упрощенно говоря). Что если к серверу подключится 100 клиентов? А если 1000? Дальше такой вопрос: если для каждой игровой сессии выделять отдельный порт, то откуда клиент будет знать на какой порт ему стучаться? Значит первоначальное соединение всё равно будет происходить через один фиксированный порт? Но тогда получается, что всё равно нужен механизм сортировки пакетов от разных клиентов. То есть его не избежать. Но и бояться этого не надо. Клиент просто должен каждый раз передавать ID сессии, а сервер легко найдет по нему нужную (это одна строчка кода).

Правильный подход будет приблизительно таким. Состояние каждой игровой сессии (стола) должно храниться в некоем объекте. При этом, никакого потока у сессии нет, просто хранится её состояние (ну типа чья очередь ходить, у кого сколько очков, кто где стоит) и всё. И таких вот объектов целый массив, по количеству столов. Один единственный поток слушает один единственный порт. Когда клиент обращается к серверу, он передает ID своей сессии. Сервер принимает пакет, и по ID находит в массиве нужную сессию. Вот тут, он запускает новый поток, и в этом потоке обрабатывает полученные данные. В результате обработки состояние сессии изменяется, клиенту при необходимости отправляется какой-то ответ, а поток обработки сразу после этого завершается. То есть суть в том, что новый поток запускается лишь тогда, когда нужно отреагировать на действия клиента, и не живет дольше чем надо.

Что это дает? Если у нас будет 1000 клиентов, то маловероятно, что все они одновременно сделают ход. Ну максимум 100 из них могут походить. Таким образом, в каждый момент времени у нас не 1000 запущенных потоков, а в 10 раз меньше (на практике будет еще меньше). В случае чего, можно легко добавить механизм, который будет ограничивать максимально допустимое количество потоков (скажем, не более 16), а «лишние» запросы выстраивать в очередь.
Возможно вы делаете любительский проект и там не будет ста клиентов одновременно. Тогда, если вы не хотите усложнять, то можете вообще не создавать новые потоки на каждый клиентский запрос, а обрабатывать всё в одном. Конечно клиентам придется ждать пока сервер ответит им по очереди. Но ИМХО это решение всё равно будет более верным с архитектурной точки зрения, чем держать долгоживущий поток на каждую сессию. Навряд ли время ожидания будет заметно человеку при количестве клиентов 10-20.

7 мая   games   room   udp