Test Driven Development For Games: What, Why, And How (Game Connect 2006)
-
Upload
kay-kim -
Category
Technology
-
view
3.107 -
download
2
description
Transcript of Test Driven Development For Games: What, Why, And How (Game Connect 2006)
![Page 1: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/1.jpg)
Test Driven Development For Games: What, Why,
And How
Noel LlopisSenior ArchitectHigh Moon Studios
![Page 2: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/2.jpg)
1. What is TDD? 1. What is TDD?
2. How We Use TDD2. How We Use TDD
3. TDD and Games3. TDD and Games
4. Lessons Learned4. Lessons Learned
5. Wrap Up5. Wrap Up
![Page 3: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/3.jpg)
1. What is TDD? 1. What is TDD? (and why would I ever want to use it)(and why would I ever want to use it)
2. How We Use TDD2. How We Use TDD
3. TDD and Games3. TDD and Games
4. Lessons Learned4. Lessons Learned
5. Wrap Up5. Wrap Up
![Page 4: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/4.jpg)
define G(n) int n(int t, int q, int d)#define X(p,t,s) (p>=t&&p<(t+s)&&(p-(t)&1023)<(s&1023))#define U(m) *((signed char *)(m))#define F if(!--q){#define I(s) (int)main-(int)s#define P(s,c,k) for(h=0; h>>14==0; h+=129)Y(16*c+h/1024+Y(V+36))&128>>(h&7)?U(s+(h&15367))=k:kG (B){ Z; F D = E (Y (V), C = E (Y (V), Y (t + 4) + 3, 4, 0), 2, 0); Y (t + 12) = Y (t + 20) = i; Y (t + 24) = 1; Y (t + 28) = t; Y (t + 16) = 442890; Y (t + 28) = d = E (Y (V), s = D * 8 + 1664, 1, 0); for (p = 0; j < s; j++, p++) U (d + j) = i == D | j < p ? p--, 0 : (n = U (C + 512 + i++)) < ' ' ? p |= n * 56 - 497, 0 : n;}n = Y (Y (t + 4)) & 1;FU (Y (t + 28) + 1536) |=62 & -n;MU (d + D) =X (D, Y (t + 12) + 26628, 412162) ? X (D, Y (t + 12) + 27653, 410112) ? 31 : 0 : U (d + D);for (; j < 12800; j += 8) P (d + 27653 + Y (t + 12) + ' ' * (j & ~511) + j % 512, U (Y (t + 28) + j / 8 + 64 * Y (t + 20)), 0);}F if (n) { D = Y (t + 28); if (d - 10) U (++Y (t + 24) + D + 1535) = d; else { for (i = D; i < D + 1600; i++) U (i) = U (i + 64); Y (t + 24) = 1; E (Y (V), i - 127, 3, 0); } }else Y (t + 20) += ((d >> 4) ^ (d >> 5)) - 3;}}
![Page 5: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/5.jpg)
![Page 6: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/6.jpg)
TDD addresses those problems
![Page 7: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/7.jpg)
Only a few Only a few minutes longminutes long
Failing testsFailing tests
Passing testsPassing testsPassing testsPassing tests
Check in
Check in
TDD cycle
TEST (ShieldLevelStartsFull){
Shield shield;CHECK_EQUAL (Shield::kMaxLevel, shield.GetLevel());
}
TEST (ShieldLevelStartsFull){
Shield shield;CHECK_EQUAL (Shield::kMaxLevel, shield.GetLevel());
}Shield::Shield() : m_level (Shield::kMaxLevel){}
Shield::Shield() : m_level (Shield::kMaxLevel){}
Writetest
Writecode
Refactor
![Page 8: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/8.jpg)
Benefits: Simplicity, modularity
![Page 9: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/9.jpg)
Benefits: Safety net
![Page 10: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/10.jpg)
Benefits: Instant feedback
Milestone: ~2 monthsMilestone: ~2 months
Iteration: 2-4 weeksIteration: 2-4 weeks
Nightly build: 1 dayNightly build: 1 day
Automated builds: ~1 hourAutomated builds: ~1 hour
TDD: 30s to 3-4 minutesTDD: 30s to 3-4 minutes
![Page 11: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/11.jpg)
![Page 12: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/12.jpg)
Benefits: Documentation
![Page 13: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/13.jpg)
TDD != Unit testsTDD != Unit testsTDD != Testing strategyTDD != Testing strategy
TDD == Development techniqueTDD == Development technique
![Page 14: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/14.jpg)
1. What is TDD?1. What is TDD?
2. How We Use TDD2. How We Use TDD3. TDD and games3. TDD and games
4. Lessons Learned4. Lessons Learned
5. Wrap up5. Wrap up
![Page 15: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/15.jpg)
Character + Shield
Character
Damage(x)
Shield
Damage(x)
class Character{
IShield* m_shield;public:
Character();void Damage(float amount);float GetHealth() const;
};
![Page 16: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/16.jpg)
Three Ways to Test
• Testing return valuesTesting return values• Testing stateTesting state• Testing object interationTesting object interation
![Page 17: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/17.jpg)
Testing Return Values
TEST (ShieldCanBeDamagedIfFull){
}
ShieldTest Shield
bool Damage()Damage?
Shield shield;CHECK (shield.Damage());
“Failure in ShieldLevelStartsFull: Expected 100 but got 0”
![Page 18: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/18.jpg)
Testing State
TEST (LevelCannotBeDamagedBelowZero){
}
ShieldTest Shield
Damage(200)
GetLevel()
Shield shield;shield.Damage(200);CHECK_EQUAL (0, shield.GetLevel());
0?
![Page 19: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/19.jpg)
Where do we put tests?
• TestGame.exe (links with Game.lib)TestGame.exe (links with Game.lib)• #ifdef UNIT_TESTS#ifdef UNIT_TESTS• GameTests.DLLGameTests.DLL• GameTests.upkGameTests.upk
![Page 20: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/20.jpg)
Writing Tests
• Use a unit test framework to make it trivial Use a unit test framework to make it trivial to add new tests.to add new tests.
• UnitTest++ well suited to gamesUnitTest++ well suited to games
![Page 21: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/21.jpg)
Run Tests With Every Build
![Page 22: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/22.jpg)
Testing Interaction(Can Be A Problem Initially)
Test Character Character
Damage()
*m_shield
TEST(CharacterUsesShieldToAbsorbDamage){
Character character(400);character.Damage(100);CHECK_EQUAL(390, character.GetHealth());
}
390?
Shield
GetHealth()
FancyShield
![Page 23: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/23.jpg)
class IShield{public:
virtual float Damage(float amount) = 0;}
class FancyShield : public IShield{public:
float Damage(float amount) { … };}
class MockShield : public IShield{public:
float damagePassedIn;float damageToReturn;float Damage(float amount){
damagePassedIn = amount;return damageToReturn;
}}
A mock object stands in for an objectoutside the unit you're testing
![Page 24: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/24.jpg)
Using a Mock in Your Test
Test Character Character
Damage()
*m_shield
TEST(CharacterUsesShieldToAbsorbDamage){
}
MockShield Parameters correct?
GetHealth()Returned damagecorrectly used?
MockShield mockShield = new MockShield;mockShield->damageToReturn = 10;Character character(400, mockShield);
character.Damage(200);
CHECK_EQUAL(200, mockShield->damagePassedIn);CHECK_EQUAL(390, character.GetHealth());
![Page 25: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/25.jpg)
Best Practices: Test only the code at hand
TestCodeundertest
TestCodeundertest
Subsystem A Subsystem BSubsystem C
Something the catdragged in
The kitchen sink
Who knows
![Page 26: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/26.jpg)
Best Practices: Keep Tests SimpleTEST (ShieldStartsAtInitialLevel){
ShieldComponent shield(100);CHECK_EQUAL (100, shield.GetLevel());
}
TEST (ShieldTakesDamage){
ShieldComponent shield(100);shield.Damage(30);CHECK_EQUAL (70, shield.GetLevel());
}
TEST (LevelCannotDropBelowZero){
ShieldComponent shield(100);shield.Damage(200);CHECK_EQUAL (0, shield.GetLevel());
}
TEST(ActorDoesntMoveIfPelvisBodyIsInSamePositionAsPelvisAnim){
component = ConstructObject<UAmpPhysicallyDrivableSkeletalComponent>();component->physicalPelvisHandle = NULL;component->SetOwner(owner);component->SkeletalMesh = skelMesh;component->Animations = CreateReadable2BoneAnimSequenceForAmpRagdollGetup(component, skelMesh, 10.0f, 0.0f);component->PhysicsAsset = physicsAsset;component->SpaceBases.AddZeroed(2);component->InitComponentRBPhys(false);component->LocalToWorld = FMatrix::Identity;const FVector actorPos(100,200,300);const FVector pelvisBodyPositionWS(100,200,380);const FTranslationMatrix actorToWorld(actorPos);owner->Location = actorPos;component->ConditionalUpdateTransform(actorToWorld);INT pelvisIndex = physicsAsset->CreateNewBody(TEXT("Bone1"));URB_BodySetup* pelvisSetup = physicsAsset->BodySetup(pelvisIndex);FPhysAssetCreateParams params = GetGenericCreateParamsForAmpRagdollGetup();physicsAsset->CreateCollisionFromBone( pelvisSetup,
skelMesh,1,params,boneThings);
URB_BodyInstance* pelvisBody = component->PhysicsAssetInstance->Bodies(0);NxActor* pelvisNxActor = pelvisBody->GetNxActor();SetRigidBodyPositionWSForAmpRagdollGetup(*pelvisNxActor, pelvisBodyPositionWS);
component->UpdateSkelPose(0.016f);component->RetransformActorToMatchCurrrentRoot(TransformManipulator());
const float kTolerance(0.002f);
FMatrix expectedActorMatrix;expectedActorMatrix.SetIdentity();expectedActorMatrix.M[3][0] = actorPos.X;expectedActorMatrix.M[3][1] = actorPos.Y;expectedActorMatrix.M[3][2] = actorPos.Z;const FMatrix actorMatrix = owner->LocalToWorld();CHECK_ARRAY2D_CLOSE(expectedActorMatrix.M, actorMatrix.M, 4, 4, kTolerance);
}
![Page 27: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/27.jpg)
Best Practices: Keep Tests Fast
Slow Test(24 > 20 ms): CheckSpotOverlapIsHandledCorrectly1TestSlow Test(25 > 20 ms): CheckSpotOverlapIsHandledCorrectly2TestSlow Test(24 > 20 ms): DeleteWaveEventFailsIfEventDoesntExistInCueTestSlow Test(22 > 20 ms): CanGetObjectsInBrowserListPackageTestSlow Test(48 > 20 ms): HmAddActorCallsCreateActorTestSlow Test(74 > 20 ms): HmReplaceActorDoesNothingIfEmptySelectionTestSlow Test(57 > 20 ms): HmReplaceActorWorksIfTwoActorsSelectedTestSlow Test(26 > 20 ms): ThrowExceptionWhenTrackIndexOutOfRangeTest
Total time spent in 1923 tests: 4.83 seconds.
Time spent in 26 slow tests: 2.54 seconds.
![Page 28: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/28.jpg)
Best Practices: Keep Tests Fast
Running unit tests TestDebugServer in Debug...116 tests runThere were no test failures. Test time: 0.016 seconds.
Running unit tests for TestStreams in Debug...138 tests runThere were no test failures. Test time: 0.015 seconds.
Running unit tests TestMath in Debug...245 tests runThere were no test failures. Test time: 0.001 seconds.
Running unit tests...184 tests runThere were no test failures. Test time: 0.359 seconds.
![Page 29: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/29.jpg)
Best Practices: Keep Tests Independent
g_CollisionWorldSingleton
![Page 30: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/30.jpg)
1. What is TDD?1. What is TDD?
2. How We Use TDD2. How We Use TDD
3. TDD and Games3. TDD and Games4. Lessons Learned4. Lessons Learned
5. Wrap Up5. Wrap Up
![Page 31: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/31.jpg)
Run the tests on consoles... less often
![Page 32: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/32.jpg)
![Page 33: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/33.jpg)
Wrap full API
![Page 34: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/34.jpg)
Test API state directly
![Page 35: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/35.jpg)
Test all code except for API calls
![Page 36: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/36.jpg)
Testing With Middleware
HavokRenderWare
UnrealNovodexOpenGLDirectX
![Page 37: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/37.jpg)
TDD With An Existing Engine
![Page 38: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/38.jpg)
I'd like to use TDD but...
![Page 39: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/39.jpg)
1. What is TDD?1. What is TDD?
2. How We Use TDD2. How We Use TDD
3. TDD and Games3. TDD and Games
4. Lessons Learned4. Lessons Learned5. Wrap Up5. Wrap Up
![Page 40: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/40.jpg)
Lesson #1: TDD can be used for high-level game code
![Page 41: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/41.jpg)
function TestEnemyChoosesLightAttack(){
FightingComp = new(self) class'FightingComponent';
FightingComp.AddAttack(LightAttack);FightingComp.AddAttack(HeavyAttack);
enemy.AttachComponent(FightingComp);enemy.FightingComponent = FightingComp;enemy.FindPlayerPawn = MockFindPlayerPawn;enemy.ShouldMeleeAttack = MockShouldAttack;ShouldMeleeAttackReturn = true;
enemy.Tick(0.666);
CheckObjectsEqual(LightAttack,FightingComp.GetCurrentAttack());
}
Fighting AI example
![Page 42: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/42.jpg)
Character behavior exampleTEST_F( CharacterFixture,
SupportedWhenLeapAnimationEndsTransitionsRunning ){
LandingState state(CharacterStateParameters(&character), AnimationIndex::LeapLanding);
state.Enter(input);input.deltaTime = character.GetAnimationDuration(
AnimationIndex::LeapLanding ) + kEpsilon;
character.supported = true;CharacterStateOutput output = state.Update( input );CHECK_EQUAL(std::string("TransitionState"),
output.nextState->GetClassInfo().GetName());const TransitionState& transition = *output.nextState;CHECK_EQUAL(std::string("RunningState"),
transition.endState->GetClassInfo().GetName());}
![Page 43: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/43.jpg)
Choice of architecture
![Page 44: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/44.jpg)
Lesson #2: TDD and code design
![Page 45: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/45.jpg)
Lesson #3: Number of tests as a measure of progress
![Page 46: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/46.jpg)
Lesson #4: TDD improves build stability
![Page 47: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/47.jpg)
Lesson #5: TDD creates more code
![Page 48: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/48.jpg)
Lesson #6: Development speed
![Page 49: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/49.jpg)
Lesson #7: Adopting TDD
![Page 50: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/50.jpg)
Lesson #7: Adopting TDD
High risk – High rewardHigh risk – High reward
![Page 51: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/51.jpg)
1. What is TDD?1. What is TDD?
2. How We Use TDD2. How We Use TDD
3. TDD and Games3. TDD and Games
4. Lessons Learned4. Lessons Learned
5. Wrap Up5. Wrap Up
![Page 52: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/52.jpg)
Conclusion
![Page 53: Test Driven Development For Games: What, Why, And How (Game Connect 2006)](https://reader036.fdocuments.net/reader036/viewer/2022062617/54c2dc824a7959b7558b4741/html5/thumbnails/53.jpg)
Questions?
ResourcesResourcesGames from Within Games from Within http://www.gamesfromwithin.comhttp://www.gamesfromwithin.com
Includes paper for this presentation with more details and Includes paper for this presentation with more details and links to other TDD resources and the UnitTest++ links to other TDD resources and the UnitTest++ framework.framework.
Noel Llopis - Noel Llopis - [email protected]