Navigation
Making a Simple Game

From Wiki.ludiloom.com
Jump to: navigation, search

In order to guide you through the process of creating a game in ludiloom, we used the project Dominoes as an example. Dominoes is a simple physics game designed to be a a tutorial or starting point to develop other simple games. You can create an arena and start form there or just to take a look at the code and object structure.

Every script, model and object used in the game are visible in the arena. The arena will contain a copy of every Object Template that exists in the RuleBook, and use those objects throughout the game code. There is only a small script in the rulebook that creates a “GameController” object in case there is none. This way, you can start playing and changing your game from the first moment you create and enter your arena, in a mechanism we'll call “instant arena”. The changes you make will only be stored and visible inside your arena. It is always a good idea to implement “instant arena” mechanisms, as described in the rest of this tutorial, because it makes it easier to create test scenarios, expand the game and change it.

Contents


Objects in ludiloom are abstract structures that can be used in different ways. They can be used much like classes in object-oriented programming languages, except that instead of “methods” they have “interactions”, instead of “parameters” they have “attributes” and “representations”, instead of instantiated they are cloned from another Object or Object Template. The ludiloom objects have a flexible “container” mechanism, meaning that any object may contain any other objects, so you can have objects that are just used to keep your simulation objects neatly arranged. Next we will present some “object patterns”, i.e., types of objects that are found in most games inside ludiloom and that may give you some ideas to build your game.

Game Controller

Typically, every game will have a “main object”, which call Game Controller that controls the overall game state, i.e., players joining and leaving the game, rounds, scores, cameras, game modes, main game mechanics, etc. In Dominoes, as in every game created by the Ludiloom team, this object can be found on the Tree with the name “GameController” and contains the user interfaces and most of the game logic, since this game only has one game mechanic: placing objects in the terrain and then knock them down.

On Load

First things, first! The onLoad is an interaction that can be found inside the Game Controller object. It is executed when this object is loaded (there is an "onLoad" listener in the object), hence every time the player enters in the arena. This is one of the most important scripts in the game because it sets the game environment before the user starts interacting with the game. It is perfectly plausible to place the “OnLoad” script in the Arena object, but we choose to put it inside the Game Controller to allow the process of “instant arena”. The script performs several tasks, such as:

  • Check and initialize important objects.

Consider this piece of code:

  1. if #Arena:getObjectsByName("Pieces") == 0 then
  2. Pieces = Arena:createObject("Pieces","Pieces","");
  3. else
  4. Pieces = Arena:getObjectsByName("Pieces")[1];
  5. end

“Pieces” is an object used to contain the pieces of domino in the game, so it's important that this object always exists in the Arena. The code above checks if there is a “Pieces” object. If there isn't one, creates it. This is also part of the “instant arena” mechanism. When an arena is created, the on load script creates all the important objects. Also note that the object “Pieces” will be referenced by Lua the variable “Pieces”. We do this because these important objects are used very often in the rest of the game code. The variable is not “local” meaning that it will be accessible from any other ludiloom interaction, thus avoiding unnecessary Arena:getObjectsByName("Pieces")[1] scattered across the other scripts. We always capitalize these special global variables so they can be easily recognizable. We initialize the camera in this script following the same principle.

  • Initialize the game state.

The on load script performs several tasks that ensure that the game variables are properly initialized and consistent with the graphical interface. In Dominoes, we reset the force and trail variables with the following code:

  1. force = 5;
  2. GameController:exec("mouseLeavePower");
  3. trail = false;
  4. GameController:exec("toggleTrail");

And center the confirmation popup boxes like this:

  1. local resX, resY = System.getResolution();
  2. this:getOverlay("delete_confirm"):setPosition(resX/2-175,resY/2-75);
  3. this:getOverlay("delete_confirm"):setVisible(false);
  4. this:getOverlay("quit_confirm"):setPosition(resX/2-175,resY/2-75);
  5. this:getOverlay("quit_confirm"):setVisible(false);
  • Configure the terrain. The following code configures the terrain if the terrain doesn't exist yet, so we can have “instant arenas”:
  1. if not Terrain.isEnabled() then
  2. Terrain.init();
  3. Terrain.setEnabled(true);
  4. Terrain.setWorldSize(1500);
  5. Terrain.setWorldHeight(300);
  6. Terrain.setTexture(0, MediaItem.newMI("0000000000000836"));
  7. Terrain.setNormalMap(0, MediaItem.newMI("0000000000000837"));
  8. Terrain.setTiling(0,0.0051);
  9. Terrain.commit();
  10. end
  • Configure the Arena. The environment and physics have to be configured in here, again because of “instant arenas” mechanism. In the next script snippet we configure the ambient light, the shadows and the physical properties:
  1. Arena:setLightColour(180,180,180);
  2. Arena.setShadowTechnique(1);
  3. Arena.setShadowFarDistance(250);
  4. Arena.setGravity(-200);
  5. Arena.setPhysicsSkinWidth(0.025);
  6. Arena.setPhysicsIterations(32);
  • Create listener. Keyboard events as well as mouse events on the terrain are caught by the Arena object. We have to create the listeners in this onLoad script. The code bellow creates a “key pressed” listener for the 'x' key to delete the piece. Then, there are three mouse move listeners and two mouse click listener. For more details on how to code listeners, see the event, listener and InterModel pages.
  1. local im = InterModel.newIM();
  2. Arena:setKeyPressedListener("\45",this,"deletePiece",im);
  3.  
  4. im:setListenerAbsolutePosition("position");
  5.  
  6. Arena:setMouseMovedListener(this,"mouseMove",im,false,false,false,false,"1");
  7. Arena:setMouseMovedListener(this,"movePiece",im,false,false,true,false,"1");
  8. Arena:setMouseMovedListener(this,"rotatePiece",im,true, false,false,false,"1");
  9. Arena:setMouseButtonPressedListener(MOUSE_BUTTON_LEFT,this,"putPiece",im);
  10. Arena:setMouseButtonPressedListener(MOUSE_BUTTON_RIGHT,this,"deselectPiece",im);

User Interface

There isn't much to say here. The user interface is the set of overlays, mostly panels and buttons. You may easily browse the tree to see how the overlays and listeners were configured. The piece palette deserves a deeper explanation, though. The overlay pieces_palette contains a scroll pane overlay, so it can be extended to include more piece models without deep changes to the user interface.

Game logic

The game logic is implemented in the several interactions inside the GameController. The most important are the "putPiece", "movePiece", "pushPiece" and "deletePiece".

Piece

The main game mechanic, putting pieces on the terrain, is implemented in the interaction “putPiece” in the GameControler. Every time the player puts a piece on the terrain, we make a clone of the object “Piece” and add she correct model to it:

  1. local piece = Pieces:copyObject(Piece, "piece");
  2. piece:setAttribute("model",selectedModel);
  3.  
  4. local m = piece:copyRepresentation(
  5. Shapes:getModel(selectedModel),
  6. "model");
  7. m:setPosition(posX,0,posZ);

In a normal ludiloom game, we would leave “Piece” as an object template configured in the RuleBook, but that would make it impossible for to change the object inside your arena.

Pieces

The object “Pieces” is just a container for all the “Piece” objects. We put all the pieces in a container for 3 reasons:

  1. To keep the objects tree organized and easier to read.
  2. To iterate them, like we do in the “resetPositions” interaction:
  1. for i,v in ipairs(Pieces:getObjects()) do
  2. v:getModel("model"):setPosition(v:getAttribute("px"),v:getAttribute("py"),v:getAttribute("pz"));
  3. v:getModel("model"):setRotation(v:getAttribute("rx")*100,v:getAttribute("ry")*100,v:getAttribute("rz")*100);
  4. end
  1. To delete them all easily, as you can see in “deletePieces”:
  1. Pieces:removeAllObjects();

Shapes

This object contains the 3d models of the pieces. Ludiloom games often have objects that just contain a bunch of models ready to be cloned. It's easier to configure and change the models with the graphical interfaces than progamatically (it's possible to do everything through the ludiloom api, though), because often you have to scale them, set the correct materials, change their physics, etc. In Dominoes, every piece model has a “normal shape” and a “preview shape”, which is a semi-transparent, physics-less version of the “normal shape”.

Set

Another typical object is the “set”. Just like a film set, this object contains models, lights and sounds and other non-playable elements that compose the game scene. Putting all these elements inside an object keeps the object tree organized and all those fixed representations (lights, models and sounds) hidden. Also, usually these elements need not to be synchronized, and in this case the simulation process can be much optimized if the object is in non-update mode. Besides, it's useful with games that can have different themes, levels or zones:

  • Themes: With many games it's possible to use the same mechanics and just change the set to create a new theme, as it happens with all those time-management games.
  • Levels: This object can be used to implement levels, where you replace one “set” for another “set” like different worlds in Super Mario.
  • Zones: In games that are supposed to be set in a large geographical arena or where there are different environments (indoors, outdoors, desert, jungle, under water...), developers try to more or less seamlessly divide the virtual world into pieces that are more manageable by the processor and graphics card. In the ludiloom platform, the best way to do this is to create several arenas, each one with a different “set”.

 Toolbox
About ludiloom     Terms & Conditions     Privacy Policy     Contacts
ludiloom® is a registered Trademark of Tapestry Software, Lda.
© Tapestry Software, Lda. All rights reserved, 2005-2009.
Tapestry Software