# Runner Step 3: Enemies

**URL:** <https://discourse.codecombat.com/t/runner-step-3-enemies/35579>\
**Category:** Level Help\
**Created:** [May 9, 2023, 9:36pm UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579 "2023-05-09T21:36:32Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![K\_P](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/k_p/32/34278_2.png) [@K\_P](https://discourse.codecombat.com/u/K_P)\
**Post date:** [May 9, 2023, 9:36pm UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579/1 "2023-05-09T21:36:32Z")

</div>

I’m having an error on line 100  
If anyone fix it that would be great

```python
# Step 3 of the Run and Dodge game tutorial.

# ENVIRONMENT
game.spawnXY("forest", -4, 64)
game.spawnXY("forest", 4, 64)
game.spawnXY("forest", 12, 64)
game.spawnXY("forest", 20, 64)
game.spawnXY("forest", 28, 64)
game.spawnXY("forest", 36, 64)
game.spawnXY("forest", 44, 64)
game.spawnXY("forest", 52, 64)
game.spawnXY("forest", 60, 64)
game.spawnXY("forest", 68, 64)
game.spawnXY("forest", 76, 64)
game.spawnXY("forest", -4, 4)
game.spawnXY("forest", 4, 4)
game.spawnXY("forest", 12, 4)
game.spawnXY("forest", 20, 4)
game.spawnXY("forest", 28, 4)
game.spawnXY("forest", 36, 4)
game.spawnXY("forest", 44, 4)
game.spawnXY("forest", 52, 4)
game.spawnXY("forest", 60, 4)
game.spawnXY("forest", 68, 4)
game.spawnXY("forest", 76, 4)

def onUpdateStatic(event):
    thing = event.target
    thing.pos.x -= 0.6
    if thing.pos.x < -4:
        if thing.type == "forest":
            thing.pos.x = 84
        else:
            thing.destroy()

game.setActionFor("forest", "update", onUpdateStatic)

def spawnRandomY(type):
    y = game.randomInteger(12, 56)
    spawn = game.spawnXY(type, 80, y)
    spawn.on("update", onUpdateStatic)

def spawnFences():
    spawnNumber = 1 + (game.time / 10)
    while spawnNumber >= 1:
        spawnRandomY("fence")
        spawnNumber -= 1

# GAME SETTINGS
game.spawnFenceTime = 0
game.spawnGemTime = 0.5
# One more spawn timer, for ogres.
game.spawnOgreTime = 1
game.score = 0
game.topScore = db.get("topScore") or 0
ui.track(game, "time")
ui.track(game, "score")
ui.track(game, "topScore")
goal = game.addManualGoal("Survive at least 20 seconds.")

# PLAYER
player = game.spawnPlayerXY("captain", 20, 34)
player.maxSpeed = 20

def onCollect(event):
    item = event.other
    if item.type == "gem":
        game.score += 5

def onCollide(event):
    unit = event.target
    other = event.other
    if other.type == "fence":
        unit.defeat()

def onDefeatPlayer():
    if game.time > 20:
        game.setGoalState(goal, True)
    else:
        game.setGoalState(goal, False)
    setTopScore()

player.on("collect", onCollect)
player.on("collide", onCollide)
player.on("defeat", onDefeatPlayer)

# ENEMIES
# This handles defeated ogres.
def onDefeatOgre(event):
    unit = event.target
    game.score += 10
    # Defeated ogres should move to the left, just like other environmental objects.
    unit.on("update", onUpdateStatic)

# This updates the positions of the ogres so they slowly catch up to the player.
def onUpdateOgre(event):
    unit = event.target
    # Only update position for un-defeated ogres, who have positive health.
    if unit.health > 0:
        # Set the unit closer to the player. We use the baseX property to track this, because the default ogre behavior might also change it's pos.x property, so we can't use that directly.
        unit.baseX += 0.1
        # If unit.baseX greater than 18:
        if unit.baseX > 18:
            # Set unit.baseX to 18:
            unit.baseX = 18
        # Set unit.pos.x to unit.baseX:
        unit.pos.x = unit.baseX

def spawnOgre():
    y = game.randomInteger(12, 56)
    unit = game.spawnXY("scout", 0, y)
    unit.baseX = 0
    # Assign onUpdateOgre to handle the "update" event on unit:
    onUpdateOgre("unit")
    # Assign onDefeatOgre to handle the "defeat" event on unit:
    unit.on("update", onUpdateOgre)
    unit.on("defeat", onDefeatOgre)
    unit.behavior = "AttacksNearest"

# GAME LOOP
def checkPlayer():
    if game.time == 20:
        player.say("Win! Bonus time!")
    player.pos.x = 20

def setTopScore():
    topScore = db.get("topScore") or 0
    if game.score > game.topScore:
        db.set("topScore", game.score)

def checkSpawns():
    if game.time > game.spawnFenceTime:
        spawnFences()
        game.spawnFenceTime += 1
    if game.time > game.spawnGemTime:
        spawnRandomY("gem")
        game.spawnGemTime += 1
    if game.time > game.spawnOgreTime:
        spawnOgre()
        game.spawnOgreTime += 2

def onUpdateGame(event):
    checkPlayer()
    checkSpawns()
    game.score += event.deltaTime

game.on("update", onUpdateGame)

```

---

<div class="post-metadata">

**Author:** ![K\_P](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/k_p/32/34278_2.png) [@K\_P](https://discourse.codecombat.com/u/K_P)\
**Post date:** [May 9, 2023, 9:36pm UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579/2 "2023-05-09T21:36:57Z")

</div>

Its the line that says if unit.health \> 0

---

<div class="post-metadata">

**Author:** ![JustALuke](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/justaluke/32/43608_2.png) [@JustALuke](https://discourse.codecombat.com/u/JustALuke)\
**Post date:** [May 9, 2023, 9:41pm UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579/3 "2023-05-09T21:41:55Z")

</div>

> [@K\_P](#):
>
> `onUpdateOgre("unit")`

You are sending the string “unit” as a argument instead of the unit itself. It should work if you remove the double quotes.

---

<div class="post-metadata">

**Author:** ![K\_P](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/k_p/32/34278_2.png) [@K\_P](https://discourse.codecombat.com/u/K_P)\
**Post date:** [May 10, 2023, 11:28am UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579/4 "2023-05-10T11:28:24Z")

</div>

I removed them but my code still has an error on line 100. It says it cannot read the property “health” of null.

---

<div class="post-metadata">

**Author:** ![MarmiteOnToast](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/marmiteontoast/32/46649_2.png) [@MarmiteOnToast](https://discourse.codecombat.com/u/MarmiteOnToast)\
**Post date:** [May 10, 2023, 12:31pm UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579/5 "2023-05-10T12:31:11Z")

</div>

Hi @K_P,

I think I found the issue in your code  
What if `event` has no target?

Add a check around the `if unit.health > 0:` loop to see whether or not `unit`/`event.target` exists.

---

<div class="post-metadata">

**Author:** ![K\_P](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/k_p/32/34278_2.png) [@K\_P](https://discourse.codecombat.com/u/K_P)\
**Post date:** [May 12, 2023, 2:16pm UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579/6 "2023-05-12T14:16:33Z")

</div>

Thank you!  
What do you mean by adding a check around that code? If you could clarify that would really help.

---

<div class="post-metadata">

**Author:** ![MarmiteOnToast](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.codecombat.com/marmiteontoast/32/46649_2.png) [@MarmiteOnToast](https://discourse.codecombat.com/u/MarmiteOnToast)\
**Post date:** [May 12, 2023, 2:30pm UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579/7 "2023-05-12T14:30:14Z")

</div>

Ok, so, you want to check whether or not `unit` exists  
To do this, you need an `if` loop.

Like in the first few “islands” where you use  
`if enemy:`  
To see whether or not there’s an enemy, here, you want to use `if unit:` so that you’re not trying to get a value from a non-existent target :)

> **TLDR**
>
> Put everything after `unit = event.target` (in the onUpdateOgre function) into an `if unit:` loop

---

<div class="post-metadata">

**Author:** ![TeacherPeter](https://avatars.discourse-cdn.com/v4/letter/t/7c8e57/32.png) [@TeacherPeter](https://discourse.codecombat.com/u/TeacherPeter)\
**Post date:** [May 16, 2023, 4:19pm UTC](https://discourse.codecombat.com/t/runner-step-3-enemies/35579/8 "2023-05-16T16:19:54Z")

</div>

Hi

There is actually a lot of errors in your code, so lets start, this is line 100

```python
if unit.health > 0:

```

The problems starts at the spawnOgre function, i have added an explanation of the error after the line with ←

```python
def spawnOgre():
    y = game.randomInteger(12, 56)
    unit = game.spawnXY("scout", 0, y)
    unit.baseX = 0
    # Assign onUpdateOgre to handle the "update" event on unit:
    onUpdateOgre("unit") <<- you need to replace this line with a setActionFor update event 
                                                         on unit. setActionFor can handle event.type that you are trying to 
                                                        use in the onUpdateOgre function
    # Assign onDefeatOgre to handle the "defeat" event on unit:
    unit.on("update", onUpdateOgre) << -- This line will fall away when you do the event two lines 
                                                                       above
    unit.on("defeat", onDefeatOgre) << -- use setActionFor again for unit
    unit.behavior = "AttacksNearest"

```

spawnOgre function should look like this

```python
def spawnOgre():
    y = game.randomInteger(12, 56)
    unit = game.spawnXY("scout", 0, y)
    unit.baseX = 0
    # Assign onUpdateOgre to handle the "update" event on unit:
    game.setActionFor(unit, "update", onUpdateOgre)
    # Assign onDefeatOgre to handle the "defeat" event on unit:
    game.setActionFor(unit, "defeat", onDefeatOgre)
    unit.behavior = "AttacksNearest"

```

You will notice that you can play the game now but the scouts does not get defeated when they collide with a fence.

You need to add an event handler for the scout when it collide with the fence to be defeated, one again you must use setActionFor.

You can add this after line 86 so the two lines will look like this

```python
player.on("defeat", onDefeatPlayer)
game.setActionFor("scout", "collide", onCollide)

```

Now when a scout collide with a fence it will be defeated

Full code:

```python
# Step 3 of the Run and Dodge game tutorial.

# ENVIRONMENT
game.spawnXY("forest", -4, 64)
game.spawnXY("forest", 4, 64)
game.spawnXY("forest", 12, 64)
game.spawnXY("forest", 20, 64)
game.spawnXY("forest", 28, 64)
game.spawnXY("forest", 36, 64)
game.spawnXY("forest", 44, 64)
game.spawnXY("forest", 52, 64)
game.spawnXY("forest", 60, 64)
game.spawnXY("forest", 68, 64)
game.spawnXY("forest", 76, 64)
game.spawnXY("forest", -4, 4)
game.spawnXY("forest", 4, 4)
game.spawnXY("forest", 12, 4)
game.spawnXY("forest", 20, 4)
game.spawnXY("forest", 28, 4)
game.spawnXY("forest", 36, 4)
game.spawnXY("forest", 44, 4)
game.spawnXY("forest", 52, 4)
game.spawnXY("forest", 60, 4)
game.spawnXY("forest", 68, 4)
game.spawnXY("forest", 76, 4)

def onUpdateStatic(event):
    thing = event.target
    thing.pos.x -= 0.6
    if thing.pos.x < -4:
        if thing.type == "forest":
            thing.pos.x = 84
        else:
            thing.destroy()

game.setActionFor("forest", "update", onUpdateStatic)

def spawnRandomY(type):
    y = game.randomInteger(12, 56)
    spawn = game.spawnXY(type, 80, y)
    spawn.on("update", onUpdateStatic)

def spawnFences():
    spawnNumber = 1 + (game.time / 10)
    while spawnNumber >= 1:
        spawnRandomY("fence")
        spawnNumber -= 1

# GAME SETTINGS
game.spawnFenceTime = 0
game.spawnGemTime = 0.5
# One more spawn timer, for ogres.
game.spawnOgreTime = 1
game.score = 0
game.topScore = db.get("topScore") or 0
ui.track(game, "time")
ui.track(game, "score")
ui.track(game, "topScore")
goal = game.addManualGoal("Survive at least 20 seconds.")

# PLAYER
player = game.spawnPlayerXY("captain", 20, 34)
player.maxSpeed = 20

def onCollect(event):
    item = event.other
    if item.type == "gem":
        game.score += 5

def onCollide(event):
    unit = event.target
    other = event.other
    if other.type == "fence":
        unit.defeat()

def onDefeatPlayer():
    if game.time > 20:
        game.setGoalState(goal, True)
    else:
        game.setGoalState(goal, False)
    setTopScore()

player.on("collect", onCollect)
player.on("collide", onCollide)
player.on("defeat", onDefeatPlayer)
game.setActionFor("scout", "collide", onCollide)

# ENEMIES
# This handles defeated ogres.
def onDefeatOgre(event):
    unit = event.target
    game.score += 10
    # Defeated ogres should move to the left, just like other environmental object.
    unit.on("update", onUpdateStatic)

# This updates the positions of the ogres so they slowly catch up to the player.
def onUpdateOgre(event):
    unit = event.target
    # Only update position for un-defeated ogres, who have positive health.
    if unit.health > 0:
        # Set the unit closer to the player. We use the baseX property to track this, because the default ogre behavior might also change it's pos.x property, so we can't use that directly.
        unit.baseX += 0.1
        # If unit.baseX greater than 18:
        if unit.baseX > 18:
            # Set unit.baseX to 18:
            unit.baseX = 18
        # Set unit.pos.x to unit.baseX:
        unit.pos.x = unit.baseX

def spawnOgre():
    y = game.randomInteger(12, 56)
    unit = game.spawnXY("scout", 0, y)
    unit.baseX = 0
    # Assign onUpdateOgre to handle the "update" event on unit:
    game.setActionFor(unit, "update", onUpdateOgre)
    # Assign onDefeatOgre to handle the "defeat" event on unit:
    game.setActionFor(unit, "defeat", onDefeatOgre)
    unit.behavior = "AttacksNearest"

# GAME LOOP
def checkPlayer():
    if game.time == 20:
        player.say("Win! Bonus time!")
    player.pos.x = 20

def setTopScore():
    topScore = db.get("topScore") or 0
    if game.score > game.topScore:
        db.set("topScore", game.score)

def checkSpawns():
    if game.time > game.spawnFenceTime:
        spawnFences()
        game.spawnFenceTime += 1
    if game.time > game.spawnGemTime:
        spawnRandomY("gem")
        game.spawnGemTime += 1
    if game.time > game.spawnOgreTime:
        spawnOgre()
        game.spawnOgreTime += 2

def onUpdateGame(event):
    checkPlayer()
    checkSpawns()
    game.score += event.deltaTime

game.on("update", onUpdateGame)

```
