Sie sind auf Seite 1von 86

CRYENGINE Flappy Boid Course 5.

5D
Student Workbook

Setting a Default Camera ........................................................................ 12


Table of Contents Hiding the FPS Gun Crosshairs ............................................................... 13
CRYENGINE Flappy Boid Course 5.5D ............................................................ 1 Previewing Physics and AI Systems........................................................ 13
Table of Contents ....................................................................................... 1 Understanding Flow Graph Data Types .................................................. 13
Course Setup ................................................................................................ 3 02: Setting Up Initial Logic ....................................................................... 16
Course Setup for Self-Study....................................................................... 3 Making the Camera Follow the Player ..................................................... 16
Installing CRYENGINE and GameSDK ..................................................... 3 Adding a Texture to the Sphere ............................................................... 16
Installing the Course Assets ....................................................................... 3 03: Adding the Pipe Obstacles ................................................................. 18
Classroom Requirements for Teachers ..................................................... 3 Game Design Considerations .................................................................. 18
Classroom Setup for Teachers................................................................... 4 Adding the Pipes ...................................................................................... 18
Course Learning Objectives ....................................................................... 4 Adjusting Lighting Using the Environment Editor .................................... 18
Course Workbook Conventions.................................................................. 4 Adding the Top Pipe ................................................................................ 19
Introduction ................................................................................................. 5 Adding A Score Trigger............................................................................ 19
Perquisites .................................................................................................. 5 04: Adding the “Game Over” Text ........................................................... 22
01: Building the Assets, View, and Basic Functionality .......................... 6 Linking vs. Grouping ................................................................................ 22
Brainstorm “Flappy Boid” Design Ideas ..................................................... 6 Editing Grouped Entities .......................................................................... 22
Seeing the Default GameSDK Setup ......................................................... 6 05: Adding a Moving Sky Background .................................................... 23
Adding a Simple Player Entity .................................................................... 6 Adding a Background Box ....................................................................... 23
Adding a RigidBodyEx Player Object ......................................................... 6 Adding a Sky Texture............................................................................... 23
Physics Properties and Strategies ............................................................. 7 Scaling the Background Texture.............................................................. 23
Using an AI Tag Point to House Flow Graph Scripts ................................. 7 Animating the Sky Texture ....................................................................... 23
Flow Graph Overview ................................................................................. 8 Removing Shadows Through Shaders .................................................... 24
First Game Mechanic: the Jump Action ..................................................... 9 Scaling and Positioning the Background Box .......................................... 24
Responding to the Jump Action ................................................................. 9 Using Global Illumination ......................................................................... 25
Modifying Game SDK Functionality .........................................................11 Optimizing Designer Entities Through CGF Export ................................. 25
Hiding the Shooter Player and HUD ........................................................11 06: Moving the Pipes ................................................................................. 27
Preventing the Shooter Player From Walking ..........................................12 Moving the First Pipe ............................................................................... 27
Adding a Camera ..................................................................................... 12 Resetting the Pipe Position ............................................................................ 28

CRYENGINE Flappy Boid Course Ver. 5.5D -1- Course Setup


Moving the Other Pipes .................................................................................. 30 Creating a Glass Material for the Stars.................................................... 63
Environmental Considerations ........................................................................ 30 Converting Designer Models to CGF Format .......................................... 63
Creating a Debugging Camera................................................................. 30 Considering Shader Issues ...................................................................... 64
07: Keeping Score ...................................................................................... 32 Adding an Animated Sky Dome ............................................................... 64
Adding A Score Variable .......................................................................... 32 Adding Moving Cloud Shadows ............................................................... 64
Incrementing the Score ............................................................................ 32 Setting Up the Scoring Stars ................................................................... 64
Displaying Score Onscreen ...................................................................... 32 Adding Particle Effects ............................................................................. 67
Adding “Score” Text ................................................................................. 33 Eliminating Physical Forces From Particle Effects .................................. 67
08: Player “Death” ..................................................................................... 35 Randomizing Particle Effects ................................................................... 67
Tracking “Death” Using a Game Token ...................................................35 11: Adding Audio ....................................................................................... 70
Detecting Collisions .................................................................................. 35 Sound Design .......................................................................................... 70
Ending the Game ..................................................................................... 35 Enabling Audio Debugging ...................................................................... 70
Freezing the Camera On Player Death ....................................................36 Adding Environmental Sounds ................................................................ 71
Setting Up a Game Over Camera ............................................................ 38 Creating an Audio Library ........................................................................ 71
Stopping Pipe Movement on Death .........................................................39 Adding Audio Triggers To Your Game..................................................... 72
Disabling Jump After Death...................................................................... 39 Adding a Collision Sound ......................................................................... 73
09: Enhancements ..................................................................................... 42 Preventing Multiple Collision Sounds ...................................................... 74
Hiding Terrain ........................................................................................... 42 Disabling Jump On Collision .................................................................... 76
Adding a Global Difficulty Setting ............................................................. 43 Adding Game Over Sounds ..................................................................... 76
Adding Dynamic Horizontal Pipe Speed ..................................................44 Adding a “Flap” Sound ............................................................................. 77
Adding Random Vertical Pipe Movement ................................................45 Adding Score Sounds .............................................................................. 78
Adjusting Pipe Speed For Actual Travel Distance ...................................47 Adding Sounds to the Particle Effects ..................................................... 78
Randomizing Z of Pipe Start Point ...........................................................49 12: Exporting a Game to a Stand-Alone Build ........................................ 80
Adding Death Triggers To Constrain Player ............................................51 Hiding Display Info In Build ...................................................................... 80
Making Level Reload Automatic After Death ...........................................52 Porting a Level To Another Computer or Build ........................................ 80
Minimizing Lens Distortion Using Camera FOV .......................................55 Challenges For Additional Enhancements............................................... 80
Exploring Cameras Further ...................................................................... 55 The Final Design ...................................................................................... 80
Optional Ending: Camera Move ............................................................... 56 Going Further ........................................................................................... 85
Optional Ending: Splash and Sink ............................................................ 56
Randomizing Pipe Materials..................................................................... 58
Disabling FPS Death Effect on Game Start .............................................60
10: Adding Animated Score Targets ........................................................62
Modeling the Stars ................................................................................... 62

CRYENGINE Flappy Boid Course Ver. 5.5D -2- Course Setup


Course Setup 4. Search for the “Flappy Boid” course asset and add it to your cart.
5. Check out and download both assets from the marketplace.
Course Setup for Self-Study 6. In the Launcher, click on Library > My Assets. Find the Flappy Boid
asset. Click on the arrow next to it and choose Reveal in Explorer.
If you are planning to work through this course independent of any classroom Double click to open the FlappyAssets folder inside it. Select
instruction, you presumably have downloaded this course from the everything in this folder and copy them (Ctrl-C).
CRYENGINE marketplace and unzipped all of the course assets, including
7. In the Launcher, click on Library > My Assets. Click on the arrow
this PDF file. The ZIP will unpack a folder called next to your GameSDK asset and choose Reveal in Explorer. You’ll
FlappyBoidCourse[version#] containing the following: be in a folder called gamesdk_5.5. Open the GameSDK folder inside
• This book: FlappyBoid[version # and revision letter].pdf this. Ctrl-V (paste) the Flappy assets (audio, materials, objects etc.
folders) into here.
• A ScreenCaptures folder featuring high resolution images from this
course book to help you see how the game logic is constructed 8. Note the location of this gamesdk_5.5 folder.
9. In the Launcher, click on Library > My Projects. Click on the
• The FlappyFinished folder, containing the finished game level, which Import button. (GameSDK is a complete project, not just an asset, so
you can copy to your GameSDK\levels folder and reference to see it needs to be imported as a project.) Browse to the gamesdk_5.5
exactly how everything is constructed folder you’d already opened, then to the GameSDK folder inside that.
• A FlappyAssets folder containing game assets that need to be moved to Click OK to import your GameSDK project into the Launcher.
your CRYENGINE project folder. Before you can do this, you must
install the CRYENGINE Launcher, CRYENGINE, and the GameSDK Installing the Course Assets and Level
asset from the marketplace, as follows:
Lastly, copy the contents of the course’s FlappyFinished folder to the
Installing CRYENGINE and GameSDK cryengine_5.5\GameSDK\levels folder you already have open.
The FlappyFinished folder contains the finished game that you will create
This course requires CRYENGINE 5.5 with the 5.5 GameSDK. If you are within this course, strictly for reference purposes. While you can study it and
taking this course as a Crytek-taught class, the staff may have pre-installed the refer to it if you have unanswered questions, the only way to learn the engine
software and course assets on each student computer. However, the steps to do is to actually build the game step by step.
this on your own computer are also outlined here:
Finally, click on the GameSDK project from the Launcher to open it. Once
1. Download and install the free CRYENGINE Launcher from here by the Editor is open, create a new level called “FlappyBoid” through File >
clicking on the Download button. Note that you will need to create a New. (We suggest keeping your levels in the levels folder.) Accept the default
free account if you don’t already have one. If you need additional help terrain settings. Unless you are using this syllabus to teach a class, you can
with this step, refer to our Installation Quick Start guide. skip to the first chapter of the course.
2. Start the Launcher and sign in to your CRYENGINE account.
3. In the Launcher, click on Marketplace > Marketplace. Search for
Classroom Requirements for Teachers
“GameSDK” and add the asset to your cart.

CRYENGINE Flappy Boid Course Ver. 5.5D -3- Course Setup


This course requires PCs that meet the minimum CRYENGINE 5.5 hardware 4. Design and build a level
requirements with CRYENGINE 5.5, Game SDK 5.5, and the Flappy course 5. Use the Environment Editor and Level Settings to control sunlight,
assets installed, as detailed above. time of day, latitude and longitude, clouds, wind, shadows, global
The Flappy screen shots are high resolution electronic copies of the screen illumination, and ocean parameters
shots published in this course book, with the advantage that students can zoom 6. Use the Level Explorer to manage, freeze, hide, rename, link and
in on them to help clarify complex Flow Graphs. assign entities to layers
For Crytek instructors, US English or German keyboard, as specified 7. Control the position, movement, scale, and rotation of entities through
Flow Graph
An HD projector connected to the instructor computer. (1920x1080)
8. Precisely position and modify objects using snap and alignment tools
A large white board (or chalk board) with multi-colored markers and eraser.
9. Add, move, and control cameras and their properties; control the
Light on the white/chalk board, but not on the projection screen. player’s view
10. Use physics for realistic movement; selectively deactivate physics on
Classroom Setup for Teachers specific entities
1. Make sure that you warn students ahead of time to bring headphones, 11. Detect and react to collisions between entities
a pen or pencil and highlighter to take notes in the course workbook, 12. Use and trigger particle effects
and a thumb drive so they can take home their finished game. 13. Script and control audio events and ambience
2. Follow the steps above to install the CRYENGINE Launcher, 14. Script game mechanics and scorekeeping using Flow Graph
CRYENGINE, GameSDK, and the course assets.
15. Use assets and functionality from the free GameSDK (Software
3. We recommend that you have students set cVar sys_asserts = 0 and Development Kit)
log_verbosity -1 or 0 to reduce alerts on all systems, and to reduce the
number of questions they might produce. 16. Modify and selectively disable GameSDK functionality
4. TEST and make sure 5.5 is running fine on all systems. 17. Export a finished game to a stand-alone executable and test it
5. Test projector and speakers. 18. Use Console Variables to control the Editor and test environments
6. Pass out pre-printed student workbooks.
Course Workbook Conventions
Course Learning Objectives To help you understand the text in this workbook, we have used the following
formatting conventions:
Upon completion of this course, students will know how to:
Important concepts are highlighted in bold, or refer to something you can do
1. Navigate the CRYENGINE interface, Editor, and tool set or click on: a button, entity, menu item, etc.
2. Work with entities, including rigid bodies, cameras, AI tag points,
brushes, and Designer objects Nested items in menus or tool palettes are separated with the right caret
character, e.g.: Tools > Level Editor > Create Object.
3. Create and edit materials and textures

CRYENGINE Flappy Boid Course Ver. 5.5D -4- Course Setup


This course assumes zero prior knowledge of CRYENGINE. It takes you Introduction
from an introduction to the interface through finishing a working game. You
can work through the course completely on your own, or in a CRYENGINE Welcome to the CRYENGINE Flappy Boid course!
class with the benefit of an instructor. We’re going to learn core CRYENGINE concepts by building a “flappy boid”-
The finished game and needed assets can be downloaded free of charge from style game. While we know that you’re all eager to learn how to build the next
the CRYENGINE Marketplace. Crysis with massive photo-realistic levels, explosions, helicopters, legions of
warriors and all of that fun stuff, you have to walk before you can run. This
The course is broken down into multiple chapters, each beginning with a introductory course will cover a lot of ground in a few short days, and the
heading like this one: concepts and tools you’ll learn will serve as the foundation for every game you
ever build in CRYENGINE.
Flappy 02: Setting Up Initial Logic
Each major step within a chapter begins with a heading in this format:
Prerequisites
Topic Heading If you have no experience using CRYENGINE, please take a few minutes to
read our Designer Quick Start before starting this course. It will introduce you
Concepts and goals are explained first, followed by the exact step by step to the basics of the Editor interface, navigation, the tools, and creating a level –
instructions to achieve them. In addition, every one of the major chapters in topics which you’ll need to understand before you start this course.
this book has been included with this CRYENGINE project as a separate level Otherwise, this course assumes zero prior knowledge of game development or
that includes the finished work up to the end of that chapter. For example, the game engines. You will need to be comfortable navigating the Windows
Flappy01 level will show you how your game should look after finishing the operating system, File Explorer, and using the mouse. Dual monitors are
steps in Chapter I. helpful in game development (many developers use three monitors) given the
Tips about best practices look like number of tools used, but certainly not necessary.
this:
Pro Tip:
Flow Graphs can quickly get very
large, so keeping them neat and
well-organized is paramount. A
simple technique is to minimize
each node by clicking the arrow at
top right.

CRYENGINE Flappy Boid Course Ver. 5.5D -5- Course Setup


01: Building the Assets, View, and Basic Functionality In addition to the player seeing a visible
“bird” apparently moving through
obstacles, it needs to respond to the jump
Brainstorm “Flappy Boid” Design Ideas action by moving upward. For that Pro Tip:Mass vs. Density
movement to look realistic, it needs to be While you can use either mass or
Take a look at this video of the finished game in action. How would you density to define an object’s
design it in a 3D environment? What’s the simplest, most efficient and elegant a “physicalized” entity that will respond weight, density is best used for
way for it to be constructed? to real-world physics. A physicalized objects which should float. You
object of some mass will accurately should never set both to positive
What needs to actually move? respond to the force of gravity that’s values; the engine will simply
prioritize Mass. If you specify only
How many pipes do we need? already present within the engine, which density, mass will be computed as
simulates real-world forces. density times the physics proxy’s
Take some time outline your Game Design Document on paper. Even if the volume. See this documentation.
game design of this course doesn’t prove to be exactly the same, thinking
about the challenges and how to solve them is a necessary part of game
Adding a RigidBodyEx Player
development. When you’re ready, open your new FlappyBoid game from the Object
Launcher.
1. In the Editor, use the Create Object tool to add a Legacy > Physics >
RigidBodyEx entity to your level. (You can either double-click the
Seeing the Default GameSDK Setup RigidBodyEx entity in the Create Object tool and then click on the
Before we start designing our game, it’s useful for you to know what terrain to create it, or drag the object onto the terrain.) By default,
GameSDK has given you. GameSDK is based on Crysis, a first person shooter unless you have another entity over which you can hover with your
mouse, it will snap to the terrain at 32m Z. (The default terrain height)
game. Press Ctrl-G now to enter game play mode. You’ll immediately see
your hands with a gun in front of you. You can move around with the standard 2. Use the Properties > General window to rename your entity
WASD keys, shoot the gun (left mouse click on a PC), and switch to a 3rd “FlappyBoid.”
person view by pressing F1, among other things. 3. Position your entity (Properties > Transform) at 500, 500, 100. 100
It’s important to understand that GameSDK gives you all of this functionality Z will be the vertical center point of our aerial game.
and much more by default, because one of the first tasks we have to 4. Scroll down in the Properties window and make sure Physicalize is
accomplish is to hide and disable this first person shooter character, given that checked and Resting is unchecked. Set the bird’s mass to 10. The
our Flappy Boid game is utterly different. Press ESC to exit game play mode mass vs. the amount of upward force we’re going to apply will
and return to the Editor. determine the entire “feel” of our game. (We won’t be changing the
default force of gravity that pulls the bird downward.) Note that the
Adding a Simple Player Entity default mass of -1 tells the engine to make an object “sleep” -
unmovable by the forces of physics, like gravity.
While we’re ultimately going to create a bird-like player entity with moving The default geometry for a RigidBodyEx is a sphere. Given the complexities
wings, we’re going to start off with a simple geometric sphere as our player to of animation, this is useful in this introductory course, as we can concentrate
keep things simple. on game play logic for now, and replace the sphere with an animated bird later.

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.

Previewing Physics and AI Systems


One last game development tip: the physics and AI systems are complex and
demanding on computer resources. If they were always enabled while you
were using the Editor, any entity you added to the sandbox would immediately
start being affected by all of the physical forces that are on by default: gravity,
wind, ocean waves, etc. Thus, both systems are kept off when you're designing programming language is that it handles data type conversions seamlessly;
in the Editor. you usually don’t have to worry about converting and matching data types.
Any signal can trigger an input node.
Any time you want to see how physics and AI are going to affect your entities
without actually switching to game play mode, you can press Ctrl-P to enable However, there are times when you may need to take the data type into
both systems. Next to that button on the toolbar, you also have buttons to step consideration. A common example is the Vec3 (yellow) type, which actually
through the game one frame at a time, and to stop the physics and AI consists of three floating point numbers: X, Y, and Z, which collectively
simulation. One advantage of these tools is that you can still see entities that describe 3D position. If you need to extract one of those values, you’ll need to
are invisible in play mode – very useful for debugging. use a FromVec3 node, which splits the Vec3 data into three separate values,
as shown here. We’ll do exactly that later in the course.

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.

Adding a Texture to the Sphere


Why not a zero time for our MoveEntityTo? Given the
massive demands of real-time 3D games on CPUs, you want
to be careful about asking for instantaneous responses except

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.

Removing Shadows Through Shaders


You may have noticed something that ruins the illusion of our “sky” –
shadows of the pipes on our “sky” box!
We can try to fix this by adjusting the Sun direction in the Environment
Editor. You might also want to move your background box farther away from
your pipes.
Take a couple of minutes to experiment with the lighting. Chances are, you’ll
still have shadows on your “sky.” We can help this by moving your
background sky box farther away from the pipes and making it bigger so it still
fills the FlappyCam view. While the Environment Editor can provide many
dramatic photorealistic effects including volumetric clouds and fog, we won’t
need anything more from it in this game, so let’s close it now.
We will still have shadow problems on our background box, no matter how we
angle the sun. In the end, the best solution is to tell our background box not to
render shadows at all by modifying its shader:
1. Select the background box.
2. In the Material Editor Legacy tool, change the Material Settings >
Shader parameter from Illum to ReferenceImage.

Scaling and Positioning the Background Box


Let’s make the background fill the screen by scaling and positioning it. How
can we be sure that it’s the right size to fill the player’s view?
Create a secondary viewport based on the FlappyCam camera and watch it as
you position and scale the background box using other viewports:
1. Click the blue Camera menu at the top left corner of the Perspective view. Keep in mind that viewports do not update in real time when
Viewport and choose Create Viewport > Perspective. you make changes in another perspective viewport.
2. In your new Perspective Viewport, click the Camera menu again and 3. Scale and move the Designer Box until it’s large and thin and fills the
choose Camera Entity > FlappyCam. Now you see the player’s FlappyCam view.

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 - 32 - 07: Keeping Score


5. Click on your DisplayMessage node. Try a font size of at least 5, You might want to add a comment box around these connected nodes and call
and change the font color to your own taste – just make sure it it something like “scoring.”
contrasts with the background!.
We need the score to update if ANY of the score triggers are touched. Let’s
6. Let’s test it while watching it with Debug enabled. Click on the add the rest of the score triggers and extend the logic:
Debug icon on the Flow Graph toolbar to enable debugging.
1. From the Level Explorer, select all four of your score proximity
Press Ctrl-G to enter game mode. You should see a 0 onscreen – your current triggers. Tip: use Ctrl-click to select non-contiguous items in the Level
score – until you jump up high enough to touch the pipeScore_trigger, at Explorer.
which point your score becomes 1. Each time you pass through the proximity
trigger, your score is incremented by one. 2. Right-click on your Flow Graph and choose Add Selected Entity.
Arrange them by name in the scoring section of your graph.
Adding “Score” Text 3. Drag the Output of the Game:Start node to the Enable inputs of each
of your proximity trigger nodes.
Let’s clarify for the player what this number means by adding the word 4. Right-click the handle in the middle of the connector between your
“Score” in front of it. Adding bits of text together into one string is called pipeScore_trigger and GameTokenModify nodes and choose
concatenation: Logic:Any.
1. Drag a String > Concat node onto your Flow Graph. 5. Map the Enter outputs of each of your pipe#Score_trigger nodes to the
1. Click on your String:Concat node and set the String1 property to In2 through In5 inputs of your Logic:Any node.
“Score: “ 6. Rearrange your nodes as necessary so your Flow Graph is easy to
2. Map the Out output of your Logic:Any node to the Set input of your follow. Don’t forget to extend your SCORING comment box to
Concat node. surround all of the scoring-related nodes.
3. Map the Out of your String:Concat node to the Show and the
Message inputs of your DisplayMessage node. This sets the debug
message as the two concatenated strings and shows them onscreen.

CRYENGINE Flappy Boid Course Ver. 5.5D - 33 - 07: Keeping Score


CRYENGINE Flappy Boid Course Ver. 5.5D - 34 - 07: Keeping Score
08: Player “Death” 3. Inside this comment box, add a Game:Start node.
4. Add an Entity:EntityInfo node. Assign your FlappyBoid to it.
Tracking “Death” Using a Game Token 5. Drag the Output of your Game:Start node to the Get input of your
Entity:EntityInfo node. This queries the EntityID of your FlappyBoid
We will want several things to happen when the player collides with a pipe. entity on game start.
All of them can react indirectly to these collisions (rather than a messy series
6. Now the important part! Add a Physics:CollisionListener node to the
of Flow Graph connections across disparate sections) simply by “listening” to
right of your other nodes.
the value of a true/false Game Token that is false until a pipe collision sets it to
true: 7. Drag the Id output of your EntityInfo node to the Add Listener input
of your Physics:CollisionListener node. This is the node that detects
1. Open the DataBase tool from the Tools menu. any collisions between physicalized entities. The entity ID is a unique,
2. Click on the Game Tokens tab. automatically created number used internally by CRYENGINE to track
3. Under Game Token Tasks, click on Add New Item. Call your Game each entity (not the name property you assign).
Token booIsDead. Note that the default variable type is Boolean with 8. Although physics will create a natural reaction between the “bird” and
a default value of false. Although this is exactly what we want, we the pipe (as long as both are physicalized), we can enhance that with an
will manually initialize its value on game start – a wise practice. additional physics impulse: add a Physics:ActionImpulse node.
9. Assign the FlappyBoid entity to the ActionImpulse node. Try setting
Detecting Collisions the Impulse to 50, 0, -50 to push the bird to the left (away from the
pipe) and downward on collision.
Now that we have our pipes moving, we need to sense when our bird collides
with any of the pipes, and end the game. As always, we need to ask ourselves: 10. Map the IdA output of the CollisionListener node to the Activate input
what is the most simple way to achieve this? of the ActionImpulse node.
11. Lastly, add a Mission:GameTokenSet node. Set its Token to
One way of looking at this is that a collision is contact between two entities – booIsDead and its Value to true. Map the IdA output of the
a pipe and our bird, in this case. That means that the pipes could detect the CollisionListener node to the Trigger input of the GameTokenSet
collision, or the bird could handle it. node. If the bird collides with any physicalized entity, our booIsDead
Given that, it makes more sense to only have one set of Flow Graph nodes on variable will be made true. Next, we need to actually act on this in a
the bird rather than duplicate nodes on each pipe. To sense the collision, we’ll Game Over section of Flow Graph that watches this variable.
use the magic of the Physics:CollisionListener node:
1. In your FG_Main Flow Graph, scroll to a blank section below your
Ending the Game
other sections. When the player collides with an obstacle and dies, the game is over. We have
2. Create a Comment Box and call it Detect Collisions. Expand it to give a “game over” text ready and waiting out of sight. At the moment of death,
yourself some room. want to simply reveal the Game Over text to the player.

CRYENGINE Flappy Boid Course Ver. 5.5D - 35 - 08: Player “Death”


If you don’t want the player to see that there are only four pipes, rotate your
CHALLENGE: Exactly what should we move when the Game Over text and camera so it faces away from the pipes.
game ends, if anything? Brainstorm 2-3 possible
approaches to showing the Game Over text.
Freezing the Camera On Player Death
Could we simply reposition our FlappyCam (just as we have been) so it sees Now that we have a place where we’re tracking the player’s death status, we
the “game over” text at the moment of death? Do you see any potential need to actually act on it by stopping FlappyCam’s move as soon as
problems? booIsDead becomes true.
This method introduces some possible conflicts, since other nodes are also We set the FlappyCam to follow the player as it jumps and falls – but it will
trying to move FlappyCam (to follow the player). We’d need to stop that also follow the player all the way down to the terrain when the player “dies.”
movement so it doesn’t conflict with moving FlappyCam.
Instead, let’s freeze the camera and let the player drop out of the bottom of
A simple method is simply to create an additional camera positioned to see the game on death, as indicated by our booIsDead Game Token being true:
the GameOver text and enable that camera when a player dies – i.e., to simply
switch cameras. In our design, we hid the Game Over text behind FlappyCam, 1. In the CAMERA MOVEMENT section of your FG_Main Flow
Graph, drag a Mission:GameToken node onto your graph.
and the game over camera behind the game over text. I.e., when the game
ends, we just jump to a view from farther away on the Y axis – far enough to 2. Click on the .. button next to the Token parameter and choose your
see that the game over text that was there all along! booIsDead Game Token.
3. Set Compare To to False.

CRYENGINE Flappy Boid Course Ver. 5.5D - 36 - 08: Player “Death”


Now instead of simply passing the bird entity’s position through our offset to 6. Map the Pos output of your EntityPos node to the In input of your
the MoveEntityTo node that moves FlappyCam, we need to check the value of Logic:Gate. This simply passes the bird’s position data to the logic
booIsDead and decide between two actions. We’ll use a logic gate to gate to wait until its Open input is triggered, at which point it will
accomplish this. pass the value to the Out output.
As long as booIsDead = false, we want to continue passing the offset position 7. Drag the Equal output of your GameToken node to the Open input
to the Start input of the MoveEntityTo node we already set up on FlappyCam. of the Logic:Gate node. This means when booIsDead equals false, the
But as soon as booIsDead = true, we need to trigger the Stop input of the logic gate opens, passing the position for the camera to move.
MoveEntityTo node instead – bringing the camera movement that was already 8. Map the Out output of your Logic:Gate node to the A input of your
in progress to a halt. SubVec3 node.
However, the EntityPos node is going to continue to feed Flappy’s position to Lastly, we can’t forget to set the initial value of booIsDead to false on game
the MoveEntityTo node, causing the camera movement to start anew! Not only start:
do we have to stop the camera movement currently in progress, we have to 9. Open your FG_Main Flow Graph and find your Game:Start node.
prevent new movement from beginning by interrupting the position data
10. Add a Mission:GameTokenSet node.
flowing to the camera:
11. Drag the Output of your Game:Start node to the Trigger input of
4. Drag a Logic:Gate node onto your graph. your GameTokenSet node.
5. Remove the old connector between the EntityPos node and the 12. Set the Token of your Mission:GameTokenSet node to booIsDead
SubVec3 A input. and the Value to false.

CRYENGINE Flappy Boid Course Ver. 5.5D - 37 - 08: Player “Death”


We’ve built a complete pipe obstacle! At this point, use what you’ve learned to 3. Click on the Perspective viewport’s Camera button (top left) and
make three duplicates of the obstacle (i.e., the two pipes and the proximity choose Create Camera from Current View. We positioned ours at
trigger) and position them as a series, 15 meters apart on the X axis. Make 471, 587, 100.
sure you name and link them carefully! 4. Find your new camera entity in the Level Explorer and rename it
(Tip: expand the linked entities in the Level Explorer and select everything GameOverCamera.
you want to copy there. You can also sort the elements in the Level Explorer 5. In a blank section of your FG_Main Flow Graph, add a Camera:View
by clicking any column name. However, note that elements are grouped by node. Assign your GameOverCamera entity to it.
entity type when sorting by name.) 6. Add a Mission:GameToken node. Set the Token to booIsDead and
Note: your right-most bottom pipe should be at 440, 500, 96. Compare To to true. This means that we are asking whether it’s true
that booIsDead = true – i.e., is the player dead?
Setting Up a Game Over Camera 7. Drag the Equal output of your Mission:GameToken node to the
Enable input of your Camera:View node to activate your new camera
1. Position your game over text group behind FlappyCam. We used 472, on player death.
555, 100.
Save and test. When you’re happy, make the nodes neat and add a “GAME
2. Navigate your Perspective view to get the desired view of the game over OVER” comment box around them. You may also want to experiment with
text with the game behind it. adding a delay before switching to the game over camera to make the
transition less jarring.

CRYENGINE Flappy Boid Course Ver. 5.5D - 38 - 08: Player “Death”


4. Copy all of these nodes and replace the old nodes on the other three
pipes.
Stopping Pipe Movement on Death
Disabling Jump After Death
Since we’re going to jump back to a camera with a different perspective and
see all of the pipes simultaneously, let’s stop their horizontal movement on If you test or analyze your design carefully, you will also discover that we
death: haven’t stopped the bird from responding to the jump key even after it collides
and supposedly “dies.” Let’s disable that on death:
1. In pipe1_bottom’s pipeMovement Flow Graph, add a
Mission:GameToken node. 1. In your FG_Main Flow Graph, drag the Equal output of your
2. Set the GameToken’s Token to booIsDead and Compare To to true. GameToken node in the game over section to the Disable input of the
ActionListener node in the Initial Setup section. I.e., you don’t need
3. Drag the Output of the Mission:GameToken node to the Stop input any new nodes; you just need to ask the node that currently monitors
of the MoveEntityTo node. Since the GameToken node is always the value of booIsDead to disable the ActionListener that has been
listening to the token value, as soon as it is set to true, the pipe listening for the jump key.
movement will stop instantly. (Since our pipes have no mass, there is
no acceleration or deceleration, nor will gravity affect them).

CRYENGINE Flappy Boid Course Ver. 5.5D - 39 - 08: Player “Death”


CRYENGINE Flappy Boid Course Ver. 5.5D - 40 - 08: Player “Death”
CRYENGINE Flappy Boid Course Ver. 5.5D - 41 - 08: Player “Death”
09: Enhancements approaches to hiding it. One easy way to hide the terrain is simply to lower it
so it’s underwater: in the Terrain Editor, choose Edit > Set Max Terrain
Height. The default ocean height is 16m, so anything lower than that is
At this point, you have a fully functioning, albeit basic game. This chapter
underwater. (You can also use the same menu to adjust the height of the ocean:
offers just some of the many enhancements you might add to your game
Edit > Remove Ocean doesn’t actually remove it; it merely sets its height to -
design to make it more interesting and better looking.
100000m.)
Hiding Terrain The second approach is to hide terrain, wherever it happens to be – but keep in
mind that although it may be invisible, objects will still react to it normally,
You may have noticed by now that hiding the terrain from the Editor by like your bird when it falls, which could be confusing to users:
clicking on the Display button does not permanently hide it in the game if you
exit and restart CRYENGINE. 1. Open your FG_Main Flow Graph and find your Game:Start node.
2. Add a Debug:ConsoleVariable node to your graph. A Console
If you look at the Terrain Editor’s Edit menu, you’ll see Erase Terrain. If you
Variable or “cVar” can be set within the editor using the Console tool
click on that, you’ll see that the question is whether you want to erase the
(a command line tool). Set the C Var parameter to e_terrain, and the
height map – information that sculpts the terrain by making hills and valleys –
Value to 0.
not the terrain itself. If you do this, you’ll simply flatten the terrain, not
remove it. 3. Drag the Output of the Game:Start node to the Set input of your
Debug:ConsoleVariable node to force the terrain to be hidden on game
While you can’t instantly remove the terrain (although you could painstakingly start.
use the Terrain Editor’s Make Holes tool to erase it bit by bit), there are a few

CRYENGINE Flappy Boid Course Ver. 5.5D - 42 - 09: Enhancements


Adding a Global Difficulty Setting Note that it’s good programming practice to indicate the
variable type within the variable name itself. It’s common
Our existing game gets boring pretty quickly as long as the practice to use abbreviated prefixes such as int for integer, boo
pipes move exactly the same way on every pass. Let’s add two Pro Tip:
for Boolean, str for string, etc. You can use any convention
Choose your Game Token names
enhancements: first, make the game faster as the player’s score you prefer, but consistency is key. This practice is a big help
thoughtfully. If you decide to
goes up, and second, let’s add random vertical movement to with debugging!
rename a Game Token after
the pipes.
you’ve created Flow Graph nodes 3. Let’s map this difficulty setting to a range of pipe
Since these two features (along with horizontal pipe spacing) that reference it, that name change speeds: add a Logic:DeMultiplexer node. Drag the Out
affect the difficulty of the entire game, a nice enhancement that will NOT cascade through your Value of the GameTokenSet node to the Index input of the
you can add later in the UI is to invite players to choose their Flow Graph; you will have to DeMultiplexer node.
own initial level of expertise, and to modify the game difficulty manually find and change them
4. Since our difficulty levels are 1-4, that will trigger
accordingly. one by one! (Flow Graph’s search
ports 1-4 on the DeMultiplexer. Add four
tool is helpful with that.)
Let’s add a game token for overall game difficulty: Mission:GameTokenSet nodes. On each of them, set the
Token to your Level.fltPipeSpeed game token.
1. Use your DataBase Tool > Game Tokens to add a
new integer game token called intDifficulty. 5. Drag Ports 1-4 to each of the Trigger inputs of the
four GameTokenSet nodes, as shown in the screen capture.
2. In the initial setup section of your FG_Main Flow Graph, add a
Mission:GameTokenSet node. Drag the Output of the Game:Start 6. Set the Value property of each GameTokenSet node to your desired
node to the Trigger input of the GameTokenSet node. pipe speed. Given our game design, we suggest 3, 4, 6, and 8 (from
slowest to fastest).
3. Set the Token to Level.intDifficulty.
7. Since we’re about to add vertical movement to our pipes, let’s set the
4. Let’s use a simple difficulty scale of 1 to 4, where 1 is the easiest and range of vertical pipe movement based on this difficulty setting: use
4 is the most difficult. Set the GameTokenSet’s Value to 1, 2, 3, or 4, your DataBase tool > Game Tokens to create a new integer type
as you prefer. Game Token. Call it intVertPipeMovement.
Given that we’re about to add dynamic horizontal pipe speed, we need a game 8. Add four more Mission:GameTokenSet nodes, and set their Token
token that we can set initially and modify each time the player scores: property to your Level. intVertPipeMovement game token.
1. From the Database tool, create a new floating point game token called 9. Drag the Out Value of each of the our GameTokenSet nodes that set
fltPipeSpeed. your fltPipeSpeed to the Trigger inputs of these four new
2. The initial value doesn’t matter, because we’re going to initialize it with GameTokenSet nodes that are going to set the range of vertical pipe
a Game:Start node. movement.
We’re using a floating point number that allows values to the right of the 10. Lastly, set the Value property of your four GameTokenSet nodes to
decimal place. If we used an integer, the smallest possible increase in speed the desired range of vertical pipe movement. Given the factors at play
would be 1, which would end up accelerating the game speed so rapidly that it - the horizontal spacing of our pipes, the bird speed, the force of
would quickly become unplayable. gravity, and the upward jump force – we suggest values of 3, 6, 8, and
10. (As always, this distance is in meters.) Any larger than a ±10m

CRYENGINE Flappy Boid Course Ver. 5.5D - 43 - 09: Enhancements


range, and your player won’t be able to jump or fall fast enough to progress will immediately be affected, because the GameToken node
navigate through the pipes, no matter how skilled they are. is always listening to the value of its Token.
Later, we’ll add a full user interface that prompts players to choose one of
these four difficulty levels when the level is loaded.

Adding Dynamic Horizontal Pipe Speed


Let’s get rid of the hard-coded speed and drive our pipe movements with the
pipe speed game token we already created and initialized:
1. Since we’ve already initialized a fltPipeSpeed game token in our
Initial Setup, let’s feed it to pipe1’s horizontal movement: in the
pipeMovement Flow Graph for pipe1_bottom, add a
Mission:GameToken node. Set its Token property to the
fltPipeSpeed Game Token we already created.
2. Drag the Output of the GameToken node to the Value input of the

3. On your MoveEntityTo node, make sure Dynamic Update is set to 1.


Pro Tip:
This forces the node to constantly listen and respond to the inputs.
Another way to keep complex Flow Save and test. When you’re confident that this is perfect, select all of these
Graphs neat and as easy as nodes, copy them, delete the old nodes in the Flow Graphs for pipes 2, 3, and
possible to debug, you can change 4, and paste the new nodes into the pipeMovement graphs.
the curvature of the connecting
lines by click and dragging
Next, we need to increase pipe speed each time the player scores:
horizontally on the circular handle 4. In the Scoring section of your FG_Main Flow Graph, add a
in the middle of the connector. This Mission:GameTokenModify node.
will help prevent lines from
5. Set the GameTokenModify node’s Token to intScore and the Value
overlapping.
to 1.
6. Drag the Out of your Logic:Any gate to the Trigger input of the
Mission:GameTokenModify node.
7. Set the Operation to Add and the Value to 0.2. Note that the bigger
Movement:MoveEntityTo node. The old value that we hard-coded
this number, the faster the pipes accelerate as the player scores, and
into the Value input will be ignored in favor of the signal sent by the
GameToken node. Note that since MoveEntityTo is using speed (as the more difficult the game. Test and adjust as desired. Later, you
could modify this based on user-selected difficulty.
opposed to time), any time this Game Token changes – namely, every
time the player scores – the speed of the pipe movement already in Save and test!

CRYENGINE Flappy Boid Course Ver. 5.5D - 44 - 09: Enhancements


Adding Random Vertical Pipe Movement make sure that the gap doesn’t get too tight for the player to navigate
through it?
This requires some careful design, and there is more than one approach!
Consider these questions: • How will you limit how far the pipes move vertically to insure that
the game remains playable? I.e., you can’t allow pipes to end up so far
• Can you still use your ai_start and ai_end tag points as destinations for above or below the previous set that the player can’t jump or fall fast
your movements but add randomization? Can they help you, or do you enough to navigate through the gap.
need a different approach?
• Do you want each pair of pipes to travel in a straight line on the X
• Should each pair of pipes maintain a consistent gap gap between top axis, or would you like them to oscillate - to move vertically up and
and bottom pipes, or should the gap vary? If you vary it, how will you down multiple times during their trip across the screen?

CRYENGINE Flappy Boid Course Ver. 5.5D - 45 - 09: Enhancements


• How will you adjust pipe speed for the variations in the distance playing field in the same length of time, which keeps the pipes evenly
between start and end points created by shifting the start and end spaced.
points up or down? I.e., while the pipes originally moved 60m in a
In the pipeMovement Flow Graph for pipe1_bottom, we need to randomize
straight line along the X axis, as soon as the start or end points move
to the Z value (within a constrained range) of ai_end’s position before it’s
up or down, that distance increases. So you can’t simply move all
passed to the MoveEntityTo node. Here are the steps:
pipes at the same speed, or they won’t be evenly spaced. For example,
the steeper the angle, the longer the distance that must be traveled, and 1. Before we start randomizing the vertical position of these pipes, we need
the more those pipes will fall behind pipes that are traveling a shorter to know the vertical range determined by the difficulty setting: add a
distance. If pipes crowd together, it becomes impossible for the player Mission:GameTokenGet node and set its Token to the
to jump or dive fast enough to navigate through them. Level.intVertPipeMovement game token.
Take a minute to discuss some possible approaches with your classmates or 2. Drag the Out of your left-most Logic:Any node (the one whose In1
brainstorm on your own if you’re working through this course independently input is connected to the Game:Start node) to the Trigger input of the
GameTokenGet node.
before you turn to our solution.
We’ll need to use the upper limit for the pipe’s Z position set in the
As an initial approach, here’s what we’re going to build; if you are working intVertPipeMovement Game Token to also establish a lower limit. We can
independently, you can try your own variations: do this simply by multiplying the original value by -1:
• The ai_start and ai_end Tag Points are useful because they give us X 3. Add a Math:Mult node. Drag the Out Value of
and Y coordinates. All we have to do is to add and subtract a intVertPipeMovement’s GameTokenGet node to the A input of the
random number from the existing Z value. Math:Mul node. Set the B value to -1.
• We need that random number to be limited so the pipes don’t move so 4. Now for the randomization: add these nodes: Vec3:FromVec3,
far up and down that they disappear or the obstacles become Math:Random, Math:Add, and Vec3:ToVec3.
impossible to navigate. This can only be determined by tests. 5. Drag the Out of the Math:Mul node to the Generate and Min inputs of
• We’ll randomize both the start and end Z positions to make the pipe the Math:Random node to set our randomization range.
movement more interesting. 6. Drag the Pos output of the ai_end node to the Vec3 input of the
FromVec3 node. FromVec3 simply separates a three dimensional
• We’ll just move the pipes in a straight line on the X axis from ai_start
coordinate (Vec3) into X, Y, and Z values.
to ai_end for now, as adding oscillation (multiple moves along the Z
axis during each pass) will be more complex. Adding many features 7. Drag the X and Y outputs of the FromVec3 node to the X and Y
simultaneously greatly complicates debugging! inputs of the ToVec3 node. We don’t need to modify these coordinates,
just to pass them to the move node as-is.
• For now, we’ll move each pair of pipes together and not vary the gap
8. Drag the Z output of the FromVec3 node to the A input of the
between them.
Math:Add node. This is the unmodified Z position of ai_end.
• To make sure that each pair of pipes travels from start to end in the 9. Now we need to add the random offset to ai_end’s existing Z position:
exact same length of time, we’ll multiply the actual distance by the drag the Out port of the Math:Random node to the B input of the
straight-line distance to derive a factor that we’ll multiply times the
current pipe speed. This ensures that every pipe travels across the

CRYENGINE Flappy Boid Course Ver. 5.5D - 46 - 09: Enhancements


Math:Add node. (NOTE: there is no difference between A and B on the Reading these steps is probably more confusing than simply looking at the
Math:Add node; they are simply added together and sent to the Out.) graph itself! Take a minute to look it over and trace the logic until you fully
10. We've added the random offset to Z; now, let's pass it on the understand it.
MoveEntityTo: drag the Out of the Math:Add node to the Z input of
the ToVec3 node. This node simply combines separate X, Y, and Z Adjusting Pipe Speed For Actual Travel Distance
values into a three dimensional coordinate (Vec3).
Now we come to a tricky bit of math and logic: since our pipes are beginning
11. Finally, drag the Vec3 output of the ToVec3 node to the Destination and ending at different Z positions, the distance they have to travel is no
input of the MoveEntityTo node. longer a straight line on the X axis; it’s an angle. And if you think back to

CRYENGINE Flappy Boid Course Ver. 5.5D - 47 - 09: Enhancements


do this by dividing the straight-line distance (the X of ai_start to the X of
ai_end) into the actual slanted distance. That will give us a number somewhat
larger than 1, which we can then multiply by the pipe speed. (Note that if the
randomized Z of ai_start and ai_end happen to be exactly the same, the pipe
will travel straight across, and our speed factor will be exactly 1 – having no
effect):
1. Let’s get the actual current position of the pipe so we can measure the
distance to ai_end: add an Entity:GetPos node. Right-click on it and
choose Assign Graph Entity. (Note that we must use the current
position of the pipe, not the position of ai_start, since each pair of
pipes start at different positions on game start.)
2. Drag the Vec3 output of the Vec3:ToVec3 node to the Get input of
your high school geometry, you’ll remember that this angled line is always the graph entity’s GetPos node.
going to be longer than a purely horizontal line, as shown in this diagram.
3. Add a Vec3:SubVec3 node. Drag the Vec3 output of the ToVec3
The problem is that our pipe speed currently doesn’t take this into account; all node (in the section you just created that randomizes the Z end
pipes are told to move at the same speed, but the distances they have to travel position) to the A input of the SubVec3 node you just added.
are no longer equal. That means that the pipes won’t travel this distance in an 4. Drag the Pos output of the GetPos node to the B input of the SubVec3
equal length of time. The result is problematic: pipes will get closer together or node. This node is now calculating the difference between the pipe’s
drift farther apart, affecting the playability of the game. current position and the recently randomized end position to which it
To fix this, we need to make sure that each pair of pipes traverses its start-to- is about to be moved – but as a Vec3 data type, which consists of
end distance in exactly the same length of time, regardless of distance. We’ll separate differences in X, Y, and Z.

CRYENGINE Flappy Boid Course Ver. 5.5D - 48 - 09: Enhancements


5. Let’s calculate the distance as a single numeric value: add a 9. Finally, we’re ready to calculate a distance factor: add a Math:Div
Vec3:MagnitudeVec3 node. Drag the Out of the SubVec3 node to (divide) node. Drag the Length output of your MagnitudeVec3 node
the Vector input of the MagnitudeVec3 node. to its A input, and the Out of your Math:Sub node to the B input.
The Length output will give us the actual distance this pipe has to travel. Now Label this node “calculate difference between actual and straight line
let’s calculate what the distance would be if the pipe traveled in a straight line distance.”
along the X axis. To do this, we’ll split the Vec3 coordinates into separate X, 10. Now let’s multiply this factor times the current pipe speed: add a
Y, and Z values, and just measure the distance from X to X: Math:Mul (multiply) node. Drag the Out of the Math:Div node to
the B input, and the Output of fltPipeSpeed’s GameToken node to
6. Add two Vec3:FromVec3 nodes. Drag the Vec3 output of the the A input.
ToVec3 node of the Vec3 input of your first FromVec3 node. To help
you keep track of what these nodes are doing, add a comment above 11. Let’s feed the adjusted speed to the entity movement: drag the Out of
this first FromVec3 node that says “get position of end point.” the Math:Mul node to both the Value and the Start inputs of the
MoveEntityTo node.
7. Drag the Pos output of the graph entity’s GetPos node to the Vec3
input of the other FromVec3 node.
Randomizing Z of Pipe Start Point
8. Now let’s get the difference in X position between the pipe and its
intended end position: add a Math:Sub (subtract) node. Drag the X We've successfully randomized the Z of the end point and adjusted the speed
outputs of your two FromVec3 nodes to the A and B inputs of the for actual distance. Now let's randomize the Z start point:
Math:Sub node, respectively. Label this node “calculate straight line
1. First, let’s once again get the Z randomization range saved at game
distance.”
start: add a Mission:GameTokenGet node and set its token to the

CRYENGINE Flappy Boid Course Ver. 5.5D - 49 - 09: Enhancements


Level.intVertPipeMovement game token. Drag the Finish output of 6. Again, let's just pass on the unmodified X and Y values: drag both
the MoveEntityTo node to the Trigger input. the X and Y outputs of the FromVec3 node to the X and Y inputs of
2. Add a Math:Mult node. Drag the Out Value of GameTokenGet the ToVec3 node.
node to the A input. Set the B value to -1. 7. Let’s pass ai_start’s existing Z position on for modification: drag the
3. We can save some time by copying and pasting the same four nodes Z output of the FromVec3 node to the A input of the Math:Add node.
that randomized ai_end’s Z. However, we want to paste just the nodes, 8. Drag the Out of the Math:Random node to the B input of the
not the links, otherwise we will have spaghetti! Drag your mouse Math:Add node.
around the Vec3:FromVec3, Math:Random, Math:Add, and 9. Drag the Out of the Math:Add node to the Z input of the ToVec3
Vec3:ToVec3 nodes, Ctrl-C to copy them, right-click to the left of node. This combines the existing X and Y with the randomized Z into
the BeamEntity node and choose Edit > Paste without Links. (Or a Vec3 coordinate.
Ctrl-Shift-V)
10. Finally, drag the Vec3 output of the ToVec3 node to both the
4. Drag the Out Value of the GameTokenGet node to the Max input of Position and Beam inputs of the BeamEntity node.
the Math:Random node. Drag the Out of the Math:Mul node to the
Min input of the Math:Random node. Save and test! Play with this for several cycles until you're satisfied that both
start and end points are randomized for the first set of pipes. This is a good
5. Delete the old connector from ai_start’s Pos output to BeamEntity’s time to hide the other three sets of pipes to make sure your graph is bug-free
Beam input. Then drag the Pos output of the ai_start entity to the
before copying it to the other pipes.
Vec3 input of the FromVec3 node. Again, this separates ai_start’s
position into X, Y, and Z. Once you've fixed any bugs, copy this entire pipe movement Flow Graph to
the other three pipes in the pipeMovement folder, making sure you
completely delete the old nodes first!

CRYENGINE Flappy Boid Course Ver. 5.5D - 50 - 09: Enhancements


Adding Death Triggers To Constrain Player In short, we need to prevent our player from accidentally or deliberately going
“out of bounds,” getting confused or frustrated, or breaking the game. We can
There are situations that we have to consider in our game design: what use an additional set of proximity triggers directly above and below our
happens if the player just lets Flappy fall straight down before the pipes even FlappyBoid to prevent this by “killing” the player on contact:
reach it? What happens if they jump up so quickly that they go over the top of
the pipes? 1. Create two proximity triggers and position them directly above and
below your player, as shown in this picture. Suggested dimensions for

CRYENGINE Flappy Boid Course Ver. 5.5D - 51 - 09: Enhancements


your triggers: 10x10x1m. (Remember, to scale proximity triggers, edit 7. Add a Mission > GameTokenSet node to your Flow Graph.
their Lua Properties > Dim X/Y/Z, not Transform > Scale.) 8. Drag the Out of your Logic:Any node to the Trigger input of your
2. We’ll use these as our “death” triggers. Name them deathTriggerTop GameTokenSet node.
and deathTriggerBottom. 9. TIP: you can collapse a Logic:Any node to only show the used inputs
You’ll probably want to experiment with how far above and below the player (or any number of inputs you choose) by clicking on the arrow on its
to position these, and this will depend on the vertical range of movement you upper right corner.
programmed into the pipe movement. 10. In the Properties of the GameTokenSet node, set the token to
Too close, and the player may not be able to dodge pipes that move to the booIsDead and the value to true.
extreme limits of their vertical constraints without dying for no apparent 11. Add a comment box around these interconnected nodes, and name it
reason and becoming frustrated. Too far, and Flappy can go over or under the “Protect Game Boundaries” or whatever you find descriptive.
pipes. Save and test!
We placed ours 11 meters above and 11 meters Pro Tip: A suggested enhancement for you to work on independently would be to make
below Flappy, and of course at 500 X, 500 Y. As your Flow Graphs get large, these game boundaries visible, so the player feels that they’ve been fairly
3. Remember that our FlappyBoid is not you may need to connect two warned about the limits within which they can jump or fall.
the “player” as far as GameSDK is nodes that are far apart in the
concerned. Uncheck the Only Player graph. If you zoom out too far (to
be able to see those disparate
Making Level Reload Automatic After Death
box under Properties > Lua
nodes), you won’t be able to click Once you actually export your game as a stand-alone application, when your
Properties for both proximity triggers.
on ports accurately in order to player dies, they will have to restart the game manually. Since this could be
4. We don’t want collisions with the pipes connect them. The solution is to rather annoying for the very players whom we want to get addicted to playing
to set off these triggers, so we need to zoom in on a port,click on the port our game over and over, let’s make the level reload automatically after death:
be specific: Paste “FlappyBoid” or your and start dragging a connector
exact player entity name into the with the left mouse button, then 1. Go to the Game Over section of your FG_Main Flow Graph.
Properties > Lua Properties > Only while holding down the left 2. Add a Mission:LoadNextLevel node.
Selected Entity box. button, use the scroll wheel and
3. Set the Next Level value of your Mission:LoadNextLevel node to the
5. Add both entities to an empty area of right mouse button to navigate to
actual name of your level. Make sure you either copy and paste it from
your FG_Main Flow Graph. (Select see the destination node, then
the File Explorer or type it exactly right! This forces the level to reload
both, right-click on your Flow Graph complete the connection.
itself after the player’s death.
and choose Add Selected Entity.)
4. Drag the Equal output of your Mission:GameToken node to the
6. We need to sense whether the player collides with either Trigger input of your Mission:LoadNextLevel node.
of our death triggers. Add a Logic:Any node to your Flow Graph, and
map the Enter output of the proximity triggers to the In1 – In2 We’ve forced our only game level to re-load as soon as the player dies, but
inputs of your Logic:Any node. there’s one problem with this: it will happen immediately, and the player will
never get a chance to see your “game over” text!
When the player collides with either of our “death” triggers, we want to set
our booIsDead variable to true:

CRYENGINE Flappy Boid Course Ver. 5.5D - 52 - 09: Enhancements


5. Let’s insert a delay to give the player time to “grieve” after death: Mission:GameToken node and the Mission:LoadNextLevel node
right-click on the center point of the connector between the and choose Time Delay.
6. Set the Delay value to perhaps 3 or 4 seconds.

CRYENGINE Flappy Boid Course Ver. 5.5D - 53 - 09: Enhancements


Note that reloading the same level will not work when you’re using the Editor – i.e., in game play test mode, only once you export the game as a stand-alone

CRYENGINE Flappy Boid Course Ver. 5.5D - 54 - 09: Enhancements


.EXE application. 5. In the Camera Movement section of your FG_Main Flow Graph, find
the Vec3:SubVec3 node that adjusts the position fed to it by FlappyBoid
Minimizing Lens Distortion Using Camera FOV and change the X and Y offsets (the B parameter) to match the
difference between FlappyBoid’s X and Y position and FlappyCam’s X
You may have noticed that the pipes at the edge of the screen as well as the and Y position in the editor: X 17, Y -55.
sphere look stretched horizontally. This is because the engine is mimicking Save, test and adjust until you’re happy with the look of your game.
how things look through normal to wide lenses, and our current default FOV
(field of view) is fairly wide at 60º. TIP: You may find that you want to shrink your background box if you
tighten your FlappyCam’s FOV, or shrink the cloud texture to avoid seeing
To change this, we need to override FlappyCam’s FOV in Flow Graph with a pixilation. (You may also need to adjust texture tiling and oscillation.)
smaller angle. However, doing so means that we will see less horizontally and Reducing the FOV effectively makes your “lens” longer, which compresses
vertically. Thus we have to also move the camera farther away from our the apparent distance between objects. I.e., your background box looks closer,
entities: and you won’t see the edges so easily.
1. Try using two viewports, one set to FlappyCam and another with a
Left view.
2. Change your current FOV on the FlappyCam viewport to 30º. This only
affects the Editor’s view, not game play. You’ll see that the FlappyCam
now sees too little of your entities.
3. Select the FlappyCam entity in the Level Explorer. In the Left
viewport, drag it farther from the pipes until the FlappyCam view looks
the way you want it. Try 483, 555, 100.
4. To effect this during game play, we need to override the default 60º
FOV in Flow Graph when the game launches: find the Camera:View
node in the INITIAL SETUP section of your FG_Main Flow Graph.
Change the FOV parameter to 30º.

CHALLENGE: If you save and test, you may be in for a


rude surprise. Why do things look the way they do? Why
Exploring Cameras Further
are you seeing so little? Try to troubleshoot the problem Just changing the position of your camera can have a tremendous effect on the
before looking ahead for the answer. look and feel of your game. You may want to break out of the “side scroller”
look of this game and experiment with creating additional cameras. For
Did you figure out the problem? Although you moved the FlappyCam’s example, trying creating one that “follows” Flappy closely from behind, as in
position in the editor, your Flow Graph code repositions it dynamically to this view using an offset of -14X, -15Y and a FOV of 25⁰.
follow FlappyBoid! You have to adjust the offset of the camera’s position in
Flow Graph to match its modified position in the editor:

CRYENGINE Flappy Boid Course Ver. 5.5D - 55 - 09: Enhancements


Optional Ending: Camera Move 1. Click to select your Game Over entity group and select Level > Group
> Ungroup from the menu.
Another way to reveal the Game Over text would be to simply move our 2. Select all eight letters and move them downward so they “sit” on the
FlappyCam backwards (called “dolly back” in movie terminology). We flat box underneath them.
already know where we need to send it: to the position of our
GameOverCamera. Let’s use that as the destination, and have the camera 3. In Level Explorer, drag all eight letters onto the box object to link
move over a one second period: them to the box. This will allow us to move all of the game over entities
just by moving the box parent object, just as we did with the pipes.
1. In the Game Over section of your FG_Main Flow Graph, add an 4. Position your GameOverBox so a frontal view of it is looking away
Entity:EntityPos and a Movement:MoveEntityTo node. from the rest of your game. We’ve positioned ours at 500, 715, 23.
2. Assign the GameOverCamera to the EntityPos node so it can query 5. Since we want to make it easy to rotate the camera that will be showing
its position. us the game over text, make sure your game over entities have zero
3. Assign the FlappyCam to the MoveEntityTo node so it knows what rotation on all three axes.
to move.
Next, we want to create a camera that initially just hovers above the ocean,
Drag the Pos output of GameOverCamera’s EntityPos node to the and have the game over text surprise the player by dropping from above the
Destination of FlappyCam’s MoveEntityTo node so the move knows camera’s FOV:
where to send our camera.
6. Position your default view in the perspective viewport until it is looking
4. On FlappyCam’s MoveEntityTo node, set the Value Type to time towards the game over text, 18m above the water, but tilted down so it
and the Value to 1 (second). You can choose a different speed if you cannot see the game over text (check the view in full screen mode).
want a slower or faster camera move. We’ve positioned our camera at 500, 705, 18 with a -15 ⁰X rotation, as
5. To see this, we need to disable our previously created logic that shown here.
enables the GameOverCamera, because we want to continue seeing 7. Once you’re happy with your view, click on the Perspective Viewport’s
the game from our FlappyCam: right-click on the center of the Camera menu and choose Create Camera From Current View.
connector between the GameToken node’s Equal output and Name your camera “DiveCam.”
Camera:View’s Enable input and choose Disable. The line should
become dotted instead of solid.
Save and test by crashing into a pipe. The camera should move backwards to
reveal the game over text.

Optional Ending: Splash and Sink


Here’s a more dramatic way to end when the player dies: switch to a close
view of the ocean, let the game over text come splashing down into the water,
float on the waves for a moment, then have the camera sink under the waves
while tilting up to watch the “game over” text as it disappears. First, make sure
your ocean is visible in the display settings.

CRYENGINE Flappy Boid Course Ver. 5.5D - 56 - 09: Enhancements


Now, let’s add the game mechanics when the game ends: splash before sinking: add a Time:Delay node and set the Delay to 4
seconds.
8. First, open the Game Over section of your Flappy > FG_Main Flow
Graphs. 15. Add a MoveEntityTo node and RotateEntityToEx node. Assign
DiveCam to both of them.
9. If you were using the t_scale cVar to create slow motion at the end,
right-click and disable the connector to the Debug:ConsoleVariable 16. On the MoveEntityTo node, set the Value Type to time and the
node that sets this when booIsDead = true, or simply delete it. Value to 8 seconds.
10. Let’s enable our new camera when the player dies: add a 17. On the RotateEntityToEx node, set the Destination’s X value to 45⁰,
Camera:View node; assign DiveCam to it; and drag the Equal the Value Type to time and the Value to 6 seconds. This will make the
output of the booIsDead Mission:GameToken node to the Enable camera tilt up to a 45⁰ angle as it’s sinking. Depending on the distance
input of your Camera:View node. between the camera and the game over text, you may want to adjust
the timing of the downward movement and rotation. The idea is to
11. As with the pipes and FlappyCam, we’ll sink the camera by using
keep the camera looking at the game over text as it sinks.
Entity:MoveEntityTo. Add that node now and assign your DiveCam
to it. 18. Drag the Out of the Time:Delay node to the Start inputs of the
MoveEntityTo and RotateEntityToEx nodes.
12. Let’s retrieve and offset the camera’s original position: add an
Entity:GetPos node and assign DiveCam to it. Drag the booIsDead Next, let’s make our game over raft fall and splash into the ocean:
Game Token’s Equal output to the Get input of the GetPos node. 19. To make our game text entities fall, we just have to disable the
Note that since we only need to query the position of DiveCam once in Resting property to enable gravity: add an Entity:PropertySet entity
the game, we’re using a manually triggered GetPos node instead of an and assign the GameOverBox to it. Click on the value box next to
EntityPos node that is always listening (and thus demanding computer Property, then on the .. button and choose the Physics > bResting
resources). property. Set the value to false.
13. Let’s add the Z offset for the camera: add a Vec3:SubVec3 node. 20. Now we just need to trigger this node when the player dies: drag to
Drag the Pos output of DiveCam’s GetPos node to the A input of the connect the Equal output of the booIsDead Game Token to the Set
SubVec3 node. Set the SubVec’s Z value of B on 15. input of the PropertySet node.
14. Since we need to allow time for our Game Over entities to fall into the
ocean, let’s add a delay to give the camera a chance to witness this

CRYENGINE Flappy Boid Course Ver. 5.5D - 57 - 09: Enhancements


Randomizing Pipe Materials effective way to enhance this illusion is to randomly swap the material on each
set of pipes as they’re beamed back to the ai_start point. Since GameSDK
Since our game design attempts to create the illusion that the player is provides many suitable materials, we have plenty of materials to enhance the
navigating through an endless series of pipes, anything we can do to hide the illusion of endless pipes:
fact that we’re only using four pipes would be desirable. A simple and very

CRYENGINE Flappy Boid Course Ver. 5.5D - 58 - 09: Enhancements


1. Open pipe1_bottom’s pipe_movement Flow Graph and find the input triggers is used.
Entity:BeamEntity node that sends your pipes back to ai_start. Below 5. We need to set the General > Material property of each pair of pipes:
your entire Flow Graph, let’s create a new comment box called add two Material:EntityMaterialChange nodes. Assign the top pipe
something like “randomize pipe material.” to one of these nodes, and the graph entity (i.e., the bottom pipe) to the
2. We want to texture our pipes from a random list of materials at the other node.
moment the game starts and every time a pair of pipes is reset to How do we translate the random integers generated by our Math:Random node
ai_start: add a Game:Start node and a Logic:Any node to your new into entity materials? If you select a pipe, click in the General > Material
section (to handle the two inputs). Drag the Done output of the property in the Properties tab, copy the text to the clipboard and paste it into a
BeamEntity node to the In1 input of the Logic:Any node. Drag the text editor, you’ll see that this is just a string of characters, specifically a
Output of the Game:Start node to the In2 input of the Logic:Any
relative path to the Materials folder and the name of a material file.
node.
3. We need to make a random selection from a list of materials: let’s add So we need the generation of a particular number to trigger the Set input of the
a Math:Random node. Drag the Out of the Logic:Any node to the Material:EntityMaterialChange node and hard-code a specific material path
Generate input of the Math:Random node. Set its Min to 0 and its and name into the Material input of the Material:EntityMaterialChange
Max to 7. Why 0 to 7? Add a Logic:DeMultiplexer node, and you’ll node. Since our DeMultiplexer has eight outputs, we can choose from eight
see that it has eight outputs, 0 to 7. materials.
4. Drag the Out Rounded output of the Math:Random node (Out We can do this two ways: we could have 16 Material:EntityMaterialChange
Rounded produces only integers) to the Index input of the nodes (one for the top and one for the bottom pipe) preset with 8 different
Logic:DeMultiplexer node. Set the Mode of the materials and trigger them directly from the Port outputs of the DeMultiplexer,
Logic:DeMultiplexer node to IndexOnly to insure that only the Index or we can pass the appropriate material as a string into a Logic:Any node with

CRYENGINE Flappy Boid Course Ver. 5.5D - 59 - 09: Enhancements


just two Material:EntityMaterialChange nodes. The latter uses less nodes, your Flow Graph to the pipe_movement Flow Graphs for the other pipes - but
and thus is a better choice: don’t forget to assign the correct top pipe to each of your
EntityMaterialChange nodes! There’s no need to change the bottom pipe’s
6. Add eight String:SetString nodes. Map the Set input of each of them
to a different Port output from the DeMultiplexer. EntityMaterialChange node, as it simply refers to the parent Graph Entity.
7. You’ll need to carefully write the exact path and material name into We’ll use exactly the same Flow Graph technique to randomize the choice of
the In property of the SetString nodes. To avoid typos, we recommend particle effects in the next chapter when we add stars where our scoring
temporarily changing the material property of one of your pipes, and proximity triggers are.
then simply copying and pasting from the material property into the
SetString’s In property: select any pipe in the editor and click on the Disabling FPS Death Effect on Game Start
folder button next to the General > Materials property. This also gives
you a chance to see a preview of how each material will look, and You may have noticed that the first time you switch to game play mode, the
choose your eight favorites. We recommend exploring the brick, screen turns red and then fades to a normal color. This effect is the “death”
concrete, metal, and wood folders within the GameSDK > Materials effect also used when the player dies, but it doesn’t make much sense in our
> Generic folder. Avoid translucent materials like glass. Assign a game. We can easily disable it by opening the Material FX folder in Flow
different material to each of your eight SetString nodes. Graph, right-clicking on the player_death graph and choosing Disable.
8. To route these eight different strings to your two
EntityMaterialChange nodes, add a Logic:Any node to the right of
your SetString nodes. Drag the Out of each of your SetString nodes
to a different input of your Logic:Any node.
9. Finally, drag the Out of your Logic:Any node to the Set and Material
inputs of both of your EntityMaterialChange nodes.
As always, this is much easier to see than to read, so consult the screen shot of
the finished Flow Graph, then save and test on just one pair of pipes. Once
you’re confident that’s working perfectly, copy and paste this entire section of

CRYENGINE Flappy Boid Course Ver. 5.5D - 60 - 09: Enhancements


CRYENGINE Flappy Boid Course Ver. 5.5D - 61 - 09: Enhancements
10: Adding Animated Score Targets it above the ocean if you’d moved it underwater – or simply hide the
ocean. In the Designer tool select the Cylinder entity. Scroll down to
the Cylinder properties and set the Subdivision Count to 5 for a five
An easy way to give the game more visual appeal and to make it more
sided pentagon.
satisfying to play is to add attractive visible score targets instead of just
invisible proximity triggers between the pipes. Let’s add some spinning stars 1. With your grid snap off, click on the terrain and move your mouse to
and make them explode when the player touches them, as if collecting them. create a pentagon about 4m across its face. Click to stop sizing on
First, let’s model the stars using the Designer tool: X/Y and move your mouse upward to make its thickness on Z 1m.
Click the X next to the Designer tab at the top of the Perspective
Modeling the Stars Viewport to exit the Designer tool.
2. Click somewhere else to deselect your Designer object, then re-select
1. To do this, we’ll need to see the terrain, so make it temporarily it.
visible through the Perspective Viewport’s Display menu, or position
3. In the Designer tool’s Selection tab, choose Polygon. Click on any of

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.

CRYENGINE Flappy Boid Course Ver. 5.5D - 70 - 11: Adding Audio


Adding Environmental Sounds you should have already copied to your
projectFolder\audio\sdlmixer\assets. See the setup instructions if you
Sound design can extend the boundaries of your game beyond what the player did not already do this.
can see. In our case, the game world consists of sky over ocean as far as the 4. As soon as your files are copied, CRYENGINE will create
eye can see. These elements suggest environmental sounds: wind, waves, corresponding .cryasset files that will expose the audio files to the
perhaps even the occasional passing seagull. engine, at which point they will appear in the Audio Controls Editor in
Environmental sounds, like all audio, originate in a specific place. Thus, they the Middleware Data panel.
come from a specific direction. While the wind can sound like it’s all around 5. On the left side of the ACE, click on the Add button, then library.
us, the wave sounds in this game definitely come from below, given our Name your new library FlappyAudio.
camera position 100M in the air. 6. Right-click on your FlappyAudio library and choose Add > Trigger.
That means that the closer “we” – meaning our camera – get to the surface of Name your first trigger ocean.
the ocean, the louder the ocean sounds should be. As Flappy Cam moves up 7. Drag the ocean.ogg audio file from the Middleware Data column
and down to follow the bird, the ocean volume should vary slightly. Also, into the Connections pane. Click on the ocean.ogg in Connections if
when our camera jumps to the game over text and it splashes into the ocean, it’s not already selected. Below the file are parameters for your audio
our camera is very close to the surface of the ocean, so the ocean ambience trigger. Set the Action to Start so triggering will start playing the
should be loud. Then we’ll have the fun of adding audio for the splash and to sound.
give us a sense that the camera is sinking beneath the surface! 8. Set the Volume to -14db, and disable Enable Panning so the sound
is all around us. Set the Min Distance to 0 and the Max Distance to
Creating an Audio Library 200, and enable Infinite Loop so the sound repeats. (This is typical
for ambiences like wind and waves, as opposed to one-time sounds
Before we can add sounds to the level, we have to choose our audio like a gunshot.)
middleware and create a library of sound.
9. Test your new trigger by right-clicking on the green ocean trigger in
In the Console tool, we set the cVar s_AudioImplName followed by the the Audio System Controls pane and choosing Execute Trigger. You
middleware library we want to load. The default is SDL Mixer: should hear the ocean sound.
1. In the Console tool, type s_AudioImplName 10. Let’s make sure that the ocean sound stops when the game is over:
CryAudioImplSDLMixer. Technically, this is not necessary, since right-click on the FlappyAudio library and choose Add > Trigger.
SDLMixer is the default middleware, but it will become important to Name your trigger stop_game (you can call it anything you like).
know this cVar later when you want to switch to one of the other 11. Drag the ocean.ogg sound into the Connections pane for your
middleware tools (CryAudioImplFmod or CryAudioImplWwise). stop_game trigger. Set the Action for this sound to Stop. You’ll also
2. In the menu, click on Tools > Audio Controls Editor. Maximize this want to add Stop actions for any other sounds that might be playing
tool window. when the game ends on this level.
3. Your default audio assets folder is 12. Lastly, click on the Save button in the upper left corner of the Audio
projectFolder\audio\sdlmixer\assets. It’s recommended to keep this Controls Editor to save changes to the audio library.
default setting. We’ve provided audio files for the FlappyBoid project
in your \ FlappyBoidCourse[version#]\FlappyAssets folder, which

CRYENGINE Flappy Boid Course Ver. 5.5D - 71 - 11: Adding Audio


Adding Audio Triggers To Your Game
Now that we’ve created a sound trigger, let’s add it to your game:
1. In the Perspective viewport, navigate to where your “game over” text
is located. Use your Create Object tool to add an AreaBox object just
above the surface of the water. This entire box will effectively be a
speaker emanating the ocean sound, so we need it to surround our
DiveCam camera. Make its size 30x30x1M, and position one edge just
past the game over text. We’ve positioned our game over text box at
483, 562, 23, our AreaBox at 483, 551, 16.5, and our DiveCam at 483,
552, 18. Name your AreaBox ab_GameOverOceanBox.
2. Let’s add a sound: use the CreateObject tool to add an Audio >
AudioAreaAmbience entity. It makes no difference where you
position these entities. They do not actually emit the sound; they are
only used to connect a sound to an area entity. As always, organization
is paramount, and as with other entity types, we recommend naming
your audio entities using abbreviations that indicate their object types.
Name your AudioAreaAmbience entity
aaa_GameOverOceanAmbience.
3. Let’s connect our AudioAreaAmbience entity to the AreaBox entity to
actually hear the sound: select the AreaBox entity and click on the
Pick button in the Properties > Area palette. Click on the
aaa_GameOverOceanAmbience object to link the entities. A
connecting line appears. You can position the AudioAreaAmbience
icon anywhere you like. We suggest putting it fairly close to the
AreaBox.
4. Let’s assign an actual sound: click on the AudioAreaAmbience entity
and scroll down to Properties > Lua Properties > Play Trigger. Click
You can now test your sound in the Editor: the closer you move the camera to
on the folder icon and select the ocean trigger.
this Aaa_GameOverOceanAmbience AudioAreaAmbience box, the louder the
5. Although SDLMixer does not have the ability to pass parameters, we ocean sound should be. Save and test the game, and you should hear the ocean
still need to match the Rtpc Distance (Real Time Parameter Control) get louder as Flappy descends, and softer as it ascends. When Flappy dies and
parameter here to the Max Distance setting, so set it to 200. the camera jumps to directly above this AudioAreaAmbience box, the ocean
6. Click on the folder next to the Stop Trigger property and choose your should be far louder.
stop_game trigger to make sure the sound stops when the game ends.
The volume effect while flying through the pipes is very subtle, however,
7. Lastly, click on the Enabled property to enable the sound. because the audio is so far away from Flappy. Given that we’re going to add

CRYENGINE Flappy Boid Course Ver. 5.5D - 72 - 11: Adding Audio


loud splashdown and sinking sounds for the game over, you might want to to strict realism. Although our player entity is currently just a sphere, we’re
move your AudioAreaAmbience box closer to Flappy for a more dramatic going to treat it like the flying bird that will eventually replace it to give it a
effect. Don’t forget to change the attenuation distance in the Max Distance more organic, fun character than a simple sphere.
property in the audio trigger, and to match it in the AudioAreaAmbience
First, let’s add an audio trigger based on a collision sound we’ve provided:
box’s Rtpc Distance property.

1. In the Audio Controls Editor, right-click on your FlappyAudio


Adding a Collision Sound library and add another trigger. Name it pipe_collision.
The shape of your models and the textures that you applied to them will help 2. Drag the pipeCollisionWithSquawk.ogg file into the Connections
determine what sounds seem appropriate, although you needn’t limit yourself window.

CRYENGINE Flappy Boid Course Ver. 5.5D - 73 - 11: Adding Audio


3. Set the Action to Start, Volume to -10db, and disable Enable choice if we were using attenuation. However, let’s keep this example
Panning, Enable Attenuation, and Infinite Loop. simple: select your FlappyCam camera in the Level Explorer, then
4. Click on the Save button in the upper left corner of the ACL, and right-click on the Audio:Trigger node and choose Assign Selected
return to your Perspective viewport. Entity. That essentially means that the sound will come from
wherever “we” are – i.e., the camera.
Unlike the ambient ocean sound, we want to trigger this sound when Flappy
collides with a pipe. We’ll need Flow Graph for that, and we can build on the Save and before you test, get your hand ready to press the Esc key. You should
physics collision listener we’ve already set up: hear the sound when Flappy collides, but you’re also going to hear some
strange things: the sound will be triggered more than once – probably many
5. Find the Pipe Collisions section of your FG_Main Flow Graph. Add times in an unrealistic way.
an Audio:Trigger node.
6. Drag the IdA output of the Physics:CollisionListener node to the Preventing Multiple Collision Sounds
Play input of the Audio:Trigger node to play the sound when Flappy
collides with something. What is happening? Flappy keeps bumping into things as it falls – the pipes,
the invisible terrain, etc! A sophisticated version of this event might include an
7. Make sure your Audio:Trigger node is selected, then in the Flow
initial collision sound followed by scraping sounds on subsequent contact with
Graph Properties window, click in the box next to the Play Trigger
property, then on the folder icon to browse. Select the pipe_collision the pipe. Let’s make sure our collision sound only happens the first time by
trigger you already created and click OK. counting collisions with a variable:
8. Lastly, we need to tell the ACL where to place the audio in 3D space. 1. From the Flow Graph menu, choose Tools > Edit Graph Tokens.
Since we disabled attenuation for this particular sound, it will make no Graph Tokens are variables just like Game Tokens, but they are local
difference. Technically, the sound should come from wherever Flappy (visible) to just one graph. (FG_Main in our case.)
is, since the sound is generated by it colliding with something. In 2. Create a new token called IntCollisions of type Integer.
terms of a realistic sound environment, that would be the correct 3. Let’s initialize our collision counter on game start: in the Initial

CRYENGINE Flappy Boid Course Ver. 5.5D - 74 - 11: Adding Audio


Setup section of your FG_Main, add a Mission:GameTokenSet node. GameTokenGet node. Set the Token property of the GameTokenGet
In the GameTokenSet node’s Properties, set the Token to the node to intCollisions.
intCollisions graph token, and the Value to 0. 8. Drag the Out Value of the GameTokenGet node to the In of the
4. Drag the Output of the Game:Start node to the Trigger input of the Math:InRange node. Set the Math:InRange node’s Min and Max to
GameTokenSet node. 1. In other words, we only want to play our sound the first time
5. Back in the Pipe Collisions section of your Flow Graph, add these Flappy collides with something – instant death.
nodes left to right: Mission:GameTokenModify, 9. Drag the IdA output of the Physics:CollisionListener node to the In
Mission:GameTokenGet, Math:InRange, and Logic:Gate. input of the Logic:Gate node. Drag the Out of the Logic:Gate to the
6. Let’s increment our counter on each collision: drag the IdA output of Play input of the Audio:Trigger node. Now we have a collision
the Physics:CollisionListener node to the Trigger input of the poised to trigger our collision sound, but we only want to open the
GameTokenModify node. Set the GameTokenModify’s Token to gate on collision #1:
intCollisions, the Operation to Add, the Type to Int, and the Value 10. Drag the True output of the Math:InRange node to the Open input
to 1. of the Logic:Gate, and the False output of the Math:InRange node to
7. To check the counter value on each collision, drag the Out Value of the Close input of the Logic:Gate.
the GameTokenModify node to the Trigger input of the

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.

CRYENGINE Flappy Boid Course Ver. 5.5D - 75 - 11: Adding Audio


Play and test. You should hear one uninterrupted collision and distress sound. and test.

Disabling Jump On Collision Adding Game Over Sounds


If you test carefully, you’ll notice that the player can still “jump” after We’ve given you two sounds for the game over sequence: a falling and
colliding with a pipe. Let’s fix that: splashing sound when the Game Over text falls into the water, and the sound
of submerging underwater for when the camera sinks. Let’s add them:
1. In the initial setup section of your Flow Graph, find the GameToken
node that checks the value of booIsDead and feeds into the Disable 1. In the Audio Controls Editor, right-click on the FlappyAudio
input of the ActionListener node (which provides the jump action). library and add a new trigger called GameOverFallAndSplash.
2. Select the GameToken node and change its Token property to 2. Drag the fall_and_splash.ogg sound into the Connections panel of
intCollisions and the Compare To property to 1. Now as soon as the the ACL. Select the sound in the Connections pane and set its
first pipe collision occurs, the jump action is disabled. properties as follows: Action = Start, Volume = -6db, Enable
Consult the screen shot of the finished Flow Graph carefully before you save Panning and Enable Attenuation disabled.
3. Add another trigger called sinking. Drag the sinking.ogg sound into

CRYENGINE Flappy Boid Course Ver. 5.5D - 76 - 11: Adding Audio


the Connections panel. Set its properties as follows: Action = Start,
Volume = -6db, Enable Panning = Disabled, Enable Attenuation =
Enabled, Max Distance = 100. Save your audio library.
4. In the Pipe Collisions section of your FG_Main Flow Graph, add
another Audio:Trigger node. Set its Play Trigger to the
GameOverFallAndSplash trigger.
5. Select the FlappyCam camera in the Level Explorer, then right-click
on the Audio:Trigger node and choose Assign Selected Entity.
Again, with attenuation disabled, this could be anywhere.
6. Drag the Out of the Logic:Gate to the Play input of the
Audio:Trigger node.
7. Let’s delay this splash sound briefly to give the pipe_collision sound a
chance to be heard: right-click on the circular handle on the
connector between the Logic:Gate and Audio:Trigger nodes and
choose Time:Delay. Set the Delay property to 0.2 seconds. 3. Drag the Out of the Time:Delay node to the Enable input of the
CameraView node to give the player a chance to watch Flappy fall
Save and test. You should hear falling and then splashing sounds. But there’s before jumping to the Game Over.
a problem: the timing of the sound doesn’t match the visual of the game-over
text hitting the water. There are many ways to handle this: we could use 4. Add an Audio:Trigger node. Drag the Out of the Time:Delay node
separate falling and splashing sounds, use an underwater proximity trigger to (the one that feeds the MoveEntityTo and RotateEntity nodes that
sense when the game over text lands in order to stop the falling sound and start control your dive camera) to the Play input of the Audio:Trigger
the splash sound, etc. node.
5. Set the Audio:Trigger node’s Play Trigger to your sinking trigger,
Since we’ve supplied a combined fall/splash sound of specific duration, let’s and assign the diveCam camera as the entity.
simply delay the switch to the game over camera to give the player a moment
to watch Flappy fall, and delay the falling of the box to give the falling sound a Save and test. Adjust your delay as needed so the splashing sound and visual
chance to be heard, as if the box was falling from a great height: are synchronized.

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 - 77 - 11: Adding Audio


library. You’ll note that we’ve provided several chicken squawking Adding Sounds to the Particle Effects
sounds at pitches from high to low, so feel free to use any of them.
Later, you may want to explore selecting the squawk sound First, let’s add a sound effect appropriate to each particle effect directly in the
dynamically based on how hard your bird is struggling to climb. Particles tool. You can try dragging various particle effects from the
(We’ve included a Flow Graph that does this in the finished game GameSDK library onto any of your four particle entities to test them and
level in the FlappyBoidCourse .zip we supplied, which is not printed decide which you want to use for this game. Just remember to check that there
here, but can be opened, studied, and perhaps even improved.) is no wind selected in the Advanced > Force Generation section, or else the
3. In the Initial Setup section of your FG_Main Flow Graph, add an shock wave will push your Flappy away.
Audio:Trigger node. Set its Play Trigger to the squawk_low trigger Now that you’ve decided which particle effects you want to use, let’s add
you just created. sounds to each of them. In this example, we’ll walk through the process of
4. Drag the Pressed output of your Input:ActionMaps:ActionListener adding a sound to the monitor > a_lingering_elec effect:
node to the Play input of the Audio:Trigger node.
1. In the Audio Controls Editor, right-click on your FlappyAudio
Save and test. Each time Flappy jumps, it should squawk. library and create a new trigger. Name it something like
“pfxMonitorLingeringElec” (where “pfx” = particle effects).
Adding Score Sounds 2. Drag the star_electrical.ogg audio file into the Connections window.
Our exploding stars cry out for sound effects! There are two ways to approach Set its properties as follows: Action = Start, Volume = -3db, Enable
Panning/Enable Attenuation = disabled. Save the audio library.
this: we can assign audio triggers directly to the particles using the DataBase
> Particles tool (you’ll note an Audio section with a Start Trigger), so when a 3. In the Database View > Particles tool, click on the effect you want to
particle effect is spawned, its sound plays. Or we can simply use the same modify (monitor > a_lingering_elec in this case) and then click on
Proximity Trigger to play a sound through an Audio:Trigger node in Flow the Add New Item button in the Particles toolbar. Name it audio.
Graph. Your new component appears as an indented item under the
a_lingering_elec effect.
However, you may have already noticed how the same four particle effects
4. Click on your new audio component and scroll down in the particle
repeat in the exact same order – making it obvious that there are only four
properties to the Audio section. Click on the folder next to the Start
pipes which get endlessly reused. Adding sound effects for each of those
Trigger property and choose your FlappyAudio >
particles that also repeat in the same 1-2-3-4 order is only going to make this
pfxMonitorLingeringElec trigger. Click on the Save Modified
more obvious.
Libraries button in the Particles toolbar.
Let’s enhance our game design by randomly assigning one of many particle As always, save and test.
effects to each pipe every time it goes back to ai_start, just as we did with the
pipe materials.

CRYENGINE Flappy Boid Course Ver. 5.5D - 78 - 11: Adding Audio


CRYENGINE Flappy Boid Course Ver. 5.5D - 79 - 11: Adding Audio
12: Exporting a Game to a Stand-Alone Build 11. Make sure you copy the entire _package folder to your customers or
testers.
Once you’ve tested and debugged and are confident in your game design, it’s
time to put your game into the hands of some serious QA (quality assurance) Porting a Level To Another Computer or Build
players who can do their best to help you by attempting to break it – to find its If you’ve built this game in a classroom or find yourself in a position of
flaws, and to give you feedback on whether it’s fun or could use some wanting to bring your level to another computer, there a few steps you’ll need
improvements. to follow. It’s also a good time to consider the folder structure of a
CRYENGINE installation and how the GameSDK folder is set up.
Hiding Display Info In Build GameSDK: all of the GameSDK components you downloaded from the
Here’s how you get your game to a stand-alone PC application: CRYENGINE marketplace
1. Save your current level.
2. From the Engine, choose File > Export to Engine.
Challenges For Additional Enhancements
3. Quit CRYENGINE. We’ve deliberately left our game imperfect in hopes that you will be inspired
to learn more by enhancing and improving it. Here are some suggested
4. Go to your project folder, right-click on your .cryproject file
enhancements that we’ll leave you to design using the skills you’ve learned:
(GameSDK.cryproject in this course) and choose Launch game.
5. Test your game. Try varying the graphics parameters. Play as long as • Connect the horizontal oscillation speed of the cloud texture (or the
you can. spin rate of the SkyDome entity) to the horizontal pipe speed to
enhance the illusion that the bird is moving at increasing speed.
6. If you find problems and need to make changes in the Editor, make sure
you start back at step one. • Create additional levels with escalating complexities to the pipe
7. Once you’re 100% confident, create the stand-alone application by movement. Try varying the geometry of the pipes on each level or
right-clicking on your .cryproject file and choosing Package Build. even randomly within a level. (You’ll find additional pipe geometry
This can take some time, so make sure the command line tells you it’s in the same folder where you found the basic pipe.)
finished before final tests. • Instead of moving the pipes right to left in a straight line, figure out
8. Finally, we can set console variables in our .cryproject file; one that how to make the pipes move up and down multiple times (i.e.,
we’re definitely going to want to set after we’re done debugging but oscillate vertically) as they cross the screen. (Hint: look at sine
before we ship the game is to hide the display information: open your waves.)
gamesdk.cryproject file in Notepad or any plain text editor.
9. Find the “console_variables” section. Add the following line below it: The Final Design
{ “name”: “r_displayinfo”, “value”: “0” }, Here are some screen shots of our finished game from various angles.
10. To test the actual application, open the _package folder
(GameSDK_package in this course) > bin > win_x64 and double click
GameLauncher.exe. Play your game!

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

Das könnte Ihnen auch gefallen