Итог декабря 2017.

Прошлый месяц по ссылке

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

Игра про остров принесла 261$ итого помесячный доход выглядит так

январь 3
февраль 9
март 35
апрель 162
май 169
июнь 200
июль 520
август 515
сентябрь 620
октябрь 630
ноябрь 317
декабрь 261

3441$

Результат получился средним. С одной стороны она продолжит приносить какие-то деньги и дальше, с другой на нее было потрачено примерно три месяца активного труда и в пересчете на помесячный доход она дала мало денег. Впрочем игра про рыцаря все равно выглядит еще более провальной. Потрачены деньги, куча времени а прибыль в декабре только 386$

Поэтому сосредоточусь на своем потенциальном хите, игре про хомячков.

Продуктивность

Рабочих 82 часа. Что для меня больше обычного. Все же освоение чего-то нового может хорошо увлечь. При этом я еще и очень много играл сразу в несколько игр. Основное время заняла oxygen not included, игра по жанру очень близкая к хомякам.

Unity

Продолжаю осваивать юнити. Допиливать свои классы и переделывать свою среду.

1) Нашел самый быстрый способ вывода графики. Благодаря шейдерам и полигональной нарезке он реально быстрый. ИМХО быстрее возможно только в кокосе получить.

2) Написал свою функцию сортировки объектов

public float recalculate_by_siblingindex(Transform tr)
    {

        float z_temp = 0;
        foreach (Transform child in tr)
        {
            var pos = child.localPosition;
            pos.z = -(z_temp);
            child.localPosition = pos;
            z_temp += recalculate_by_siblingindex(child);
            z_temp += 1f;
        }
        return z_temp;
    }

Он выстраивает иерархию через z индекс в зависимости от иерархии вложений.

Почему мне пришлось ее делать? Потому, что стандартный компонент SortingGroup не сортирует коллайдеры.
Зато теперь я могу использовать привычный 2D механизм очередности, как это было в флеше, и как это в общем-то и должно быть в 2D играх.

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

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

4) Много возился с масками. Понял, что для масок нужны другие шейдеры (не самые быстрые) не критично, хотя и не круто.

5) Вставил анимацию из спайна. При чем сделал это через код, что было не так-то просто.

ИСПРАВИЛ ОШИБКУ в официальном runtime коде для спайна, который не давал мне использовать самые быстрые шейдеры. (Самые быстрые шейдеры рисуются только с одной стороны. Сторона рисовки определяется порядком вершин треугольника, таким образом, чтобы они шли по часовой. В самом спайне есть возможность повернуть объект. После чего при сохранении того же порядка вершин треугольников, треугольник встает к нам обратной, невидимой, стороной.)
Так вот в файле https://github.com/EsotericSoftware/spine-runtimes/blob/3.6/spine-unity/Assets/spine-unity/Mesh%20Generation/SpineMesh.cs есть кусок

    var tris = currentSubmeshBuffer.Items;
    int triangleIndex = 0;
    var skeleton = submeshInstruction.skeleton;
    var skeletonDrawOrderItems = skeleton.drawOrder.Items;
	for (int a = submeshInstruction.startSlot, endSlot = submeshInstruction.endSlot; a<endSlot; a++) {			
		var attachment = skeletonDrawOrderItems[a].attachment;
		if (attachment is RegionAttachment) {
			tris[triangleIndex] = attachmentFirstVertex;
			tris[triangleIndex + 1] = attachmentFirstVertex + 2;
			tris[triangleIndex + 2] = attachmentFirstVertex + 1;
			tris[triangleIndex + 3] = attachmentFirstVertex + 2;
			tris[triangleIndex + 4] = attachmentFirstVertex + 3;
			tris[triangleIndex + 5] = attachmentFirstVertex + 1;
			triangleIndex += 6;
			attachmentFirstVertex += 4;
			continue;
		}
        var meshAttachment = attachment as MeshAttachment;
		if (meshAttachment != null) {
			int[] attachmentTriangles = meshAttachment.triangles;
			for (int ii = 0, nn = attachmentTriangles.Length; ii<nn; ii++, triangleIndex++) tris[triangleIndex] = attachmentFirstVertex + attachmentTriangles[ii]; attachmentFirstVertex += meshAttachment.worldVerticesLength >> 1; // length/2;
    }

 

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

Так, вот они просто игнорируют поворот и создают повернутый полигон.

Чтож, я просто проверяю слот на разворот и меняю порядок вершин треугольников!

var tris = currentSubmeshBuffer.Items;
int triangleIndex = 0;
var skeleton = submeshInstruction.skeleton;
var skeletonDrawOrderItems = skeleton.drawOrder.Items;
for (int a = submeshInstruction.startSlot, endSlot = submeshInstruction.endSlot; a < endSlot; a++) {
    
	var attachment = skeletonDrawOrderItems[a].attachment;
	if (attachment is RegionAttachment) {

        if (submeshInstruction.skeleton.slots.Items[a].bone.ascaleX < 0) //Моя правка, чтобы треугольники смотрели в камеру.
        {
            tris[triangleIndex] = attachmentFirstVertex+1;
            tris[triangleIndex + 1] = attachmentFirstVertex + 2;
            tris[triangleIndex + 2] = attachmentFirstVertex + 0;
            tris[triangleIndex + 3] = attachmentFirstVertex + 1;
            tris[triangleIndex + 4] = attachmentFirstVertex + 3;
            tris[triangleIndex + 5] = attachmentFirstVertex + 2;
        }
        else

        {
            tris[triangleIndex] = attachmentFirstVertex;
            tris[triangleIndex + 1] = attachmentFirstVertex + 2;
            tris[triangleIndex + 2] = attachmentFirstVertex + 1;
            tris[triangleIndex + 3] = attachmentFirstVertex + 2;
            tris[triangleIndex + 4] = attachmentFirstVertex + 3;
            tris[triangleIndex + 5] = attachmentFirstVertex + 1;
        }
		triangleIndex += 6;
		attachmentFirstVertex += 4;
		continue;
	}
	var meshAttachment = attachment as MeshAttachment;
	if (meshAttachment != null) {
		int[] attachmentTriangles = meshAttachment.triangles;
		for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++) tris[triangleIndex] = attachmentFirstVertex + attachmentTriangles[ii]; attachmentFirstVertex += meshAttachment.worldVerticesLength >> 1; // length/2;
	}
}

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

6) Еще в юнити есть удобная возможность добавить все графичесские атлассы в одну папку (папка при этом должна быть в папке Resources) и потом просто вызвать код

public static Sprite[] sprites;
...
...
sprites = Resources.LoadAll<Sprite>("Atlases/");

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

7) И в итоге я так и не понял до сих пор на кого рассчитан юнити на дурачков или на профессионалов. С одной стороны там есть много достаточно сложных вещей.
С другой я несколько недель парился с тем, что юнити от балды подставляет позиции и масштабирование, пока не узнал что, оказывается в функции
transform.SetParent(parent) есть второй параметр, который при вызове функции ломает напрочь все позиционирование и масштабирование таким образом, чтобы родитель не оказывал влияние. То есть если у родителя масштабирование 0.5 и мы добавялем объект, то объекту выставялется масштабирование 2, чтобы на выходе получилось 1, которое было до добавления. Так же и с координатами.
И по умолчанию он ВКЛЮЧЕН. Блин, ну если я назначаю родителя, то очевидно не просто так же, а чтобы через родителя в том числе влиять на потомков. А юнити зачем-то ломает эту базовую логику.

В итоге мой кодовый фреймворк-надстройка занимает уже около 100 кб кода. (Спайн и прочие сторонние асеты я конечно не считаю), несколько материалов, пачку разных папок. При всем при этом в редакторе у меня только один объект — камера. И к ней прикреплен только один скрипт, который уже тянет все остальное и в итоге, во время исполнения те же хомяки выглядят вот так в 3D режиме

(Для снимка сделал все объекты активными)

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

Сам перенос хомяков закончен на 90%. Кодовая база в юнити уже 675кб.
Хотел закончить к новому году, но все время то там то там вылазят расхождения старого и нового кода и приходится или переписывать под новый, или создавать реализацию старых механизмов.

Так же решил повысить ставки, и сделать хомяков мультиплеерными.

В целом по юнити было еще много всякого. Все же 80 часов было потрачено.

Акции

Основной счет -1%.
Второстепенный счет -7.5%
Тиньков +1,2%
Крипта -3,7%

По итогам всего 2017 года

Чистое изменение на конец года от всех вложенных денег.

Основной счет -6,9% (Большую часть из которых я потерял вот так)
Второстепенный счет -21,5% (которые он получил еще когда был под ДУ)
Тиньков +3,4%

Тут чистое изменение по итогам года не получается посчитать, потому, что не знаю сколько было на счету в начале года. Поэтому просто перемножу проценты помесячно.
Крипта +67,4%

___
UPD
Правда в итоге я еще раз переписал код спайна, потому, что если представить две кости, которые вложены друг в друга, то если родительская кость повернута, то повернута будет и вложенная кость, но через код указанный выше этого не узнать. В итоге я ввел дополнительный параметр всем костям и считают их фактичесское состояние. В камеру они сморят, или от нее и тем кто смотрит от камеры перестраиваю треугольники.


Автор: Elsper.ru


VN:F [1.9.14_1148]
Rating: 7.2/10 (12 votes cast)

Unity. Тесты скорости разных способов вывода графики.

(Кому лень читать весь пост, читайте вывод в самом конце)

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

Для теста берется 1000 элементов квадратов 200 на 200 между которыми раскидано 16 текстур (200 на 200) с прозрачными и полупрозрачными кусками.
И рандомно меняем им позицию каждый кадр. Плюс часть вариантом тестировались с тряской общей сцены, а не отдельных элементов.

Статья получилась очень специфичная, так, что тем, кому не интересно, лучше пропустить.

Continue reading «Unity. Тесты скорости разных способов вывода графики.»


Автор: Elsper.ru


VN:F [1.9.14_1148]
Rating: 4.0/10 (21 votes cast)

Ноябрь 2017

Прошлый тут

Общий доход с игр 2800. -480 относительно прошлого месяца
Игра про остров принесла только 317. И теперь у нее 3180, не очень много, но и не очень мало.

январь 3
февраль 9
март 35
апрель 162
май 169
июнь 200
июль 520
август 515
сентябрь 620
октябрь 630
ноябрь 317

Новый релиз принес копейки. Только 33 доллара. Это демотивирует, потому, что из всех игр в нее вложено больше всего времени, денег и сил.

Для других проектов не написал ни строчки, потому, что решил переводить оба на Unity и пока трачу время на его осваивание.

Продуктивность.

Выхожу из черной полосы бездельничанья потихоньку.

Хотя rescuetime.com уверяет меня, что я показал результат хуже чем в прошлом месяце на самом деле в ноябре 44 часа программирования, а в октябре только 23 с половиной. Плюс на графике видно, что динамика продуктивности положительная.

Акции

Основной счет -2%
Второстепенный счет +2%
Тиньков +2,2%
Криптовалюты +16,8% (Сейчас 92% счета в кэше, и пока не вижу возможности войти)

В середине месяца снизил долю русских акций, обжегшись на аэрофлоте (вышел в коридоре 157-160 по пути чуток по-спекулировав, сейчас аэрофлот 148.), но снова влез, на этот раз в втб и еще в пять компаний «по мелочи».
По ВТБ сейчас моя средняя 0,056, актуальная цена в данный момент 0,0516, то есть я потерял 7,86%. Собственно если бы я не полез обратно на российский рынок то месяц был бы в плюсе.

Unity

Всерьез и окончательно решил переходить на юнити.
Осталась еще некоторая неуверенность, потому, что не рассмотрел варианты corona и cocos2d…
Но:
1)Бесплатность. После флеша я побаиваюсь бесплатных решений. Рано или поздно с них придется уходить.
2)Язык. Lua у меня сразу вызвал отторжение.

Сравните сами

while num < 50 do
  num = num + 1  -- Нельзя ++ и +=
end

И

while (num < 50) {
  num++; //Можно и ++ и +=
}

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

К тому же у corona мало серьезных проектов.

Cocos2d уже выглядит серьезным решением.
Но я никогда не писал в плюсах, а как только где-то обсуждают плюсы, то о них говорят как о сложном языке.

У юнити же C#, на котором я уже написал хорошее приложение и остался очень высокого мнения о языке.

3)Перспективы. Ну тут очевидно. С юнити всегда можно перейти в 3D разработку, уже как минимум просто повернув камеру. Потому, что на самом деле разработка и идет в 3D.
Но главный секрет в том, что ВСЕ быстрые игры это 3D, даже мои три последние игры написанные на флеше это технически все тот же 3D (но только если они написаны через starling).
Просто, если вы не видите 3D, это лишь значит что его так глубоко обернули, что оставили только 2D абстракцию (как в том же флеше)

Юнити же изначально трехмерный и максимальной быстрый выход к базовым функциям графики подразумевается сам собой. Поэтому, да можно начать с спрайтов, но если захочется максимальной скорости, то переход на уровень mesh потребует только подтянуть некоторые теоретические знания, касающиеся 3D.

С другой стороны это неприкрытое 3D может мешать, когда делаешь плоскую игру. Но это уже дело привычки.

__

Другие системы?
Unreal?
Тот же 3D и слишком дорогой. 5% отчислений хотят.

Флэш?
Он прекрасен для 2D, но годы шоу под названием «похороны флеша» не прошли даром. Он стал отставать от андроида. И время от времени то там то там какая-нибудь ошибка в релизнутой игре происходит. И со временем процент ошибок стал критичной причиной для перехода.

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

__

В целом потихоньку осваиваю. Структура завязанная на компоненты немного сбивает с толку. И из-за нее некоторые вещи выглядят громоздкими, впрочем я уже слепил свой микрофреймворк, который прячет в себе код не имеющий значения для меня, но важный для юнити.
А некоторые вещи наоборот простые. Например загрузка текстуры из файла

Texture2D texture= Resources.Load("имя_файла_без_разрешения", typeof(Texture2D)) as Texture2D;

Файл должен быть в папке Resources.
Нет папки Resources? Не проблема, создай ее где нибудь (на любом уровне вложения) в папке Assets и кидай туда картинки.

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

Ответы есть на каждый запрос, но каждый раз авторы пропускают какую-то важную (для меня) деталь.
Чаще всего дают код, без малейшего пояснения куда это вставить, ответ висит заплюсованный, а мне ничего не понятно.
Так например, маска на меши делается через шейдеры, в гугле есть несколько вариантов этих шейдеров, но нет ни одного ответа, объясняющего куда этот шейдер ставить.
Просто запрос про шейдеры выводит десятки статей о том, как это круто использовать шейдеры и какие интересные вещи с ними можно сделать. О том, что шейдер выставляется в настройках материала ни одной строчки.
Генерация меша? Пожалуйста, вот статья прям в мануале https://docs.unity3d.com/ru/530/Manual/Example-CreatingaBillboardPlane.html
Вон там вершины, нормали, координаты на текстуре. А вот понять КАКОЙ ИМЕННО ТЕКСТУРЕ соответствуют эти координаты я должен как-то сам.
(В итоге я конечно понял, когда где-то увидел пример кода, что берется текстура материала меша)
Как текстуру прилепить к материалу в графичесском редакторе я так и не понял. В коде просто

GetComponent<Renderer>().material.mainTexture = текстура из примера выше;

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


Автор: Elsper.ru


VN:F [1.9.14_1148]
Rating: 6.5/10 (15 votes cast)

Итог октября. Акции падают.

Прошлый тут

Игры

Общий доход с игр 3280. На 20 больше чем месяц назад.

Игра про остров принесла 630.
Итого уже 2863$.

Или если помесячно:

январь 3
февраль 9
март 35
апрель 162
май 169
июнь 200
июль 520
август 515
сентябрь 620
октябрь 630

Работаю сразу над двумя играми. Над хомячками, о которых пишу в блоге, и над игрой про кузнеца, который будет сражаться в подземельях и крафтить себе оружие.

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

Продуктивность

А вот тут полный провал.

Рабочих только 23 часа. И ноябрь на данный момент еще хуже.
Впрочем я не сильно грущу. Из реальных проблем только, что по одной из игр художница сильно опережает меня и непонятно, какие задачи давать. Но вроде пока придумываются и получается поддерживать загрузку работников.

Акции

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

И в общем, казалось было ставшая положительной торговля, снова стала отрицательной.

Основной счет -8%
Второстепенный счет -5,4%
Тиньков +0,4%
Криптовалюта +1% (на фоне роста биткойна это конечно полный провал)

Думаю надо снижать плечо, а то состояния так не накопить ))

Прочее

Треть месяца проболел, что собственно и послужило основным тригером для переходя а режим распиздяя.
Но вообще-то и радоваться жизни тоже надо уметь, а не только думать о работе.
И проводя время за играми или ютубчиком, я откровенно наслаждаюсь состоянием потока.
Самое интересное, что я заметил анализируя свое прошлое, что такие дни/недели когда я нонстопом играл или смотрел сериальчики мне не вспоминаются как «потерянное время».
Потерянным ощущается только время, которое утекало в какую-то прокрастинационную шелуху, которой были наполненные в том числе более успешные по продуктивности месяцы.

А время осознанно и с интересом потраченное на игру оно не «потерянное», а «использованное». Конечно это звучит, как оправдание.
Но мало кому в голову придет называть, например, время потраченное в чтении потерянным. Вот и тут так же.

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

Могу так же добавить, что осознание того, тратишь ли ты своё бесценный ресурс в виде времени или же просто тупо его теряешь, в целом, один из самых жизненно важных навыков.
Как мне кажется необходимый для того, чтобы чувствовать себя счастливым и целостным.
Ведь в некоторых обстоятельствах наоборот работа 10 на 7 является потерянным временем (например нелюбимая или бесполезная работа). Или уже приведенный пример чтения плохих книг.

 


Автор: Elsper.ru


VN:F [1.9.14_1148]
Rating: 6.6/10 (12 votes cast)

Публичная разработка игры. Часть 11

Прошлый пост тут

По итогам прошлого поста было 95 часов.

Сейчас 97 часов. Работал на интерфейсом (одна глупая мелочь отняла пол часа), тестировал отображение разных шкурок у хомяков.

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

На скрине одна из новых комнат и одна из новых шкурок хомяка.

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

104. Полоску строительства сделал. Уход с территории сделал. Попутно исправил еще одну ошибку, хотя пришлось переделать отображение хомяков. Добавил хомякам отображение мыслей/задач (выглядит круто).

108. Активно работал над интерфейсами.

Добавление нового хомяка

Выбор комнаты для строительства

Оба скриншота выглядят невзрачно, потому, что это технические эскизы. Над ними еще не работала художница.

___

110 часов. Поставил некоторые картинки интерфейсов. И частично реализовал поддержку комнат, занимающих три, а не два сектора.

Вообще между 108 и 110 был огромный перерыв в работе. И по итогу весь октябрь получился очень ленивым. Плюс работа над релизом другой игры. Плюс у меня есть еще одна параллельная игра и там накопилось задач для меня.
Но я ведь сразу решил измерять работу не днями а часами.
Поэтому текущее состояние 110 часов. (+15 часов от последнего поста) и 654кб кода (+146кб)

Из ближних планов. Доделать трехсекторные комнаты и продолжить работу над интерфейсами.


Автор: Elsper.ru


VN:F [1.9.14_1148]
Rating: 4.6/10 (16 votes cast)

Спoнcopcкиe ссылки