
Today I want to talk about a little-known game engine that we have been using for a year for cross-platform development of mobile games. For 2D, it completely suits us, and the only competitor can be only Unity3d because of its editor. The lack of proper attention to the
MOAI SDK is obviously related to the high entry threshold - the developers themselves (Zipline Games) are positioning their product as "The mobile platform for game developers", although you can understand the installation and configuration of the environment very quickly and easily. Lua.
What I liked so MOAI:- The engine is written in C ++, the game logic is written in Lua. There is support for luajit (on iOS only in interpreter mode)
- Open source. CPAL license - you must specify the logo, title, authors, and a link to MOAI on the boot screen or in the captions
- Cross-platform: Windows, Mac OS X, Linux, iOS, Android, OUYA, and also have experiments with html5 via emscripten. Development is supported on Windows, Mac OS X and Linux. To build on iOS, you need a Mac. Theoretically, adding a new platform is not difficult - you need to write a “host” that will create an OpenGL context and will invoke input processing methods.
- Lua API is very low level. This is a plus and a minus. Lua needs a higher level framework for effective development.
- Inside are cool algorithms and technologies. Renderer with automatic batching (cocos2d seems to have learned this too). Action tree - everything that is periodically updated (animation, physics) is presented in the form of a tree, the parent nodes transmit the past tense (delta) to their children; This allows you to build a hierarchy of animations, stop and continue them at once, change the playback speed
- There is no usual scene graph as in other 2D engines. For dependency processing, dependency graph is used. Objects have many attributes (coordinate, color, shader, ...) - you can set dependencies between them, for example, attach the rotation of one sprite to the X coordinate of another. The engine calculates only the changed attributes, which in theory reduces the cost of updating. In fact, this is similar to the Maya, Nuke node architecture, materials from the UE - attach whatever you want to whatever you want, as long as the type matches. There is a special ScriptNode to which you can add your attributes and set a callback to process them.
- Several classes for working with tilemaps. Hex, diamond, rectangular grid, search path
- There is support for 3D - that is, all the transformations and objects are inherently 3D
Minuses and shortcomings:- Documentation gaps, examples are often non-working. Few community
- For assembly it is used Cmake. There is no one button "to collect under ..." as in Unity or Corona, often it is necessary to struggle with errors of the compiler and linker
- Lua api is not complete. For example, there is often no balance between setters and getters (there are more setters). Therefore, it is useful to understand the writing of binders and expand them if necessary.
- No editor
- The built-in sound engine UNTZ is very primitive. There are binding to fmod, but most likely they are very outdated, because they kind of like nobody uses
- Apparently, the developers didn’t work with the monetization of the framework - we absolutely don’t want to make it paid and closed, and the MOAI Cloud did not pay off. Zipline Games has neither time nor motivation for any nonsense like putting order in order of documentation and examples, everything is basically done by the community. This does not mean that MOAI SDK is dead, no, Zipline Games use MOAI for internal projects, development continues (just recently support for vector primitives appeared through libtess, in the process of developing its own engine for handling simple collisions so as not to drag the whole box2d or chipmunk)
Installation (Mac OS X)
I will describe the installation only on OS X, because I do not have windows systems at hand.
')
Clone the official repository:
git clone https://github.com/moai/moai-dev.git
Run the script that will assemble the host under our system:
cd moai-dev bin/build-osx-sdl.sh
I hope everything passes without errors, then the executable file will be available in release / osx / host-sdl / bin / moai, make a link to it (~ / bin I added to the PATH):
ln -s /Users/vavius/moai-dev/release/osx/host-sdl/bin/moai ~/bin/moai
Run an example, make sure everything works:
cd samples/hello-moai moai
We see a spinning fig and greeting text:
We write on Lua
Let's start with a minimal example - draw a square sprite in the center of the screen:
Code:
Description of what is happening in points:- Create a window and a viewport. Viewport allows you to work in logical coordinates, without being attached to pixels.
- A layer is a container for proping (and everything that can be painted is called propy). The layer can be set to a camera, and only those props that fall into the current viewport will be rendered. The layer is responsible for sorting (rendering order) - there are many options, by X, Y, Z coordinate individually or by vector, by priority (integer), as well as a special kind of ISO_SORT for isometric tile games. Each layer has an MOAIPartition container for optimizing spatial queries - hit test and raycast, inside it uses a multi-level grid.
- We set the render table - a list of renderable objects that will be drawn into the framebuffer in order. Render layer draws all the added props. The table can contain nested tables, which is very convenient for creating a scene manager.
- Deck - an object that defines the visual part. It stores the geometry (in this case, quad - two triangles), UV coordinates, a link to the texture and shader
- Prop is a collective image of an object that is drawn on the screen. In principle, this is not necessarily one separate sprite, but it can also be a 3D mesh and a tile map, depending on the installed deck.
Immediately striking that painfully many lines are needed for the seemingly simple task of drawing a sprite. Most often this is done in one line, but here you need at least six. Therefore, the API provided by the engine is not used "as is", and many write their wrappers on Lua. In the C ++ part of the MOAI SDK, many familiar things are missing, such as the texture cache, loading atlas sprites, the scene manager and transitions between them, all sorts of buttons, and other gui elements. All this is proposed to implement on Lua. This is unlikely to have a significant effect on overall performance, since most operations are performed only during scene initialization. Of course, you need to be wise in writing code, do not produce unnecessary tables, use old objects, cache what you can.
Absolute freedom
Suppose we do not want a square quad, but we want a trapezoid, instead of setRect we use setQuad:
local deck = MOAIGfxQuad2D.new () deck:setTexture ( "moai.png" ) deck:setQuad ( -64, 64, 64, 64, 100, -64, -100, -64 )
Here is what comes out:
Let's cover the background entirely with our picture. You can use GL_REPEAT on a texture, but it works only for sizes multiple to powers of two, and you won’t be able to use the picture from the atlas. Therefore, we use the MOAIGrid class:
local deck = MOAIGfxQuad2D.new () deck:setTexture ( "moai.png" ) deck:setRect ( -0.5, -0.5, 0.5, 0.5 ) local grid = MOAIGrid.new () grid:initRectGrid ( 1, 1, 128, 128 ) grid:fill ( 1 ) grid:setRepeat ( true, true ) local prop = MOAIProp.new () prop:setDeck ( deck ) prop:setGrid ( grid ) layer:insertProp ( prop )
MOAIGrid is needed for working with tiles; here we initialize a map from one tile of 128x128 in size. Then set it to index 1 using the fill method. Some types of decks support indexing, for example, MOAIGfxQuadDeck2D allows you to specify many pairs of vertex and UV coordinates for a single texture, which is used to represent the sprite atlas. In this case, there is only one index in our deck. We turn on the repetition and indicate that we should use the grid for rendering.
At this stage it is very easy to make an animated scrolling background. Add one line to the end:
prop:moveLoc ( -128, 0, 0, 4, MOAIEaseType.LINEAR ):setMode ( MOAITimer.LOOP )
Just in the cycle we move our prop to the width of one tile, and the engine itself substitutes the missing pieces in order to tile the entire screen:
Animation and Action Tree
Moving and rotating objects, as well as setting animation playback modes:
local move = prop:moveLoc ( 200, 0, 0, 2 )
By default, animations are added to the action tree root. But you can group them:
local action = MOAIAction.new () action:addChild ( move ) action:addChild ( rot ) action:start () action:throttle ( 0.5 )
Now we can stop and start both animations at once, and use throttle to set the playback speed.
The sequence of actions is implemented through Lua Corutina. MOAI provides the MOAICoroutine class inherited from MOAIAction, which allows you to add cortutins to the action tree. The blockOnAction function calls yield until the action ends.
Move the picture left and right, and when reaching the extreme points do one full turn:
local function func () local distance = 200 while true do local action1 = prop:moveLoc ( distance, 0, 0, 2 ) MOAICoroutine.blockOnAction ( action1 ) local action2 = prop:moveRot ( 0, 0, 360, 2 ) MOAICoroutine.blockOnAction ( action2 ) distance = -distance end end local thread = MOAICoroutine.new () thread:run ( func )
Conclusion
The article deals with very primitive examples - my goal was to show some aspects of the Lua API, namely its low level and modularity. MOAI SDK tries not to make any decisions for us, does not force everything to be done in any one generally accepted way, but leaves complete freedom. Of course, the community has already implemented several high-level wrappers on pure Lua, with texture caching, gui elements, scene manager, etc.
I would not advise using MOAI SDK in production without C ++ knowledge, the nuances of assembling for the chosen platform and the willingness to change something inside. Almost everyone who uses the MOAI SDK has its own fork, which is slightly different from the main branch. Historically, this is due to the fact that Zipline Games did not have time to pull pull requests. However, now some members of the community got access to the official repository and the development went brighter.
Due to openness, we were able to implement live reload of the code and resources directly to the device. Now I slowly saw the editor, in the image of Unity3d. Although things went slower after earned a live reload'a - it suffices with a head for an incredible acceleration of development. Interfaces are collected in a vector editor and export directly into the code (of a declarative form, here is an example:
gist.github.com/Vavius/9868572 ). Of course, all this could be attached to any engine, to cocos2d-x without any problems at all, to the Crown more complicated, but also real. In general, for 2d games we moved from coconut to MOAI and do not regret at all, here somehow more and more grown-up, more flexible and steeper + the code is clean and beautiful.
Links
getmoai.com - official site
getmoai.com/docs/annotated.html - docks
moaiwebsite.imtqy.com is an unofficial site, sawn by the community. Someday will be a new face
github.com/makotok/Hanappe is a high-level OOP-style Lua framework. Of all such decisions, only this one is being developed and maintained.
Update:moaifiddle.com/Q09BJWGMW6/3 - js engine version. Now you can play with the engine without installation!