{
	"article_slug": "why-is-my-path-failing-in-godot",
	"generated_utc": "2026-06-10T12:27:21",
	"godot_version": "4.6.2-stable (official)",
	"measurement_scope": "Local PathForge article verification for Godot 4.6.2 API claims and proof artifacts. Use as article evidence only after reviewing the generated JSON.",
	"os_name": "Windows",
	"processor_name": "AMD Ryzen 5 2600X Six-Core Processor",
	"results": [
		{
			"claim": "TileMapLayer.map_to_local(cell) returns the centered local position; global coordinates should pass through to_local() before local_to_map().",
			"evidence": {
				"cell": {
					"x": 3,
					"y": 2
				},
				"expected_center": {
					"x": 112.0,
					"y": 80.0
				},
				"local_center": {
					"x": 112.0,
					"y": 80.0
				},
				"round_trip_cell": {
					"x": 3,
					"y": 2
				},
				"tile_size": {
					"x": 32,
					"y": 32
				}
			},
			"name": "tilemaplayer_map_to_local_returns_cell_center",
			"passed": true
		},
		{
			"claim": "AStarGrid2D exposes native isometric cell shapes CELL_SHAPE_ISOMETRIC_RIGHT and CELL_SHAPE_ISOMETRIC_DOWN.",
			"evidence": {
				"down_constant": 2,
				"down_ok": true,
				"right_constant": 1,
				"right_ok": true
			},
			"name": "astargrid2d_isometric_cell_shapes_exist",
			"passed": true
		},
		{
			"claim": "A fresh NavigationServer2D map starts with iteration_id 0; guard path queries until the map has synchronized.",
			"evidence": {
				"map_iteration_id": 0
			},
			"name": "navigationserver_new_map_iteration_starts_at_zero",
			"passed": true
		},
		{
			"claim": "A solid target with allow_partial_path returns a closest reachable point and raw search is measurably slower than cheap preflight rejection in this workspace.",
			"evidence": {
				"cheap_validation_average_usec": 10.4445,
				"goal": {
					"x": 30,
					"y": 30
				},
				"grid_size": "32x32",
				"partial_last_cell": {
					"x": 30,
					"y": 29
				},
				"partial_path_size": 58,
				"raw_allow_partial_average_usec": 123.11
			},
			"name": "allow_partial_path_solid_goal_returns_partial_and_is_costly",
			"passed": true
		},
		{
			"claim": "AStarGrid2D.update() after a shape change clears point solidity and weight_scale data; obstacles and weights need a replay source of truth after shape updates.",
			"evidence": {
				"after_clean_update_without_shape_change": {
					"blocked_is_solid": true,
					"weighted_scale": 7.5
				},
				"after_update_with_shape_change": {
					"blocked_is_solid": false,
					"weighted_scale": 1.0
				},
				"before_update": {
					"blocked_is_solid": true,
					"weighted_scale": 7.5
				},
				"blocked_cell": {
					"x": 2,
					"y": 2
				},
				"dirty_after_shape_change": true,
				"weighted_cell": {
					"x": 3,
					"y": 2
				}
			},
			"name": "astargrid2d_update_clears_solid_and_weight_data",
			"passed": true
		},
		{
			"claim": "AStarGrid2D.diagonal_mode changes whether diagonal corner cutting is legal.",
			"evidence": {
				"always_path": [
					{
						"x": 0,
						"y": 0
					},
					{
						"x": 1,
						"y": 1
					}
				],
				"blocked_cells": [
					{
						"x": 1,
						"y": 0
					},
					{
						"x": 0,
						"y": 1
					}
				],
				"constants": {
					"ALWAYS": 0,
					"AT_LEAST_ONE_WALKABLE": 2,
					"NEVER": 1,
					"ONLY_IF_NO_OBSTACLES": 3
				},
				"only_if_no_obstacles_path": []
			},
			"name": "astargrid2d_diagonal_modes_control_corner_cutting",
			"passed": true
		},
		{
			"claim": "AStarGrid2D.jumping_enabled ignores weight_scale, so the route can cross a high-cost cell that weighted A* avoids.",
			"evidence": {
				"jumping_enabled_path": [
					{
						"x": 0,
						"y": 1
					},
					{
						"x": 4,
						"y": 1
					}
				],
				"jumping_path_crosses_weighted_cell": true,
				"normal_path_crosses_weighted_cell": false,
				"normal_weighted_path": [
					{
						"x": 0,
						"y": 1
					},
					{
						"x": 1,
						"y": 1
					},
					{
						"x": 1,
						"y": 0
					},
					{
						"x": 2,
						"y": 0
					},
					{
						"x": 3,
						"y": 0
					},
					{
						"x": 4,
						"y": 0
					},
					{
						"x": 4,
						"y": 1
					}
				],
				"weighted_cell": {
					"x": 2,
					"y": 1
				}
			},
			"name": "astargrid2d_jumping_enabled_ignores_weight_scale",
			"passed": true
		},
		{
			"claim": "Godot exposes navigation/2d/default_edge_connection_margin as the 2D edge merge distance setting.",
			"evidence": {
				"setting_path": "navigation/2d/default_edge_connection_margin",
				"value": 1.0
			},
			"name": "navigation2d_edge_connection_margin_project_setting_exists",
			"passed": true
		},
		{
			"claim": "NavigationAgent2D.radius and NavigationPolygon.agent_radius are separate knobs; public copy should avoid claiming bake shrink from this check alone.",
			"evidence": {
				"navigation_agent_radius": 64.0,
				"navigation_polygon_agent_radius": 64.0,
				"scope_note": "This verifies the separate properties. Corridor shrink should remain [verify] until a bake-specific scene proves the geometry change."
			},
			"name": "navigation_agent_and_polygon_radius_are_distinct_properties",
			"passed": true
		}
	]
}