This article is the seventh entry in the Open-World Player Vehicle Driving series. It follows P5’s navigation route and P6’s driving strategy. The question here is what happens when a pedestrian, vehicle, object, or impassable boundary suddenly appears on the road: how can the vehicle handle the immediate conflict without rebuilding the entire destination relationship?
The central claim is: local avoidance is neither a second navigation system nor a direct writer of vehicle control values. It is a short-lived runtime with explicit inputs, geometric tests, candidate generation, result scoring, and recovery exits. It converts the current local space into a direction, speed, or waiting constraint that can be consumed by the existing task and execution chain. The global route remains owned by P5’s route layer, driving preference remains shaped by P6’s strategy layer, and final control values and the physics seam remain with P8.
This article is based on source-reading notes related to GTA5. Public class names, function names, and project identifiers are anonymized. The text distinguishes direct source evidence, structures abstracted from call relationships, and migration proposals for a target runtime. The local-avoidance material primarily exposes geometric helpers used by pedestrian movement tasks, but its input organization, candidate search, collision timing, and result consumption are relevant to vehicle-driving runtime design. Material about player near misses, road hazards, and horn states is explicitly treated as a player-information path rather than AI driving control.

Previous article: Open-World Player Vehicle Driving P6: Driving Strategy and Risk Models — Why Does the Same Route Produce Different Driving Behavior?
Introduction: The Route Has Not Changed, but the Local Space Has
Imagine a vehicle traveling along a navigation route on a city arterial. The route holder has already confirmed the destination, the current road segment, the next junction, and the intended direction. Driving strategy has also supplied the current driver’s speed preference, following distance, and risk weight. Then a parked vehicle opens a door, the vehicle ahead brakes in the lane, a pedestrian steps into the vehicle’s path, or a dynamic object occupies space that was previously available.
From the player’s perspective, the response seems simple: avoid the obstacle or slow down and wait. From the runtime’s perspective, several questions must be answered together:
- Is the object actually inside the vehicle’s movement corridor?
- Will its velocity and heading create a conflict within a short time window?
- Does the current route leave an acceptable local direction on either side?
- Which candidate is closer to the original target direction?
- Is the risk sufficient to require waiting, braking, or a temporary offset?
- When the offset ends, how does the vehicle reconnect with its route?
- If local handling fails, who may request higher-level replanning?
These questions cannot be represented by a single Avoid = true Boolean. A Boolean can record that some state exists, but not which object caused it, when contact is predicted, which candidates were considered, why one was selected, or when the temporary state expires. Local avoidance maintains a short-lived relation: detect a local conflict, build candidates, select a temporary direction, deliver it to the movement task, and release the temporary influence when the conflict clears.
The simplified chain is:

The value of local avoidance is not route replacement. It allows the route to remain continuous while the local space changes for a short period.

I. Local Avoidance Resolves Spatial Conflicts; the Route Layer Maintains the Destination Relation
P5 separates the destination, the route, and the local target. The vehicle knows where it must eventually go and which roads it should follow next, but the route does not contain the position of every dynamic object on every frame. A road graph describes connectivity, a route describes planned passage, and local avoidance handles temporary changes in the current geometry.
The three responsibilities can be separated as follows:
| Layer | Core question | Main result |
|---|---|---|
| Goal layer | Where must the vehicle ultimately arrive? | Goal constraint |
| Route layer | Which roads should the vehicle pass through? | Route segments, lanes, and junction context |
| Local layer | Which short-term actions are geometrically feasible now? | Wait, brake, local offset, or candidate direction |
If the object ahead is only temporarily occupying the road, the local layer should handle it first instead of asking the route holder to search the whole city again. If the road structure itself has become invalid, repeated left-right attempts cannot solve the problem; the route holder must receive a blocked signal and decide whether to replan.
This is the first seam between P5 and P7: local avoidance may change how the vehicle approaches a local target, but it does not automatically gain permission to change the global destination or the route lifecycle.
A Common Misreading: Treating Route Deviation as Route Failure
A vehicle may briefly leave the route centerline to avoid a temporarily parked vehicle. That does not by itself mean that the global route is invalid. The local movement task can preserve the original route direction, clear the temporary separation vector after the obstacle disappears, and reconnect to the route target.
If every local offset is treated as global route failure, the system will repeatedly issue asynchronous searches: the vehicle avoids one object, the route is rebuilt, the new route changes the lane, and local avoidance fires again. The result is route oscillation rather than stable driving.
II. Local Avoidance Provides Task-Invoked Computation, Not Permanent Global State
One of the easiest mistakes in source reading is to see a file or namespace named for avoidance and assume that it owns every avoidance state. The structure visible in the current material is closer to this: the movement task owns execution lifecycle, while the local-avoidance layer provides geometric helpers and short-lived results.
In this article, LocalAvoidanceKernel is a public responsibility alias for the local geometric calculation, and MoveToPointTask is a public alias for the movement task that invokes it and consumes its result. These aliases do not identify unique source classes or imply a single implementation entry point.
From the responsibility distribution, LocalAvoidanceKernel receives:
- the current movement entity’s position and velocity;
- the target direction or current separation direction;
- a local reference for the current route segment;
- scan distance and deviation from the route;
- entities that should be ignored;
- whether special objects may be processed;
- thresholds and switches supplied by the caller.
Its output is deliberately narrow:
- a local avoidance direction or separation vector;
- optional collision time;
- optional collision speed or risk feedback.
It does not store the global route, decide task completion, own the nearby-entity list, or write rigid-body control values. The caller decides when to run it, how often to run it, which task phase receives the direction, and when the result is no longer valid.
This organization allows the geometric calculation to be reused by different movement tasks while each task retains its own target, success condition, failure exit, and recovery path. What is reused is a calculation responsibility; the movement behaviors remain task-specific.

III. Local Solving Starts with Qualification
Local avoidance cannot treat every entity inside the scan range as an equal obstacle. Nearby objects may include ignored entities, dead pedestrians, characters entering a vehicle, objects at a different height, objects attached to another entity, doors, pickups, and decorative entities that do not participate in the current path service.
The input therefore normally passes through two filters:

Qualification is not only a performance optimization. It defines what the runtime considers a current risk. Sending a non-moving door, a pedestrian already inside a vehicle, or an object on a clearly different height layer to the predictor may produce a mathematically valid but behaviorally wrong result.
Pedestrian Candidates
A pedestrian can often be approximated by position, velocity, and a radius. Candidate filtering needs to consider:
- whether the entity is the caller itself or explicitly excluded;
- whether it is dead and whether the current task avoids bodies;
- whether it is already inside a vehicle or in an entry/exit relationship;
- whether it occupies a different height layer or disjoint interior/exterior space;
- whether it is excluded by global, group, or task flags;
- whether its current speed requires a larger prediction radius;
- whether a running, fleeing, or temporary expanded-avoidance state is active.
Seeing a pedestrian and treating that pedestrian as a local collision candidate are two different events. The scanner provides possible objects; the local layer uses task and capability flags to determine which objects enter the calculation.
Object Candidates
Dynamic objects may provide boundary vertices and velocity through a path service or dynamic-object cache. Attached objects, doors, pickups, and objects excluded from the path service may be filtered out. A box or quadrilateral boundary is more useful than a single radius because the moving entity needs the object’s orientation and edge locations.
Vehicle Candidates
Vehicle candidates may look like dynamic bounded objects geometrically, but their filtering and consumer semantics differ. A vehicle may require body bounds, current speed, participation in path services, vertical separation, and scan distance checks. Vehicle avoidance must go beyond center-point distance: two body boundaries may intersect even when their centers are far apart, while nearby centers do not necessarily imply a path conflict.
Who Owns the Filter Parameters?
Obstacle qualification can also depend on task switches, reset flags, navigation capabilities, and global debug switches. The local layer reads these inputs, but does not necessarily own their lifecycle. A capability flag that permits avoidance of a fire is navigation-capability data; it does not mean that the avoidance layer created or maintains the capability.
This boundary matters during migration: the target runtime needs an explicit input surface. The local-avoidance layer should not discover every world state by itself.
IV. Circular and Box-Shaped Obstacles Need Different Geometric Models
Different entities use different geometric approximations because the prediction problem is different.
Circular Model: Fast-Moving Pedestrians and Fire
For an entity approximated by position, velocity, and radius, relative motion can be treated as two circles approaching one another. The runtime estimates:
- current relative position;
- current relative velocity;
- predicted contact time;
- tangent directions around the predicted position.
The circular model is inexpensive and can be repeated during one movement-task update. It does not require prediction of a pedestrian’s complete animation or the exact future action. It only needs a safe local approximation over the current time window.
Box Model: Vehicles and Dynamic Objects
Vehicles, boxes, and dynamic objects supplied by the path service generally need boundary vertices and orientation. A box model can test rays, local edges, and relative velocity, then estimate which edge is more likely to block the current direction.
The model also shows that boundary data may be owned outside local avoidance. A path service maintains dynamic-object bounds, an entity scanner maintains nearby objects, and local avoidance converts those data into candidates for the current solve.
Navigation Blocking Is a Different Kind of Spatial Evidence
A navigation boundary, an invisible line-of-sight obstruction, or a locally non-traversable area may not correspond to a dynamic entity returned by the scanner. It may require an additional query through a navigation tracker or path service.
The candidate sources therefore include at least:

The sources can enter one scoring loop, but their evidence and error characteristics differ. Reducing everything to one radius loses the meaning of vehicle orientation, object edges, and navigation boundaries.

V. Collision Prediction Focuses on Contact Time and Relative Speed
If the runtime checks only whether entities are intersecting now, avoidance happens too late. The local runtime is more interested in time: if the current relative motion continues, how long until the spatial relationship becomes unacceptable?
Typical outputs include:
- predicted collision time;
- relative or approach speed;
- current path deviation;
- which side of the target direction contains the obstacle;
- whether the situation has entered an emergency or unrecoverable interval.
Time to collision can contribute to scoring, but it cannot make the final decision alone. A nearby object with almost no relative speed and a slightly more distant object crossing the path at high speed should create different avoidance pressure.
Why Speed Alone Cannot Define Risk
The collision geometry between a vehicle and a pedestrian differs from the geometry between two vehicles. At the same distance, lateral crossing and same-direction following produce different time relations. At the same predicted time, the road boundary on the left and right may still differ. Local risk therefore depends on shape, relative motion, and available directions together.
The Authority of Collision-Time Output
The source material suggests that collision time and speed returned by a local helper may retain values from the previously processed object rather than always representing the globally nearest predicted collision. Such output is better understood as current avoidance feedback or a diagnostic value than as the world’s sole authoritative collision-prediction service.
The important point for a public article is: a return-value name does not replace the consumption relationship. To decide whether a time value is authoritative, one must trace who uses it, whether a later stage overwrites it, and whether it exists only for the current steering solve.
VI. The Target Direction Is Only a Candidate Origin; Tangents Create the Local Search
The initial direction usually comes from the movement task’s target direction or separation direction. It represents where the vehicle would continue if no local conflict existed. It is the starting point of candidate search, not the final answer.
When a conflict is predicted, the runtime generates a new direction. A circular obstacle can produce left and right tangents around its predicted position. A box obstacle or navigation boundary can produce rotational candidates around a blocking edge. Candidates are then limited by navigation boundaries, path tolerance, and task phase.

Left and right are candidates for the current solve, not a permanent rule such as “always pass on the right.” The runtime compares target direction, current heading, road boundary, candidate distance, and predicted conflict.
When No Tangent Exists
If obstacle radius, relative position, and safety margin leave no valid tangent, the runtime may use a tuned fallback angle, reduce speed, or request waiting. A fallback angle is only a short-term direction; it is not proof that a safe path exists. Downstream navigation-boundary and execution checks must still run.
The Candidate May Equal the Original Direction
A successful local calculation does not necessarily change the heading. Candidate search may confirm that the original direction remains the best-scoring option while still refreshing risk checks and local state. This prevents a debugging mistake: interpreting “returned success” as “the vehicle must turn.”

VII. Scoring Selects a Side, but Does Not Own Driving Strategy
Candidate directions need a comparable score. From the call relationships currently traced, the factors include:
- angle from the original target direction;
- angle from the moving entity’s current heading;
- deviation from the route or path center;
- predicted collision time and approach speed;
- whether the task is fleeing, moving quickly, or recovering urgently;
- available left and right angles from navigation constraints.
An abstract expression is:

This is not a reproduction of a public formula. It is a responsibility model inferred from the inputs and call relationships. It shows that local avoidance considers multiple factors rather than sorting only by distance or always preferring one side.
P6 may influence soft preferences such as waiting cost, lateral-movement penalty, or risk weight. The local layer still collects geometric facts. Strategy may make one feasible candidate more attractive, but it cannot turn a hard boundary intersection into a safe candidate.
Hard Boundaries and Soft Preferences
| Type | Function | Typical source |
|---|---|---|
| Hard boundary | Reject infeasible candidates | Body collision, navigation block, road edge |
| Soft preference | Rank feasible candidates | Deviation, waiting cost, heading change |
If every condition is folded into one score, a near collision may be outweighed by a shorter goal direction. If every condition is made a hard rejection, driving style loses its adjustable range. A clearer organization filters infeasible candidates first and ranks the survivors with soft preferences.
VIII. The Movement Task Owns the Call and Consumption Path
The local helper does not decide when to scan. The movement task commonly owns state such as:
- current target position or target direction;
- current separation vector;
- path tolerance;
- maximum avoidance time or distance threshold;
- previous avoidance result;
- the timer for the separation vector;
- whether pedestrians, objects, vehicles, and navigation blocking are enabled;
- whether the target has been reached or the task has been canceled.
At the appropriate update stage, the movement task constructs the avoidance parameters, invokes the helper, and writes the returned direction into its separation target or local-target state. It then continues to own velocity blending, heading changes, arrival, stopping precision, and task completion.
This answers a key question: the local result is a temporary intermediate result consumed by the movement task during one phase; the vehicle task and physics system retain their own lifecycle and execution responsibilities.
If the helper is promoted into a global task tree, it begins to own routes, goals, completion, and recovery. If the physics system calls it directly, it bypasses task lifecycle. Both choices remove the boundary from short-term geometric judgment.
IX. Scan Frequency and Distance Thresholds Define the Risk Timescale
“Real-time avoidance” does not mean every system scans every object on every frame. Local avoidance is constrained by scan distance, speed, path deviation, task phase, and timers.
Higher Speed Requires a Larger Look-Ahead Window
At the same scan distance, a fast vehicle has less time to respond. Look-ahead distance, maximum avoidance time, or candidate refresh frequency can change the response window. Such parameters may be provided by the movement task or vehicle type rather than owned exclusively by local geometry.
Route Deviation Can Change Candidate Qualification
Some object avoidance activates only after the moving entity has deviated from the path by a certain amount. Navigation-edge checks may also become active only after dynamic avoidance has started. These gates are runtime-budget decisions that prevent continuous solving of irrelevant distant edges during ordinary route following.
Reset Flags Can Change Safety Margins
Emergency recovery, fleeing, or task-reset states may tighten tangent and collision padding and restrict the acceptable heading range. They are strategy context supplied by the caller. Local avoidance uses them to adjust geometry, but does not own the task state.
Sampling Budget Is Runtime Semantics
An open world contains many moving entities. If local avoidance always expands the scan radius and applies high-precision geometry to every candidate, each vehicle’s short-term response becomes a full-world query. A better sequence uses speed, route phase, and current risk to choose a budget, then performs type-specific solving within that budget.
At low speed or near a stop, the system can reduce distant prediction and confirm nearby boundaries first. At high speed, it should increase look-ahead and prioritize fast crossers. In a narrow junction, there may be fewer candidates, but boundary checking must be stricter. These budget changes alter the local result’s timescale and should therefore be present in diagnostics.
The scan budget also has to align with task refresh. If scanning runs every few frames while the movement task consumes the previous separation vector every frame, the result needs an explicit validity period. If an emergency disappears before the next scan, the old direction must not remain forever. Stability comes from geometry, call frequency, cache cleanup, and task phase together.

X. Navigation Queries Provide Local Feasibility Evidence
The route describes the road relation the vehicle wants to follow. A navigation mesh or spatial query can help determine whether a local offset remains feasible. They are different data sources.
When a dynamic object creates a conflict, the system may first generate left and right candidates, then use a navigation tracker to check for an impassable edge near each candidate. If a wall, curb, or navigation gap blocks the left side, the candidate is restricted. If both sides are infeasible, local avoidance should stop generating angles indefinitely and report that local resolution has failed to a higher layer.
Why Not Recompute the Route with the Navigation Mesh?
Navigation search may be suitable for finding spatial connectivity, but player vehicles, road traffic, and different vehicle types have different semantic constraints. Vehicle width, lanes, junction permissions, speed limits, and route ownership cannot be erased merely because a local query was used.
The relationship is better expressed as:

The navigation query is a service for local judgment; it does not become the owner of the driving task.
XI. Shared Geometric Principles, Type-Specific Interpretation
P7’s geometric principles can be reused across entities, but the same local result still needs interpretation by the current vehicle type. Motion semantics, dimensional constraints, and executable ranges differ. This article keeps only that interface boundary; the control laws for cars, boats, aircraft, and other vehicles remain in P8.
Shared elements include:
- current target direction;
- obstacle candidates;
- prediction time;
- left and right candidates;
- risk score;
- temporary target or waiting request.
The following should not be shared directly:
- final steering angle;
- tire or propeller control;
- body attitude;
- physics recovery;
- kinematic constraints.
This follows P2’s conclusion: shared contract, different motion semantics. P7 can provide local intent and constraints; P8’s type-specific executor converts them into motion.

XII. The Player Vehicle’s Immediate-Risk Path Is Not AI Local Avoidance
Player-road-risk material provides an example that is easy to conflate. The player-information path can record red-light violations, road entry, wrong-way driving, collision, near miss, road type, and highway state. These facts may be consumed by statistics, audio, warnings, population, or dispatch systems.
They do not thereby become an AI avoidance strategy for the player’s vehicle.
AI Vehicle Local Avoidance
An AI vehicle must decide in the current cycle whether to slow, wait, offset, or choose another side. Its local result enters the AI task and execution chain.
Player Vehicle Risk Observation
The player’s primary motion intent normally comes from player input. The runtime may observe proximity to collision, wrong-way travel, or highway driving and produce cues, statistics, and world responses. The observation path cannot override player input without an explicit control rule.
Near Miss and Collision Have Different Semantics
A near miss may be inferred from high approach speed, a short-lived boundary-overlap risk, or an expanded physical boundary without actual contact. It is suitable as an event and feedback entry point; it should not automatically become damage or a confirmed collision.
This distinction prevents “risk” from becoming a universal switch. Risk may be an AI decision input, a player-behavior observation, or an event source for statistics and audio.

XIII. Local Avoidance State Must Distinguish Processing Phases
Local handling needs to distinguish at least these stages:

Any stage may fail: the object may disappear, road boundaries may reject every candidate, the vehicle executor may be unable to turn within its constraints, the route task may be canceled, the entity velocity may change abruptly, or the offset may exceed the permitted corridor.
In a target runtime, the local result should carry:
- creation time or validity cycle;
- the source of the target direction;
- the conflict object or conflict type;
- result state;
- whether the original target can be recovered;
- whether the route layer should receive a blocked report.
If the runtime stores only bAvoiding, it cannot distinguish waiting, lateral detour, recovery, or an expired result.
XIV. Failure Path: Who Decides the Next Step When No Direction Is Found?
Local avoidance failure does not necessarily mean route failure. At least four cases should be separated.
1. No Qualified Obstacle Candidate
This may mean that the space is safe, or that the scanner did not provide complete data. The caller must interpret the empty set with scan state and task context; it cannot treat an empty array as proof that the road is clear.
2. Every Candidate Is Rejected by Geometric Boundaries
If both left and right are rejected by navigation edges, body bounds, or spatial conditions, the local layer may request waiting or report a local blockage. It must not invent a direction through an obstacle.
3. A Candidate Exists but the Executor Cannot Complete It
Geometric feasibility does not guarantee that a vehicle executor can turn or brake in time. Executor rejection, abnormal physics feedback, or insufficient deceleration must return a failure state. A geometric result is not proof that execution succeeded.
4. Local Failure Persists Beyond Route Tolerance
Only after waiting, offsetting, and recovery have repeatedly failed should the route holder decide whether to request a new path, change route mode, or end the task.

The local layer provides evidence that the current space cannot be traversed. The route layer decides whether a higher-level route must change.
XV. Recovery Should Reconnect with the Original Route Gradually
After an obstacle clears, the vehicle may still be on one side of the route. Resetting the target directly to the route center can create a large lateral correction and trigger another avoidance event.
A more stable recovery sequence is:
- Confirm that the original route target remains valid;
- Clear references to expired obstacles;
- Preserve current speed and vehicle-type limits;
- Create a local target that approaches the route corridor gradually;
- Let the same movement task consume the route direction again;
- Release temporary separation when the deviation returns within tolerance.
Recovery should not rebuild the entire task tree. It should clear temporary local state and allow the original task to regain control of the target direction.
Why Recovery Belongs to the Calling Task
The local helper knows that it generated a direction, but may not know whether the route advanced, the target changed, or the task completed. The calling task stores those lifecycle facts, so it should decide when the local result expires, when reconnection begins, and when the route layer receives a blocked report.
XVI. Source Entry Points: How the Local Helper, Movement Task, and External Services Divide Work
To keep this article from becoming a generic “automatic obstacle avoidance” explanation, the source-reading evidence can be expanded one level. Three public aliases are used here: LocalAvoidanceKernel for the local geometric helper, MoveToPointTask for the movement task that builds parameters and consumes the result, and EntityScanner for the service that supplies nearby candidates. LocalAvoidanceKernel is a responsibility alias, not the name of a unique source class.
LocalAvoidanceKernel: Few Inputs, Small Result
The helper’s inputs describe a local solve rather than a complete vehicle. It needs the current point, target direction, local route reference, scan distance, path deviation, excluded entities, and avoidance settings. It does not need to own the full route or know when the task completes.
Its result is narrow as well: a new two-dimensional direction plus optional time or speed feedback for the current candidate. It does not contain a complete next task or a new destination. The narrow interface lets the caller preserve its own task state.
MoveToPointTask: Owns Call Timing and Consumption
From the call responsibilities, the movement task can be abstracted as the organizer of target adjustment, path tolerance, separation timing, and local-avoidance input. After local computation, it may replace the current separation vector, update the separation target, request a navigation line-of-sight check, and continue its own velocity blending, heading handling, arrival, and stopping logic.
This chain indicates that local avoidance is one local calculation inside the movement task, not a master controller before the executor. The task still knows why it is moving, what its current target is, when it may exit, and when local state expires.
EntityScanner and Path Services: Facts, Not Choices
The entity scanner provides nearby pedestrians, vehicles, and objects. A path service provides dynamic-object bounds. A navigation tracker provides locally impassable edges. These services provide facts for local avoidance; they do not decide left or right.
Keeping fact providers separate from the selector improves diagnosis. An empty scan may mean no candidates were supplied. A filtered candidate may indicate a qualification rule. A candidate with no safe direction is a local-solve failure. If all steps are inside one function, debugging sees only “avoidance returned false” and cannot identify the failing layer.
Debug Drawing Is Not Runtime Ownership
Debug drawing may display obstacle boxes, tangent candidates, navigation edges, collision circles, and the final avoidance vector. These outputs are valuable for understanding the algorithm, but they are observation paths. A debugger drawing a candidate does not own candidate generation; displaying collision time does not make the debugger responsible for deciding whether the task waits.
The same distinction applies to the article’s diagrams. The arrows show responsibility relationships; they do not require every box to become one class.
XVII. How a Local Result Enters a Driving Command Without Crossing P3 or P8
P3 defines the driving command as a consumable contract formed by several sources in the current cycle. A P7 result should enter that process as a constraint, local target, or temporary action. It should not overwrite the entire command structure.
Three Common Delivery Forms
1. Direction Offset
The local layer returns a direction that deviates from the original target. The movement task stores it as the current local separation target. Command formation can still combine route direction, driving policy, and vehicle capability.
2. Short-Term Speed Limit
When changing direction is not immediately suitable, the local layer can provide a waiting or speed-reduction constraint. It says “do not advance at the original speed this cycle”; it does not generate the final brake value. The vehicle task and executor interpret braking.
3. Temporary Waiting State
When neither side is safe, the task can enter a wait or hold state. Waiting does not mean that the route is complete or the task has failed. It needs a validity period, release condition, and escalation condition.
Merging Local Results with Task Commands
The current cycle may contain:
- a local target from the route layer;
- waiting cost and risk preference from P6;
- an immediate-conflict constraint from P7;
- the primary movement intent from the player or AI;
- an executable range supplied by the vehicle executor.

Local avoidance should not become the command’s sole source. It provides a short-lived constraint while the spatial conflict exists; after the conflict clears, the command chain resumes normal consumption of the route and primary control source.
Why This Matters Especially for Player Vehicles
While the player holds throttle or steering input, local avoidance may provide a speed limit, waiting state, or local-target constraint through the command contract. It should not silently destroy player input or change driving authority. If a near miss automatically switches the player vehicle into AI evasion, the player feels that control has been taken away. If the system provides no safety constraint at all, local traffic relations cannot remain stable.
The correct boundary is neither “player input always wins” nor “avoidance always overrides the player.” The active control rule must define which local constraints may influence the command, for how long, and when the original source is restored.
Local Results Need Type Semantics
Returning “a vector” is convenient for implementation but insufficient for runtime diagnostics. The system should distinguish whether the vector means avoiding a dynamic entity, correcting along a navigation edge, recovering from a wait, or responding to a task-level local-target change. These sources can have different validity and cleanup conditions.
For example, a result caused by a temporarily blocking vehicle can refresh as that vehicle moves. A road-edge constraint can remain until the vehicle leaves the area. A temporary target created by a task change should expire immediately when the task version changes. If all of them are compressed into one two-dimensional direction, an expired source may continue affecting the command.
The target runtime can model the local result as a narrow contract:
| Result type | Main use | Expiry condition |
|---|---|---|
| Offset direction | Avoid a short-lived dynamic conflict | Obstacle gone, direction expired, or task changed |
| Speed constraint | Reduce forward risk | Risk window ends or recovery condition is met |
| Wait request | Hold before entering infeasible space | Feasible candidate, timeout, or route escalation |
| Blocked feedback | Ask an upper layer to reassess | Route layer receives it and creates a new version |
The contract does not require the local layer to know the full route or understand every vehicle’s dynamics. It only tells the downstream consumer why the vehicle should not advance along the original direction this cycle and when that restriction may be cleared.
XVIII. How P6 Influences P7 Without Owning It
P6 can provide soft inputs such as:
- the time cost of waiting;
- a penalty for lateral offset;
- a weight for forward risk;
- a preference for holding the route or continuing forward;
- a modulation range derived from vehicle and driver capability.
P7 still owns:
- obstacle scanning;
- geometric candidate generation;
- collision-time calculation;
- navigation-edge checks;
- temporary direction results;
- avoidance success, failure, and recovery entry points.
An aggressive policy may reduce the cost of waiting, making a feasible lateral candidate easier to select. If an adjacent vehicle boundary already intersects that candidate, the policy cannot skip collision checks. A conservative policy may increase risk penalty and choose waiting earlier; the downstream task still executes the wait.
The P6-to-P7 interface should therefore contain parameters and preferences, not a command such as “turn twelve degrees left.” The latter crosses the ownership boundary of local geometry and vehicle execution.
XIX. Source Evidence: How to Locate the Avoidance Responsibility
Class and file names are entry points, not proof of ownership. Four evidence chains help locate the local-avoidance responsibility.
Who Collects Obstacles?
If nearby pedestrians come from a character-intelligence scanner, dynamic-object bounds come from a path service, and navigation blocking comes from a navigation tracker, local avoidance builds one calculation input but does not permanently hold those data.
Who Decides When to Call?
If the movement task calls the helper according to target state, timers, path deviation, and global switches, the movement task owns the runtime rhythm. The helper should not be described as a permanent system that automatically runs every frame.
Who Stores the Result?
If the returned vector is written into the movement task’s separation target, the task owns the current local result. If the result exists only for debug drawing or a one-shot query, its lifecycle is shorter.
Who Decides Completion and Recovery?
If arrival, stopping precision, task cancellation, and route reconnection are all processed by the movement task, local avoidance is an intermediate execution phase rather than a high-level task.
| Observed relationship | Safe abstraction | Do not expand it into |
|---|---|---|
| Helper returns direction and time | Local geometric calculation surface | Global avoidance manager |
| Movement task builds inputs and consumes output | Caller owns lifecycle | Helper owns the route |
| Scanner supplies nearby entities | External service supplies candidates | Avoidance owns world entities |
| Debugger draws tangents and obstacles | Observability output | Debugger decides policy |
XX. The Feeling of Smoothness Comes from Local-State Continuity
Players do not see tangent equations or candidate scores. They feel whether:
- the vehicle reacts promptly after an obstacle appears;
- the response is excessive or oscillates left and right;
- a temporary object causes a complete route rebuild;
- the vehicle returns naturally to the target direction after the obstacle clears;
- a safety constraint appears when necessary while the player holds throttle;
- AI vehicles show explainable differences in similar situations.
These experiences do not come from one steering function. They come from continuity across route state, local target, risk window, and executor feedback. If local avoidance chooses a completely different side on every update, the result may be collision-free but still feel hesitant.
Candidate scoring should therefore consider continuity with the previous cycle’s direction. That constraint may live in the helper, or the calling task may store the previous result and limit candidate changes.
XXI. Three Runtime Cases: One Local Algorithm, Different Conflicts
The model can be mistaken for a static geometric algorithm if it stops at obstacle input, candidate generation, and scoring. Runtime behavior depends on the context in which different tasks invoke the same helper. The following cases connect route, policy, scanning, local result, and recovery.
Case One: A Pedestrian Crosses the Route
The vehicle approaches a junction on an arterial; route and destination remain unchanged. A pedestrian enters the road from the front-right. The scanner returns the pedestrian. Qualification confirms the same height layer, no exclusion flag, and a position and velocity inside the current scan window, so the candidate enters circular prediction.
If relative speed makes the predicted collision time short, the local layer generates left and right tangents around the pedestrian’s future position. The curb or another vehicle may restrict the right side, leaving a left candidate with a smaller deviation from the target. P6’s waiting cost may affect the wait-versus-detour ranking, but it cannot remove the pedestrian’s hard boundary.
After consuming the result, the movement task may reduce local-target speed, create a short lateral separation target, or wait when candidates are insufficient. When the pedestrian leaves the vehicle corridor, the pedestrian reference and temporary separation result are cleared, and the route target becomes the dominant local direction again.
The destination did not change. Only a spatial conflict within one time window was handled.
Case Two: The Vehicle Ahead Stops and the Adjacent Lane Is Uncertain
The vehicle enters congestion and the vehicle ahead slows rapidly. The scanner returns its dynamic bounds and velocity; prediction shows the collision time shrinking if the original direction is maintained. Policy may prefer route retention and fewer lateral movements, or an aggressive driver may assign a lower cost to waiting.
The local layer checks adjacent-lane bounds, the route corridor, and road edges. If both candidates contain geometric risk, an aggressive policy can still only slow or wait. If the left side is feasible but deviates far from the route, that deviation becomes a soft cost. If the right side is rejected by a hard boundary, it does not enter final ranking.
When the vehicle ahead starts moving again, the local result should not remain active. The movement task evaluates how long the obstacle has been clear, gradually clears the separation target, and reconnects following or route direction. If the vehicle remains stopped and the queue continues to grow, the route layer may receive a blocked report and reassess the route.
Case Three: A Player Vehicle Has a Near Miss but Remains Player-Controlled
The player drives through a junction at high speed. Another AI vehicle briefly approaches the expanded boundary of the player vehicle without actual contact. The player-information path can record the time, object, and statistics for the near miss, and can trigger an ability, voice cue, or warning. The AI vehicle’s local-avoidance task may consume the player vehicle as a scan candidate and decide whether to slow or sound its horn.
The two directions must remain separate: AI vehicle avoidance belongs to the autonomous command chain; the player’s near miss belongs to the player-information path. The player still owns the current primary command submission, and recording a near miss must not automatically switch the player vehicle to an AI control source.
This case also shows why risk-state ownership must be tracked separately. A near-miss record may be consumed by statistics without owning the vehicle task. A horn flag may be read by an AI vehicle without creating a new route. A highway-state flag may affect audio or traffic response without entering player-input interpretation.
The Common Structure

The candidate source, policy input, control source, and downstream consumer differ, but local avoidance still owns short-term spatial handling.

XXII. Time Windows, Deduplication, and Late Results
Local avoidance is not necessarily a synchronous one-shot call. Scanning, prediction, task update, and physics feedback may occur at different times. Continuous behavior requires explicit validity for each result.
Validity of Scan Results
An object that was a candidate in the previous cycle may no longer occupy the same position. For fast objects, an old scan can become stale quickly; for slow or stationary objects, it may be reusable briefly. Validity should depend on relative speed, scan distance, and task phase.
Deduplicating One Conflict
The same object may trigger prediction over several cycles. Treating every cycle as a new event inflates diagnostics and repeatedly resets separation state. The runtime can deduplicate by entity identity, time window, conflict phase, and previous result, while still allowing geometry to update as the object moves.
Late Local Results
If a solve reads an obstacle at the beginning of a cycle but the vehicle changes lane, the task is canceled, or the object disappears before the result returns, the old result must not overwrite current task state. In a target runtime, the result should carry the target direction, task phase, or valid version from the calculation context.
This is the same class of problem as P5’s asynchronous route request, only at a shorter timescale: the route request prevents an old search from replacing a new route; local avoidance prevents an old geometric result from replacing a new target. Both separate what the result is from the context to which it belongs.
Why All Temporary State Should Not Share One Cache
Scan-cache validity, collision-prediction validity, separation-vector validity, and route-target validity differ. Putting them into one “current avoidance state” makes cleanup prone to two errors: clearing too early removes the vehicle’s goal, while clearing too late lets an expired obstacle continue to influence the vehicle. Separate source, version, validity period, and cleanup condition are safer.
XXIII. Failure Design: Letting Local Avoidance Become the Whole Driving System
Local avoidance can become a place where every “cannot pass” case receives another patch. These designs may avoid one obstacle in a short demonstration while breaking runtime boundaries.
Failure One: Every Obstacle Starts a Full Route Search
This upgrades a short-lived dynamic object into a global navigation event, causing asynchronous request bursts and route oscillation. Try waiting, braking, or local offset inside the local corridor first. Notify the route layer only when the blockage persists or the road structure is invalid.
Failure Two: The Local Layer Writes Steering and Pedal Controls Directly
This may produce visible avoidance quickly, but it bypasses P3’s command contract, P6’s soft preferences, and P8’s vehicle-specific executor. When the vehicle changes to a boat, motorcycle, or aircraft, the local layer must understand every control law and becomes an unmaintainable master controller.
Failure Three: Treating Every Nearby Entity as an Obstacle
Characters inside vehicles, entities at another height, attached objects, and irrelevant decoration will continuously trigger avoidance. Qualification must combine entity relation, path service, task state, and navigation capability rather than cutting a list only by distance.
Failure Four: One “Avoiding” Field Covers Every Phase
Waiting, lateral detour, candidate failure, route blockage, and recovery have different cleanup conditions. One Boolean cannot express whether a temporary direction remains valid or whether the next step is retry, reconnection, or route escalation.
Failure Five: Feeding Player-Risk Observation into the AI Control Source
A red-light violation, near miss, or wrong-way event can feed statistics, warnings, and traffic response. It must not automatically replace the player’s command source. Observer records and controller arbitration remain separate.
The common failure is compressing states with different timescales and owners into one local module. The closer local avoidance gets to a “universal driver,” the harder it becomes to explain why it changed vehicle behavior at a particular phase.
XXIV. Validation Must Test More Than “Did the Vehicle Crash?”
A P7 validation matrix should cover at least these dimensions.
Obstacle Types
Test pedestrians, vehicles, dynamic objects, navigation edges, and special risks such as fire controlled by capability flags. Confirm that filters do not reduce every type to one circular obstacle.
Relative Motion
Hold the route constant while changing lateral speed, same-direction speed, and stationary state. Check that collision time, candidate generation, and waiting differ reasonably.
Route Boundaries
Place feasible space, curbs, and non-traversable areas on both sides. Confirm that scoring never restores a direction already rejected by a hard boundary.
Policy Preference
Hold geometry constant and change only P6 waiting cost and lateral preference. Confirm that policy changes ranking among feasible candidates but does not authorize a geometrically colliding candidate.
Speed and Refresh Period
Compare low speed, high speed, and near-stop states. Confirm that look-ahead, scan frequency, and emergency thresholds retain their meaning as speed changes.
Result Recovery
Create, maintain, and remove an obstacle, then observe reconnection to the original route. Cancel the task or change the target during the offset and check that temporary avoidance state is cleared.
Player-Path Isolation
Create near-miss and collision contexts while the player holds input. Verify that risk records, warnings, and statistics update while the player control source remains unchanged.
Diagnostics should record at least:
- current route version;
- current local target;
- candidate obstacle type and filter reason;
- predicted collision time and approach speed;
- left and right candidates and rejection reasons;
- soft preference supplied by P6;
- vector or waiting state delivered to the task;
- whether the P8 executor accepted it;
- creation and cleanup time of temporary state.
This makes “the vehicle crashed” diagnosable: the object was not scanned, was filtered incorrectly, prediction was wrong, a candidate was selected incorrectly, the task did not consume the result, the executor rejected it, or physics feedback invalidated it.
Validation should also include counterexamples rather than only successful detours: make both sides infeasible and check for waiting or blocked reporting; remove the obstacle while solving and check that a late result is discarded; change the task target during a local offset and check that the old route direction is cleared; switch vehicle type or control source and check that the local result still enters the correct command contract. Interruptions, cancellation, and recovery are what prove that local avoidance is a lifecycle runtime rather than a turn formula that works only in a demonstration scene.
XXV. Final Boundary Between P7, P5, P6, and P8
The four articles can be summarized as:

P7 does not:
- create the destination or global route;
- maintain driving personality or a long-term risk record;
- generate final throttle, brake, and steering values;
- explain tire, buoyancy, rotor, or fixed-wing control;
- handle network authority, replay, or distant-entity lifecycle.
P7 owns a short-lived, recoverable, observable spatial relation: what the current obstacle is, when conflict may occur, which directions remain feasible, whether to wait or offset, and how to return the result to the existing task.
XXVI. Migration to a Target Runtime: Preserve the Seams Before Choosing the Algorithm
Rebuilding local avoidance in a target engine should not begin with “write an obstacle-avoidance function.” Fix the boundaries first:
- The movement task decides call timing and validity;
- A scan service supplies candidates rather than having the avoidance layer traverse the world;
- A geometry-query layer supplies circle, box, and navigation-edge tests;
- A scoring layer returns local direction, risk feedback, and result state;
- The task converts the result into a local target and clears it when complete;
- The vehicle-specific executor decides whether the intent can be realized;
- The route layer receives persistent blockage and decides whether to replan.
This order allows a pure, observable calculation module to exist before real scanning and executors are connected. The prototype may not initially contain the complete vehicle physics, but it must answer which obstacles were input, why a candidate was rejected, why the left side was selected, and when the temporary direction was released.
If avoidance is written directly into the vehicle controller first, geometry failure, task-consumption failure, and physical-execution failure become difficult to separate. Fix the seam first; the algorithm can then be replaced without moving ownership.
XXVII. AI Collaboration Review: Turn “Local Evasion” into Verifiable Relations
Local-avoidance material is easy to compress into the phrase “automatic obstacle avoidance,” but that phrase neither explains the source structure nor guides migration. In this article, AI helps align geometry, task, and player-risk material into a reviewable chain:
- Who owns the nearby-entity list?
- Which objects qualify as current obstacles?
- Which approximations apply to circles, boxes, and navigation edges?
- How do collision time and approach speed enter scoring?
- Who generates and limits left and right candidates?
- Which task stores and consumes the local result?
- When is failure only waiting, and when does it escalate to route replanning?
- Why does a player near-miss record not equal AI control authority?
The human still decides which relations are directly shown by code, which are abstractions from call relationships, and which require validation in the target prototype. AI’s value is not to package local avoidance as a universal module. It is to preserve the inputs, consumer, and expiry condition of each short-lived result.
Local avoidance does not choose a new vehicle destination. While the goal remains valid, it provides a recoverable next step for the current spatial conflict.
XXVIII. Conclusion: How a Vehicle Handles the Immediate World While Keeping Its Destination
Open-world obstacles do not appear according to a route-request schedule. A pedestrian crosses suddenly, the vehicle ahead stops, a dynamic object enters the road, or a navigation edge blocks the offset that initially looked available. With only a global route, the vehicle stops at the conflict. With only local avoidance, it loses the destination and task relation.
A stable vehicle runtime connects both layers. The route retains direction over a longer period, strategy describes how different drivers prefer to trade off options, and local avoidance collects candidates, predicts conflict, generates a direction, and delivers the result to the current task within a shorter time window. When the conflict ends, temporary state is released and the original goal remains valid. When the conflict exceeds local capability, blocked evidence returns to the route layer.
P5 explains how the vehicle continues to know where it should go. P6 explains why the same route produces different driving choices. P7 explains what remains possible when the current space changes. P8 will continue with the next question: once a local task has produced a direction, speed, or waiting intent, how does a vehicle-specific executor convert it into real control values across the physics seam?