Quick answer: Use the return value of instance_create_layer directly. instance_find uses an index into the object’s instance list, which doesn’t guarantee creation order.

A spawner creates an enemy and then tries to configure it via instance_find(obj_enemy, instance_number(obj_enemy) - 1). Returns noone — or returns the wrong instance entirely. Setting var e = instance_create_layer(...) and using e directly works first try.

instance_find Semantics

instance_find(obj, n) returns the n-th instance of obj in the active instance list. The order isn’t documented as creation order; it’s implementation-defined. Don’t use it to find “the most recently created” instance.

The Right Pattern

/// Spawn an enemy and configure it
var e = instance_create_layer(x, y, "Instances", obj_enemy);
e.hp = 100;
e.target = id;

The variable e holds the new instance’s ID. Subsequent property writes act on that specific instance regardless of what the instance list looks like.

For Looping

When you actually want to iterate every instance:

for (var i = 0; i < instance_number(obj_enemy); i++) {
    var inst = instance_find(obj_enemy, i);
    if (inst != noone) {
        inst.hp -= 5;
    }
}

Iterate from 0 to instance_number - 1. instance_find returns noone if the index is out of bounds. Check before dereferencing.

with-Statement for Bulk Actions

Often cleaner than loop + find:

with (obj_enemy) {
    hp -= 5;
}

Iterates all instances of obj_enemy and runs the block in each one’s scope. Faster than the loop in many cases and more readable.

Verifying

Print the new instance’s id immediately after create, and again via instance_find. They may differ if the instance list has reordered. Use the create return; rely on direct ID references.

“instance_create returns the ID. Use it. Searching for ‘the new one’ is fragile because list order isn’t creation order.”

Make it a habit: every instance_create_layer call assigns to a local var. The pattern guards against this entire class of bugs.