

= Лучшие методы для jME3 разработчиков.

Английская версия: <<jme3/intermediate/best_practices#,Best Practices>>


Каждая веха развития проекта игры состоит из фаз: Планирование, разработка, тестирование и выпуск. Каждый этап развития требует, как правило, обновление ресурсов разработки игры.


Эта страница - коллекция рекомендаций и опытных подсказок. Не стесняйтесь добавлять свои собственные!



== Требования и планирование.

Если Вы - новичок, Вы должны сначала прочитать некоторые статьи о разработке игры link:http://www.hobbygamedev.com/digests/?page=free[read some] link:http://gamasutra.com/[articles about] link:http://www.google.com/search?q=3d+game+development[game development]. Мы не сможем осветить все общие вопросы здесь.



=== Список требований:

Устройте себе краткий обзор будущей игры, и ответьте на некоторые вопросы:


*  Преследуемая цель при создании игры.
**  Приведите идею своей игры в одном предложении. Если сделать этого не удается то разработка игры по началу для вас будет очень сложной. +
Например “Ремесло за днем, бой ночью!
**  Кто целевая аудитория? Вы делаете ее для себя, или вы пытаетесь привлечь большую аудиторию?

*  Какой тип игры.
**  Точка наблюдения в игре (положение камеры)? Каким персонажем (или же персонажами) управляет игрок? (если это применимо).
**  Время, которое вы можно уделить разработке вашей игры.
**  Жанр, история, сюжет или это будет просто песочница без сюжета.

*  Геймплей.
**  Как игра начинается и как она закончится? (если такое имеет место).
**  Какими ресурсами игрок может управлять. Какие ресурсы, накопил, продал, потратил? +
Например “очков, здоровье, скорости, золото, опыта, маны.
**  Как игрок взаимодействует с миром. Определите механику и правила взаимодействия.
**  Каковы границы локаций или же это открытый мир.

*  Мультимедийные ресурсы.
**  В каких ресурсах вы будете нуждаться? Как вы хотите их получить? +
Например, модели, ландшафты, материалы, текстуры, звуки, музыка, голоса, видео, сцены, разговорный/письменный диалог, карты уровня, задания, история, ИИ.

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



=== Планирование вех развития.

Используйте link:http://en.wikipedia.org/wiki/Issue_tracking_system[системы для отслеживания проблем]. Обрисуем в общих чертах этапы разработки при отслеживании и, возможно, обновлении игры:


.  Pre-Alpha разработка
**  Работа художника: Разработка дизайна персонажей, локаций, всех основных моментов.
**  Дизайн меню, панелей и пр.
**  Разработайте хотя бы один полностью рабочий уровень игры прежде чем вы могли бы сообщить об Альфа-выпуске.

.  Alpha выпуск
.  Pre-Beta разработка
**  Работа художника: Замените все временные ресурсы игры реально теми которые будете использовать.
**  Все члены команды по разработке игры должны проводить оптимизацию игры на своем уровне (художник оптимизирует текстуры, кодеры код, моделеры модели и т.д.).
**  Объявите о заморозке ресурсов игры до выпуска Бета версии (отсутствие необходимости оптимизировать ресурсы).

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

.  Gamma выпуск, Delta выпуск … = Release Candidat
**  Думаете это все? Проведите тестирование, сбор информации и рецензий (всевозможные голосования, бланки опроса вам в помощь).
**  Проведите последний жесткий тест для отлова скрытых ошибок.

.  Omega = заключительный выпуск

Ваша команда должна быть в курсе именования стадий проекта и их нумераций. Нумеруйте файлы на этапах разработки (m1, m2, m3), греческими буквами (например, альфа, бета, гамма, дельта), версионная нумерация (например, “2.7.23-1328), или комбинации всего этого.



=== Контролируйте изменения в файлах проекта.

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


*  Вам будет приятно знать что сделанные вами изменения сохранены где то помимо вашей папки, это повышает надежность целостности данных.
*  JmonkeyEngine SDK поддерживает контроль версий, таких как Subversion, Mercurial, и Git.

Если Вы не знаете что выбрать то Subversion - хороший выбор для начинающих.


*  Настройте свой собственный локальный сервер или получите свободное место в открытом источнике таком как Sourceforge, Github, bitbucket (поддерживает частные проекты), Java.net, Google Code…


== Pipeline: Мультимедийные ресурсы.
[cols="2", options="header"]
|===

a|Это можно нужно делать.
a| Это делать не рекомендуется нельзя.

a| Сохраняйте текстуры моделей вашей игры в assets/Textures. 
a| Не ссылайтесь на текстуры или модели вне вашего проекта JME. 

a| Сохраняйте звуки, музыку в assets/Sounds. 
a| Не ссылайтесь на аудио файлы вне своего проекта JME. 

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

a| Используйте только Diffuse Map, Normal Map, Glow Map, Specular Map. 
a| Не используйте не поддерживаемые свойства материала, которые не перечислены в Кратком обзоре Материалов <<jme3/advanced/materials_overview#,Materials Overview>>. 

a| Используйте UV текстуры / атлас-текстуры / запекание для каждой текстуры 
a|

a| Конвертируйте новые модели в j3o. Переместите j3o файлы в assets/Models. 
a| Не ссылайтесь на файлы Blender/Ogre/OBJ в своем коде, потому что эти не оптимизированные файлы не упакуются в JAR.

|===

Узнайте детали о Pipline: Мультимедия ресурсы здесь.



== Этап разработки.

“+
“



=== Наследование от SimpleApplication.

Каждая jME3 игра сосредоточена вокруг одного главного класса, который (прямо или косвенно) наследуется от com.jme3.app. <<документация/jme3_ru/начальная/знакомство_с_простым_приложением#,SimpleApplication>>



““


Для Ваших будущих релизов игры вы захотите положиться на свою собственную структуру (основанной на jME): Ваша начальная структура наследуется от SimpleApplication jME и включает ваши начальные методы для того, чтобы загрузить, обновить и установить сцены, ваши начальные навигационные методы, ваши экраны загрузки и худ'ы, базовые модели NPC, физика, сетевая синхронизация, и т. д.


+




=== С чего начинать?

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


.  Удостоверьтесь, что структура игры, составленная вами (переключение экрана, сетевая синхронизация, загрузка/сохранение) имеет под собой здравую мысль.
.  Начните с реализации самой сложного момента игры – того, которая налагает большинство ограничений на структуру вашего проекта (например: многопользовательская организация сети или локальная. )
.  Добавляйте только одну большую опцию за один раз. Если есть сложные взаимодействия (такие как “организация сети + физика), начните с маленького и проложите себе путь. Старт с целой сцены вводит слишком много дополнительных возможных источников ошибки.
.  Художественные оформления низкой сложности (аудио и визуальные эффекты) добавьте в конце.
.  Тестируйте разработанные код по окончании какого либо этапа разработки (выберите сами).

““_drop_



=== Эффективный способ добавить пользовательские методы и поля.

*Избегайте анти-патерна:*+
`Node`–`MyMobileNode`–`MyNPC``MyFighterNPC``MyShopKeeperNPC``MyNPC`+
““


Вы пишете Java классы называемые `Controls` для реализации ваших игровых объектов, и определяете сущности в атрибутах и поведениях. В jME, `Spatials` (`Node` или `Geometry`) являются визуальным представлением в игре графа сцены.


*  В игре все состоит из *методов* -– Все методы являются нейтральными, только их _атрибуты_ определяют чем _они_ является (человек это или кирпич). В Jme мы называем эти поля класса из Spatials “пользовательскими данными. +
Пример: Игроки имеют поля класса для `ID, здоровье, монеты, инвентарь, оборудование, профессии`.
*  Компоненты игры имеют *поведение* – поведение системы обмениваться информацией о состоянии игры и изменять атрибуты. В Jme эта игровая механика реализуются в методе `Update()`, главный метод обновления в игре. +
Пример: У игроков есть *методы*, такие как `walk(), addGold(), getHealth(), pickUpItem(), dropItem(), useItem(), attack()`.

*Follow the Best Practice:*““
`<<jme3/advanced/spatial#,setUserData()>>`


*  Use <<jme3/advanced/custom_controls#,Controls>> and <<jme3/advanced/application_states#,Application States>> to define custom behaviour systems.




If your game is even more complex, you may want to learn about “real Entity Systems, which form a quite different programming paradigm from object oriented coding but are scalable to very large proportions. Note however that this topic is very unintuitive to handle for an OOP programmer and you should really decide on a case basis if you really need this or not and gather some experiences before diving head first into a MMO project emoji:smiley


*  link:http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/[http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/] 
*  link:http://www.gamasutra.com/blogs/MeganFox/20101208/88590/Game_Engines_101_The_EntityComponent_Model.php[http://www.gamasutra.com/blogs/MeganFox/20101208/88590/Game_Engines_101_The_EntityComponent_Model.php]
*  link:http://gamedev.stackexchange.com/questions/28695/variants-of-entity-component-systems[http://gamedev.stackexchange.com/questions/28695/variants-of-entity-component-systems]
*  link:http://louisstowasser.com/post/19279778476/entity-component-systems-inheritance-vs-composition[http://louisstowasser.com/post/19279778476/entity-component-systems-inheritance-vs-composition]
*  link:http://t-machine.org/index.php/2012/03/16/entity-systems-what-makes-good-components-good-entities/[http://t-machine.org/index.php/2012/03/16/entity-systems-what-makes-good-components-good-entities/]
*  link:http://entity-systems.wikidot.com/[http://entity-systems.wikidot.com/]


=== Хороший способ получить доступ к функциям игры.

<<документация/jme3_ru/начальная/знакомство_с_простым_приложением#,SimpleApplication>> предоставляет вам доступ к особенностям игры таким как rootNode, assetManager, guiNode, inputManager, audioManager, physicsSpace, viewPort, и camera. Но что, если Вы нуждаетесь в этом из другого класса? Не наследуйте SimpleApplication во второй раз и не раздавайте тонны объектных ссылок в конструкторах! Если необходим доступ к объектам уровня приложения из другого класса, что этот класс должен быть выполнен как <<jme3/advanced/application_states#,AppState>>(узнать детали здесь).


У AppState есть доступ ко всем особенностям игры в SimpleApplication через `this.app` и `this.stateManager` объекты. Пример:


[source,java]

----
Spatial sky = SkyFactory.createSky(this.app.getAssetManager(), "sky.dds", false);
...
this.app.getRootNode().attachChild( sky );
----


=== Хороший способ осуществить логику игры.

Поскольку ваша находящаяся в SimpleApplication игра становится более продвинутой, вы вставляете все больше взаимодействий в метод `simpleUpdate()` и ваш `simpleInitApp()` метод становятся более длинным и длинным. Это лучшая практика, чтобы переместить блоки механики игры в повторно используемые составляющие собственные классы. В jME3 называют эти используемые классы `Controls` и `AppStates`.


*  Используйте <<jme3/advanced/application_states#,AppStates>> для реализации _глобальной механики игры_.
**  Каждый AppState класс вызывает свой собственный `initialize()` и `cleanup()` методы когда он часть или отделен от игры.
**  Каждый AppState класс управляет своим собственным безопасным `update()` методом, который подключается к основному simpleUpdate() методу.
**  Вы указываете что произойдет если AppState делает паузу/возобновление.
**  Вы можете использовать AppState чтобы переключиться между наборами AppStates.
**  У AppState есть доступ ко всему в SimpleApplication (rootNode, AssetManager, StateManager, InputListener, ViewPort, и т.д.).

*  Элементы <<jme3/advanced/custom_controls#,управления>> используются для реализации _поведения в игре_.
**  Средства управления добавляют тип поведения (методы и поля) Spatial (игрок, NPC).
**  Каждый элемент управления имеет собственный `controlUpdate()` метод, который подключается к `simpleUpdate()` методу.
**  Каждый Spatial может быть под влиянием нескольких контролов. (!)
**  Каждый Spatial должен иметь свой контроль.
**  Контроль только управляет доступом к Spatial к которому присоединен (и его sub-spatials).





Controls and AppStates often work together: An AppState can reach up to the application and `get` all Spatials from the rootNode that carry a specific Control, and perform a global action on them. Example: In BulletPhysics, all physical Spatials that carry RigidBodyControls are steered by the overall BulletAppState.





Read all about <<jme3/advanced/custom_controls#,Custom Controls>> and <<jme3/advanced/application_states#,Application States>> here.



=== Optimize Application Performance

*  <<jme3/intermediate/optimization#,Optimization>> – How to avoid wasting cycles
*  <<jme3/advanced/multithreading#,Multithreading>> – Use concurrency for long-running background tasks, but don't manipulate the scene graph from outside the main thread (update loop)!
*  You can add a <<sdk/debugging_profiling_testing#,Java Profiler>> to the jMonkeyEngine SDK via Tools → Plugins → Available. The profiler presents statistics on the lifecycle of methods and objects. Performance problems may be caused by just a few methods that take long, or are called too often (try to cache values to avoid this). If object creation and garbage collection counts keep increasing, you are looking at a memory leak.


=== Don't Mess With Geometric State

*These tips are especially important for users who already know jME2.* Automatic handling of the Geometric State has improved in jME3, and it is now a best practice to _not_ mess with it.


*  Do not call `updateGeometricState()` on anything but the root node!
*  Do not override or mess with `updateGeometricState()` at all.
*  Do not use `getLocalTranslation().set()` to move a spatial in jME3, always use `setLocalTranslation()`.


=== Maintain Internal Documentation

It's unlikely you will fully document _every_ class you write, we hear you. However, you should at least write meaningful javadoc to provide context for your most crucial methods/parameters.


*  What is this? How does it solve its task (input, algorithm used, output, side-effects)? 
*  Write down implicit limits (e.g. min/max values) and defaults while you still remember.
*  In which situation do I want to use this, is this part of a larger process? Is this step required, or what are the alternatives? 

Treat javadoc as messages to your future self. “genNextVal() generates the next value and “@param float factor A factor influencing the result do _not_ count as documentation.



== Debugging and Test Phase

*A <<sdk/debugging_profiling_testing#,Java Debugger>>* is included in the jMonkeyEngine SDK. It allows you to set a break point in your code near the line of code where an exception happens. Then you step through the execution line by line and watch object and variable states live, to detect where the bug starts.


*Use the <<jme3/advanced/logging#,Logger>>* to print status messages during the development and debugging phase, instead of System.out.println(). The logger can be switched off with one line of code, whereas commenting out all your `println()`s takes a while.


*Unit Testing (link:http://download.oracle.com/javase/1.4.2/docs/guide/lang/assert.html[Java Assertions])* has a different status in 3D graphics development than in other types of software. You cannot write assertions that automatically test whether the rendered image _looks_ correct, or whether interactions are _intuitive_. Still you should <<sdk/debugging_profiling_testing#,create simple test cases>> for individual game features such as loaders, content generators, effects. Run the test cases now and then to see whether they still work as intended – or whether they are suffering from regressions or side-effects. Keep the test classes in the `test` directory of your project, don't include them in the distribution.


*Quality Assurance (QA)* means repeatedly checking a certain set of features that must work, but that might be unexpectedly broken as a side-effect. Every game has some crazy bugs somewhere – but basic tasks _must work_, no excuse. This includes installing and de-installing; saving and loading; changing options; starting, pausing, quitting; basic actions such as walking, fighting, etc. After every milestone, you go through your QA list again and systematically look for regressions or newly introduced bugs. Check the application _on every supported operating system and hardware_ (!) because not all graphic cards support the same features. If you don't find the obvious bugs, your users will, and carelessness will put them off.


*Alpha and Beta Testing* means that you ask someone to try to install and run your game. It should be a real user situation, where they are left to figure out the installation and gameplay by themselves–you only can include the usual read-me and help docs. Provide the testers with an easy method to report back what problems they encountered, what they liked best, or why they gave up. Evaluate whether reported problems are one-off glitches, or whether they must be fixed for the game to be playable for everyone.



== Release Phase


=== Pre-Release To-Do List

*  Prepare a web page, a cool slogan, advertisements, etc
*  Verify that all assets are up-to-date and converted to .j3o. 
*  Verify that your code loads the optimized .j3o files, and not the original model formats.
*  Prepare licenses of assets that you use for inclusion. (You _did_ obtain permission to use them, right…?)
*  Switch off fine <<jme3/advanced/logging#,logging>> output.
*  Prepare promotional art: The most awesome screenshots (in thumbnail, square, vertical, horizontal, and fullscreen formats) and video clips. Include name, contact info, slogan, etc., so future customers can find you.
*  Prepare a readme.txt file, or installation guide, or handbook – if applicable.
*  Get a certificate if one is required for your distribution method (see below).
*  Specify a link:http://en.wikipedia.org/wiki/Video_game_content_rating_system#Comparison[classification rating] (needed for e.g. app stores).


=== Distributing the Executables

The <<sdk/application_deployment#,jMonkeyEngine SDK helps you with deployment>>: You specify your branding and deployment options in the Project Properties dialog, and then choose Clean and Build from the context menu. *If you use another IDE, consult this IDE's documentation.*


Decide whether you want to release your game as WebStart, desktop JAR, mobile APK, or browser Applet – Each has its pros and cons.

[cols="3", options="header"]
|===

a|Distribution
a|Pros
a|Cons

a|Desktop Launcher +
(.EXE, .app, .jar+.sh)
a|This is the standard way of distributing desktop applications. The jMonkeyEngine SDK can be configured to automatically create zipped launchers for each operating system. 
a|You need to offer three separate, platform-dependent downloads.

a|Desktop Application +
(.JAR)
a|Platform independent desktop application. 
a|User must have Java configured to run JARs when they are opened; or user must know how to run JARs from command line; or you must provide a custom JAR wrapper.

a|Web Start +
(.JNLP)
a|The user accesses a +++<abbr title="Uniform Resource Locator">URL</abbr>+++, saves the game as one executable file. Easy process, no installer required. You can allow the game to be played offline.
a|Users need network connection to install the game. Downloading bigger games takes a while as opposed to running them from a CD. 

a|Browser Applet +
(.+++<abbr title="HyperText Markup Language">HTML</abbr>++++.JAR)
a|Easy to access and play game via most web browsers. Userfriendly solution for quick small games.
a|Game only runs in the browser. Game or settings cannot be saved to disk. Some restrictions in default camera navigation (jME cannot capture mouse.)

a|Android +
(.APK)
a|Game runs on Android devices.
a|Android devices do not support post-procesor effects.

|===

Which ever method you choose, a Java-Application works on the main operating systems: Windows, Mac +++<abbr title="Operating System">OS</abbr>+++, Linux, Android.


The distribution appears in a newly generated `dist` directory inside your project directory. These are the files that you upload or burn to CD to distribute to your customers.

'''

See also:


*  link:http://www.gamedev.net/page/resources/_/creative/game-design/developing-your-game-concept-by-making-a-design-document-r3004[gamedev.net: Developing Your Game Concept By Making A Design Document]
