Показаны сообщения с ярлыком ios. Показать все сообщения
Показаны сообщения с ярлыком ios. Показать все сообщения

понедельник, 9 декабря 2013 г.

5 things you need to implement in any mobile game

русская версия - здесь

I have three posts in drafts(called "You don't need server" and "3 reasons to switch from Asset Server", "Execute impossible to pardon: how to deal with hackers"), but decided to write this one just because it seems more timely than others.

We had discussion with Yuri about what makes any game perfect and what features must be implemented and come up with some common and must-have features:

  • in-app-purchases. No comments here. If you want to make money from your game, you'd better have well-tested, stable in-apps;
  • analytics. The thing is you can not predict user behaviour unless you have any clue what your user is doing in the game. And it's better to have as much information as possible - you know where is your problem in your game mechanics and can easily fix it up;
  • local and remote push notifications. We didn't implement them in the first releases of Road Smash and we feel regret about it. What is the easiest way to let the users play updated game? Obviously, push notifications.I know that users may hate pushes and remove your app just because they are got annoyed by your app, but in 70% it works.
  • Anticheat protection. You know, cheaters always exist, especially on android and you need to prevent your game from being hacked. Somebody may say that you need to protect everything, somebody have an opinion that you need to give up on hackers and let them play. I think that hackers wouldn't pay. They would keep hacking the game until they find something or even delete it from their devices, but they would never pay. So I came up with the decision here: protect only that things that cost money or may affect other users. In business terms there are two most important things for developer: users that bring money. When I say money, I mean in-apps, when I say affect other users, I mean scoreboard, social, competition parts of your game. And you need to keep tiny balance between letting gamers play comfortably and prevent players from stealing your money.
  • Ads. I underestimated role of ads, thought it's annoying and may push your user away. But I was wrong. Firstly, you can integrate ads, so they will become part of your gameplay. Users will want to see some ads just to get some goods instead. And of course, it is a great chance to  get money from users that will never pay :)
The main purpose of any game is to have a lot of users in game and keep them as long as long as possible, letting them pay for any reason. In that meaning these five features described must be implemented, well-tested as soon as possible.

And to make this post more concrete, I have some links to assets to share with you to get that features implemented in the easiest way.
  • in-apps: use unibill. It supports app store, google play, windows store out-of-box, including receipts, subscriptions, etc. Must-have!
  • analytics: there's a wonderful and free plugin, called GameAnalytics. It supports events, heat maps, gameplay stats. If you are fan of old-school analytics, you may check out for my wrapper to Flurry plugin in my github repository, I'll push all the code as soon as I find free time for it. 
  • push notification: there are too many good plugins in assets, so I don't know what's the best option here. I'd recommend pushwoosh service, because it provides a lot of features out-of-box, but let me leave this topic open.
  • anticheat: well... there's no common solution as it really depends on what kind of game you are working on. Maybe some kind of playerprefs encryption, in-apps encryption? Did I miss something?
  • ads: there is a bunch of different options: admob, tapjoy, adcolony, applifier. Some of them provide banner and image ads, some of them kind of video or partnership ads. Choose one you like the most.

вторник, 8 октября 2013 г.

Интересное об app store review

Кто хоть раз заливал приложение в app store, знает, что нужно пройти  этапы ожидания ревью, самого ревью и ready for sale. Ну так вот, несколько интересных моментов об ожидании в app store и ускорении ожидания (только ios и под каждым словом надо ставить имхо, ибо только мой опыт):
  • Среднее время review - 5 рабочих дней
  • Походу действительно весь штат apple сидит в США, поэтому надо еще рассчитывать их часовой пояс(где-то -7 UTC), их локальное рабочее время. Это важно в случае написания писем.
  • Expedited app review(это запрос на review без ожидания в случае, если там оказался критический баг или вот-вот начнется пиар-кампания) работает магическим образом. Более того, мне кажется, это сильно зависит от настроения отвечающего на запрос. Однажды я нашел некритичный баг после двух часов релиза и получил добро на expedited review. В другом случае я за пять дней до пиар-выставки отправил приложение и получил отказ в досрочном ревью. В общем, сделал следующий вывод: на expedited app review нельзя полагаться.
  • Форма Contact us работает оперативно. Даже если они не отвечают, в течение часа что-то происходит.
  • Статья хабра не сработала. Или я не перескочил минимальный порог приложений для ожидания, или звезды ушли в параллельную вселенную, но это нисколько не повлияло на время ожидания.
  • Если прошло более пяти рабочих дней, то стоит черкнуть письмецо через Contact us. Реально, они начинают проверять! 
  • А теперь самое интересное: если в ожидании ревью висит несколько приложений и написать письмо(а там в форме надо написать id-шник приложения, у которого ты хочешь обновить статус проверки/ожидания проверки), то начинают проверять сначала не то приложение, которое ты упомянул в письме. Я думал, это одноразовый баг, но такое поведение повторялось у меня несколько раз! И до сих пор в ожидании ревью висит приложение, на которое я отправил запрос проверить в первую очередь, хотя остальные давно проверены.

понедельник, 25 марта 2013 г.

Особенности национальной верстки или привет зоопарк устройств

Часто приходится писать UI на NGUI с резиновой версткой, для того, чтобы приложение везде выглядело одинаково, еще чаще приходится обсуждать, как это сделать так, чтобы было меньше головной боли. И уже не в первый раз спрашивают требования к нарезке, а также описание процесса как это должно происходить, выкладываю в общий доступ стандарт, чтобы потом можно было просто на него ссылаться.

Итак, как нарезать дизайнерам, а также как это вставить программистам, чтобы на всех девайсах все выглядело одинаково. Но сначала предупреждение:

  • (дизайнерам) Забудьте о pixel-perfect верстке. Ее не будет. Но именно благодаря этому на всех экранах все будет выглядеть одинаково.
  • (программистам) Свыкнитесь, что будут грязные хаки. Это вначале все будет идти гладко да хорошо, а потом вдруг запустишь аpk на 320x240 и удивляешься, что все друг на друга наплыло.
А теперь описание процесса, как мы достигаем вселенского счастья:
  • Есть UI (кнопки, слайдеры, менюшки), а есть бэкграунд(бэк). Ну так вот, бэк - это просто картинка(чаще всего однородная) на заднем фоне. Она нужна для того, чтобы по бокам не было черных фонов.
  • Мы делаем картинку бэка максимально большим и широким, а потом на каждом девайсе скейлим вниз пропорционально по высоте. К примеру, у нас бэк размером 2764 x1536.  На айфоне 5 отрисуется центральные 2726x640 пикселей. Таким образом, получается, что на самом деле наш бэк будет выходить за границы отрисовки. Скейл вверх нежелателен, но если есть ограничение по памяти, то тут никуда не денешься - никто не даст тебе рисовать картинки 4096x4096.
  • Бэк центрируется. Ваш кэп.
  • В нарезке UI сюрпризов нет, нарезаем по обычному.
  • При верстке UI абсолютно все располагаем относительно UIAnchor-ов. Каждый элемент экрана должен принадлежать к какой-то отдельной части. Да, на каждый чих индивидуального пространства создаем отдельный якорь. Типично используемых якорей хотя не так уж и много: центр, левый верхний угол, правый верхний угол, нижние углы по краям, верх и низ. Остальные используются редко.
Да, еще одно ограничение: надо уложиться в 50МБ выходного файла. Это было интро, а теперь требования и настоятельные рекомендации:
  • (дизайнерам) Размеры бэкграундов: 1460x768(HD), 1090x460(SD).
  • (дизайнерам) Верстка под экраны: 1024x768(HD), 2048x1536(если совсем не жалко памяти). 
  • (дизайнерам) Формат картинок: png
  • (дизайнерам) По максимуму избегать альфы (особенность unity - чем больше площадь наложения альф, тем сильнее просаживается fps)
  • (дизайнерам) По максимуму избегать градиента (из-за проблем со скейлом)
  • (дизайнерам) По возможности, используем nine-patch везде, где только можно.
  • (дизайнерам) Шрифты в растровом формате. Более подробно: на ютубе
  • (программистам) UI элементы пакуем в одну текстуру с помощью NGUI, бэки оставляем как отдельные картинки(преимущество от запаковки бэков теряется при огромном размере атласа).
  • (программистам) Сжатие текстур: PVRTC для ios, ETC/DXT(1/5) для android.
  • (программистам) Атласы имеют размеры 2^N
  • (программистам) Все используемые картинки - квадратные.
Может быть, что-то забыл. Что забыл, напишу позже.

понедельник, 18 марта 2013 г.

Разговаривать на общем языке

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

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

Теперь у меня новая проблема: мне надо объяснить моим коллегам, что когда нужна какая-либо функциональность, не нужно страдать синдромом not invented here, нужно взять готовую либу и, если нужно, добавить недостающую функциональность. И, блин, не унаследовав от базового класа, а используя композицию!

Когда я вижу простыню из 900 строк, у меня возникает желание сделать вот так:


Когда я вижу код, в котором вместо стандартных решений использован собственный костыль, у меня вот эта реакция:

 и обязательно ищу в нем баг, чтобы получилось вот так:


Вы не поверите, в 90% я его нахожу :)



Честно, не надо придумывать заново колесо, не надо проявлять фантазию в именах переменных, пользуемся готовыми паттернами, реюзаем код. Проще говоря, для себя вывел следующие правила:
  • Используем единый стиль форматирования, желательно тот же самый, что используется внутри общества, в котором вы живете. Потому что если вы пишете иначе, то вам сложно понять код других программеров, а другие будут плеваться на ваш код. Это все равно как русскому туристу в Китае на рынке договориться о скидке.
  • Самое сложное - придумывать названия (переменным, классам). Это правда. Вот не ленимся переименовать кнопку c ButtonX на MessageButtonBehaviour, anotherTemp на что-либо более подходящее. Я уж молчу о переменных типа ttt, secondVar, var5 (я не шучу - сегодня видел в боевом проекте).
  •  Юзаем паттерны, а не изобретаем их! И не надо делегат называть адаптером(привет андроид!), не надо хвалиться, что придумал новое супер решение, не прочитав шестую страницу банды четырех. 
  • Не забываем, что паттерны паттернами, но принципы KISS и YAGNI игнорировать нельзя. Вообще, сначала применяем здравый смысл, а потом бегите за стереотипным решением.
  •  Изучаем алгоритмы и структуры данных не для того, чтоб победить на топкодере и получить новую футболку, а чтоб знать внутренности структуры данных и алгоритмов, уметь применять на практике и если нужно, написать самому. 
  • И да, если знаем алгоритм или структуру, то применяем готовое решение, а не пишем собственный мегабыстрый класс! Сегодня рыдал от строчки типа такого: public List<string> itemsStack = new List<string>();. Угадайте, что это за структура данных? Угадайте, как автор этого шедевра делал push, pop, top? И это было в файле объемом 900 строк!!!!!1111 Я рискнул рефакторить, но позже понял, что это было плохой идеей, потому что этот гребанный стек применялся еще где-то и передавался ref-ом в какой-то левый класс, который зачем-то использовал его по-своему как список(linkedList)!
  • И да, не боимся пользоваться плагинами, не ходим грудью колесом аля "я все умею!", все самое лучшее уже давно написано за нас. Мы жмотимся на плагин стоимостью 100 баксов, но сами в течение пяти дней готовы допиливать собственный говнокод, почти выполняющий функции того плагина.
  • Не забываем развиваться, изучать новые фичи своего инструмента. Поверьте, вопреки распространенному мнению, обновление - это фикс багов и добавление новых фичей, а не наоборот! И если в языке X появилась штука, которая позволяет в одну строчку написать то, что вы писали в сорок - то даже дурачок Боб, не сумеющий написать свое имя наоборот(с), поймет, что надо юзать эту штуку!
Я очень рад, что в лкш ввели ручную проверку кода. Прикиньте, сколько бы еще можно было родить алгоритмических монстров, способных написать соптимизированную регекспу, но не способных разобраться в лапше из кучи классов. Надеюсь, они вряд ли столкнутся с теми проблемами, c которыми сталкиваюсь я.

P.S. На проекте у нас два программиста: коллега и я. Сегодня произошел священный спор по поводу египетских скобок. Я сторонник египетских скобок, аргументировал так:

  • меньше ненужного пространства при той же читабельности
  • большинство проектов (включая исходные коды юнитеков), написано с применением данного стиля, то есть он стандарт де-факто.
Он аргументировал это так:
  • египетские кнопки это плохо
  • я привык писать по bsd стилю, по-другому не умею.
  • весь мир неправ.
В общем, это был священный спор и каждый остался при своем мнении. Вдруг кто считает иначе, велкам :)








среда, 24 октября 2012 г.

Your app status is In Review

"Your app status in review"(54 minutes ago)
I'm going to bed after reading new e-mail from Apple company with that subject. I hope it will pass review and tomorrow about 4000 users will get an update.

If everything goes ok, we'll have an update for lugat sozluk. Now it's called cep lugat and has redesigned icon(thanks a lot to our designer)!
What's new:

  • iPad support - some users will be really excited with this!
  • better detailed view - it's much better than previous one
  • automatic paste from copy/paste buffer - i heard this feature was implemented in Lingvo and is one of the most favourite users feature, so why not use that?
  • some bug fixes that will prevent from crash, slow working, etc...

What will be in next release?
  • more words - now it has just only osman words. I have some arabian-osman words, they will be added soon. And I would like to add turkish words to dictionary, but I can't find turkish-turkish offline dictionary. If someone has it(not a paper :) ), please tell me.
  • the most searched words - it's awesome thing when you try to memorize words.
  • [maybe] ANDROID version! I have just wrote some sketches and app seems to be working on android simulator, but i don't have any device to test, so it's delayed until I buy an android device.