- •Credits
- •Foreword
- •About the Authors
- •About the Reviewers
- •www.PacktPub.com
- •Table of Contents
- •Preface
- •Introducing SFML
- •Downloading and installation
- •A minimal example
- •A few notes on C++
- •Developing the first game
- •The Game class
- •Game loops and frames
- •Input over several frames
- •Vector algebra
- •Frame-independent movement
- •Fixed time steps
- •Other techniques related to frame rates
- •Displaying sprites on the screen
- •File paths and working directories
- •Real-time rendering
- •Adapting the code
- •Summary
- •Defining resources
- •Resources in SFML
- •Textures
- •Images
- •Fonts
- •Shaders
- •Sound buffers
- •Music
- •A typical use case
- •Graphics
- •Audio
- •Acquiring, releasing, and accessing resources
- •An automated approach
- •Finding an appropriate container
- •Loading from files
- •Accessing the textures
- •Error handling
- •Boolean return values
- •Throwing exceptions
- •Assertions
- •Generalizing the approach
- •Compatibility with sf::Music
- •A special case – sf::Shader
- •Summary
- •Entities
- •Aircraft
- •Alternative entity designs
- •Rendering the scene
- •Relative coordinates
- •SFML and transforms
- •Scene graphs
- •Scene nodes
- •Node insertion and removal
- •Making scene nodes drawable
- •Drawing entities
- •Connecting entities with resources
- •Aligning the origin
- •Scene layers
- •Updating the scene
- •One step back – absolute transforms
- •The view
- •Viewport
- •View optimizations
- •Resolution and aspect ratio
- •View scrolling
- •Zoom and rotation
- •Landscape rendering
- •SpriteNode
- •Landscape texture
- •Texture repeating
- •Composing our world
- •World initialization
- •Loading the textures
- •Building the scene
- •Update and draw
- •Integrating the Game class
- •Summary
- •Polling events
- •Window events
- •Joystick events
- •Keyboard events
- •Mouse events
- •Getting the input state in real time
- •Events and real-time input – when to use which
- •Delta movement from the mouse
- •Playing nice with your application neighborhood
- •A command-based communication system
- •Introducing commands
- •Receiver categories
- •Command execution
- •Command queues
- •Handling player input
- •Commands in a nutshell
- •Implementing the game logic
- •A general-purpose communication mechanism
- •Customizing key bindings
- •Why a player is not an entity
- •Summary
- •Defining a state
- •The state stack
- •Adding states to StateStack
- •Handling updates, input, and drawing
- •Input
- •Update
- •Draw
- •Delayed pop/push operations
- •The state context
- •Integrating the stack in the Application class
- •Navigating between states
- •Creating the game state
- •The title screen
- •Main menu
- •Pausing the game
- •The loading screen – sample
- •Progress bar
- •ParallelTask
- •Thread
- •Concurrency
- •Task implementation
- •Summary
- •The GUI hierarchy, the Java way
- •Updating the menu
- •The promised key bindings
- •Summary
- •Equipping the entities
- •Introducing hitpoints
- •Storing entity attributes in data tables
- •Displaying text
- •Creating enemies
- •Movement patterns
- •Spawning enemies
- •Adding projectiles
- •Firing bullets and missiles
- •Homing missiles
- •Picking up some goodies
- •Collision detection and response
- •Finding the collision pairs
- •Reacting to collisions
- •An outlook on optimizations
- •An interacting world
- •Cleaning everything up
- •Out of view, out of the world
- •The final update
- •Victory and defeat
- •Summary
- •Defining texture atlases
- •Adapting the game code
- •Low-level rendering
- •OpenGL and graphics cards
- •Understanding render targets
- •Texture mapping
- •Vertex arrays
- •Particle systems
- •Particles and particle types
- •Particle nodes
- •Emitter nodes
- •Affectors
- •Embedding particles in the world
- •Animated sprites
- •The Eagle has rolled!
- •Post effects and shaders
- •Fullscreen post effects
- •Shaders
- •The bloom effect
- •Summary
- •Music themes
- •Loading and playing
- •Use case – In-game themes
- •Sound effects
- •Loading, inserting, and playing
- •Removing sounds
- •Use case – GUI sounds
- •Sounds in 3D space
- •The listener
- •Attenuation factor and minimum distance
- •Positioning the listener
- •Playing spatial sounds
- •Use case – In-game sound effects
- •Summary
- •Playing multiplayer games
- •Interacting with sockets
- •Socket selectors
- •Custom protocols
- •Data transport
- •Network architectures
- •Peer-to-peer
- •Client-server architecture
- •Authoritative servers
- •Creating the structure for multiplayer
- •Working with the Server
- •Server thread
- •Server loop
- •Peers and aircraft
- •Hot Seat
- •Accepting new clients
- •Handling disconnections
- •Incoming packets
- •Studying our protocol
- •Understanding the ticks and updates
- •Synchronization issues
- •Taking a peek in the other end – the client
- •Client packets
- •Transmitting game actions via network nodes
- •The new pause state
- •Settings
- •The new Player class
- •Latency
- •Latency versus bandwidth
- •View scrolling compensation
- •Aircraft interpolation
- •Cheating prevention
- •Summary
- •Index
Chapter 10
The logic is simple. If the aircraft belongs to a remote player, we will interpolate its position between the current local position and the server's position
(aircraftPosition). We have hardcoded an interpolation "amount" of 0.1f, which means that we will always move 10 percent of the distance between both positions. This small value avoids having the aircraft "jump" from place to place, except when the network conditions are really bad and the synchronization is suffering too much.
Cheating prevention
By now you probably are scratching your chin and asking yourself: "But is this secure? Is a hacky player able to exploit the game to its benefit somehow?"
If you answered "No" to yourself, you are correct. By all means we would like to explain you how to make every little thing cheat-proof. However, we don't want to give you the fish by bloating the code with lots of validations; but rather, explicitly writing about how you can learn how to fish.
The current game, as is, is not cheat-proof whatsoever. There are a lot of validations that are not performed, so it will only work predictably until a clever user starts doing packet-sniffing and sending things that are not really expected by our protocol.
Let's try to understand how cheating could be achieved in our particular case, and how would we prevent it by looking at a few examples:
•In the client's tick, we let the client decide where its planes are going to be at. If a user with malicious intent sent this packet after modifying, he would be able to position its aircraft in any location, effectively warping from place to place as much as he wanted. We would fix this by not accepting the new positions in the server without some validations first. We would need to check if the new position is possible. Whether it could be achieved with normal gameplay, given the aircraft velocity and previous positions. Right here we could spot on a cheater and act upon it by banning or kicking or simply logging what happened to a file.
•Another great example of how we could exploit this game is to look at the
PlayerEvent packet on the client-side. It carries an aircraft identifier and an action to perform. However, as the server doesn't check if the identifier sent is owned by that peer, a malicious user could effectively make other people's planes shoot bullets and missiles.
We intentionally left such things uncovered so you could see how serious it can be if you don't check all the data coming from a client. Users will often try to break the server state for an in-game profit.
[ 267 ]
www.it-ebooks.info
Company Atop the Clouds – Co-op Multiplayer
The golden rule to prevent cheating is, when handling a packet in the server, always ask yourself if what the client is requesting is possible! Do as many validations as possible in the server's logic. The ultimate goal for a safe online simulation is reaching that point when there is no possible combination of data coming from the client that will produce unpredicted results. Always remember, as
long as the server's state is sane and controlled, there is no cheating, as hard as it may be to achieve this.
Summary
In this final chapter, you learned about basic networking concepts. We had a look at sockets, different network architectures, and protocols. We incorporated this knowledge to our game, and extended the existing design to cope with new challenges of networking. By using SFML's Network module, we implemented a
mechanism to communicate with other players on the same keyboard, the local area network, or the Internet. Although we had to make compromises in some places, you should have learned a lot of techniques which you can eventually apply in another game.
Along with this chapter, also ends the book! It has been a long ride all the way and we can only thank you for reading through our pages patiently. Finally, our aircraft top-scroller has reached a state where it is not only playable, but contains many features to create an immersive experience. We began with rendering, resource and input handling, and went over to shape different states and menus with a graphical user interface. We implemented actual gameplay mechanisms, polished the appearance using a variety of visual effects, played sound and music, and eventually added multiplayer support. Nevertheless, there are hundreds of possibilities to further improve our game, there are virtually no limits!
By now, you have seen many different aspects of game development—maybe a lot of unconventional approaches—and you are certainly motivated by these ideas to create your own work. Remember, what we showed you should only be a source of inspiration, not the one and only truth. We made choices that other people would handle differently. Therefore, don't be afraid of experimenting and trying out your own ideas! Be it code design, art style, or the gameplay itself—be creative, this is the most important attribute of any game developer. We hope you have enjoyed reading this book and following the development of our game, and wish you good luck on your journey!
[ 268 ]
www.it-ebooks.info