# Tips on making enemy ai

**URL:** <https://forum.makecode.com/t/tips-on-making-enemy-ai/45073>\
**Category:** Help\
**Created:** [July 25, 2026, 7:31pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073 "2026-07-25T19:31:09Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sword\_Studios](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/sword_studios/32/35216_2.png) [@Sword\_Studios](https://forum.makecode.com/u/Sword_Studios)\
**Post date:** [July 25, 2026, 7:31pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/1 "2026-07-25T19:31:09Z")

</div>

Any tips on how to do this would be highly appreciated.

---

<div class="post-metadata">

**Author:** ![CodaKnight](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/codaknight/32/33491_2.png) [@CodaKnight](https://forum.makecode.com/u/CodaKnight)\
**Post date:** [July 26, 2026, 6:32pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/2 "2026-07-26T18:32:46Z")

</div>

One thing that helped me a lot is thinking of enemy AI as a **state machine** instead of one giant update loop.

For example, each enemy can be in one of these states:

- **Idle** – stand still or wander around.
- **Search** – look for the player within a radius or line of sight.
- **Chase** – move toward the player.
- **Attack** – if close enough, perform an attack.
- **Stunned/Retreat** – optional states for more interesting behavior.

Then, every update, the enemy only asks two questions:

- “What state am I in?”
- “Should I switch to a different state?”

This keeps your AI much easier to expand later instead of having one giant `game.onUpdate()` full of `if` statements.

If you’re using JavaScript/TypeScript, an `enum` is a nice way to organize your states instead of using numbers or strings:

```typescript
enum EnemyState {
    Idle,
    Search,
    Chase,
    Attack,
    Stunned
}

```

Then each enemy can simply store its current state:

```typescript
let enemyState = EnemyState.Idle

```

Or, if you’re making multiple enemy types, I’d even recommend giving each enemy its own class (or interface + class) with an `enemyState` property. That way every enemy shares the same basic AI structure but can override how each state behaves. For example, a sniper and a melee enemy could both have `Idle`, `Search`, `Chase`, and `Attack` states, but each would implement them differently.

Starting with a state machine makes it much easier to add things like patrol routes, line-of-sight, boss phases, fleeing, or different enemy personalities later without rewriting all your AI.

Also, some extensions can help you such as:  
[https://github.com/jwunderl/arcade-tilemap-a-star](https://github.com/jwunderl/arcade-tilemap-a-star) : A\* algorithms for path following

[https://github.com/felixtsu/pxt-sight](https://github.com/felixtsu/pxt-sight) : To see if an enemy can see you.

Also the **Sprite Utils and Timer** extensions.

---

<div class="post-metadata">

**Author:** ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)\
**Post date:** [July 26, 2026, 6:34pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/3 "2026-07-26T18:34:45Z")

</div>

You make me want to continue trying. I would look into how unity it done other 3d engine does it, or really any engine. But I’m going to continue trying now.

---

<div class="post-metadata">

**Author:** ![coppercode](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/coppercode/32/26022_2.png) [@coppercode](https://forum.makecode.com/u/coppercode)\
**Post date:** [July 26, 2026, 6:51pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/4 "2026-07-26T18:51:54Z")

</div>

heres a tip if you think that your ai is dumb its not because of your code its because theres something you forgot to give the ai like memory sight and more good luck!

---

<div class="post-metadata">

**Author:** ![Vital](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/vital/32/33353_2.png) [@Vital](https://forum.makecode.com/u/Vital)\
**Post date:** [July 26, 2026, 6:54pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/5 "2026-07-26T18:54:35Z")

</div>

What type of enemy? Is this a top-down game or a platformer? Are there any key things that you want the enemy to do?

---

<div class="post-metadata">

**Author:** ![Sword\_Studios](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/sword_studios/32/35216_2.png) [@Sword\_Studios](https://forum.makecode.com/u/Sword_Studios)\
**Post date:** [July 26, 2026, 9:15pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/6 "2026-07-26T21:15:36Z")

</div>

since we don’t use JavaScript, would a function like this work?

 ![image](https://us1.discourse-cdn.com/flex020/uploads/makecode/original/3X/a/d/ad89e90d8511dae4f42bc200969fc9b1c7c41ff2.png)

---

<div class="post-metadata">

**Author:** ![Sword\_Studios](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/sword_studios/32/35216_2.png) [@Sword\_Studios](https://forum.makecode.com/u/Sword_Studios)\
**Post date:** [July 26, 2026, 9:16pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/7 "2026-07-26T21:16:02Z")

</div>

A dungeon style game, and the enemy should start following the player if they get close enough.

---

<div class="post-metadata">

**Author:** ![YamJam](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/yamjam/32/29681_2.png) [@YamJam](https://forum.makecode.com/u/YamJam)\
**Post date:** [July 27, 2026, 3:54am UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/8 "2026-07-27T03:54:25Z")

</div>

Is this the wrong topic?

---

<div class="post-metadata">

**Author:** ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)\
**Post date:** [July 27, 2026, 3:55am UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/9 "2026-07-27T03:55:06Z")

</div>

yes it works, but its less readable heres an extension i wipped up in an hour: [https://github.com/c-minusminus/enum-blocks](https://github.com/c-minusminus/enum-blocks)

---

<div class="post-metadata">

**Author:** ![CodaKnight](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/codaknight/32/33491_2.png) [@CodaKnight](https://forum.makecode.com/u/CodaKnight)\
**Post date:** [July 27, 2026, 3:57am UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/10 "2026-07-27T03:57:33Z")

</div>

Yep! That’ll work just fine in Blocks. Passing in a number like `enemyAI(1)`, `enemyAI(2)`, etc. is basically accomplishing the same thing as an enum—it lets your AI know which behavior to run. Just make sure you set the enemy ai type to whether in the if statements.

**Question: Are you planning on using the variable “EnemyAI” for multiple enemies or one? Because then you’ll need to change some things and use data (specifically helpful is the “sprite-data” extension).**

The only thing I’d watch out for is something called **magic numbers**. Those are numbers like `1`, `2`, and `3` where you have to remember what each one means. They work, but later on it can be hard to remember if `2` was “Chase” or “Attack.”

In JavaScript/TypeScript, people often use an enum instead:

```typescript
enum EnemyState {
    Idle,
    Search,
    Chase,
    Attack
}

```

Then instead of writing `enemyAI(2)`, you’d write:

```typescript
enemyAI(EnemyState.Chase)

```

It does the same thing, but it’s much easier to read and avoids accidentally passing the wrong number.

For Blocks, though, your approach is perfectly fine. If you ever move to JavaScript, enums are just a cleaner way to represent those numbers.

---

<div class="post-metadata">

**Author:** ![YamJam](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/yamjam/32/29681_2.png) [@YamJam](https://forum.makecode.com/u/YamJam)\
**Post date:** [July 27, 2026, 4:25pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/11 "2026-07-27T16:25:55Z")

</div>

Instead of using numbers, you could also simply use strings instead -\_-

---

<div class="post-metadata">

**Author:** ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)\
**Post date:** [July 28, 2026, 2:04am UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/13 "2026-07-28T02:04:11Z")

</div>

no, I one tried to make a 2D enemy following thing but gave up. Specifically I tried one for platformer, which means A\* won’t work.

---

<div class="post-metadata">

**Author:** ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)\
**Post date:** [July 28, 2026, 2:04am UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/14 "2026-07-28T02:04:16Z")

</div>

does that mean top-down? If so, use A\*. otherwise maybe look something up.

---

<div class="post-metadata">

**Author:** ![Sword\_Studios](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/sword_studios/32/35216_2.png) [@Sword\_Studios](https://forum.makecode.com/u/Sword_Studios)\
**Post date:** [July 28, 2026, 2:04am UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/15 "2026-07-28T02:04:31Z")

</div>

I’ve actually been wondering what the enum does for a while. Is it like an array or a function? Or something else?

---

<div class="post-metadata">

**Author:** ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)\
**Post date:** [July 28, 2026, 9:03pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/16 "2026-07-28T21:03:42Z")

</div>

so an enum is basically something so avoid magic numbers. got example, take this:

```typescript
const damage =
    baseDmg * (diff === 0 ? 1.0 : diff === 1 ? 1.4 : 3.5) +
    (zone === 5 ? 50 : zone === 12 ? 120 : 0);

```

what does that mean? I don’t know. What about this:

```typescript
enum Difficulty { EASY = 1.0, MEDIUM = 1.4, HARD = 3.5 }
enum HazardZone { SAFE = 0, SWAMP = 31, LAVA = 120 }

damage =
    baseDmg * (diff === 0 ? Difficulty.EASY : diff === 1 ? Difficulty.MEDIUM : Difficulty.HARD) +
    (zone === 0 ? HazardZone.SAFE : zone === 1 ? HazardZone.SWAMP : HazardZone.LAVA);

```

Oh, its to calculate the damage token in different areas and hardnesses!

Another benefit with this is that it is much easier to change the damage multipliers, now that there enums!

---

<div class="post-metadata">

**Author:** ![CodaKnight](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/codaknight/32/33491_2.png) [@CodaKnight](https://forum.makecode.com/u/CodaKnight)\
**Post date:** [July 28, 2026, 9:04pm UTC](https://forum.makecode.com/t/tips-on-making-enemy-ai/45073/17 "2026-07-28T21:04:01Z")

</div>

I kinda explained it already in my previous quote

> [@CodaKnight](#):
>
> If you’re using JavaScript/TypeScript, an `enum` is a nice way to organize your states instead of using numbers or strings:
> 
> ```typescript
> enum EnemyState {
> Idle,
> Search,
> Chase,
> Attack,
> Stunned
> }
> 
> ```
> 
> Then each enemy can simply store its current state:
> 
> ```typescript
> let enemyState = EnemyState.Idle
> 
> ```

But…here:

It’s something else. An **enum** (short for _enumeration_) is basically a way to give names to numbers.

For example, instead of remembering:

```typescript
0 = Idle
1 = Search
2 = Chase
3 = Attack

```

you can write:

```typescript
enum EnemyState {
    Idle,
    Search,
    Chase,
    Attack
}

```

Then instead of doing:

```typescript
enemyAI(2)

```

you can do:

```typescript
enemyAI(EnemyState.Chase)

```

Under the hood, `EnemyState.Chase` is still just the number `2`. The enum just gives it a meaningful name, which makes your code much easier to read and avoids “magic numbers” (numbers like `2` or `3` where you have to remember what they mean).
