Ответы пользователя по тегу Разработка игр
  • Как ограничить FPS в OpenGL и glut?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Само ограничение частоты кадров делается очень просто. Снаружи idle-функции нужно содержать переменную с временем последнего вызова idle-функции, а в самой функции нужно просто накопить дельту частоты кадров и вызвать glutPostRedisplay.
    double GetCurrentTime()
    {
    	using Duration = std::chrono::duration<double>;
    	return std::chrono::duration_cast<Duration>( 
    		std::chrono::high_resolution_clock::now().time_since_epoch() 
    	).count();
    }
    
    const double frame_delay = 1.0 / 60.0; // 60 FPS
    double last_render = 0;
    void OnIdle()
    {
    	const double current_time = GetCurrentTime();
    	if( ( current_time - last_render ) > frame_delay )
    	{
    		last_render = current_time;
    		glutPostRedisplay();
    	}
    }


    Данный код является сильно упрощенным механизмом, лишь показывающим общий принцип ограничения частоты кадров. Его можно применять там, где не требуется точный контроль дельты между кадрами. К слову, представление времени в типе double помогает легче находить дельту между кадрами и контролировать ошибку дельты.
    Для более точного контроля частоты кадров стоит обратиться, например, к такому материалу.
    Ответ написан
  • OpenGL не сразу отображает данные из кадрового буфера?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Я не вижу в твоем коде вызова glutIdleFunc. В документации написано что GLUT будет постоянно вызывать переданную функцию в свободное от обработки системных сообщений время. А если в glutIdleFunc передан nullptr (или idle-функция не была задана), то GLUT будет строго ждать следующего системного сообщения.

    Если я все правильно помню, то передача настоящей функции, в которой будет вызываться функция glutPostRedisplay, в glutIdleFunc приведет и к регулярной перерисовке экрана.
    Как правило, в качестве idle-функции в GLUT передают update-функцию, в которой обновляется состояние объектов перед рендерингом.
    Ответ написан
  • Как создается единая физическая-графическая модель?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    И почему крупные компании не могут реализовать свою такую технологию, а покупают ее у других?

    Ответ будет таков
    5a2b8fc21c685856187802.jpeg

    Если компания крута, она, как мыслящий организм, прекрасно поймет, на что время тратить разумно, а на что - нет.

    А почему так мало игр ее использует?

    Скажем прямо, с "еще парой игр" ты слегка промахнулся, ведь Morpheme и Euphoria от Natural Motion используется далеко не в паре просто игр. Полный список игр не раскрывается и не может быть раскрыт по простым причинам своей масштабности. Это очень распространенный и очень мощный инструмент.

    Теперь стал интерисовать вопрос - как прикрутить к этому всему физику.

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

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

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

    Более подробно можно узнать в соответствующих источниках. Нужна секция: "Game engine development".
    Часть этих книг есть в русском переводе.
    Ответ написан
  • Стоит ли заранее заботится о возможности поддержки предыдущих версий многопользовательской мобильной онлайн игры? И как?

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

    Честно говоря, изменение и обновление протокола между версиями продукта - это норма жизни. Только не путай с выпуском обновлений контента, это другой вопрос.

    Можно сказать так: сетевой протокол полезно периодически полностью менять. Это хорошая профилактика от разного рода паразитов твоего проекта. Этакая мера гигиены.

    В процессе обновления протокола мы обычно приходим к одному из двух вариантов:
    • Меняется именно протокол - т.е. набор и содержание пакетов.
    • Меняется сервисный код протокола - т.е. сервисный код для сериализации данных в пакеты.


    В первом случае проблем особых не возникает. Второй случай действительно приводит к нарушению совместимости.
    Чтобы в первом случае добиться совместимости между версиями клиентов и сервера, разработчик обычно использует библиотеки сериализации с поддержкой обратной (или/и прямой) совместимости.
    Примерами таких библиотек являются Google Protobuf, Google Flatbuffers и Cap'N Proto. (да, тега C++ нет, но делу это не мешает)
    Еще я сталкивался с самостоятельно разработанными решениями, которые в разной степени обладают достоинствами приведенных библиотек.

    Есть ли статистика по влиянию обязательных обновлений игры на заинтересованность пользователей?

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

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

    Если мы ведем проект для мобильных платформ, то там ситуация с обновлениями еще интереснее. Тебе никто никогда не скажет, когда в конкретном маркете обновится твоя версия клиента. Выкладка версии - это долгий процесс, синхронизировать его между разными маркетами невозможно. Если у тебя в охвате только GooglePlay и AppStore, то это еще половина проблемы. Обычно маркетов десятки, куда обязательно входит Я.Стор для Android, маркеты от Самсунга, сотовых операторов, мелких лавочников и тому подобного. А если мы заходим в Китай, то число маркетов начинает достигать сотен. И каждый из них твое приложение обновит только когда захочет.
    Это все говорит о том, что обновление сервера и мобильных клиентов - дело несинхронизируемое. Сервер сразу должен быть готов принять обновленные клиенты, поэтому его надо обновить одномоментно с выкладкой версий в маркеты. И в то же время этот новый сервер должен уметь впускать старые клиенты, потому что новые еще не прошли проверку и не выложились для скачивания пользоавтелям.

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

    Да, реально, примеры таких игр уже лет 8 с лишним бороздят просторы Appstore и GP. Названий не дам, рекламой не занимаюсь, пеарить не привык.
    Я в своей работе использую Cap'N Proto и Flatbuffers. Эти две библиотеки покрывают задачи обратной совместимости для протокола и бинарных ресурсов. Использования этих библиотек хватает для свободы изменять данные не боясь потерять клиентов.
    В общем, для решения этой проблемы нужны инструменты обеспечения обратной и прямой совместимости.

    Важно понимать, что совместимость обеспечивать надо не только для протокола, но и для ресурсов клиента.
    Ресурсы могут быть залиты на локальный CDN провайдера пользователя и поставляться по каналу связи с льготным тарифом, но у пользователя может не быть возможности зайти в Appstore и обновить само приложение клиента.
    Поэтому, старый клиент должен иметь возможность запускаться с новыми ресурсами в режиме совместимости.
    Именно эту задачу и решает библиотека Flatbuffers. Она дает возможность обновлять формат бинарных данных вперед и сохранять очень эффективный доступ к ним через старую версию формата.

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

    Может ли задача сопровождения предыдущих версий сильно влиять на архитектуру ПО, скорость и процесс разработки?

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

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

    Если сказать в общем. Да, обеспечивать совместимость - это тяжело. Это ряд архитектурных решений, которые должны быть сделаны правильно. Но если навыки уже есть, если есть опыт, если есть видение проекта, то обеспечение совместимости - штука посильная.
    Ответ написан
  • Как стать художником в геймдеве?

    @MarkusD
    все время мелю чепуху :)
    Юра Березовский , читать сгодится все то, что полезно для укрепления знаний. Книги по архитектуре, машиностроению, анатомии животных и людей, бодибилдингу (т.к. там хорошо рассказывают про моторику и мышцы).

    Конкретнее... Вот, что глазом у жены с полок ухватил:
    * Джеймс Гани - Цвет и свет.
    * Готтфрид Баммес - Образ человека
    * Ф. Делавье - Анатомия силовых упражнений.

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

    Основные инструменты артиста имеют или вот такое название:
    Логотипчики
    148715.gif
    или вот такое:
    huion-logo-1421263547.jpg


    Wacom - дороже и считаются более крутыми. Huion - молодые, дерзкие, все время норовят куснуть у вакома долю.
    Бытует мнение, что даже если сейчас у тебя не получается работать с планшетом, все равно работе с ним стоит уделять минимум 2 часа в день. Привыкнешь.

    ArtStation хорошо мотивирует самообучаться.
    Роман Гура, вроде, иногда берет учебные группы за денежку. Навык Ромка поднимать умеет как у тех, у кого все кисло, так и у тех, кто уже чего-то добился.
    Лео Хао, вроде бы, тоже недавно занимался обучением начинающих.

    А вот на счет того, как развивать свои навыки, есть вот такой совет:
    i9Cbdc9K9XA.jpg

    Кстати, советую запиннить группу "Берешь и рисуешь", она полезная.

    Как-то так, в общем. Дерзай.
    Ответ написан
  • Что такое анимация и с чем ее кушать если OpenGL?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Spine C runtime.
    https://github.com/EsotericSoftware/spine-runtimes...
    Это не серебряная пуля и не идеальные практики. Пожалуй, в плане кода это пример наоборот, как код писать точно не надо.
    Но вот в плане реализации анимаций эта репка тебе очень поможет.

    Суть такова. Есть модель, она статична. Есть отрезок времени (таймлайн), на этом отрезке есть точки - ключевые кадры. Ключевой кадр несет в себе информацию о том, какую часть модели и как сместить. Чем проще инструкция в ключевом кадре, тем удобнее. Масштаб, поворот и смещение многие любят разделять по разным таймлайнам.
    OGL в этом деле не нужен, до поры.

    С помощью SRT таймлайнов можно анимировать объекты в пространстве целиком, но если тебе захочется точно так же анимировать части меша модели, то впереди тебя будут ждать трудности.
    Анимацию меша лучше реализовать на основе скелета. Это дело в двух словах уже не описать, тут лучше читать статьи.
    www.gamedev.ru/code/terms/SkeletalAnim
    www.gamedev.ru/code/articles/skeletal_animation
    https://habrahabr.ru/post/219509/
    https://habrahabr.ru/post/304042/
    www.gamedev.ru/code/articles/?id=4182

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

    Только на одной скелетной анимации далеко все равно не уедешь. Когда требуется на одной модели одновременно задействовать сразу несколько скелетных анимаций, если сделать в лоб, то меш поплывет во все стороны.
    Для смешивания различных скелетных анимаций применяют так называемые Blend Trees (ссылок под рукой нету, так что сорри).

    В общем, как то так анимация выглядит. Анимируем в цикле обновления, вершины трансформируем в момент формирования кадра. OGL нам нужен, собственно, чтобы нарисовать раскоряченый анимацией меш.
    OGL для непосредственного анимирования мешей тебе понадобится только тогда, когда ты достаточно глубоко нырнешь в анимации, в тот же момент ты уже полностью поймешь что от OGL понадобится для этого.
    Ответ написан
  • Как сделать управляемый интерфейс?

    @MarkusD
    все время мелю чепуху :)
    Макар Герасимов , такс, для начала отключись от рисования и восприятия процесса глазами.

    Первое, что тебе надо - это модель игрового поля. Модель - от слова "данных". В первую очередь тебе надо представить игру в виде модели данных, а не визуального представления. Вот давай пробуем...

    Тетрадный лист в клетку напоминает что? - правильно, двухмерный массив. Стало быть, игровое поле удобно представить в виде двухмерного массива. А какой тип ячейки массива? - раз у нас игра про слова, которые по буквам пишутся в клетках, то, пожалуй, в ячейках надо хранить символы.

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

    Хорошо, идем дальше. У нас есть два игрока, которые могут писать слова.
    Ага... Если писать, то надо знать - куда. Пользователю нужно указание, куда он сейчас будет писать - указать ячейку, в которую он сейчас поставит символ. А ячейки у нас в двухмерном массиве. Удобнее всего будет хранить координаты текущей ячейки пользователя!

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

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

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

    И заметь, это все полностью отвязано от графического представления. Сперва всегда надо продумывать именно модель данных.
    На данном этапе описания у нас есть поле, пользователи с их выделениями и введенные слова. Модель данных дает полное представление как ее представлять пользователю.

    Ну разве проблема отрисовать двухмерный массив символов? А по координатам закрасить другим цветом выделенную пользователем ячейку?

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

    Когда твоя модель данных игры будет хоть немного готова, ее можно будет без труда хоть в консоль рисовать, хоть на поверхности окна.
    Модель - это набор классов со связями. Поле, игра, игрок, ход, слово, словарь, таблица введенных слов... символ слова(?). Полный список сущностей ты знаешь лучше меня. Просто думай на уровне данных. Тогда и управлять ими сможешь. :)
    Ответ написан
  • Как устроен игровой протокол передачи данных?

    @MarkusD
    все время мелю чепуху :)
    https://habrahabr.ru/post/209144/
    https://habrahabr.ru/post/209524/
    https://habrahabr.ru/post/213559/

    Оригиналы:
    web.archive.org/web/20190328001900/https://gaffero...

    Дополнительные материалы:
    web.archive.org/web/20190328001900/https://gaffero...

    По этому поводу, в целом, советую почитать блог Гленна Фидлера.

    Так же есть удобные библиотеки, которые сами собой отвечают на остальные твои вопросы:
    https://developers.google.com/protocol-buffers/
    https://capnproto.org/
    Ответ написан
  • Какие есть движки для пиксельных платформеров?

    @MarkusD
    все время мелю чепуху :)
    К списку xmoonlight еще добавляю (все движки позволяют создавать игры с применением Lua):
    1. Defold
    2. MOAI
    3. Urho 3D
    4. Anki 3D
    5. Cocos2d-x
    Ответ написан
  • Как упаковать текстуры в libGDX?

    @MarkusD
    все время мелю чепуху :)
    Андрей, у тебя вопрос, как видно по тексту, немного о другом. По описанию видно что ты перед собой стену видишь, а про дверь в стене даже не подозреваешь. Итак, вот дверь, даже несколько. :)

    Первое - надо понять, насколько много графики у тебя в проекте. Для современного mid-end устройства на андроиде 5.0 совсем не проблема держать 2-4 RGBA текстуры с разрешением 4096 по ребру. Это не говоря о сопутствующих шейдерах, буферах растра/глубины/вершин/индексов. Минимализм в ресурсах приветствуется, но и зажимать себя в тески не стоит.

    Второе - давай взглянем на параграф "Open GL Version" странички https://developer.android.com/about/dashboards/ind...
    OpenGL 3.x занимает большую долю всех устройств. Эта версия OpenGL умеет работать с форматом ETC2 (благодаря заявленной поддержке от GPU), в котором уже можно сохранять альфу. А в вики ( https://en.wikipedia.org/wiki/Ericsson_Texture_Com... ) еще и написано про обратную совместимость.
    Тут в моем опыте пробел, с ETC2 я еще не работал и наглядно про обратную совместимость с ETC1 ничего не знаю. Поэтому предлагаю устроить обмен знаниями в этой теме. :)

    Третье - Аппаратно-поддерживаемых форматов сжатия текстур на самом деле много: S3TC, ATC, PVR-TC. ETC - не единственный. Каждый из форматов поддерживается своим производителем. ATC - Quallcomm; PVR-TC - Imagination Tec. Но вот S3TC (более известный как DXT3/DXT5) поддерживается обоими QC и ImgTec, но тайно. И только ARM Mali поддерживает один лишь формат ETC.
    К чему я это. Тройка профильных форматов и альфу поддерживает, и обрабатывается быстрее того же ETC (и уж тем боле пары ETC1).
    Поэтому может тебе удобнее будет использовать конвертацию в эту тройку форматов?
    У меня на гитхабе есть очень быстрая библиотека для программного чтения PVR-TC.v2 в RGBA буфер, что позволит загрузить текстуры для Mali GPU.
    Ответ написан
  • Деление игры на GameState'ы: как?

    @MarkusD
    все время мелю чепуху :)
    ps. Тут на Phaser.js кто-нибудь пишет, есть смысл вопросы по нему задавать?

    Это не форум, тут формат общения - вопрос-ответ. Один вопрос от тебя и много ответов от других.
    Пиши с тегом javascript или phaser-js и тебе наверное ответят.

    По поводу организации: как душе будет угодно. Но лучше все таки подойти к вопросу аналитически.
    Как у тебя сменяются уровни? Ширма между сценами есть?
    Если есть, то геймплей удобнее сделать двумя стадиями - стадией сцены игры и стадией ширмы. Если ширмы нет и геймплей не прерывается между уровнями, то лучше его оформить одной стадией.

    Вот мой ответ: Подходи к вопросу аналитически, пойми что для твоей структуры геймплея будет удобнее. Информации ты никакой по своему вопросу не дал, так что и ответов внятных вряд ли можно ждать. Асам вопрос очень прост.
    Ответ написан
  • Как бы вы реализовали принятие решений программой в pick'n'point игре?

    @MarkusD
    все время мелю чепуху :)
    Классами это все решать - это бросок самого себя через свое бедро... Убьешься, в общем.

    Читай Шампандара, тебе нужен раздел деревьев поведения (Behavour Tree) и планировщика решений (Goal Planning).
    Любое действие игрока - это триггер. Скапливаясь, или каждый сам по себе, триггеры влияют на внутреннюю память автомата. Автомат просто выполняет то действие, которое соответствует его текущей внутренней памяти.
    Описание автомата лучше всего делать на скриптовом языке (LUA/Python embedded).
    Каждый уровень - это лишь описание автомата в скрипте.
    Сами действия. Куда то перейти итд... Это уже смотря как твоя сцена сделана. Это можно сделать как жесткой анимацией с именем (которую будет запускать автомат), так и с помощью подсистемы AI (в которую и будет отдавать указания все тот же автомат).

    С такой организацией ты себе гору времени и нервов убережешь.
    Ответ написан
  • Каким путем развиваться как специалист в геймдеве?

    @MarkusD
    все время мелю чепуху :)
    За плечами 2,5 курса универа, более менее вменяемо освоен язык С++ и есть понимание как пишутся программы.

    Ты уж прости, в моих словах нет ни капли неуважения, только скепсис. Первое что надо понять - так это что плюсы у тебя не освоены даже на начальном уровне. Нужно подготовиться к тому, что на рабочем месте надо будет сперва забыть все из универа, а потом научиться заново, уже специализируясь в производстве. Для многих людей этот момент является психологическим барьером в начале работы.

    Так вот, нужен ли я буду с знаниями как программируется сама графика и движки, но без умения работать с готовыми решениями?

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

    Ты молодой человек, дело ясное что руки у тебя чешутся за все сразу взяться. Попробуй решить свой вопрос кратковременными занятиями во всех направлениях. Unity тебе поможет быстро вополтить игру в прототипе. Разные MDK к существующим играм помогут со скриптингом/модингом. Пакеты типа SDL/Cocos2d вполне смогут помочь тебе быстро поднять окружение для изучения невидимых с верхнего уровня фишек, типа вот таких:
    habrahabr.ru/post/241760
    habrahabr.ru/post/248381
    habrahabr.ru/post/250467
    habrahabr.ru/post/238425
    habrahabr.ru/post/248313
    habrahabr.ru/post/244367

    А важны всегда все люди. Точно сказать не получится: важнее ли ипользователи UDK чем его создатели. Каждый просто занял свое место в индустрии.
    Ответ написан
  • GameDev - куда "шагнуть", и как туда попасть для обучения?

    @MarkusD
    все время мелю чепуху :)
    Новосибирск значит?..
    Почитай про C#, про Unity. Попробуй себя в создании чего-нибудь в этой среде.
    О плюсах даже не думай. Шарпом владеть легче и спокойнее.

    Твоя первая задача - войти в состав группы разработчиков. В центре и Академе есть несколько контор, кто делает недоигры на Unity. Эта цель на ближайшие год-два, начиная с даты приема на работу.
    Математика на этом этапе поднимается сама собой, без нее у тебя просто ничего не выйдет.
    Цель вторая - сбор информации о внутренней кухне. Алгоритмы, методики, парадигмы/идиомы/шаблоны/подходы программирования. Собирай знания и прокачивайся через Unity. Занять может до года, до двух.

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

    Цель три. Если тебе хочется работать именно в области C/C++, то самое время начинать сползать с шарпа. Это может оказаться болезненным периодом, но иголки в кактусе не бесконечны. Справишься если захочешь.

    Советую прочитать от корки до корки (и гвоздями прибить к мозгу, дабы ни слова не забывалось) книгу Дж. Пойя "Как решать задачу" в редакции от Гайдука. Книга маленькая, но ее надо прочувствовать. В целом-то, с нее и начать свое движение будет полезно.

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