AI Madness: Using AI to Bring Open-City Racing to Life
City People: Simulating Pedestrians
In real cities, pedestrians are on nearly every street corner. They walk and go about their business, so it should be no different in the cities we create in our games. The pedestrians wander along the sidewalks and sometimes cross streets. They avoid static obstacles such as mailboxes, streetlights, and parking meters, and also dynamic obstacles such as other pedestrians and the vehicles controlled by the players. And no, players can't run over the pedestrians, or get points for trying! Even so, interacting with these "peds" makes the player's experience as a city driver much more realistic and immersive.
Simulation bubbles for pedestrians. Just as the ambient traffic has a simulation bubble, so do the pedestrians. And while the pedestrian bubble has a much smaller radius, both types are handled similarly. During initialization, the pedestrians are created and inserted into the pedestrian pool. When the player is inserted into the city, the pedestrians are populated around him. During population, one pedestrian is added to each road in the bubble, round-robin style, until all the pedestrians in the pool are exhausted.
Pedestrians are initialized with a random road distance and side distance based on an offset to the center of the sidewalk. They are also assigned a direction in which to travel and a side of the street on which to start. As the pedestrians get to the edge of the population bubble, they simply turn around and walk back in the opposite direction from which they came.
Wandering the city. When walking the streets, the pedestrians use splines to smooth out the angles created by the road subsegments. All the spline calculations are done in 2D to increase the performance of the pedestrians. The Y value for the splines is calculated by probing the polygon the pedestrian is walking on in order to give the appearance that the pedestrian is actually walking on the terrain underneath its feet.
Each pedestrian has a target point for it to head toward. This target point is calculated by solving for the location on the spline path three meters ahead of the pedestrian. In walking, the ped will turn toward the target point a little bit each frame, while moving forward and sideways at a rate based on the parameters that control the animation speed. As the pedestrian walks down the road, the ped object calculates a new spline every time it passes a sidewalk vertex.
Crossing the street. When a pedestrian gets to the end of the street, it has a decision to make. The ped either follows the sidewalk to the next street or crosses the street. If the ped decides to cross the street, then it must decide which street to cross: the current or the next. Four states control ped navigation on the streets: Wander, PreCrossStreet, WaitToCrossStreet, and CrossStreet (see Figure 3). The first of these, Wander, is described in the previous section, "Wandering the City." PreCrossStreet takes the pedestrian from the end of the street to a position closer to the street curb, WaitToCrossStreet tells the pedestrian waiting for the traffic light that it's time to cross the street, and CrossStreet handles the actual walking or running of the pedestrian to the curb on the other side of the street.
![]() |
|
![]() | ||
![]() | ||||
![]() |
Figure 3. In this situation, the PreCrossStreet state has moved the pedestrians next to the street curb, and now the WaitToCrossStreet state is holding the peds in place until the light turns green. |
Animating actions. The core animation system for the pedestrians is skeleton-based. Specifically, animations are created in 3D Studio Max at 30FPS, and then downloaded using Angel's proprietary exporter. The animation system accounts for the nonconstant nature of the frame rate.
For each type of pedestrian model, a data file identifies the animation sequences. Since all the translation information is removed from the animations, the data file also specifies the amount of translation necessary in the forward and sideways directions. To move the pedestrian, the ped object simply adds the total distance multiplied by the frame time for both the forward and sideways directions. (Most animation sequences have zero side-to-side movement.)
Two functions of the animation system are particularly useful. The Start function immediately starts the animation sequence specified as a parameter to the function, and the Schedule function starts the desired animation sequence as soon as the current sequence finishes.
Avoiding the speeding player. The main rule for the pedestrians is to always avoid being hit. We accomplish this in two ways. First, if the pedestrian is near a wall, then the ped runs to the wall, puts its back against it, and stands flush up against it until the threatening vehicle moves away (see Figure 4).
![]() |
|
![]() | ||
![]() | ||||
![]() |
Figure 4. When the oncoming player vehicle threatens these pedestrians, they decide to hug the wall after sending out a probe and finding a wall nearby. |
Alternatively, if no wall is nearby, the ped turns to face the oncoming vehicle, waits until the vehicle is close enough, and then dives to the left or right at the very last moment (see Figure 5).
![]() |
|
![]() | ||
![]() | ||||
![]() |
Figure 5. The pink lines visualize the direction the peds
intend to walk. When a player vehicle introduces a threat, the
pedestrians decide to dive right or left at the last moment, since
no wall is nearby. |
The pedestrian object determines that an oncoming vehicle is a threat by taking the forward directional vector of the vehicle and performing a dot product with the vector defined by the ped's position minus the vehicle's position. This calculation measures the side distance. If the side distance is less than half the width of the vehicle, then a collision is imminent.
The next calculation is the time it will take the approaching vehicle to collide with the pedestrian. In this context, two distance zones are defined: a far and a near. In the far zone, the pedestrian turns to face the vehicle and then goes into an "anticipate" behavior, which results in a choice between shaking with fear and running away. The near zone activates the "avoid" behavior, which causes the pedestrian to look for a wall to hug. To locate a wall, the pedestrian object shoots a probe perpendicular to the sidewalk for ten meters from its current location. If a wall is found, the pedestrian runs to it. Otherwise, the ped dives in the opposite direction of the vehicle's rotational momentum. (Sometimes the vehicle is going so fast, a superhuman boost in dive speed is needed to avoid a collision.)
Avoiding obstacles. As the pedestrians walk blissfully down the street, they come to obstacles in the road. The obstacles fall into one of three categories: other wandering pedestrians; props such as trash cans, mailboxes, and streetlights; or the player's vehicle parked on the sidewalk.
In order to avoid other pedestrians, each ped checks all the pedestrians inside its obstacle grid cell. To detect a collision among this group, the ped performs a couple of calculations. First, it determines the side distance from the centerline of the sidewalk to itself and the other pedestrian. The ped's radius is then added to and subtracted from this distance. A collision is imminent if there is any overlap between the two pedestrians.
In order to help them avoid each other, one of the pedestrians can stop while the other one passes. One way to do this is to make the pedestrian with the lowest identification number stop, and the latter ped sets its target point far enough to left or right to miss the former ped. The ped will always choose left if it's within the sidewalk boundary; otherwise it will go to the right. If the right target point is also past the edge of the sidewalk, then the pedestrian will turn around and continue on its way. Similar calculations to pedestrian detection and avoidance are performed to detect and avoid the props and the player's vehicle.