Beruflich Dokumente
Kultur Dokumente
5D
Student Workbook
CRYENGINE Flappy Boid Course Ver. 5.5D -6- 01: Building the Assets, View, and Basic Functionality
Physics Properties and Strategies begins to react to the forces of physics. Don’t forget to assign a mass to
anything you want to behave realistically; the default -1 value is no mass.
A few notes about some key properties of the RigidBodyEx entity type:
RigidBodyEx is a “legacy entity” – it’s specific to GameSDK. It has so many Using an AI Tag Point to House Flow Graph Scripts
properties that you could regard it as a kind of “super” entity, with more
All of our game play logic in this game is going to be accomplished using
properties than you will need for many entity types, such as a table or a rock.
Flow Graph. Flow Graph is a node-based visual scripting tool that you'll get
These legacy entities are in the process of being replaced by the new Entity to know well! It allows us to program our game mechanics, behavior, etc.
Components system. If you look at the Component object type in the Create
While you can have Flow Graph modules that aren’t attached to anything, in
Object tool, you’ll notice components that are more simple than RigidBodyEx
this case the best approach is to attach our player control logic to something
because they are intended for more specific purposes than RigidBodyEx.
tangible and visible in the level that’s dedicated to that purpose
As a designer of photo-realistic 3D games, you need to be very strategic about
We will house all of our main Flow Graph functionality in a simple entity
the characteristics you assign to your game entities and the demands they place
called an AI Tag Point. AI Tag Points are visible to you, the designer, but
on computing power. Enabling physics is one of the most demanding aspects
invisible to the player.
of this strategy.
1. From the Create Object tool, choose AI > Tag Point and drag the
When adding entities to a level, consider the following: half-sphere looking object into the level. We suggest positioning it
• Will the player ever be allowed to physically contact this entity? reasonably close to your FlappyBoid object at the same height: 100m.
Remember, it's invisible to the player, so anywhere is fine as long as it
• Will any other entities collide with it? (Non-physicalized entities will doesn't make it difficult to see other objects, and it isn’t so far from the
allow other entites to pass right through them in an unrealistic way.) game play area that seeing and selecting it is difficult.
• Will the entity ever need to be modified during game play, to show NOTE: If you don’t see your AI TagPoint, make sure your Helpers are turned
damage? on: click on the H button in the top right corner of your Perspective viewport.
• Will the entity ever move? What will force it to move? Entities close to the camera will have a box above them, and entities invisible
to the player will have outlines or forms in the Editor.
• Does the entity need to be affected by physical forces such as gravity,
2. Set the TagPoint object’s Properties > General > Name to
wind, rain, the ocean, etc.?
“FG_Main.” (We’re using “FG” to abbreviate Flow Graph.) Giving
A basic strategy to optimize game performance is to physicalize entities only your objects meaningful names that describe their actual function in
when and if they need to be affected by physics. For example, if you want the the game helps you keep track of the long, complex hierarchy of
player to be able to pick up a rock and throw it, there is no need for the rock to objects that comprise any game.
have physics enabled until the moment the player tries to pick it up, if ever. At 3. In the object’s Properties > Flow Graph, click Open and call your
that moment of contact, the object can be physicalized, but if the player never new Flow Graph “Flappy.”
touches it, the rock won’t waste system resources.
4. The Flow Graph tool will appear if you didn’t already have it open.
With respect to the RigidBodyEx entity, the Physicalize property enables NOTE: if the Entities > Flappy > FG_Main module doesn’t appear,
physics on the entity, and the Resting property determines when the object close the Flow Graph tool and re-open it to force the node tree to
refresh: Tools > Flow Graph.
CRYENGINE Flappy Boid Course Ver. 5.5D -7- 01: Building the Assets, View, and Basic Functionality
There are nodes that perform mathematical functions, that affect the
appearance or position or movement of entities, play sounds, make it rain, and
which do pretty much everything else CRYENGINE can do. A good way to
understand what a node does it to hover the mouse over its inputs and outputs
and read the tool tips that appear.
You can edit the values of ports in the Properties window or simply double
click on a port to edit its value:
2. Double click on the Message input port of your DisplayMessage
node and type in “Hello, world!” or whatever amuses you. This node
does just what it says – displays a message on the screen, but nothing
will happen until it receives a signal from the Show input. That’s the
trigger that makes this node take action. Not all nodes need to be
triggered, as you’ll see; some are always working in the background.
Flow Graph Overview 3. Let’s make our message appear when the game begins: find the Game
folder in Nodes and drag the Start node onto the graph to the left of
Let’s take a look at the Flow Graph tool for a moment: you’ll notice that it has
your DisplayMessage node.
its own menu, toolbar, and tool palettes on the left and right. Some of the
graphs you’ll create will grow quite large and complex, so it’s useful to 4. Let’s get our first bit of logic flowing: drag the Output port of the
maximize your Flow Graph window. Game:Start node to the Show input port of the DisplayMessage
node. A connecting line and arrow will appear indicating which way
Nodes are listed on the left under a long list of categories. The types and the signal will flow. In plain language, when the game starts, a
locations for graphs are listed in the Graphs window. You’ll notice that your message will be displayed.
FG_Main AITagPoint entity houses a folder called Flappy and your first 5. Lastly, let’s set up the way our message looks: select your
graph, FG_main. DisplayMessage node. Make the Font Size 10, the PosX (horizontal
The time-honored first exercise for any new programming language is to position) 960, PosY (vertical position) 400, and click the Centered
display a simple “hello, world” message. Let’s do that to get introduced to how property to enable text centering around the PosX position.
Flow Graph works: 6. Before we test our first bit of game play logic, we want to get into the
1. In the Nodes window, find the Debug category. Click on the + sign to habit of saving our game each time before testing – Ctrl-S. It’s always
open it and drag the DisplayMessage node onto your graph. a good practice to save your level with Ctrl-S before switching into
game mode. Entering game play mode enables the physics and AI
By default, your newly added node is selected (indicated by a blue border), systems, which add a great deal of complexity that are more likely to
and its properties are diplayed in the Properties window at right. Below that is crash the engine than the Editor.
basic information about the node itself. Nodes have input ports on the left
and output ports on the right. They receive signals from the inputs, or you 7. Make sure that your camera is no more than two meters above the
terrain (or else your character will fall to the surface and die!) and
can assign values directly to those inputs, and send signals to the outputs.
press Ctrl-G to jump into game mode. You’ll see the shooter
CRYENGINE Flappy Boid Course Ver. 5.5D -8- 01: Building the Assets, View, and Basic Functionality
character, but should also see a big “Hello, world!” message on the just another entity. The game isn’t
screen. assigning any default behavior to our
sphere, nor does it think of it as THE Pro Tip:
A couple more quick tips: use the scroll wheel on your mouse to zoom in and Although the spacebar key on the
out on a graph. Pan around with the right mouse button. (The graph is virtually player. We have to program its PC platform makes the player
infinite) Now that we’re done testing, drag the mouse around both nodes to functionality manually. jump into the air, there is no
select them and press delete to remove them. spacebar on console platforms; it’s
Responding to the Jump a different button altogether. So
rather than listening for the
First Game Mechanic: the Jump Action Action spacebar key specifically, we want
to respond to the “jump” action
The player’s control in this game is very simple: each time the “jump” action We’re ready to call on our physics engine (triggered by the console-specific
is triggered (spacebar on a PC platform), our bird needs to jump upwards button).
to actually perform the jump!
against the constant downward force of gravity:
1. From Flow Graph’s Nodes
1. Add an Input > ActionMaps > ActionListener node to the graph. window, drag the
2. Add a Actor:LocalPlayer node to the graph. LocalPlayer is THE Physics:ActionImpulse node onto the right side of your graph.
player entity built into the game. Every entity has a unique, internal 2. Select your FlappyBoid entity from the Perspective Viewport.
numerical ID (an integer). 3. Right-click on your ActionImpulse node and choose Assign
3. Let’s tell the ActionListener which entity to listen: drag the Entity Id Selected Entity to force the node to affect the sphere entity.
output port of the LocalPlayer node to the Choose Entity input port 4. Connect the Pressed output of the ActionListener node to the
of the ActionListener node. The “Choose Entity” input is now labeled Activate input of the ActionImpulse node. This means the “jump”
“<Input Entity>.” action (spacebar key on the PC platform) will now trigger whatever
4. Click on your ActionListener node to make it active. action we’re about to assign.
5. From the Flow Graph Properties window, click on the value box to 5. Select the ActionImpulse node and set the Z axis of its Impulse
the right of Action. The .. button will appear. Click on it and choose parameter to 80 so the jump action will push the bird upward. In
the player > jump action. Click OK. terms of how big this force should be, it’s just a matter of
6. Let’s enable this listening action to begin when the game begins: experimentation, and it’s also a significant creative decision that has a
right-click on your Flow Graph canvas and choose Add Start Node. big effect on the “feel” of your game. The smaller the force, the more
Since the Game:Start node is so frequently used, this is just a shortcut often the player will have to tap the jump key, and the more control
to add it quickly. they have. The larger the force, the less often the jump key needs to
be pressed – but the stronger and less controlled the reaction will be.
7. Drag the Output of the Game:Start node to the Enable input of the
ActionListener node. 6. An optional enhancement to the illusion of forward motion would be
to spin our ball clockwise, (although this wouldn't make sense for a
The default player (the first person shooter character) receives the “jump”
bird). To do this, add an angular impulse of -.3 on the Y axis.
command. The player’s entity ID is now what the ActionListener node is
listening to. Now we just have to respond to this signal by making our “bird” Let’s put ourselves in a position where we can see if our “bird” is responding
jump up. Note that our bird entity is NOT the default player; to the engine, it’s to the jump. From the main menu, choose Level > Go To Position and enter
CRYENGINE Flappy Boid Course Ver. 5.5D -9- 01: Building the Assets, View, and Basic Functionality
coordinates of 515, 500, 34 and a Z rotation of 90⁰. You should be sitting at some fun shooting the sphere and making it roll away if you like.
eye level on the terrain with the shadow of the player in front of you.
Before we go any further, let’s build some quick documentation into our
Let’s test! Save first, then Ctrl-G to switch to game mode. Flow Graph to make it easy for other developers to understand – now to
mention ourselves as we try to debug complex games later! Thorough
So far, the first person shooter setup is still controlling where our player is
documentation is an essential best practice when developing games or any
initially spawned (wherever the camera happens to be when we start the game,
software.
but forced by gravity down to the terrain if not already on it), and the view we
see, which is always from the player’s head, looking out over his hands (or Right-click on your graph and add a comment box called “INITIAL SETUP.”
slightly behind him if you use F1 to switch to 3rd person perspective). Resize it so it surrounds the nodes we’ve created so far.
If you quickly use the right mouse button to look up, you will see our bird Right-click and add a simple comment called “move Flappy upward.”
sphere falling to the terrain. After it crashes to the ground, press the spacebar Position it over the ActionImpulse node.
key. You, the player, will jump up – but so should your “bird!” You can have
Through these simple annotations, we’ve started to create a self-documented
CRYENGINE Flappy Boid Course Ver. 5.5D - 10 - 01: Building the Assets, View, and Basic Functionality
game! 525 X, 500 Y, 32 Z. Our game will be built at 100m in the air (68m
above the terrain) so we'll never see this player.
As always, refer to the screen capture in your Flappy assets or printed here to
see what your Flow Graph should look like. You may find it easier to Why 32 on the Z axis? 32m is the default height of terrain so it sits
understand by looking at a picture than by reading the written steps. (The somewhat above the ocean at 16m (allowing you to sculpt valleys above the
finished Initial Setup Flow Graph for this chapter is printed at the end of the waterline, for example). If we put our player up in the air with our other
chapter.) entities, the first thing that will happen on game start is that gravity will send it
plummeting to the ground, where he’ll “die,” shaking the camera in the
Modifying Game SDK Functionality process. Putting it at 32m insures that it waits quietly!
2. Just to keep things clear, rename your Spawn Point object
You may have noticed that the CRYENGINE “SpawnPoint_Player.”
Launcher prompts you to choose a template. Pro Tip:
Among them are first person shooter (i.e., We’ll use our SpawnPoint_Player as a reference point in 3D space where we
There are several ways to add
GameSDK), side scroller, rolling ball, third can force the first person shooter to appear on game start, safely out of view:
nodes to Flow Graph: from the
person, isometric, etc. Nodes window; right-clicking and 3. Make sure your SpawnPoint_Player is selected, then right-click in
choosing Add; and by pressing the
The only difference between these templates is Q key and typing the node name.
the graph area of your Flow Graph tool and choose Add Selected
the functionality supplied with the template The last way is fastest, but you Entity. A node named entity:SpawnPoint appears. This illustrates an
that controls the default position and must already know what you’re important Flow Graph concept: you can add entities as nodes directly
looking for, making it an expert’s to a graph! The inputs and outputs of entity nodes overlap with other
perspective of the player. The engine itself tool. Flow Graph nodes, but sometimes this is the right choice.
remains the same.
4. Let's force the player to spawn (begin its existence) at the
Our game was created using the CRYENGINE SpawnPoint_Player every time the game begins: drag from the
Game SDK, which contains assets and functionality from CRYSIS 2, a first Output of the Game:Start node to the Spawn input of the Spawn
person shooter game. While we do need some of the Game SDK Point node.
functionality, we actually need to eliminate the first person shooter HUD
5. Let’s start listening for the jump key (as heard by the Player) as soon
(heads-up display, like computer graphics about ammunition and health
as the player has spawned: drag the Spawn output of the SpawnPoint
superimposed inside a helmet) and camera in our game.
node to the Enable input of the ActionListener node.
We’ll do that by setting up a spawn point where we can hide the default Before we test what we’ve built, make your camera position something other
player, because we’re going to control the player's view with a camera which than where the Spawn Point is.
is disassociated with the player entity. A spawn point is simply a place where
you can initially position your player when a level is loaded. In case we want to use this as our test starting point again, let’s save this
location so we can come back to it easily: in the menu, choose Display >
Hiding the Shooter Player and HUD Location > Remember Location > Remember Location 1. Note that these
saved locations just exist within the Editor, not within the game play
1. From the Create Object tool, choose Legacy Entities > Others and environment. To return here in the future, press Ctrl-F1. You can save
double click SpawnPoint. Place your man-in-a-box spawn point at locations to all 12 function keys.
CRYENGINE Flappy Boid Course Ver. 5.5D - 11 - 01: Building the Assets, View, and Basic Functionality
Save and test. You’ll notice that we still see the hands and gun of the FPS 1. In the Create Object tool, click on Misc > Camera.
player, but notice where we are: the player begins exactly where we put our 2. Click in the Perspective Viewport to add your new camera. Position it
Spawn Point! That’s what our Flow Graph logic accomplished. We’ve at 482, 523, 100.
successfully controlled the player’s position in the game.
3. Set its Z rotation to 180 so it’s pointed at FlappyBoid.
Note that with the GameSDK template, you can also press F1 to toggle 4. Rename your camera object “FlappyCam.”
between first and third person perspective.
If you’re curious about what this camera is seeing, you can click on the
Notice too that when you ESC to exit game play mode, all of your entities are Camera button at the top left corner of your perspective viewport and click
right where you left them. on Camera Entity > FlappyCam. You now see what your FlappyCam sees!
Keep in mind that you still control the size and shape of your viewport, which
Preventing the Shooter Player From Walking affects your field of view, whereas the player’s window will ultimately be
fixed. Thus this isn’t an exact view. Try F11 – full screen view.
1. Next, let’s stop the unused player from walking around. Add an Input
> ActionMaps > ActionFilter node to your Flow Graph. You could use the 2D viewports to tweak the position of the camera while
2. Click to make sure the ActionFilter node is selected. seeing the result, but for now let’s switch back to the default camera by
clicking on Camera > Default.
3. In Flow Graph’s Properties window, you’ll see Selected Node
Inputs at the top, and under it, Filter highlighted in blue. Click on
the .. button to the right of the blue Filter button.
Setting a Default Camera
4. From the list of ActionFilters that pop up, choose no_move and We need to tell the game to set
click OK. FlappyCam as the player’s view when
5. Connect the Spawn output port of the entity:SpawnPoint node to the the game launches:
Enable input port of the ActionMaps mode. 1. In Flow Graph, add a Camera
Let’s test to see what this has accomplished. Let’s also enable Flow Graph > View node onto the canvas.
debugging so we can watch what Flow Graph is doing: choose Debug > 2. In the perspective viewport,
Enable Debugging (or click on the bug icon). Save and press Ctrl-G to enter click on your FlappyCam to
game mode. You’ll notice that although you as the player can still look around, select it.
the player cannot move. (WASD no longer moves the player.) In the Flow 3. Right-click on your
Graph nodes, you’ll see the actions being executed in yellow. Camera:View Flow Graph
Now we just need to create a camera pointed at our “bird” to replace the node and choose Assign
unused first person shooter perspective. Selected Entity to assign the
FlappyCam to this node.
Adding a Camera 4. Drag from the Output port of
the Game:Start node to the
We are essentially building a side scroller style game with a fixed, constrained Enable input port of your
camera. Let’s add that camera: Camera:View node. Your
CRYENGINE Flappy Boid Course Ver. 5.5D - 12 - 01: Building the Assets, View, and Basic Functionality
camera is now enabled as the player’s view on game start. Understanding Flow Graph Data Types
Let’s test! Ctrl-S to save and Ctrl-G to enter game mode.
You may have noticed that the inputs and outputs of Flow Graph nodes have a
Voila, we immediately see the FlappyCam’s view of your player as it falls to variety of colors. These colors indicate the data type, as follows:
the terrain!
Green any data type
Next, let’s remove the crosshairs that are still lingering from the FPS
functionality. The crosshairs are part of the HUD (Heads Up Display). Its Red integer
visibility is controlled through a Console Variable (usually called a cVar). Blue Boolean (true/false or 0/1)
White floating point number
Hiding the FPS Gun Crosshairs
Cyan string
1. From Flow Graph’s Nodes window, drag a Debug:ConsoleVariable
node onto your graph. Yellow Vec3 (three dimensional coordinate)
2. In Flow Graph’s Properties window, set the C Var (Console One of the aspect of Flow Graph that makes it easier to use than a
Variable) to hud_hide and the Value to 1 (true).
3. Connect the Output port of the Game:Start node to the Set input
port of the Debug node.
CRYENGINE Flappy Boid Course Ver. 5.5D - 13 - 01: Building the Assets, View, and Basic Functionality
CRYENGINE Flappy Boid Course Ver. 5.5D - 14 - 01: Building the Assets, View, and Basic Functionality
CRYENGINE Flappy Boid Course Ver. 5.5D - 15 - 01: Building the Assets, View, and Basic Functionality
02: Setting Up Initial Logic when absolutely necessary. Pinging the CPU with hundreds of
complex requests for instantaneous responses risks bogging
down the computer and creating sluggish performance. In
Making the Camera Follow the Player computer time, there's a big difference between NOW and
Since we're only planning to allow our bird to jump up and fall down (not 1/100th of a second from now!
move on the X or Y axes), presumably we could just set our initial camera Remember, we want the FlappyCam to follow the FlappyBoid at a sufficient
position to see the bird and enough pipes that the player can dodge them, and distance to be able to see it (as well as the first couple of oncoming pipe
be done with it. However, there’s a potential problem: what if the player jumps obstacles). While we could feed the Pos (position) of the FlappyBoid directly
so high or falls so low that they go out of our camera’s view? to FlappyCam’s Movement:MoveEntityTo node, that will position the
An optional approach is to force our camera to follow our player as it moves camera exactly where the bird itself is – and we won’t be able to see the bird!
up and down. To a certain extent, this is a matter of personal preference, Instead, we need to offset the camera position from the bird’s position:
although each approach introduces its own complexities. 6. Add a Vec3:SubVec3 node. This node simply allows us to pass the
For now, let's make the camera follow the player by simply offsetting the positional input of A offset by the values we put in B.
FlappyCam camera’s position relative to the current position of the 7. Set the SubVec3 node’s B values (the offset) to 10,-20,0. This will
FlappyBoid entity: place the camera slightly back and to the right of the bird so there is
room to see the pipe obstacles we’ll be adding later.
1. Below the INITIAL SETUP section of your Flow Graph, let’s add an
Entity:EntityPos (position) node. Assign the FlappyBoid entity to 8. Drag the Pos output of the EntityPos node to the A input of the
this node. This will query the FlappyBoid’s current 3D position every SubVec3 node. Drag the Out of the SubVec3 node to the Destination
frame of game play. and Start inputs of the MoveEntityTo node.
2. Add a Movement:MoveEntityTo node. This allows us to seize Let’s test! Ctrl-S, Ctrl-G. You may feel that the camera follows the bird too
control over an entity’s position and move it there over a specific faithfully, that the camera jerks too quickly. Try adjusting the Value (response
period of time or at a fixed speed. Note that the MoveEntityTo is only time) of the MoveEntityTo to 0.5 seconds. Test it, and you may feel that the
appropriate for entities that are not being affected by physics – i.e., camera movement is more natural and smooth.
that have no mass (-1). Otherwise the forces of physics will “fight”
Put a comment box around this section of your Flow Graph and call it
with the brute force of the MoveEntityTo.
something like Camera Follows Player.
3. Assign the FlappyCam entity to the Movement:MoveEntityTo node.
4. Make sure that the Coord Sys (coordinate system) of the
Movement:MoveEntityTo node is set to Parent. It’s important to remember here that this game takes place in
5. Change the Value Type parameter to time, and set its Value to .01. the sky – we’re going to be hiding the terrain, so there will be
This effectively will make the camera reposition itself so quickly no visual point of reference to indicate that anything is moving
relative to the player that it will appear to be instantaneous. except the edges of the camera’s view.
CRYENGINE Flappy Boid Course Ver. 5.5D - 16 - 02: Setting Up Initial Logic
The only problem is, right now we have a simple sphere with no texture, so
even though the sphere is spinning, we won’t be able to see it! Let’s add a
surface texture to make the spinning visible.
1. Click on your FlappyBoid sphere to select it.
2. In the Properties window, click on the folder icon to the right of the
Material property.
3. Find an interesting, clearly visible texture in one of the materials
folders. We’ve used wood_beams_a_red from the GameSDK >
materials > generic > wood folder in our screen shots.
CRYENGINE Flappy Boid Course Ver. 5.5D - 17 - 02: Setting Up Initial Logic
03: Adding the Pipe Obstacles transformations applied to it - as you saw when we practiced adding boulders
to our terrain (part of them was placed “underground”)
Game Design Considerations Let’s take a look at the part of the pipe that’s hiding under the surface of the
terrain.
Our bird is up and flying, but this won’t be much of a game until we give our
bird some obstacles to navigate. Dodging them will result in points; colliding 1. First, insure that camera-terrain collisions are off (click on the
Camera menu at the top left corner of the Perspective viewport and
with them means instant death!
un-check it).
Another aspect to consider is that this is an “infinite scroll” type of game – as 2. Click and drag your middle mouse button down until you fly under
long as the player lives, it continues to endlessly score points; there is no end the terrain. You may want to zoom out to see the entire pipe extending
to this game. However, like most games, we down into the ocean.
want the challenges to escalate. So later, we’ll
add acceleration to the speed of the pipes as 3. At this point, we might as well hide the terrain, as this is an “aerial”
Pro Tip: game that doesn’t require a ground plane. Click on the blue Display
the player’s score increases. If an object ever disappears from button at the top right side of the Perspective viewport, scroll to
view, an easy way to find it is to
Adding the Pipes
Render Types and un-check Terrain.
select your Perspective Viewport
and press the G key to move the 4. If you tilt your camera and look down, you’ll now see the ocean that
We’ll use another Rigid Body entity for the camera to it. (Or Level > Go to was hiding under your terrain. Let’s get rid of it: in the Terrain
Selection in menu.) Editor, click on Edit > Remove Ocean in the menu. (You could also
pipes. We have no need to deform the shape of
the pipes, so rigid bodies will work just fine. choose to leave it there if you like the way it looks.)
1. Use the Create Object tool and 5. Use the Properties tool to rename your pipe pipe1_bottom.
double click Legacy Entities > Physics > RigidBodyEx. 6. Let’s move our pipe up in the air where we need it: set its position to
2. Click in your level to add your RigidBodyEx entity. It will appear as a 485, 500, 96.
sphere on the terrain. We have the shape of our pipe entity, but we still need a surface texture:
3. Let’s replace the default sphere with a pipe entity that we’ve already 7. With the pipe still selected, click on the folder icon next to Properties
modeled for you. In the Properties > Lua Properties window, click on > General > Material and select a texture you like. We’ve used
the folder icon to the right of the Model property. Browse to GameSDK > materials > generic > concrete > roof_tar_paper_01
GameSDK > objects > props > flappy_boid and click on a pipe you in our screen shots.
like from the several provided.
You’ll notice at this point that it’s quite difficult to evaluate how your texture
You’ll see what looks like a thick ring sitting on the terrain. In fact, this is the looks because of the default lighting: the sun is directly overhead. We can
“lip” of a large pipe, but everything except the lip is hidden beneath the control that using the Environment Editor:
terrain.
It’s important to understand that when you add entities to your level, the Adjusting Lighting Using the Environment Editor
modeler has pre-defined the pivot – the center point for the entity and any
From the main menu, choose Tools > Environment Editor.
CRYENGINE Flappy Boid Course Ver. 5.5D - 18 - 03: Adding the Pipe Obstacles
Expand this tool palette so you can see the timeline. You’ll noticed that by 2. Rotate it 180º so its head faces the lower pipe’s. Make sure snapping
default, a new game begins at high noon at the equator of planet Earth. That to angle is enabled and set to 90⁰. Click and drag the white or red arc
means the sun is directly overhead – typically not ideal from a lighting to rotate it 180º. Move it to 485, 500, 104. This leaves a 8m vertical
standpoint. There are three main factors that are going to affect our lighting: gap between the pipe for your player to navigate.
1. Time of day, represented by the timeline across the top right 3. Rename your top pipe pipe1_top.
(currently 12:00) 4. Make sure your top pipe is exactly at 485, 500, 104. You can use snap
2. Sun direction (lower left corner) to grid or edit the Properties > Transform to position the pipe at the
exact position.
3. Latitude, represented by the North Pole..Equator..South Pole slider
lower left
Adding A Score Trigger
First, try dragging the time of day cursor. While you’ll see some changes,
when we’re standing at the equator, the sun travels on its highest path through Now that we have our first set of pipe obstacles, we need to detect when the
the sky – directly overhead at noon. player collides with them – or when it passes cleanly through the gap between
the pipes, and should be awarded a point.
Restore the time of day to exactly noon by typing 12:00 in the Current box.
Let’s deal with scoring first: how can we detect when the bird passes through
Let’s adjust our latitude (north-south position relative to the equator) to get
the gap between a pair of pipes? There’s nothing there to sense a collision, for
the sun traveling through a lower path in the sky. Adjust the North
example. (Remember too that the pipes and thus the gaps between them will
Pole..Equator..South Pole slider until the light is coming from the front right
always be moving!)
at about a 45 degree angle. (Remember, our sphere will eventually become a
bird facing to the right, so we probably want to see its To accomplish this, we will use an entity called a Proximity Trigger – an
face.) invisible box that can sense when another entity intersects its boundaries
We’ve used a sun direction of 240⁰ and a latitude of 165⁰ It doesn’t need to be the same shape as the pipes; it simply needs to as wide as
at 12:00 noon in our example. the diameter of the pipes on the Y axis (perpendicular to the direction of
game play) and at least as tall as the gap so that the bird is sure to touch it as is
Adding the Top Pipe passes through the gap.
Let’s add another pipe above this one with the two heads facing each other. The image here shows such proximity triggers: 1x5x10m – a thin shape as
The gap between the upper and lower pipes will be the gap through which the wide as the diameter of the pipes. The bird will collide with the pipe before it
player must navigate without colliding. Thus the smaller the gap, the harder collides with the score trigger, so we can safely extend the length of our thin
the game. We’ll try 8m: score triggers to 10m to overlap with the pipes a bit.
1. Make sure your pipe1_ bottom is selected. We want to drag a copy of The overlap shouldn’t be a problem, as the player would collide with the
it upward. Press Ctrl-D to duplicate. Your copy will appear and you outside of the pipe before hitting the score trigger inside it. Even if passes
can drag it upward eight meters (Z=104). TIP: For precise positioning, through the score trigger at a vertical angle and then grazes the top or bottom
make sure the Properties > Transform palette is visible and watch of one of the pipes, there isn’t a problem with scoring right before death. Let’s
the XYZ coordinates as you drag the duplicate. In some cases, it may create them:
be easier to use the Move tool after you’ve made the duplicate.
CRYENGINE Flappy Boid Course Ver. 5.5D - 19 - 03: Adding the Pipe Obstacles
1. Using the Create Object tool, drag a Legacy Entities > Triggers > 8. Copy and paste the name of your FlappyBoid entity into the
ProximityTrigger entity anywhere onto the Perspective viewport. proximity trigger’s Properties > Lua Properties > Only Selected
2. Let’s align the Proximity Trigger exactly with the position of our Entity box so it will only respond to collisions with our bird.
bottom pipe using Snap To Pivot: 9. Rename the Proximity Trigger pipe1Score_trigger.
3. Select the Proximity Trigger entity. 10. Make sure Grid Snapping is turned on and set to .5m, and drag the
4. Press P or click the Snap To Pivot button top right in your pipe1Score_trigger up 4m so it’s exactly centered in the 8m gap
Perspective viewport. between the top and bottom pipes. (Grid snapping is the button
directly to the right of the Display button in the top right corner of
5. You’ll notice the top of the Perspective viewport says “Pick Object.” the Perspective viewport. Click and hold it to set the value.)
Click on the bottom pipe. The Proximity Trigger is perfectly aligned
and centered over the head of the pipe. 11. In the Level Explorer, drag the pipe1Score_trigger onto pipe1_
bottom to link it. Pipe1_bottom is now the parent object; moving the
If you have difficulty selecting the proximity trigger, use the Level Explorer to pipe will also move the trigger.
freeze pipe1_bottom so you can’t select it: select the pipe1_bottom entity and
click on the right-most Frozen column next to the pipe1_bottom entity. Its We’ve created the score triggers. We’ll add the Flow Graph scoring logic in a
handle will dim, and you can easily select the Proximity Trigger. subsequent chapter.
6. Change the Proximity Trigger’s Properties > Lua Properties > Dim CHALLENGE: Consider how best to sense collisions
X/Y/Z to 1, 5, 8. Be sure you don’t edit the Transform > Scale between the pipes and the bird. Should we use proximity
properties by accident! Those have no effect on the dimensions of a triggers?
proximity trigger, since they are not physical entities.
7. Because our game is based on the first person shooter Game SDK Is there a way to avoid adding and coding eight “death”
framework, but we are not actually using the player entity, we need to proximity triggers coinciding with the dimensions of each
sense when entities other than the unused default player collide with pipe? Do we have to use proximity triggers at all? Do we
this proximity trigger. In the Properties panel > Lua Properties, need to program every pipe to detect a collision?
uncheck Only Player.
You have some time to consider the best approach; we’ll
address this in a later chapter.
CRYENGINE Flappy Boid Course Ver. 5.5D - 20 - 03: Adding the Pipe Obstacles
CRYENGINE Flappy Boid Course Ver. 5.5D - 21 - 03: Adding the Pipe Obstacles
04: Adding the “Game Over” Text Linking vs. Grouping
It makes sense to connect all the pieces of the “game over” text together. You
When the player dies, we need to display a “game over” message. We’ll build
can either link them with one entity as the parent, or group them. Keep in mind
ours out of 3D text entities provided in the GameSDK, keeping it out of
that grouping makes it simple to manipulate a group of entities as one, but a
FlappyCam’s view until the player actually dies.
group object hides many of the properties of its members, whereas linking
To help us set this up, make your terrain visible again, and enable your grid does not.
snap for .5 meters. 1. Select all eight letters and the box.
1. Use the Create Object tool to drag another Legacy Entities > 2. Click on the Group button in the toolbar. A bounding box appears
Physics > RigidBodyEx entity into the level. around the objects. Any transformations now affect the entire group as
2. Let’s change the default sphere to a box that will sit under our “game a single entity.
over” text. Click on the folder icon to the right of the Model property
in the Properties > Lua Properties tool. Editing Grouped Entities
3. Select GameSDK > objects > default > primitive_box.
If at any point in the future you needed to edit the individual entities within the
4. Scale your box to 6x1x1m. (Unlink the three axes before scaling.) group, you can click on the Open button in the Properties window to access
Name it “GameOverBox.” Give it a Density of 20 and a Mass of 500. and modify the individual entities without losing your group. Just be sure to
5. Duplicate your box and drag it upward to just above the original. click the Close button when you’re done!
6. Let’s change the copied box to the letter “G:” click on the folder icon
to the right of the Model property in the Properties > Lua Properties
tool. Select the “G” from GameSDK > objects > props > misc >
3dtext. Pro Tip:
Any transformations applied to an
7. The “G” is there, but the transform has distorted its shape. Reset all
entity’s initial position are
three values under Properties > Transform > Scale to 2 on all axes.
remembered in its Properties (not
8. Assign your “G” a Mass of 200. the steps taken, but the final result
9. Duplicate your “G” and move it to the right. Use Grid snapping to of the move/rotation/scaling).
help you.
10. Replace the “G” with an “A” using the same Model property.
11. Repeat this process until you have your “GAME OVER” text looking
good. Adjust the width of the box beneath the text if necessary. Use
your Front or Left 2D viewport to help you align things.
12. It’s always good practice to name your entities well, and a big help
with debugging. Name your letters gameOverText_G, etc.
CRYENGINE Flappy Boid Course Ver. 5.5D - 22 - 04: Adding the “Game Over” Text
05: Adding a Moving Sky Background 2. In the Material Editor Legacy tool, click on the Add New Item button.
3. Name your material flappyBG and save it in your Materials folder.
Since we know that our pipes are going to move right to left while our bird 4. On the left Select your flappyBG material.
only moves up and down, the illusion that the bird is moving horizontally 5. Scroll down to Advanced > Texture Maps > Diffuse. Click on …
would be greatly enhanced by a background. You don’t have to delve deeply button and browse to GameSDK > materials and select the
into Einstein’s theories of the relativity of motion to see that if the background cloudtiling_diff.dds file. Note that this is a texture that we prepared
is moving, it will feel like the bird is moving in the opposite direction. that tiles (repeats) seamlessly.
To do this, we’ll create a simple box using our whiteboxing (prototyping 6. Click the top left button in the Material Editor to assign this texture
modeling) Designer tool and texture it with an image of a blue sky with to our Designer Box. If you zoom in, you’ll see many clouds tiled
clouds, and make the cloud texture move right to left. As long as the camera across your box, but they’re much too small.
doesn’t see past the edge of our “sky,” the illusion will work. NOTE: It’s
useful to keep the Terrain visible during this section. Scaling the Background Texture
Adding a Background Box Let’s scale the cloud texture without scaling the box itself:
1. Make sure your background box is still selected.
1. Turn on snap to grid with 1m accuracy.
2. In the same Advanced > Diffuse parameters in the Material Editor
2. From the Designer Tool, select Box. Click and drag on the terrain
Legacy tool, adjust the TileU and TileV parameters. The smaller the
right behind and to the left of the pipes to make a 1x100m base (i.e.
number, the larger the clouds. Try values of 1.5. Note that if you don’t
thin but very wide on the X axis), then click and move the mouse
match these two values, the texture map will be distorted.
upward to make the box 100m tall. Zoom as necessary to make room
for your big background box. 3. Try an OffsetV value of to .2 so the tiling is less obvious.
3. Tip: you can hold down Alt and drag the middle mouse button to
orbit around a selected entity. Animating the Sky Texture
4. You’ll notice that when you’re using the Designer tool, there’s a 4. Now let’s animate the cloud texture across the box: in the same
Designer text at the top of your viewport. Once you’re done creating Texture Maps > Diffuse section of the Material Editor Legacy tool,
your box, ESC or click the X to exit the Designer tool. click on the triangle to the left of Oscillator to open its parameters.
5. Name your background box something like bg_box. TypeU moves a texture horizontally; let’s change its value to Constant
Moving.
6. Set the position of your background box about 10 meters behind your
pipes and centered on X and Z. 5. We need to change the RateU speed to something other than zero to see
movement; let’s try 1. (Note that PhaseU is for blinking a texture on and
Adding a Sky Texture off, which we won’t use.)
6. We also need to change the Amplitude to something greater than 0; let’s
1. Let’s add our sky texture: first make sure the Designer Box is try 1 again.
selected. In the main menu, click on Tools > Material Editor Legacy
if it’s not already visible.
CRYENGINE Flappy Boid Course Ver. 5.5D - 23 - 05: Adding a Moving Sky Background
7. While this speed will probably need to be adjusted by eye once we’re in
game play mode, viewed from FlappyCam, you can probably already
see that it’s quite fast. Try lowering RateU to .3 and AmplitudeU to .2.
CRYENGINE Flappy Boid Course Ver. 5.5D - 24 - 05: Adding a Moving Sky Background
TIP: As long as FlappyCam is moving up and down with Here’s one view of the game layout to give you a sense of the entity positions,
the bird, the background box will actually need to be seen from a front left angle.
bigger than the current static view. We can’t fine tune its
size until we know how far the bird might move! Optimizing Designer Entities Through CGF Export
Using Global Illumination The Designer tool is designed for quick, easy prototyping of your level
designs, not delivering a finished game. The geometry it generates is not
If you look at both the front and back side of your box, you may notice that the efficient, thus it’s expensive for the computer to render.
moving cloud texture seems to disappear. The texture is applied to all sides, Thus it’s a good practice to convert Designer entities into standard mesh files
so it’s not a matter of rotation. (.CGF, .OBJ, etc.) and re-import them, replacing the originals, to optimize
So what could the problem be? game design before you ship. Here are the steps:
The answer is that the sun is not angled to illuminate both sides of your 1. First, save your level.
background box! There are a few solutions to this. 2. Select the bgBox background box object.
The simple solution is to enable Global Illumination. You’ll notice there is a 3. In the Designer tool palette, click on the Transform palette, then the
lot of contrast in the current lighting. Global Illumination renders reflected Export button. Scroll down until you see the .CGF button and click on
light through ray-tracing. You can enable this feature in your Level Settings: it. Save your file as something like FlappyBackgroundBox.cgf in the
Main menu > Tools > Level Editor > Level Settings > Total Illumination GameSDK folder.
V2. Click on Active to enable GI (Global Illumination), and you’ll 4. Delete your old background box Designer entity.
immediately see lower contrast. 5. Use the Create Object tool to add a brush, and select your
While there is a performance cost to using Global Illumination, it has a major FlappyBackgroundBox.cgf as the brush type. Place it, position, and
impact on the look of your game. Another aspect over which CRYENGINE transform as desired.
provides precise control is the nature of the sunlight in your levels.
CRYENGINE Flappy Boid Course Ver. 5.5D - 25 - 05: Adding a Moving Sky Background
CRYENGINE Flappy Boid Course Ver. 5.5D - 26 - 05: Adding a Moving Sky Background
06: Moving the Pipes Flow Graph’s Graph list under Entities, you’ll see a pipeMovement
folder and a new graph called pipe1_bottom. Click on it to open it.
Rather than moving our player to the right, which creates numerous problems TIP: If the Flow Graph tool was already open when you did this, you may not
– running out of playable game space, needing to constantly reposition the see the change. Close and re-open the Flow Graph tool to force the graph tree
pipes to new locations – we’re going to move our pipes to the left while the to refresh.
player only moves up and down. 4. Add a Movement:MoveEntityTo node to your new Flow Graph.
Also, since our camera narrowly constrains the player’s view (from a third 5. Assign your pipe1_bottom group to this Movement:MoveEntityTo
person perspective), we can control how many pipes the player sees at any node simply by right-clickong on the MoveEntityTo node and
given moment – just enough to position themselves to dodge the next couple choosing Assign Graph Entity.
of oncoming pipes. You may find it strange that the Movement:MoveEntityTo node now says
We’ll exploit this constrained view to wait until each pipe is out of the “<Graph Entity>” as the entity assigned, rather than the entity name
camera’s frame on the left to instantly send it back to a pre-defined start point (pipe1_bottom). Remember that this Flow Graph is directly attached to the
off-camera on the right side. That way we achieve a seemingly endless series pipe1_bottom set of linked entities. “Graph Entity” refers to the parent entity
of pipes without actually making more than four sets – game play that only containing the Flow Graph – i.e., the pipe1_bottom entity itself.
ends when the player dies. The advantage of this is that since the entity name is not hard-coded into the
node, we can re-use these same nodes on the other pipes without making any
Moving the First Pipe changes. It is always good development practice to avoid burying hard-coded
names and numbers in what will eventually become a large game design.
First, let’s get our first set of pipes moving right to left. We need to define start
Hard-coding makes your design inflexible and difficult to debug.
and end positions, and detect when a pipe has reached the end point. Since the
pipes should presumably begin moving the moment the game begins, we’ll Note that we need our ai_end to be at exactly the same vertical position as the
trigger the initial movement with a Game Start node. parent entity – the bottom pipe - otherwise the pipes will drift vertically from
their Z start position.
Before we start moving the pipes, let’s give them some fixed start and end
coordinates by using AI Tag Points: 6. Set the Value Type of the pipe1Reset_trigger to speed and the Value
to 5. This number directly determines how fast your pipe moves, thus
1. We need to choose an end position just past the left side of the
how difficult your game is.
FlappyCam view (i.e., just out of view). Use your Create Object tool
to add an AI Tag Point object. 7. Make sure the Coord Sys of the MoveEntityTo node is set to World.
2. Name it ai_end, and set its position to 515, 500, 96. 8. We need to tell Flow Graph where to move the pipe: select your ai_end
Tag Point in the Editor. Right-click in Flow Graph and choose Add
We’ll attach the pipe movement Flow Graph separately to each pipe. Let’s
Selected Entity. Drag the Pos output of the ai_end node to the
begin with pipe #1:
Destination input of the MoveEntityTo node.
3. Right-click on the pipe1_bottom group and choose Create Flow
Graph. Click on New… and name your folder PipeMovement. In
CRYENGINE Flappy Boid Course Ver. 5.5D - 27 - 06: Moving the Pipes
9. Finally, we need to actually start the 3. Right-click on the BeamEntity node and choose Assign Graph
movement. Let’s get the pipe moving the Entity. The graph entity is the object to which this Flow Graph is
moment the game starts: Add a Game > attached: pipe1_bottom. This makes it easy to copy and paste these
Pro Tip:
Start node. Drag its Output to the Start nodes to the other pipes without needing to change the pipe names.
Setting this speed value inside a
input of your MoveEntityTo node. 4. Next, we need to communicate the position of this ai_start entity to the
Flow Graph node is a practice
10. Before we test this, let’s hide the other called “hard coding” – burying a beam action: select the ai_start entity in the Editor. Right-click in
three sets of pipes. Use Level Explorer precise value into what will your graph and choose Add Selected Entity.
probably become a complex maze
to hide them. of nodes or code, making changes 5. Let’s tell the beam where to send the pipes: drag the Pos output of the
Let’s test! Ctrl-S to save; Ctrl-G to enter play and debugging difficult. Instead, ai_start node to the Position input of the BeamEntity node. Make
mode. The first pipe should move to the left! the best practice is to use a sure you don’t confuse ai_start and ai_end!
variable – a Game Token – that
Note that once the MoveEntityTo is finished, can be set in the initial setup 6. Now for the actual magic! Drag the Finish output of the
physics take over again, and the pipe will fall to section of your Flow Graph, or MoveEntityTo node to the Beam input of the BeamEntity node. The
the terrain, even if that terrain is hidden. even controlled through the UI by a logic here is simple: we wait for the pipe entity to reach its destination/
“difficulty” slider. Bottom line:
Also, note that we only had to move the bottom organize important game The “Finish” output of MoveEntityTo is sent a signal when and if the
pipe. Since pipe1_top and pipe1_scoreTrigger elements like this so they’re easy move is successfully completed, telling the BeamEntity node to send
are linked to the bottom pipe, they move in
to find and change! the pipe back to the start position.
parallel with their parent entity. Note that there is an important distinction between the Done and the Finish
outputs of the MoveEntityTo node: if you hover the mouse over each of these
Resetting the Pipe Position outputs, the tool tip text will explain that while the Done output is triggered if
the move reaches its destination (i.e., completes the movement) or if the
Now that we’ve managed to move the pipe out of camera view to the left, we movement is stopped, Finish is only triggered if the movement is completed.
need to send it back to the starting position. This needs to happen This difference will become especially significant later when we need to
instantaneously, so instead of using a move node, we’ll use a beam node. interrupt all pipe movement in progress when the player collides with a pipe.
Beam means instantaneous movement a la Star Trek’s transporter.
We’ve completed the functionality, but there’s one thing missing: how do we
We’ll use another AI Tag Point to define a fixed start point in 3D space. loop this functionality so the pipe repeats this move-beam cycle? The answer
is again to use the Done output of the BeamEntity to trigger the
CHALLENGE: Why do we even need this AI Tag Point? MoveEntityTo’s Start input. However, we can’t feed two outputs into the same
Why not just beam the leftmost pipe to the position of input. We need a logic gate that will accept multiple inputs, so either
the rightmost pipe itself? Game:Start OR Beam’s “Done” signal will trigger the MoveEntityTo:
7. Right-click on the circle in the middle of the connector between
1. Use your Create Object tool to add an AI > TagPoint to the level.
Game:Start and the MoveEntityTo’s Start node. (The cursor turns
Name your Tag Point ai_start. Position it at 455, 500, 96.
into a small white arrowhead.) Choose Logic:Any to insert a logic
2. In order to move an entity somewhere instantly, add an gate in the middle of your connector without losing its start and end
Entity:BeamEntity node to your Flow Graph. points. You’ll notice that the previous connector now passes through
the In1 input.
CRYENGINE Flappy Boid Course Ver. 5.5D - 28 - 06: Moving the Pipes
8. Drag the Done output of the BeamEntity node all the way back to the One enhancement we might consider is to add a short delay before the pipes
In2 input of your Logic:Any gate. Long looping connectors like this start moving on game start to give the player a chance to get into position. An
are what make a Flow Graph look messy, but they are inevitable. easy way to do this is to right-click on the center point of the connector
Arrange your nodes as neatly as you can. between your Game:Start node and your Logic:Any gate and choose Time
9. Finally, let’s document this section of the Flow Graph by adding a Delay. You can vary the Delay value of this node (the units are seconds) of
comment box around it called “pipe movement.” this Time:Delay node as you see fit.
We’ve closed the loop on our pipe movement! Let’s test: Ctrl-S; Ctrl-G.
After the pipe finishes moving, it should beam back to the position of the
right-most pipe and start moving again, ad infinitum.
CRYENGINE Flappy Boid Course Ver. 5.5D - 29 - 06: Moving the Pipes
Moving the Other Pipes • Moonlight
• Stars
We’ve initially positioned our four sets of pipes as they should be spaced. All • Volumetric clouds (3D, affected by sunlight)
we have to do now is copy the Flow Graph logic we attached to pipe1 and • Wind
paste it onto the three other bottom pipes. • Ocean
Since the Game:Start event is what initially triggers the movement towards the • Random breezes
ai_end Tag Point, all four pipes will start moving the instant the game begins. • Terrain
• Physics
1. Make all of your pipes visible again using the Level Explorer.
• Atmospheric density
2. In Flow Graph, drag a box around all of the pipe movement nodes,
including the comment box, and copy them to the clipboard (Ctrl-C). These aspects of our virtual world are all “on” by default. So could one of
3. In the Editor, right-click on pipe2_bottom and choose Create Flow these be the cause?
Graph. If you open up Tools > Level Editor > Level Settings and scroll to the Wind
4. Click on the existing PipeMovement folder and click OK. In Flow parameter, you’ll notice that it is set to 1 by default. There is a slight wind
Graph, you’ll see that pipe2_bottom has been added as another Flow blowing along the X axis, pushing our bird steadily to the left!
Graph in the pipeMovement folder. Click to open it.
Let’s change this to 0. Since horizontal movement of our bird is only a visual
5. Paste the Flow Graph nodes into the Entities > pipeMovement > illusion; we actually want it to be static on the X axis, otherwise the whole
pipe2_bottom graph. movement system we’ve built for our pipes including the AI start and end
Now you see the beauty of reusable nodes: we don’t have to tell those nodes to points would have to move too to keep up with the effect of the wind –
specifically move pipe2 because they move the graph entity to which they’re complexity we don’t need!
attached.
Follow the same procedure for the other pipes, then test. All four pairs of pipes
Creating a Debugging Camera
should move right to left, evenly spaced, resetting themselves to the ai_start In cases like this when you’re testing and trying to understand what’s
position, and looping past the player. happening, it’s useful to see outside of a constricted view like that presented by
our FlappyCam. For example, it would be useful to step back and see all of the
Environmental Considerations pipes to insure that they’re moving as expected. To do this, let’s create an
additional camera:
If you test your game for a while, jumping to keep your bird in the air and 1.
viewing it through FlappyCam, you will eventually notice that your bird drifts 1. Navigate to a view that you like using the Editor. One of the views
to the left and ultimately ends up off-screen! that might be useful is parallel to the pipes (perpendicular to their
What is causing this? Our jump impulse only acts on the Z axis, not X. movement) so you can see that the pipes are evenly spaced as they
move.
One of the fundamental principles of CRYENGINE is that it reconstructs a
2. Click on the Camera menu in the Perspective viewport and choose
real-world environment in as many ways as possible. That includes:
Create Camera From Current View.
• Sunlight 3. Use the Level Explorer to rename your camera debugCamera1.
CRYENGINE Flappy Boid Course Ver. 5.5D - 30 - 06: Moving the Pipes
4. In the initial setup section of your Entities > Flappy > FG_Main
Flow Graph, assign your debugCamera1 to the Camera:View node.
(Select the debugCamera1 in the Sandbox, right-click on the
Camera:View node and choose Assign Selected Entity.)
Save and test. You should immediately see the view from your
debugCamera1. Make sure you restore FlappyCam as your selected camera in
Flow Graph when you’re done debugging!
CRYENGINE Flappy Boid Course Ver. 5.5D - 31 - 06: Moving the Pipes
07: Keeping Score 3. Map the Enter output of the pipeScore_trigger node to the Trigger
input of your GameTokenModify node to trigger the modify action
each time the player enters the proximity trigger.
We need to store the player’s score as an integer in a variable that we can
increment each time the player touches a score trigger, and also keep the score 4. Select your GameTokenModify node. Under its Properties, set the
displayed onscreen. Selected Node Inputs > Token value to the intScore Game Token.
5. Change the Selected Node Inputs > Operation type to Add to
Adding A Score Variable increment the score.
6. Change the Selected Node Inputs > Type to integer.
To begin, let’s create an integer Game Token (variable) to keep track of the
player’s score: 7. Change the Selected Node Inputs > Value to 1 to increment your
score by 1 each time.
1. From the menu, choose Tools > DataBase View.
2. Click on the GameTokens tab. Displaying Score Onscreen
3. Under Game Token Tasks, click on Add New Item. Name it
Now we need to create a way to actually display the player’s score onscreen.
“intScore.”
While ultimately we’d want to build a bit of UI that looks good, for now,
4. By default, your new game token is a Boolean; change its type to we’re going to take a prototyping approach using a Debug node called
Integer. Set the initial value to 0. DisplayMessage to display simple text onscreen to verify that our score is
5. Let’s begin by retrieving the current value: in your player’s Flow working properly.
Graph, add a Game > Start and a Mission > GameTokenGet node.
1. Drag a Debug > DisplayMessage node onto your Flow Graph.
6. Select the GameTokenGet node. In the Flow Graph Properties under
2. Map the Out Value of your GameTokenModify node to the Show
Selected Node Inputs > Token, click on the .. button and choose your
input of your DisplayMessage node.
intScore game token.
3. Right-click on the round handle in the middle of the connector you
7. Map the Output of the Game:Start node to the Trigger input of the
just made and choose Logic:Any. This inserts a logic gate that
GameTokenGet node. This retrieves the initial value of the intScore
functions like an “OR” with 10 possible inputs instead of just two.
Game Token so our scoring logic can increment it.
Reposition your nodes so there is space between them, with your
Logic:Any gate between the GameTokenModify and
Incrementing the Score DisplayMessage nodes.
Every time the player intersects this proximity trigger, we want to increment 4. Map the Out Value of your GameTokenGet node to the In2 input of
the player’s score. That means we need to modify the value of our score game your Logic:Any node. This means that starting the game will trigger
token by adding one point per score trigger collision: the GameTokenGet to retrieve the initial score (which is zero), and
display it with the DisplayMessage node, and thereafter, any time the
1. Drag a Mission > GameTokenModify node onto your Flow Graph to score Game Token is modified, it will pass the score through the logic
the right of the pipeScore_trigger node. gate as well.
2. Select your pipe1Score_trigger in the Editor, then right-click in your
Flow Graph add choose Add Selected Entity.
CRYENGINE Flappy Boid Course Ver. 5.5D - 62 - 10: Adding Animated Score Targets
the five side faces of your pentagon to select it. (You’ll see a purple
box in the middle of the polygon that will turn orange when selected.)
4. In the Designer tool’s Advanced > Extrude/Delete tab, select the
Extrude tool.
5. Click and drag the selected face away from the middle of the
pentagon until its length is about the same as the pentagon itself.
6. Without deselecting the pentagon or the Extrude tool, hold down the
Alt key and click with the left mouse button on each of the other four
faces to extrude them the same way as the first. Move your camera
around the pentagon as necessary to see each face before clicking it. 3. Let’s copy this material before we modify it: click on the Save button
in the Material Editor Legacy. A copy appears in the list of materials.
7. Once again, select the Designer Tool > Selection > Polygon tool. Right-click on your copy and choose Rename. Rename it
Click on any of the five outermost faces to select it. glass_frosted_red.
8. Click on the Designer Tool > Advanced > Extrude/Delete > 4. Modify the lighting specular and emissive color settings as desired to
Collapse tool. The selected face will become a single point. make your star more colorful, as in this example.
9. Repeat these last two steps on each of the other outermost faces.
(Note that unlike the extrusion tool, you cannot use the Alt-Left Converting Designer Models to CGF Format
Mouse Button click to simply repeat the transformation.) Consult the
step by step pictures for guidance. The Designer tool is a whiteboxing tool – great for quickly designing a level,
10. Deselect the star and re-select it. Use your rotation gizmo to stand it but the models it produces are not optimized. Let’s optimize our star geometry
up as if sitting on two legs. Use your rotation snap to make sure it by exporting it as a CGF mesh, which will also allow us to use it as the model
rotates exactly 90⁰ (or -90⁰). You’ll probably find that you’ll also need for any entity type we like:
to rotate it slightly around its own center. 1. With the finished star selected, click on the Designer Tool >
Advanced > Export button. In the Export options, click on the .CGF
Creating a Glass Material for the Stars button. Save your file as star.cgf in the
GameSDK\objects\props\flappy_boid folder.
1. Let’s give the star a material: with the star selected, click on the
browse button next to Material in the Properties > General window. 2. You can now either delete the designer object, hide it, or just leave it
Select GameSDK > materials/generic/glass/glass_frosted. somewhere out of sight.
NOTE: If your camera is positioned such that your cloud background box is 3. Use the Create Object tool to add a Legacy Entities > Physics >
behind the star, it will disappear. We’ll discuss how to address this shader BasicEntity to your level. As usual, the default model is a sphere.
Drag it onto the terrain.
issue further down; for now, reposition your camera so the cloud background
box is not visible behind the star.) 4. Select the BasicEntity and scroll down in the Properties window to
Lua Properties > Model and click on the browse button next to
2. Let’s make the material more colorful: in the Material Editor Legacy, primitive_sphere.cgf. Select your
click the Get Properties From Selection button. The glass_frosted GameSDK\objects\props\flappy_boid\star.cgf mesh.
material is selected, and its properties displayed.
CRYENGINE Flappy Boid Course Ver. 5.5D - 63 - 10: Adding Animated Score Targets
5. Name your first star something like “ScoreStar1.” 5. Set its speed on the Z axis to 2. You may want to experiment with the
speed depending on how fast your pipe movement is set. If you really
Considering Shader Issues want to make your game dynamic, you could create a Game Token for
the cloud speed and increment it with the score as you did with the
We need to position our star between the first set of pipes, but if you move it pipe movement.
so you’re looking at with the background box/cloud texture behind it, the star 6. Since the sky movement’s purpose is simply to create the illusion that
will become invisible! (Rotate the camera to look at it without the box behind our Flappy character is moving to the right, let’s make it stop when
it to verify that it’s still there. the player dies: add a Mission:GameToken node to the left of your
Why is this happening? RotateEntity node.
It’s because we changed the shader type on the background box to 7. Set the Token value to your booIsDead Game Token, and the
ReferenceImage, which removes all lighting and shadow information. Since Compare To value to true.
our star has a translucent glass material, it cannot be rendered in front of that 8. Map the Equal output of the GameToken node to the Paused input
box. of the RotateEntity node to cause the rotation to pause on player
death.
We could change the star’s material to something opaque, but since we’re
planning to use particle effects (smoke, fire, sparks), we’ll have the same Save and test, adjusting speed as desired.
problem: only completely opaque particles will render.
We have to change the background box’s shader back to Illum, which means
Adding Moving Cloud Shadows
dealing with the pipe shadows somehow, or find a different way to create our Another way to extend the physical reality of the lighting is to use a cloud
clouds background. texture to simulate shadows cast by clouds. We do this in the Level Settings:
1. In your Level Settings, scroll to the Cloud Shadows properties. Click
Adding an Animated Sky Dome on the box next to Cloud Shadow Texture and find the
Here’s one common option for adding a cloudy sky using a simple half-sphere textures/clouds/cloud_pattern.dds or similar file.
that has a cloud and sky image textured onto it: 2. If you want this cloud shadow texture to move as if from the wind, set
the Cloud Shadow Speed X and/or Y values to a small number (Z
1. First, hide or delete your existing background box. does nothing). Try .005.
2. Use your Create Object tool to select the Static Mesh Entity >
objects > sky > forest_skydome.cgf model and drag it into your Setting Up the Scoring Stars
level. You might want to look at your level from the Top viewport to
make sure the sky dome is centered around your game play area. Its Z 1. Move and rotate your star as necessary to center it between your first
position should be 0. Name it SkyDome. set of pipes (485, 500, 100) facing the same direction as the camera (0
3. Let’s make it spin so it looks like Flappy is moving to the right: make rotation on Z). Scale it as you like so it’s easy to see, but doesn’t
sure the SkyDome is selected. In the Initial Setup section of your crowd the gap between the pipes.
FG_Main Flow Graph, add a Movement:RotateEntity node.
4. Right-click on the RotateEntity node and assign the SkyDome to it.
CRYENGINE Flappy Boid Course Ver. 5.5D - 64 - 10: Adding Animated Score Targets
2. Drag your ScoreStar1 onto Pipe1_bottom to link it to the pipe 6. Let’s keep the star spinning constantly: add a
assembly. This way the star will move with our existing pipe Movement:RotateEntity node. Right-click and assign the graph
movement Flow Graph. entity (i.e., the star itself).
3. Let’s add our game mechanics: first, right-click on the star and 7. Set the Speed on Y to 50. Your axis may be different depending on
choose Create Flow Graph. Since we’re going to use the existing the rotation of your model. Note that this node has no input trigger; it
score triggers, we could extend the scoring section of our Flow Graph, will begin on game start automatically.
but it would be messy to organize, and we wouldn’t have the We’ve hidden the star on contact; now let’s make it re-appear when the pipe
advantage of using the star as the graph entity. Choose your existing assembly is beamed back to the start position to be recycled:
FG_Main folder.
1. Open your PipeMovement Flow Graph for pipe1_bottom.
4. Right-click on your new Flow Graph and choose Add Graph Default
Entity. You’ll notice that the entity node has a Hide input. Let’s make 2. Select your ScoreStar1 entity if you haven’t already.
the star disappear when the player contacts it: select your 3. All the way on the right side next to your BeamEntity node, right-
scoreTrigger1 (or whatever you called your proximity trigger click and choose Add Selected Entity.
between the first set of pipes). Right-click in your graph and choose
4. Drag the Done output of the BeamEntity node to the UnHide input of
Add Selected Entity.
the ScoreStar1 node.
5. Drag the Enter output of the ProximityTrigger node to the Hide
5. Save and test. Don’t duplicate the star to the other pipes yet, as we’ll
input of the star’s GraphEntity.
add an explosion effect and additional Flow Graph nodes first that
you’ll want to copy.
CRYENGINE Flappy Boid Course Ver. 5.5D - 65 - 10: Adding Animated Score Targets
CRYENGINE Flappy Boid Course Ver. 5.5D - 66 - 10: Adding Animated Score Targets
Adding Particle Effects 10. Name your effect ScoreEffect1. Drag it onto pipe1_bottom to link it.
Save and test your first score star. Once you’re confident in it, duplicate the
Particle effects use 2D translucent textures to provide effects like sparks, fire, star and particle effect three more times and position them between the other
smoke, etc. A large library of them is already provided in the GameSDK. Let’s pipes. Be sure to rename them properly, to copy the Flow Graph nodes, and to
add an effect each time the player collides with the score triggers: modify the entity assignments properly. Don’t forget the added node in the
1. Open the DataBase View tool (Tools > DataBase View) and click on PipeMovement graph. We’ve also added a 30⁰ difference in rotation on the Z
the Particles tab. axis between each of the four stars so they aren’t all in the same position at the
2. Click on the dropdown list under the Particles tab that says “Level” same time.
and select “explosions.” A folder tree listing all explosion effects When you test these effects in game play mode, you will find that some of
appears on the left below the toolbar. them don’t work as-is because they include a shock wave that pushes Flappy
3. Click the plus sign next to the monitor folder and drag the away – i.e., they generate wind. You can change this by editing the particle
a_linger_elec effect onto ScoreTrigger1 to place it in the level. effect in the DataBase View.
Position it exactly between the first pipe pair at 485, 500, 100.
4. Name your particle effect ScoreEffect1. In Eliminating Physical Forces From Particle Effects
the Properties > Lua Properties, uncheck
1. First, select your particle effect in the Perspective Viewport.
the Active property so the effect doesn’t
fire every time you open this level in the Pro Tip: 2. In the DataBase View > Particle tool, expand the particle effect
Editor. Any time you want to see how a parent folder and look for a component usually called wind. In
particle effect in your level looks GameSDK, the designers usually kept any wind (shockwave) effect in
5. So you can easily select the particle effect,
while in the Editor, right-click on it a separate component to make it easy to find – otherwise you’d have
use the Level Explorer to freeze
and click on Events > Spawn. to check every single component.
ScoreStar1 and ScoreTrigger1. You can also test different particle
3. Scroll down through the long list of parameters to the Advanced
6. With the ScoreEffect1 entity selected, effects by dragging them from the
section, and find where Force Generation is set to Wind. Set it to
right-click in your ScoreStar1 Flow Graph Database > Particles window onto
None.
and choose Add Selected Entity. a ParticleEffect entity in the
scene. 4. Save your changes by clicking the Particles Save Modified
7. To make sure that the particle effect
Libraries button.
doesn’t appear until the first collision, let’s
disable it on game start: add a Game:Start
node. Randomizing Particle Effects
8. Drag the Output of the Game:Start node to the Disable input of the Just as randomizing the pipe materials enhanced the illusion of endless pipes,
ParticleEffect entity node. we’ll use the same technique to randomly choose from a selection of suitable
9. We’ve disabled the particle effect, so we need to enable it in order to particle effects:
trigger (spawn) the effect: drag the Enter output of the 1. Open pipe1_bottom’s pipe_movement Flow Graph and find the
ProximityTrigger entity node to the Enable and Spawn inputs of the Entity:BeamEntity node that sends your pipes back to ai_start. Why
ParticleEffect node. put the particle randomization here? Because we’re going to assign a
CRYENGINE Flappy Boid Course Ver. 5.5D - 67 - 10: Adding Animated Score Targets
random particle effect at the same moment we assign a pipe material: temporarily changing the Particle Effect property of one of your ParticleEffect
when each pipe assembly is beamed back to the ai_start point. entities, and then simply copying and pasting from the Lua Properties >
2. We want to assign a particle effect from a random list at the moment Particle Effect property into the SetString’s In property:
the game starts and every time a pair of pipes is reset to ai_start: add a 7. Use the DataBase Tool > Particles tab to drag various explosions
Logic:Any node (to handle the two inputs) to the right of your onto your selected ParticleEntity to assign and preview them. Don’t
BeamEntity node. Drag the Done output of the BeamEntity node to forget that you must disable the Advanced > Force Generation
the In1 input of the Logic:Any node. Drag the Output of the property, or else the effect will push your Flappy player away.
Game:Start node that you already added for the pipe material
randomization to the In2 input of the Logic:Any node. 8. As you find each particle effect that you want to use, copy its name
from the Lua Properties > Particle Effect property into each of the
3. Add a Math:Random node. Drag the Out of the Logic:Any node to eight SetString’s In properties, using a different effect on each of
the Generate input of the Math:Random node. Set its Min to 0 and its your eight SetString nodes.
Max to 7.
9. To route these eight different strings to your Entity:PropertSet node,
4. Add a Logic:DeMultiplexer node. Drag the Out Rounded output of add a Logic:Any node to the right of your SetString nodes. Drag the
the Math:Random node to the Index input of the Out of each of your SetString nodes to a different input of your
Logic:DeMultiplexer node. Set the Mode of the Logic:Any node.
Logic:DeMultiplexer node to IndexOnly to insure that only the Index
input trigger is used. 10. Finally, drag the Out of your Logic:Any node to the Set and Value
inputs of the Entity:PropertSet node.
5. We need to set the Lua Properties > Particle Effect property of each
ParticleEffect entity: add an Entity:PropertySet node. Select the Save and test. Once you’re confident your logic is correct, copy and paste the
scoreEffect1 ParticleEffect entity in your level, right-click on this nodes to the other pipeMovement Flow Graphs, being careful to assign each of
node, and choose Assign Selected Entity. Set this node’s Property your four ParticleEffect entities to the Entity:PropertySet nodes.
parameter to Properties:ParticleEffect. (Use the .. button to browse Note that you can easily experiment with different effects by selecting an
to the correct property.) existing ParticleEffect entity and dragging a new effect from the Database
6. Add eight String:SetString nodes. Map the Set input of each of them window onto an effect entity in your level. Be careful not to accidentally
to a different Port output from the DeMultiplexer node. create additional effect entities by dragging someplace other than onto an
You’ll need to carefully write the exact path and effect name into the In existing effect.
property of the SetString nodes. To avoid typos, we again recommend
CRYENGINE Flappy Boid Course Ver. 5.5D - 68 - 10: Adding Animated Score Targets
CRYENGINE Flappy Boid Course Ver. 5.5D - 69 - 10: Adding Animated Score Targets
11: Adding Audio Once you’ve created your sounds, you’ll need to put them in the
projectFolder\audio\sdlmixer\assets folder. CRYENGINE will automatically
create .cryasset files for each .OGG file that expose them to the engine.
Our game is missing one major component: sound! Sound design and music
for video games is in itself a vast specialization and an art, as well as being
highly technical, but adding basic sounds to your game is quite simple – and it Enabling Audio Debugging
makes a huge difference in the gaming experience. There is a separate debugger just for audio entities and events that’s
While audio is handled by what’s known as middleware, CRYENGINE is not enormously helpful when you’re designing the audio in your game. Use the
tied to a specific middleware. The Audio Translation Layer (ATL) Console tool to type in the following:
communicates between game events, entities, sound files, triggers, and s_DrawAudioDebug ?
parameters within your game, abstracting and translating them to your choice
of audio middleware. You’ll see all of the parameters for the audio debugger displayed, as follows:
A very simple and free audio middleware called SDL Mixer is bundled with Usage: s_DrawAudioDebug [0ab...] (flags can be combined)
0: No audio debug info on the screen.
CRYENGINE, although you can also use the more full-featured fMod and a: Draw spheres around active audio objects.
Wwise middleware. The greater functionality of these tools comes with b: Show text labels for active audio objects.
significant licensing fees and obligations before you can distribute a game c: Show trigger names for active audio objects.
commercially, depending on how many sounds you use. d: Show current states for active audio objects.
e: Show Parameter values for active audio objects.
The Audio Controls Editor tool is your interface to set up audio libraries of f: Show Environment amounts for active audio objects.
sounds that can be triggered in many ways. Adding audio brings with it a g: Show distance to listener for active audio objects.
whole new set of design issues that you’ll learn to plan carefully, including h: Show occlusion ray labels.
timing, the order of events, mixing multiple sounds, proximity and apparent i: Draw occlusion rays.
location, and more. j: Show object standalone files.
m: Hide audio system memory info.
Since Wwise is complex enough to merit an entire course in and of itself, this n: Apply filter also to inactive object debug info.
introduction to audio will focus on the significantly less complex SDL Mixer u: List standalone files.
middleware. We highly recommend that you take a few minutes to read v: List active Events.
through our documentation on using SDL mixer. w: List active Audio Objects.
x: Show FileCache Manager debug info.
Sound Design Let’s enable some useful information using the following Console command:
s_DrawAudioDebug abdfgmv
SDL Mixer will only play .WAV or .OGG files with a 48kHz sample rate and
a 16 bit sample size. However, you’ll need to use the compressed .OGG format You’ll immediately see audio information being superimposed in the
to keep your build size within reason. We recommend that you design and save Perspective viewport. Remember, to turn this off once you’re done debugging,
your sounds in a high quality uncompressed format like .WAV or .AIFF, then type s_DrawAudioDebug 0
export copies in the compressed .OGG format using quality level six (60%) to
balance quality and file size.
Pro Tip:
The Find tool in Flow Graph is
very helpful when you need to find
a specific node, entity, port, or
even a specific value – especially
as your graphs get complex. Just
press Ctrl-F or choose Edit > Find
from the Flow Graph menu. The
Search panel includes many
options, including the scope of
your search and the type of data
you want to find. Double click on a
result to jump to it in the graph.
1. First, drag the Out output of the Logic:Gate node to the Trigger
input of the Mission:GameTokenSet node that sets booIsDead to
Adding a “Flap” Sound
true. This insures that this only happens on the first collision. Every time the player presses the jump key, our Flappy exerts itself to move
2. In the Game Over section of your Flow Graph, insert a Time:Delay upward. Let’s add a simple humorous sound and trigger it on each jump:
node between the GameToken node that checks booIsDead and the 1. In the Audio Controls Editor, right-click on the FlappyAudio
Entity:PropertySet node that disables the bResting property of the library and add a new trigger called squawk_low.
GameOverBox. Try a delay of 1.3 seconds. You may need to adjust
this. 2. Drag the squawk_low.ogg audio file into the Connections window.
Set the trigger’s properties as follows: Action: Start; Volume: 0db;
Enable Panning/Enable Attenuation: disabled. Save your sound
CRYENGINE Flappy Boid Course Ver. 5.5D - 80 - 12: Exporting a Game to a Stand-Alone Build
CRYENGINE Flappy Boid Course Ver. 5.5D - 81 - 12: Exporting a Game to a Stand-Alone Build
CRYENGINE Flappy Boid Course Ver. 5.5D - 82 - 12: Exporting a Game to a Stand-Alone Build
CRYENGINE Flappy Boid Course Ver. 5.5D - 83 - 12: Exporting a Game to a Stand-Alone Build
CRYENGINE Flappy Boid Course Ver. 5.5D - 84 - 12: Exporting a Game to a Stand-Alone Build
Going Further
Congratulations, you’ve built a fun finished game and learned a set of core
skills that you can apply to all of your future CRYENGINE game designs!
The best thing you can do at this point is to apply what you’ve learned to
building your own games. You might also try extending the functionality of
your flappy boid game. While you probably have plenty of ideas for
enhancements, here are a few suggestions for which we will publish step by
step instructions in future editions of this tutorial:
Replace the debug message score with a polished Flash UI
Trade out the default sphere and replace it with an animated bird (try a
ParticlePhysics object, as RigidBodyEx only supports .CGF models)
Add features like play again y/n, a finite number of points to accrue to
finish the level, etc.
Add additional levels and automatically load the next one when a player
reaches a certain score.
Lastly, we always welcome feedback. If you have suggestions, see typos or
mistakes anywhere in this tutorial, please get in touch with us!
CRYENGINE Flappy Boid Course Ver. 5.5D - 85 - 12: Exporting a Game to a Stand-Alone Build