Game 1024: Advanced Game Programming Lesson 7: Super Magnificent Hyper Game Features Hardcore Extreme Black Turbo!

Download 474 b.
Hajmi474 b.

GAME 1024: Advanced Game Programming

  • Lesson 7: Super Magnificent Hyper Game Features Hardcore Extreme Black Turbo!

  • By Kain Shin


  • Write your name either…

    • In binary ASCII format or …
    • Spelled backwards
  • When does a static variable’s constructor get called when declared inside a function?

  • Give one reason for game localization

  • What is one thing you can do to make a tester’s job easier?

  • What is one thing you can do to make an artist’s job easier?

  • Give one reason to add profiling to your game

  • Name a favorite game of yours. Give an example of a user statistic that might be collected in that game

  • What is the difference between input spoofing and event spoofing when recording and playing back a user play session.

Bonus Topic: An Informal Vector Math Overview

  • Game use vectors to represent position, orientation, and velocity

  • Game change vectors via matrix multiplication

  • What goes into a translation matrix? An offset.

  • What goes into a rotation matrix? Euler angles or a quaternion.

  • What are Euler angles?

  • What’s a quaternion?

  • How do you tell when a player is in the enemy’s view cone?

    • The Dot Product of two normalized direction vectors placed tail to tail equals the cosine of the angle between the vectors
  • How do you find the axis of rotation for something that needs to rotate at an odd angle, like a guided missile following a target?

    • The Cross Product of two vectors placed tail to tail is a third vector that is perpendicular to the plane defined by both source vectors
    • The direction of the cross product vector is the same as your thumb when you curl your hand inward from the first vector to the second vector… whether it is your right hand or left hand depends on whether you are using the right-handed or left-handed coordinate system (look it up if you want to know more about the right/left handedness of coordinate systems).

Today’s Lecture is About…

  • Optimization Recipes

    • Reducing Event System Overhead
    • Custom Memory Allocation
    • Resource Management
  • Game Feature: Save/Load

Event System Optimizations

  • Register functors or function pointers for events instead of listener classes

  • Minimize the number of listeners for an event

  • Unregister listeners that no longer need to listen for events

  • Queue up events and eliminate redundancy or duplicates

  • If only one thing is going to listen for the event, then consider eliminating event system usage altogether

Custom Memory Allocation

  • Why?

    • “operator new” (or malloc) is more expensive than assigning pointers to pre-allocated heap memory
    • On a console, you want full control over how much RAM you use and you want to be warned when you pass the limit, because consoles have no virtual memory.
    • Fragmented memory leads to slower access due to having to juggle the contents of the CPU cache to access things that would normally be next to each other in memory
  • Basic Recipe (The web is full of various implementations of this):

    • Pre-allocate a huge block of memory on the heap at the very beginning of the game
    • Instead of allocating new chunks off the global heap when you need a new object, Assign a pointer to an address within your big giant block by…
      • Implementing “operator new” as a member of the classes that you want allocated within this big giant block or…
      • #define your own version of “new” and “delete” that recognizes your big giant block or…
      • #define your own version of “NEW” and “DELETE” that recognizes your big giant block and gets used only when you specifically use it… this way, you don’t collide with other people’s custom memory allocator usages in your third party libraries
    • C++ Tip: “Placement new” works like regular “new”, except it constructs your object at an address you specify
      • Usage Example: cThing* pMyThing = new(myDesiredAddress) cThing; //pMyThing==myDesiredAddress after this

Block Loading

  • What is it?

    • Loading a single large file from the disc that contains the contents of multiple resources that were packed together into a single memory-mapped file.
    • This giant memory-mapped file can be compressed (zipped). This makes loading faster because there is less data to load, and decompression of a zipped file is typically faster than the extra time it takes to load the uncompressed file.
    • A memory mapped file is a file that starts with name and offset information followed by consecutive blocks of resource data packed together so that whatever loads the file can access the resource data it is looking for
  • Why use it?

    • Because disc access is your bottleneck during loading, and loading is faster when you load one large file instead of many small ones
    • Because it discourages users from mucking with the assets and posting screenshots of their “modded” content on the internet
  • Basic Recipe:

    • Make sure all resources in the game (graphics, sound, etc.) can be converted to/from generic blocks of memory (address + size)
    • Creating the Memory-Mapped Resource File
      • Create an external tool that can pack these files into a single file for you (i.e. wad files used in DOOM)… this external tool could either be your level editor or a specific tool made just for resource packing
      • OR write code inside the game to have the game dump all mappable resources into a special resource file for later loading when you tell it to
    • Loading the Memory-Mapped Resource File into the Game
      • Load the block file at the start of the game before the other systems get set up
      • Instead of reading individual files for a resource, have the game’s initilization code grab the resource data from this managed resource block to set up its sprites, sounds, textures, models, etc.

Resource Instancing

  • What is it?

    • Separating source data from instance data so that multiple objects can use the same loaded resource for separate instances.
    • An instance is a unique manifestation of a resource in the game. In the example of a sprite…
      • Source data on a sprite is the actual bitmap of the sprite. This can be shared between multiple sprites
      • Instance data on a sprite is position, size, and rotation information about that sprite
  • Why use it?

    • Sharing data instead of duplicating data uses up less RAM
  • Basic Recipe:

    • Figure out what resources can be shared
    • Centralize the storage of these shared resources in a central “database” that can be accessed by other systems
    • Have the entities (Sprites, AudioBuffers, etc.) that use these shared resources store only a pointer or reference to the resource, but not own it

Streaming Technology

  • What is it?

    • Background loading while the game is still active (as seen in city-roaming games such as the recent Grand Theft Auto series)
  • Why use it?

  • Basic Recipe:

    • Arrange your dynamically loading resources into groups that will load together, such as all resources related to a certain geographical sector
    • Separate your game’s dependency on having these dynamic resources in memory so that it can still run even if no dynamic resources were currently loaded… in other words, make sure that the game logic does not depend on these dynamic resources
    • Depending on the game, you will be unloading old blocks and loading new blocks as needed

Resource Manager Class

  • You can write a central ResourceManager class that can combine block loading, instancing, and streaming functionality as you see fit

  • Beware: Some 3rd Party APIs for a resource may not support conversion to/from a generic block of memory, you might have to exclude that resource type from your set of managed resources

  • Sometimes, it is useful during development to be able to run the game from individual source files instead of the giant “cooked” block-loaded memory-mapped files, but…

  • You rarely ever see shipped games with these individual files in the install directory

Saving/Loading The World State

  • Don’t wait until the end of the project to implement this feature!

  • Basic Recipe:

    • Define your game state. A game state is a set of properties that define the state of the game at any one time
    • Make it so that the game state can be stored into a file
    • Make it so that the game can read the game state from a file and set all relevant parts of the game to the proper state
    • Maintain this functionality during development as new features come into the game
    • Expose this functionality with a user interface that the user can use to save/load the game

Your Project

  • Milestone 3 (Your syllabus has changed, BTW)

    • Optional Bonus: Write a resource manager that loads all bitmaps used in the program into a single memory mapped file. Make it so that when you call your program with a cook parameter, it basically creates one giant super-bitmap that holds all bitmaps used in the game. When the game runs and detects a “cooked” bitmap, it will load one large file instead of a bunch of tiny files. All sprites will share a spot on the bitmap so that no graphics data is duplicated.
    • Optional Bonus: Write a custom memory allocator which you will use with your versions of NEW and DELETE to ensure that no memory is leaked and that the number of heap allocation occurences are minimized
    • Optional Bonus: Integrate your custom memory allocator with STL or whatever template library you are using

Final Thought

  • "You should not have a favorite weapon. To become over-familiar with one weapon is as much a fault as not knowing it sufficiently well. You should not copy others, but use weapons which you can handle properly. It is bad for commanders and troops to have likes and dislikes." --Miyamoto Musashi, Book of Five Rings Excerpted From "Musashi’s most well-known duel was in 1612 when he was in the Ogawa, Bunzen province. His opponent was Sasaki Kojiro, a young man who had developed a strong fencing technique known as Tsubame-gaeshi or “swallow counter”, inspired by the motion of a swallow’s tail in flight. Kojiro was retained by the lord of the province, Hosokawa Tadaoki. Musashi applied to Tadaoki for permission to fight Kojiro through the offices of one of the Hosokawa retainers who had been a pupil of Musashi’s father, one Nagaoka Sato Okinaga. Permission was granted for the contest to be held at eight o’clock the next morning, and the place was to be an island some few miles from Ogura. That night Musashi left his lodging and moved to the house of Kobayashi Taro Zaemon. This inspired a rumor that awe of Kojiro’s subtle technique had made Musashi run away afraid for his life. The next day at eight o’clock Musashi could not be wakened until a prompter came from the officials assembled on the island. He got up, drank the water they brought to him to wash with, and went straight down to the shore. As Sato rowed across to the island Musashi fashioned a paper string to tie back the sleeves of his kimono and cut a wooden sword from the spare oar. When he had done this he lay down to rest. The boat neared the place of combat and Kojiro and the waiting officials were astounded to see the strange figure of Musashi leap from the boat brandishing the long wooden oar with his unkempt hair tied up in a towel. He rushed through the waves up the beach towards his enemy. Kojiro drew his long sword, a fine blade by Nagamitsu of Bizen, and threw away his scabbard. “You have no more need of that” said Musashi as he rushed forward with his sword held to one side. Kojiro was provoked into making the first cut and Musashi dashed upward at his blade, bringing the oar down on Kojiro’s head, killing him. Musashi noted Kojiro’s condition and bowed to the astounded officials before running back to his boat."

  • In other words, adapt to your environment, and you will prevail… fail to adapt, and your employment status will remain fragile. It is not the tool that makes the programmer, it is the programmer.

Download 474 b.

Do'stlaringiz bilan baham:

Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan © 2020
ma'muriyatiga murojaat qiling