The Objects of Driver: SF

Instead of breaking down the story elements and discussing the finer points of Driver: San Francisco, which I would like to leave for later (or maybe for comment sections on other articles) I would like to discuss the well-formed structure of the game. Driver: SF had a very nice and polished feel to it. Every mechanic felt like it was designed in a player-centric manner, the structure of all kinds of missions in the game had this feel of  “uniformity” to them.  I still feel surprised by the fact that it is only as popular as it is, feels like something that deserved more than what it achieved.

As I played through the game, every mission struck to me as a well structured Object, of a Class Mission. I’m sure Object Oriented/Modular Design appears in many forms of engineering and sciences, being a programmer myself, all I could see was Objects, Classes and member functions. After finishing the game I was left with this itch to try and reverse engineer the game design just through game play and get an understanding of how a modular approach might have enabled the Team responsible for Driver San Francisco to create such a polished experience.

I’ll try and describe these using some custom pseudo-code notations that would make for abstract reading. Now lets take a look!

Following is a basic class for all the optional Missions. These are all those little dots on the map, that could very well have been randomly generated.

So many that they're almost auto-gen!

So many that they’re almost auto-gen!

 
Class Activity{

var activityType; //possible values [ heart_beat, race, crash, police ]
var reward; // Willpower rewarded
var timeLimit; //placed according to type.

//Given a Starting pointA and an Ending pointB, based on the type of event, the route can be generated.
function define_route(var pointA, var pointB);

// Then there would setters and getters for the values of every variable.

}

One of the distinctive features of the game is that there is a lot of dialogue in any given mission of the game. There is a pattern to when each of it is said, which gives a look at how the Class MissionSpeech would have been structured.


Class MissionSpeech {

// This was probably the most used structure in the game.

var initialConversation;
var randomBanter[];
var directedDialogues[];
var sidewalkComment;
var damageComments[];
var finishComment;

//setters and getters

//A specific dialog from directedDialogues is called at a fixed percentage of route completion for every mission.
function direct_dialogue_at_percentage();

//Similarly there would be other functions that echo the sidewalkComment for a mission when driving on a sidewalk, etc etc.
//These things happen in every mission hence easy to spot out.

}

Class StoryMission extends Activity, MissionSpeech {

//Story Missions are similar to a basic Activity on the map in every way, they just have their own Speech/Dialogues in addition to the basic activity.

}

So on and so forth, the structure of  Driver: SF can be broken down into Classes (of course, there is more to it than what I exactly gave in here). This basic structure is interesting to me because it helps in explaining how and why the most noticeable parts of the game felt very polished. All the game Director would have to do, is make sure that the characters involved in a mission are made to say these extra bits of dialogues. Once you have the artists in the recording booth, they might as well say 10-20 lines in addition to the cutscene, which will feel like less work, but add a lot of polish to the game as a whole. Whenever I heard those sidewalk comments, and the same banter at the same section of a mission (thanks to timed missions and multiple restart) this kind of Encapsulation was visible.

The Object Oriented Game Design approach.

It felt like this whole approach extended to the design philosophy behind the game too, which created this resonating feeling of uniformity throughout the game. Let us look at it this way, if we consider the actual Player of the game as the seed:


Class PlayerActions {

var controller;
var playerCharacter;

function control_player_character(controller);

}

We have the playerCharacter (John Tanner) who is controlled by the player (You). A player (You) can then in turn as a playerCharacter (John Tanner), control various nonPlayerCharacters (Ordell, etc) who are inside vehicles in the game. This can be explained as.

 
Class TannerActions  extends PlayerActions {

@override
function control_player_character(controller){

}

//Tanner Specific Functions

}
The playerCharacter jumping to control a nonPlayerCharacter

The playerCharacter jumping to control a nonPlayerCharacter

Tanner can essentially do everything that a player can do, here Tanner’s “special power” of controlling different nonPlayerCharacters acts as the controller for Tanner’s playerCharacters. The playerCharacter for John Tanner is a nonPlayerCharacter for the game’s player (You). So basically, the game can be explained as Tanner himself playing a game… not realizing that he is being controlled by an actual player (You) outside of the game!

This kind of Inheritance and Encapsulation also helps in explaining one of the better missions of the game where Tanner is being followed by a thug ( Ordell Williams ), and Tanner controls both Ordell and himself at the same time.

Think of it this way


Class OrdellActions extends TannerActions {

@override
function control_player_character(controller1p){

    super.control_player_character(controller1p); ...
}}

Not technically, but theoretically, you can explain it as Tanner calling an instance of OrdellActions within his control_player_character() function and the control_player_character() of Ordell is configured in such a way that it calls the same function of the superclass with the same controller parameters (both turn left, etc at same time); which is a possible scenario in most Object Oriented Programming avenues. This kind of approach allows the designer to create a moment like that final Ordell Mission where Player -> Tanner -> Ordell -> Tanner is possible!

Player within a Player.

Interesting Twist: Now think of it in such way that there is one more layer of abstraction, which the player inherits. This would be the designer! The designer can be seen as the player who is using the game as their controller! The playerCharacter for this designer is the Human Player(You)! The designer then uses their game design skills and the game’s narrative to control_player_character() by obfuscating everything that is going on, via the game’s design!

This way the general flow of control in the game can be described as something that goes like this:

Designer -> Player -> Character -> NPCs

So when you are playing the game, you are in a situation similar to that of Tanner and the NPCs.

  1. The NPCs don’t know someone’s controlling them but Tanner knows.
  2. You are controlling Tanner but he doesn’t know.
  3. Via the game design, the designer is playing with your perspective & beliefs but you are not aware of their existence!

In Conclusion

Hats-off to the designers, developers and everyone involved in the game. It was most certainly one of the more enjoyable and interesting racing games that came out recently. In addition to enjoying the game, it was able to spark this idea inside me to sit down and write this thing. However incoherent it might have turned out to, It sure was fun tying to get the idea out of my mind and into writing. I guess I could draw up some diagrams and lay these out in more polished and sensible manner… buuut, I’m not writing for anyone or a paper for publishing purposes, so I can choose to be a bit lazy :P

 

Reetesh

Videogame Thinker and Tinkerer

You may also like...