Table of Contents for
Gaming Hacks

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Gaming Hacks by Simon Carless Published by O'Reilly Media, Inc., 2004
  1. Cover
  2. Gaming Hacks
  3. Credits
  4. Contributors
  5. Acknowledgments
  6. Foreword
  7. Preface
  8. How to Use This Book
  9. How This Book Is Organized
  10. Conventions Used in This Book
  11. Using Code Examples
  12. Comments and Questions
  13. Got a Hack?
  14. 1. Playing Classic Games
  15. Legal Emulation
  16. Play Commodore 64 Games Without the C-64
  17. Play Atari ROMs Without the Atari
  18. Use Atari Paddles with Your PC
  19. Run Homebrew Games on the Atari 2600
  20. Create Your Own Atari 2600 Homebrew Games
  21. Play Classic PC Graphic Adventures
  22. Play Old Games Through DOSBox
  23. Play Reissued All-in-One Joystick Games
  24. Play Arcade Games Without the Arcade
  25. Add and Manipulate a MAME Frontend
  26. Keep Your ROMs Tidy and Organized
  27. Learn Game-Specific MAME Controls
  28. Filter Inappropriate MAME ROMs
  29. Autoboot into MAME Heaven
  30. Play Emulated Arcade Games Online
  31. Play Classic Pinball Without the Table
  32. Emulate the SNES on the Dreamcast
  33. 2. Playing Portably
  34. Play Games on Your iPod
  35. Mod Your Game Boy
  36. Take and Print Photos with Your Game Boy
  37. Compose Music on Your Game Boy
  38. Explore the GP32 Handheld Gaming System
  39. Take Your Console with You
  40. Explore the Bandai WonderSwan
  41. Play Real Games on Your PDA
  42. Install a PlayStation 2 in Your Car
  43. 3. Playing Well with Others
  44. Practice Proper MMORPG Etiquette
  45. Understand MMORPG Lingo
  46. Grind Without Going Crazy
  47. Make a Profit in Vana’diel
  48. Write MMORPG Macros
  49. Build an Effective Group
  50. Catch Half-Life FPS Cheaters Redhanded
  51. 4. Playing with Hardware
  52. Build a Quiet, Killer Gaming Rig
  53. Find and Configure the Best FPS Peripherals
  54. Adapt Old Video Game Controllers to the PC
  55. Choose the Right Audio/Video Receiver
  56. Place Your Speakers Properly
  57. Connect Your Console to Your Home Theater
  58. Tune Console Video Output
  59. Tune Your TV for Console Video
  60. PC Audio Hacking
  61. Optimize PC Video Performance
  62. Build a Dedicated Multimedia PC
  63. Use a Multimedia Projector for Gaming
  64. 5. Playing with Console and Arcade Hardware
  65. Play LAN-Only Console Games Online
  66. Hack the Nuon DVD Player/Gaming System
  67. Play Import Games on American Consoles
  68. Find a Hackable Dreamcast
  69. Play Movies and Music on Your Dreamcast
  70. Hack the Dreamcast Visual Memory Unit
  71. Unblur Your Dreamcast Video
  72. Use Your Dreamcast Online
  73. Host Dreamcast Games Online
  74. Burn Dreamcast-Compatible Discs on Your PC
  75. Burn Dreamcast Homebrew Discs
  76. Buy Your Own Arcade Hardware
  77. Configure Your Arcade Controls, Connectors, and Cartridges
  78. Reorient and Align Your Arcade Monitor
  79. Buy Cart-Based JAMMA Boards
  80. Programming Music for the Nintendo Entertainment System
  81. 6. Playing Around the Game Engine
  82. Explore Machinima
  83. Choose a Machinima Engine
  84. Film Your First Machinima Movie
  85. Improve Your Camera Control
  86. Record Game Footage to Video
  87. Speedrun Your Way Through Metroid Prime
  88. Sequence-Break Quake
  89. Run Classic Game ROM Translations
  90. Change Games with ROM Hacks
  91. Apply ROM Hacks and Patches
  92. Create PS2 Cheat Codes
  93. Hack Xbox Game Saves
  94. Cheat on Other Consoles
  95. Modify PC Game Saves and Settings
  96. Buff Your Saved Characters
  97. Create Console Game Levels
  98. 7. Playing Your Own Games
  99. Adventure Game Studio Editing Tips
  100. Create and Play Pinball Tables
  101. Put Your Face in DOOM
  102. Create a Vehicle Model for Unreal Tournament 2004
  103. Add a Vehicle to Unreal Tournament 2004
  104. Modify the Behavior of a UT2004 Model
  105. Download, Compile, and Create an Inform Adventure
  106. Decorate Your IF Rooms
  107. Add Puzzles to Your IF Games
  108. Add Nonplayer Characters to IF Adventures
  109. Make Your IF NPCs Move
  110. Make Your IF NPCs Talk
  111. Create Your Own Animations
  112. Add Interactivity to Your Animations
  113. Write a Game in an Afternoon
  114. 8. Playing Everything Else
  115. Tweak Your Tactics for FPS Glory
  116. Beat Any Shoot-Em-Up
  117. Drive a Physics-Crazed Motorcycle
  118. Play Japanese Games Without Speaking Japanese
  119. Back Up, Modify, and Restore PlayStation Saved Games
  120. Access Your Console’s Memory Card Offline
  121. Overclock Your Console
  122. Index
  123. Colophon

Modify the Behavior of a UT2004 Model

Not satisfied with new art? Add new behavior!

Other hacks demonstrate how to model a 1969 Plymouth Barracuda ( [Hack #82] ) and how to turn it into a playable Actor in Unreal Tournament 2004 ( [Hack #83] ). This hack builds on that to add nitrous-style speed boosts to the ‘Cuda using UnrealScript.

While it isn’t required, you’ll have better luck understanding this hack if you understand high-level object-oriented languages such as Java or C++. Being familiar with vector math and basic physics will help, and a working knowledge of UnrealScript and how “replication” (the Unreal networking idiom) works is also beneficial.

Tip

Download the source code mentioned in this hack as well as the art packages necessary to use this example from http://www.demiurgestudios.com/CudaExample/.

What Is Nitrous?

Nitrous is short for nitrous oxide, a gas that produces a significant horsepower boost when injected into a gasoline engine. Street and drag racers often use nitrous to add speed boosts at key moments. In general, you cannot carry enough nitrous oxide to use it at all times. For more information on how nitrous oxide works, see its How Stuff Works page at http://auto.howstuffworks.com/question259.htm.

In this example, you’ll simulate the use of nitrous for the ‘Cuda. You’ll add a short speed boost when you click the left mouse button (by default, the AltFire key). During the boost, the ‘Cuda will accelerate rapidly, and flames will shoot out of the tailpipes. Despite the fact that the amount of nitrous a car can practically store is relatively small, the ‘Cuda in this example will have 50 nitrous hits just because it is more fun!

Physics of the Nitrous Boost

To simulate nitrous, we will use a very simple approach: apply a large force to the back of the car when the nitrous is on. Of course, you should apply the force only when the car is on the ground, or else the car could fly. You accomplish this by applying the force only if bVehicleOnGround is true.

The next consideration is that the force of the nitrous should depend on the force with which the tires press against the ground. If you don’t account for this, the ‘Cuda will be able to drive straight up walls; bVehicleOnGround is true if its wheels touch anything! To deal with the force on the wheels, we average the TireLoad of all the wheels. Then cap the average tire force to keep the nitrous force under control if there is a lot of downforce on the tires, as there is after a jump. Once you’ve calculated the magnitude of the force, apply it in the direction the car is pointing.

All this code lives in the KApplyForce function. Unreal calls this function to give Actors a chance to adjust the forces applied to them. Note that you never assign a value to Force; you just add to it. If you assign a value to Force, that value overrides all the other forces the engine applies to the car. Here is the function for adding the nitrous force as well as some of the variables used by the nitrous system:

// Nitrous
// Set to true while pending and during a nitrous boost
var bool bClientDoNitrous;

// How much force to apply per-tick
var float NitrousForce;

simulated event KApplyForce(out vector Force, out vector Torque)
{
    local int i;
    local float avgLoad;

    Super.KApplyForce(Force, Torque); // apply other forces first

    // If the car is nitrousing and vehicle is on the ground
    if (bClientDoNitrous && bVehicleOnGround)
    {
        // apply the nitrous force as a function of how much grip
        // each wheel has
        avgLoad = 0;
        for(i=0; i<Wheels.Length; i++)
        {
            avgLoad += Wheels[i].TireLoad;
        }
        avgLoad = avgLoad / Wheels.Length;

        // cap avgLoad with experimentally determined value
        avgLoad = FMin(avgLoad, 20.0);

        // normalize avgLoad factor with respect to cap 
        // it can only reduce the nitrous force, never increase 
        // it beyond 100%
        avgLoad = avgLoad / 20.0;

        // add forces to any existing forces already being applied
        // DO NOT OVERWRITE PREVIOUS FORCE VALUES
        // get direction of hot rod and apply force in that direction
        Force += vector(Rotation); 
        Force += Normal(Force) * NitrousForce * avgLoad;
    }
}

defaultproperties
{
    ...
    // Nitrous
    NitrousForce=250.000000
    ...
}

Triggering the Nitrous Boost

The code that follows, working with the code described earlier, does the triggering and counting of nitrous. The triggering mechanism is slightly confusing because it has to work in a multiplayer game.

When the server detects an AltFire press (done in VehicleFire), it calls the Nitrous function. This function checks to see if you’re not using nitrous and if you have any nitrous left. If this check passes, it plays the nitrous sound and decrements the number of nitrous hits remaining. The most important part is that it sets bClientDoNitrous to true. The server replicates bClientDoNitrous to each client so that everyone in the game knows that a particular car has fired its nitrous.

The KApplyForce function, shown previously, uses the bClientDoNitrous value to determine if it should apply the nitrous force. Also, Tick, which the game calls every frame, checks the value of bClientDoNitrous and sets a timer to time how long the nitrous should last (DoNitrousTime). Once the designated amount of time has passed, the Timer event fires, turning off the nitrous by setting bClientDoNitrous to false.

// Nitrous
var float   DoNitrousTime;    // How long to boost for
var int     NitrousRemaining; // How many nitrous shots left in this car.
var ( ) sound NitrousSound;   // Sound when nitrous is fired

replication
{
    reliable if(bNetDirty && Role=  =ROLE_Authority)
        bClientDoNitrous, NitrousRemaining;
}

function VehicleFire(bool bWasAltFire)
{
    if(bWasAltFire)
    {
        Nitrous( );
    }
    else
        Super.VehicleFire(bWasAltFire);
}

function Nitrous( )
{
    // If we have any left and we're not currently using it
    if(NitrousRemaining > 0 && !bClientDoNitrous)
    {
        PlaySound(NitrousSound, SLOT_Misc, 1);
        bClientDoNitrous = true;
        NitrousRemaining--;
    }
}

simulated event Tick(float DeltaTime)
{
    Super.Tick(DeltaTime);

    // If bClientDoNitrous and pipe fire don't agree
    if(bClientDoNitrous != bPipeFlameOn)
    {
        // it means we need to change the state of the car (bPipeFlameOn)
        // to match the desired state (bClientDoNitrous)
        EnablePipeFire(bClientDoNitrous); // show/hide flames

        // if we just enabled pipe flames, set the timer
        // to turn them off after nitrous time has expired
        if(bClientDoNitrous)
        {
            SetTimer(DoNitrousTime, false);
        }
    }
}

simulated event Timer( )
{
    // when nitrous exceeds time limit, turn it off
    bClientDoNitrous = false;
}

defaultproperties
{
    ...
    // Nitrous
    DoNitrousTime=2.000000
    NitrousRemaining=50
    NitrousSound=Sound'WeaponSounds.Misc.redeemer_shoot'
    ...
}

Adding the Tailpipe Fire

The final bit of polish to add to the nitrous system is tailpipe flames. I’ve created a tailpipe fire particle system found in the class CudaPipeFire.uc, as found with the rest of source described here. Unfortunately, talking about how to create particle systems in Unreal is outside the scope of this hack.

The first step is to create the tailpipe flames and stick them on the tailpipes. The PostBeginPlay event does this. The server calls this function after creating the ‘Cuda. Use the spawn function, which makes new objects in the world, to create the flames. Next, attach the flames and then rotate them correctly. Once this is done, EnablePipeFire(false) disables all the emitters so the tailpipe flames look like they are off.

It works better to just turn the flames on and off as opposed to creating and destroying the flames each time they are needed. The bClientDoNitrous variable in the Tick event controls their visibility. When the CudaCar is destroyed, the server calls the Destroyed event, which destroys the flames so that you’ll never have nitrous flames left after a ‘Cuda blows up.

The following code is specific to tailpipe flames. Keep in mind that some of code presented earlier deals with tailpipe flames as well.

// Fire
var ( )       class<Emitter>     TailPipeFireClass;
var      Emitter            TailPipeFire[2];
var ( ) Vector             TailPipeFireOffset[2];
var ( )  Rotator            TailPipeFireRotOffset[2];
var      float              PotentialFireTime;
var       bool               bPipeFlameOn;
var ( ) Sound              TailPipeFireSound;

simulated event PostBeginPlay( )
{
    Super.PostBeginPlay( );

    // Dont bother making emitters etc. on dedicated server
    if(Level.NetMode != NM_DedicatedServer)
    {
        // Create tail pipe fire emitters.
        TailPipeFire[0] = spawn(TailPipeFireClass, self,, Location +
            (TailPipeFireOffset[0] >> Rotation) );
        TailPipeFire[0].SetBase(self);
        TailPipeFire[0].SetRelativeRotation(TailPipeFireRotOffset[0]);

        TailPipeFire[1] = spawn(TailPipeFireClass, self,, Location +
            (TailPipeFireOffset[1] >> Rotation) );
        TailPipeFire[1].SetBase(self);
        TailPipeFire[1].SetRelativeRotation(TailPipeFireRotOffset[1]);

        EnablePipeFire(false);
    }
}

// Enable/disable pipe fire effects
// via passed bool Enable
simulated function EnablePipeFire(bool bEnable)
{
    local int i,j;

    // enable/disable emitters
    if(Level.NetMode != NM_DedicatedServer)
    {
        for(i = 0; i < 2; i++)
        {
            for(j = 0; j < TailPipeFire[i].Emitters.Length; j++)
            {
                TailPipeFire[i].Emitters[j].Disabled = !bEnable;
            }
        }
    }

    bPipeFlameOn = bEnable; // update state of pipe flames
}

simulated event Destroyed( )
{
    if(Level.NetMode != NM_DedicatedServer)
    {
        TailPipeFire[0].Destroy( );
        TailPipeFire[1].Destroy( );
    }

    Super.Destroyed( );
}

defaultproperties
{
    ...
    // TailPipeFire
    TailPipeFireClass=Class'CudaPipeFire'
    TailPipeFireOffset(0)=(X=-140.000000,Y=20.000000,Z=-16.000000)
    TailPipeFireOffset(1)=(X=-140.000000,Y=-20.000000,Z=-16.000000)
    TailPipeFireRotOffset(0)=(Yaw=32768)
    TailPipeFireRotOffset(1)=(Yaw=32768)
    ...
}

Hacking the Hack

The ‘Cuda is now ready to go. The example download provides the map ONS-CudaExample. You can play in single player or multiplayer.

Once you are accustomed to how the CudaCar plays, consider adding or changing parts. For example, try adding bAllowAirControl=true to defaultproperties to allow you to control the orientation of the car in the air. When in the air, strafe left and strafe right to rotate left and right and use the jump and crouch controls to change the pitch up and down. You can also add bEjectPassengersWhenFlipped=false so you aren’t ejected from the vehicle when it flips over; you have to press the Use key to escape. You can also increase or decrease the force of nitrous or maybe even change the direction so the car can hover and fly. Have fun!