Разработка клиентской части игры для Windows 8
Добрый день. Стараясь читать материалы о разработке игр нигде не встречал цифр по времени разработки, связи со сложностью и материальными средствам. Об этом хочется поговорить на нашем опыте. Конечно, можно говорить о сложности лишь субъективно, но связь со временем все же будет прослеживаться. Каждый сможет выделить коэффициент связи, бегло просмотрев приложение и статью. Обращаю внимание, разговор пойдет исключительно о клиентской части, серверная часть заранее готова, покрыта тестами и какое-то время работала с клиентами на других платформах. Но не обойдется без небольших изменений серверной части, которые пойдут ей на пользу.
Изначально в наличии были четыре человека, серверная часть, немного наличных денег и абстрактный план в голове. Опыта разработки, на платформе Windows 8, ни у кого из нас не было, поэтому мы спешно читали литературу на тему: Windows 8, C#, .Net. Через два дня мы были готовы начать разработку, получив достаточно информации о структуре Metro приложений, сказался общий опыт работы с .NET. Далее двое начали заниматься прототипированием и экспериментами с платформой, что в будущем дало нужные ответы в максимально сжатые сроки. Параллельно составлялся первый календарный план работ, а последний человек постоянно искал дизайнера, который мог бы взяться за работу вместе с нами. Все продолжалось около 13-15 дней, за это время совместно оценивали присланные наброски частей игры, каждый набросок старались адекватно, с нашей точки зрения, оплатить. Дизайнер же сам выбирал, что он может и за какой срок нам представить, для этого у него в распоряжении была игра, использовавшая в своей основе HTML и JS. Стоимость набросков варьировалась от 1000 до 2000 рублей, в общей сложности рассмотрели 4 наброска. В итоге выбрали макет, получили время в 2 месяца на создание всего и стоимость примерно в 40 000 рублей за весь дизайн. Стоить отметить, что были претенденты с ценами от 100 000 рублей, что нас не устраивало. Далее, по составленному ТЗ, дизайнер присылал элементы, а мы решали подходят они или нет. Каждый элемент был разрезан на кусочки и подогнан в XAML разметке разработчиками, дизайнер использовал только графический редактор, не трогая Blend.
Серверная часть состоит из набора WCF сервисов, использующих привязку wsHttpBinding. Сервисы развернуты на базе Windows Service в среде Windows 2008 R2. Поскольку ранее использовался клиент на HTML, то все вопросы с аутентификацией и авторизацией решало MVC .NET приложение, а сервис принимал его как доверительное. Здесь же использование такого подхода было лишним и сложным так, как Metro приложения умеют взаимодействовать с WCF сервисами напрямую, хотя требуют использование сертификатов и basicHttpBinding. Тестовый сертификат был успешно установлен на машинах разработчиков и привязан к порту, использовавшемуся WCF, а так же получен реальный сертификат для публикации. Получилась такая инструкция для разработчиков:
- Получите сертификат и импортируете его;
- Запустите cmd и просмотрите порты с назначенными сертификатами: netsh http show sslcert, проверте, что на нужных адресах не указан сертификат до нас, нам нужен порт 8734 т.е. записи: 0.0.0.0:8734;
- Добавьте запись с параметрами сертификата, импортированного на первом шаге: netsh http add sslcert ipport=0.0.0.0:8734 certhash=ЗначениеХешаСертификата appid={GUID}. Значение хеш тега берется из поля «Отпечаток» сертификата на закладке «Состав», вводится без пробелов. Далее необходимо проверить наличие записи, повторив второй пункт.
Проблема аутентификации была решена реализацией наследника от UserNamePasswordValidator и использованием Windows Live ID. Полученный валидатор был добавлен в app.config сервисов.
<behaviors>
<serviceBehaviors>
<behavior name="Security">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Thisislogic.XGame.Service.Common.SecurityManager, Thisislogic.XGame.Service.Common" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
В валидаторе разбирается, с использованием секретного ключа сервиса Live ID, пользовательский идентификатор и дается заключение, разрешено использование сервиса или нет.
public class SecurityValidator : UserNamePasswordValidator
{
private const string LiveSecretClientKey = "My_Secret_Key";
public override void Validate(string userName, string password)
{
try
{
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
{
throw new Exception("User or Password not set");
}
var d = new Dictionary<int, string>();
d.Add(0, LiveSecretClientKey);
var jwt = new JsonWebToken(password, d);
var jwtUserName = jwt.Claims.UserId;
if (jwtUserName != userName)
{
throw new Exception("Manipulated Username");
}
}
catch (Exception e)
{
var fe = new FaultException("Unknown Username or Incorrect Password n" + e.ToString());
throw fe;
}
}
}
Позже была добавлена и аутентификация на основе уникального идентификатора пользователя, без участия Live ID. Ниже показан один из вариантов получения уникального идентификатора пользователя.
private string GetHardwareId()
{
var token = HardwareIdentification.GetPackageSpecificToken(null);
var hardwareId = token.Id;
var dataReader = DataReader.FromBuffer(hardwareId);
var bytes = new byte[hardwareId.Length];
dataReader.ReadBytes(bytes);
return BitConverter.ToString(bytes);
}
К моменту согласования дизайнера, плану использования сервисов, окончанию прототипирования созрела декомпозиция работ и примерные сроки, многие из которых после неоднократно пересматривались. План был составлен с использованием MS Project и подсистемы Work Items в TFS 2010. Все задачи были распределены на TFS, в конце каждого рабочего дня получали обновления из TFS в план и смотрели, что и как следует поменять.
В качестве общей точки взаимодействия кода, документов и задач мы использовали TFS. Какие-то обсуждения проходили в Skype, но большая часть проведена лично. Код писался вместе двумя и более разработчиками, что позволило быстро распространить новый для нас подход MVVM, с одинаковым пониманием. Тут нам очень помог плагин Kind of Magic, позволивший не писать тонны кода с INotifyPropertyChanged.
[MagicAttribute]
public abstract class PropertyChangedBase : INotifyPropertyChanged
{
protected virtual void RaisePropertyChanged(string propName)
{
var e = PropertyChanged;
if (e != null)
{
SmartDispatcher.BeginInvoke(() => e(this, new PropertyChangedEventArgs(propName)));
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
protected static void Raise() { }
public event PropertyChangedEventHandler PropertyChanged;
}
Архитектура приложения, в основном, зависела от того, что серверная часть уже есть. Все сводилось к тому, что процесс игры полностью происходит на сервере, клиент лишь, с определенным интервалом, запрашивает данные с сервера и обрабатывает их, отправляя ответы. Была принята терминология событий: серверных и клиентских, при этом сервер никогда не обращается к клиентам, привязка basicHttpBinding не подразумевает дуплекса. Работа с XAML частично была знакома по Silverlight и WPF технологиям, но все же основной опыт работы был с Windows Forms и ASP MVC. На работу с кодом и адаптацию дизайна было потрачено основное время, около 2 месяцев. Написание кода и сопутствующие вопросы ничем особым не отличались от других проектов, рассказывать о привязках, валидации, async-await не имеет смысла. После окончания разработки мы опубликовали в Windows Store игру.
В итоге сводная таблица результатов:
Деятельность | Время | Деньги |
---|---|---|
Обучение | 7 дней | 10000 |
Аренда помещения и технические расходы | 3 месяца | 35000 |
Дизайн | 3 месяца | 40000 |
Начальные эскизы | 15 дней | 6500 |
Зарплата | 2 месяца | 50000 |
Итого | 141500 |
Всего затрачено около 141500 рублей и 3 месяца работы.
Автор: vladimirkolyada