Back to Blog
·Summer Team

How to Make AI in Godot 4: A Step-by-Step Guide (2026)

A practical guide to building AI in Godot 4, from enemy state machines and pathfinding to LLM-driven NPCs, with copy-paste GDScript and a faster AI-assisted path.

Ask "how to make AI in Godot" and you will get two completely different answers depending on what you meant, because the same phrase covers two unrelated jobs.

One is classic game AI: the goblin that spots you, chases you around a pillar, and swings when it gets close. This is decision logic plus movement, and it has been the bread and butter of game development for decades.

The other is language-model AI: the shopkeeper you can actually talk to in your own words, who answers in character. This is new, it sends text to a model over the internet, and it solves a different problem.

Most games need the first kind for almost everything and reach for the second only for a handful of talking characters. This guide covers both, in order, with GDScript you can paste into Godot 4. At the end it shows how an AI-native engine writes this code for you and tests it by running the game, which is the part tutorials usually skip.

Part 1: Classic Game AI (the kind you need most)

When a designer says an enemy "has good AI," they almost never mean it runs a neural network. They mean it makes sensible decisions: it notices the player, picks a reasonable action, and changes its mind when the situation changes. In code, that is a state machine.

A state machine is a list of states (idle, patrol, chase, attack) and the rules for moving between them. It is the single most useful pattern in game AI, and Godot 4 has everything you need to build one.

Step 1: Set up the enemy scene

Create a new scene with a CharacterBody2D as the root (use CharacterBody3D for 3D, the logic is identical). Add these children:

  • A Sprite2D or AnimatedSprite2D so you can see it
  • A CollisionShape2D so it has a body
  • An Area2D with its own CollisionShape2D, sized larger than the enemy, to act as a detection radius
  • A NavigationAgent2D so the enemy can route around walls

The detection Area2D is how the enemy "sees." When the player enters it, the enemy knows to react.

Step 2: Write the state machine

Attach this script to the root. It defines four states and switches between them based on distance to the player.

extends CharacterBody2D

enum State { IDLE, PATROL, CHASE, ATTACK }

@export var move_speed: float = 120.0
@export var attack_range: float = 40.0

var state: State = State.IDLE
var player: Node2D = null

@onready var nav: NavigationAgent2D = $NavigationAgent2D

func _physics_process(_delta: float) -> void:
	match state:
		State.IDLE:
			velocity = Vector2.ZERO
			if player != null:
				state = State.CHASE
		State.CHASE:
			_chase()
		State.ATTACK:
			velocity = Vector2.ZERO
			_attack()
	move_and_slide()

func _chase() -> void:
	if player == null:
		state = State.IDLE
		return
	var distance := global_position.distance_to(player.global_position)
	if distance <= attack_range:
		state = State.ATTACK
		return
	nav.target_position = player.global_position
	var next_point := nav.get_next_path_position()
	velocity = global_position.direction_to(next_point) * move_speed

func _attack() -> void:
	# play attack animation, deal damage, then return to chase
	if player != null and global_position.distance_to(player.global_position) > attack_range:
		state = State.CHASE

# connect these from the detection Area2D in the editor
func _on_detection_area_body_entered(body: Node2D) -> void:
	if body.is_in_group("player"):
		player = body

func _on_detection_area_body_exited(body: Node2D) -> void:
	if body.is_in_group("player"):
		player = null
		state = State.IDLE

Two things make this work. The match statement on state keeps each behavior isolated, so adding a new state later does not tangle the others. And the Area2D body-entered and body-exited signals (connected from the editor's Node tab) flip the enemy between aware and unaware without polling every frame.

Put your player in the player group (select it, Node tab, Groups, add "player") so the detection check finds it.

Step 3: Add pathfinding so the enemy walks around walls

The script above uses NavigationAgent2D, but the agent needs a map of where the floor is. Add a NavigationRegion2D to your level scene and give it a NavigationPolygon that covers the walkable ground, with holes cut out for walls. Godot routes the agent through it automatically.

The key idea: your AI script decides the destination (nav.target_position = player.global_position), and the navigation system decides the route. You never write pathfinding math yourself. get_next_path_position() hands you the next waypoint, and you move toward it.

In 3D, the flow is the same with NavigationRegion3D and NavigationAgent3D. You bake a navigation mesh over the level geometry instead of drawing a polygon, but the script pattern does not change.

Step 4: Add line of sight (optional but worth it)

A detection radius alone means the enemy sees through walls. To fix that, add a RayCast2D and check whether the ray to the player hits anything before committing to a chase.

func can_see_player() -> bool:
	if player == null:
		return false
	$RayCast2D.target_position = to_local(player.global_position)
	$RayCast2D.force_raycast_update()
	if $RayCast2D.is_colliding():
		return $RayCast2D.get_collider() == player
	return true

Gate your IDLE -> CHASE transition on can_see_player() and the enemy now needs an actual sightline, which feels far more fair and intelligent to the player.

That is a complete, shippable enemy AI: it detects, chases around obstacles, respects walls for sight, and attacks in range. Patrol routes, fleeing at low health, and group tactics are all just more states and more transitions on the same skeleton.

Part 2: LLM-Driven AI (talking NPCs)

The second meaning of "AI in Godot" is an NPC you can converse with freely. This is a different mechanism entirely. Instead of a state machine, you send text to a language model and turn the reply into dialogue.

Godot 4 has no built-in model, but it has HTTPRequest, which is all you need to call one.

Step 1: Send a message to a model

Add an HTTPRequest node and a script that posts the player's message plus a short character description to a model API.

extends Node

@onready var http: HTTPRequest = $HTTPRequest

const ENDPOINT := "https://api.example-model.com/v1/chat"
const API_KEY := "your-key-here" # keep this out of shipped builds

func ask_npc(player_message: String) -> void:
	var headers := [
		"Content-Type: application/json",
		"Authorization: Bearer " + API_KEY,
	]
	var body := {
		"system": "You are Bram, a tired village blacksmith. Stay in character. Keep replies under two sentences.",
		"message": player_message,
	}
	http.request(ENDPOINT, headers, HTTPClient.METHOD_POST, JSON.stringify(body))

func _ready() -> void:
	http.request_completed.connect(_on_response)

func _on_response(_result, _code, _headers, response_body: PackedByteArray) -> void:
	var data = JSON.parse_string(response_body.get_string_from_utf8())
	var reply: String = data.get("reply", "...")
	show_dialogue(reply)

func show_dialogue(text: String) -> void:
	# push text into your dialogue UI
	print(text)

Step 2: Give the NPC memory

A model with no memory restarts every conversation. To make the blacksmith remember you, keep a running list of past exchanges and include a short summary in each request. Store it on the NPC, append each turn, and when it gets long, ask the model to summarize the old turns into a sentence or two so the prompt does not grow without bound.

Step 3: Know the tradeoffs before you commit

LLM dialogue is powerful but it is not free. Every message costs money, takes a moment to come back over the network, and needs an internet connection, which means it cannot run offline. It can also drift off-topic or out of character if your instructions are loose.

This is why the realistic pattern is hybrid: classic AI for behavior on every NPC, and LLM dialogue reserved for a few characters where open conversation is the point. If you want the full version of this, including personality prompts, memory systems, and keeping characters grounded in game state, we wrote a dedicated walkthrough on building AI NPCs with memory and personality in Godot 4. The AI NPC generator is the fastest way to scaffold one.

The faster path: let an AI-native engine write it

Everything above is the manual route, and it is worth understanding because it teaches you the patterns. But writing, wiring, and debugging a state machine by hand is slow, and the bugs only show up when you run the game.

This is where an AI-native engine changes the work. Summer Engine is compatible with Godot 4 and builds the AI assistant into the editor itself, so it does not just suggest code in a side panel. It reads your scene tree, writes the GDScript, wires up the NavigationAgent and detection Area2D, runs the game, reads the runtime errors, and fixes them. You describe the behavior in plain language:

Make the skeleton patrol between two points, chase the player when it sees them, and attack when close. Use navigation so it goes around walls.

It produces the same state machine you saw above, attached to a real enemy scene, then presses play to confirm the skeleton actually chases instead of walking into a wall. That write, play, read loop is the difference between an AI that hands you a code snippet and one that delivers working behavior, because most AI bugs in a game are runtime bugs a chat window never sees.

The honest version: the free tier covers building, testing, and exporting, which is enough to learn the patterns and ship a first AI-driven prototype. Paid plans add more usage and stronger models for daily work. If you want to compare the options for AI in a Godot workflow, the Godot AI page lays them out, and the template library gives you starting projects with enemies already wired so you are editing behavior instead of building it from zero.

Where to start

If you are learning, build Part 1 by hand. A state machine and a NavigationAgent will carry you through nearly every enemy, companion, and creature you will ever need, and the pattern scales from a single goblin to a full combat encounter.

Reach for Part 2 only when open conversation is genuinely the point of a character, and keep it to a few NPCs so cost and latency stay sane.

And when you want to move faster than typing each state by hand, describe the behavior and let the engine build and test it for you. The patterns in this guide are exactly what it writes, so understanding them makes you better at directing it, whichever route you take.

Frequently asked questions

How do you make an enemy AI in Godot 4?

Build a state machine. Create an enemy scene with a CharacterBody2D or CharacterBody3D and a NavigationAgent node, then write a script with an enum of states like IDLE, PATROL, CHASE, and ATTACK. Each frame, check conditions (is the player in range, is the player visible) and switch states, then run the behavior for the current state. Use the NavigationAgent's get_next_path_position to move toward the player so the enemy walks around walls instead of into them. This guide includes a working chase-and-attack script you can paste.

Does Godot have built-in AI?

Godot 4 has the building blocks for classic game AI, not a finished AI brain. It ships NavigationServer with NavigationAgent2D and NavigationAgent3D for pathfinding, NavigationRegion nodes for walkable areas, raycasts for line of sight, and Area nodes for detection zones. It does not ship a state machine or behavior tree for decision-making, so you write that yourself in GDScript or add a plugin. For language-model AI, Godot has HTTPRequest to call an external model, but no built-in model. An AI-native engine compatible with Godot 4 like Summer Engine can write all of this decision logic for you.

How do I add pathfinding to a Godot game?

In 3D, add a NavigationRegion3D and bake a navigation mesh over your level so Godot knows where the floor is. Add a NavigationAgent3D to the character that needs to move. In script, call set_target_position with where you want to go, then each physics frame read get_next_path_position and move toward it. The 2D flow is identical with NavigationRegion2D and NavigationAgent2D. The agent handles routing around obstacles, so your AI script only decides the destination, not the route.

Can I make an AI NPC in Godot that talks like ChatGPT?

Yes. Send the player's message plus a short system prompt that describes the character to a language model using Godot's HTTPRequest node, then show the reply as dialogue. Keep a running summary of past interactions so the NPC remembers context, and constrain the model with clear instructions so it stays in character and does not break the game's tone. The tradeoffs are latency, cost per message, and the need for an internet connection, which is why most games use LLM dialogue for a few key characters rather than every NPC.

Do I need to be good at coding to make AI in Godot?

For classic behavior, you need comfortable GDScript: enums, match statements, and the physics process loop. It is learnable in a weekend if you follow a guide. For LLM NPCs you also need to handle HTTP requests and JSON. If coding is the blocker, an AI-native engine compatible with Godot 4 like Summer Engine lets you describe the behavior in plain language and writes the state machine and navigation code for you, then runs the game to check it works. You still benefit from understanding the patterns so you can direct it well.

Is Summer Engine free for building AI behavior?

Summer Engine has a free tier that covers building, testing, and exporting a game, including writing AI behavior code like state machines and navigation. Paid plans add more usage, faster responses, and stronger models, which matters once you are working on a project daily. For learning the patterns and shipping a first AI-driven prototype, the free tier is enough.