Game Dev 3 Smooth Run - need help understanding objects

This isn’t a normal request for level help. I followed the prompts and finished the level already. (It was well-written and clear, thanks Creators!)

However, I really want to understand the concepts underneath it, and feel like I’m missing something.

In particular, the prompted code creates a bunch of fences. It then assigns an arbitrary number to each under the variable “fence#.dir” to define its direction of travel. Then, it goes on to show us how to tell a fireball-spewer how to move and change direction, where there is only one spewer.

Repeating the directions almost exactly, we are invited to use the same code to direct the movement of fences.

Here is the confusing bit: there are many fences, and the code I used never appeared to differentiate which fence should use which direction parameter (or argument? or property? I am confused on that too.) Full code at bottom, but relevant snippets shown here:

# Fences will be our "enemies" here.
fence1 = game.spawnXY("fence", 10, 10)
# This property will define the moving direction: 1 is up, -1 is down.
fence1.dir = 1
fence2 = game.spawnXY("fence", 22, 56)
fence2.dir = -1
fence3 = game.spawnXY("fence", 34, 22)
fence3.dir = 1
# redacted (and more fences, etc.)

# This fire-spewer will move along the top, spewing fire.
spewer = game.spawnXY("fire-spewer", 70, 62)
#redacted for length
# This property will define the moving direction: 1 is right, -1 is left.
spewer.dir = -1

#redacted for length

# This function moves the spewer.
def onUpdateSpewer(event):
    spewer = event.target
    # Multiply the spewer speed by the moving direction.
    dist = spewerSpeed * spewer.dir
#redacted
        # Then it's time to change the moving direction.
        spewer.dir *= -1

game.setActionFor("fire-spewer", "update", onUpdateSpewer)

# This function moves the fences.
def onUpdateFence(event):
    fence = event.target
    # Multiply fenceSpeed and fence.dir to calculate the moving distance and direction.
    # Assign the result to the variable 'dist':
    dist = fenceSpeed * fence.dir
    # Add the value of the 'dist' variable to fence.pos.y:
 #redacted
        fence.dir *=-1
        pass

#redacted

Note that “spewer.dir” is defined as -1 at the beginning. Yet there is no “fence.dir”. There is “fence1.dir”, “fence2.dir”, etc. (There is also no “fence” variable in the top list, but “fence” is defined within “onUpdateFence”, so I think that one makes sense.)

But how does the program know that I want to call “fence3.dir” in the function when the event target happens to be “fence3”? Surely the order of the list of variables at the beginning is not relevant, right? There is a “spewer.direction” and ALSO a “spewer.dir”. Does that make the latter one arbitrary? Could “spewer.dir” have been called “spewer.lollipop” and still worked?

In other words, would some wonderful programmer-type please explain how to set individual instructions for an object in a group of objects, so they remain linked without explicitly describing them as such in the functions? What are the limits of this? (Are they defined by the game engine, are they infinite in variety and scope?)

Thank you!
DNC


# Animate static objects.

player = game.spawnPlayerXY("captain", 4, 34)
player.maxSpeed = 15

# Fences will be our "enemies" here.
fence1 = game.spawnXY("fence", 10, 10)
# This property will define the moving direction: 1 is up, -1 is down.
fence1.dir = 1
fence2 = game.spawnXY("fence", 22, 56)
fence2.dir = -1
fence3 = game.spawnXY("fence", 34, 22)
fence3.dir = 1
fence4 = game.spawnXY("fence", 46, 44)
fence4.dir = -1
fence5 = game.spawnXY("fence", 58, 34)
fence5.dir = 1
fence6 = game.spawnXY("fence", 70, 34)
fence6.dir = -1

# This fire-spewer will move along the top, spewing fire.
spewer = game.spawnXY("fire-spewer", 70, 62)
spewer.direction = "vertical"
spewer.spamInterval = 9000
spewer.spamEvery = 1
spewer.scale = 2
# This property will define the moving direction: 1 is right, -1 is left.
spewer.dir = -1

# The speed of the fences and the spewer: meters per frame. Remember there are 30 frames per second.
fenceSpeed = 0.4
spewerSpeed = 0.5

# This function moves the spewer.
def onUpdateSpewer(event):
    spewer = event.target
    # Multiply the spewer speed by the moving direction.
    dist = spewerSpeed * spewer.dir
    # Add the result to x coordinate.
    spewer.pos.x += dist
    # If the spewer is out of the range (10, 70).
    if spewer.pos.x > 70 or spewer.pos.x < 10:
        # Then it's time to change the moving direction.
        spewer.dir *= -1

game.setActionFor("fire-spewer", "update", onUpdateSpewer)


# This function moves the fences.
def onUpdateFence(event):
    fence = event.target
    # Multiply fenceSpeed and fence.dir to calculate the moving distance and direction.
    # Assign the result to the variable 'dist':
    dist = fenceSpeed * fence.dir
    # Add the value of the 'dist' variable to fence.pos.y:
    fence.pos.y += dist
    # If the fence's y position is less than 10 or greater than 56:
    if fence.pos.y > 56 or fence.pos.y < 10:
        # Multiply fence.dir by -1 and save it:
        fence.dir *=-1
        pass

game.setActionFor("fence", "update", onUpdateFence)

# This function tracks player collisions.
def onCollide(event):
    unit = event.target
    collided = event.other
    if collided.type == "fence" or collided.type == "fire-spewer":
        unit.defeat()

player.on("collide", onCollide)

game.addSurviveGoal()
game.addMoveGoalXY(77, 34)