• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM [SOLVED] RTS resource mining/multiple instances of same object

A

AtomicToilet

Guest
Hola!

My question is: what's the best way to handle this?

At the moment, an obj_worker unit depletes an obj_resources' 'resource' variable, and the obj_resource is destroyed once resource = 0. But, because I used other.resource (in the obj_worker collision event with obj_resource) this then causes all the other obj_resource instances to disappear as soon as the worker goes to another one to mine it.

Here's the collision code I'm using at the moment:
Code:
with (other)
{
rock_resources -= .1
}

if other.rock_resources <= 0
{
state = "mined";
}
I wondered if somehow calling an instance id would be the best way to do this, so that only that specific instance's resource variable is affected? Or maybe an array...? Regards the latter, I understand these can be used to store multiple variables but I'm not entirely clear how I would call only the relevant one for each individual obj_resource instance.
 
Last edited by a moderator:

Simon Gust

Member
Hola!
But, because I used other.resource (in the obj_worker collision event with obj_resource) this then causes all the other obj_resource instances to disappear as soon as the worker goes to another one to mine it.
What do you mean with that?

The code looks ok apart from the worker getting his state to "mined" when the resource is depleted. Is that intentional?

Using other should be fine and the resources shouldn't act like that.
 
A

AtomicToilet

Guest
What do you mean with that?

The code looks ok apart from the worker getting his state to "mined" when the resource is depleted. Is that intentional?

Using other should be fine and the resources shouldn't act like that.
Yep, the state change is intentional as it then tells the worker to go the the base and store the resources :) the worker than (should) return to another resource but...

Here's a gif so you can see the behaviour - I can even send another worker to another resource at the same time and that's all gravy; it's just as soon as (any) worker object interacts with a second resource, it makes all of them vanish...
 

Attachments

Relic

Member
The code you have given is not responsible for this unwanted behaviour. Please show us all the code relevant to destroying the resources.
 
A

AtomicToilet

Guest
Sure! Here's the full code for obj_worker collision with obj_rock:
Code:
///Change to mined state

if (target != -1 && instance_exists(target) && target != obj_base && target != obj_rock)
{
    
    with (target) instance_destroy();
}

with (other)
{
rock_resources -= .1
}

if other.rock_resources <= 0
{
state = "mined";
}
in obj_rock:
Create event
Code:
rock_resources = 100;
Step event [maybe this is interfering...?
Code:
if rock_resources <= 0
{
instance_destroy();
}
The obj_worker has this is in the Step event, but I don't think any of this is mucking things up (let me know if you'd like to see any of the script codes)
Code:
///Control the worker states
event_inherited();
if state == "move"
{
scr_villager_move();
}

else if state == "idle"
{
scr_villager_idle();
}

else if state = "mine"
{
scr_villager_move();
target = obj_rock;
//selected = false;
}

else if state == "mined"
{
scr_villager_move();
target = obj_base;
}
 
Yes, the step event IS what is mucking this up. Specifically this line:
Code:
target = obj_rock;
You are targeting an object, not an instance. This is probably the most common rookie error and there are literally thousands of threads dealing with this problem. One fix could be:
Code:
target = instance_nearest(x,y,obj_rock);
That will replace the target being the generic obj_rock object (which will, as you have found out, mean that anything done to target after this point applies to every single obj_rock instance in the game) and instead set the target to the nearest instance of the the obj_rock object (which will only apply to the obj_rock instance that is closest to the miner). While this fix has a high likelihood of working, it all depends on how you've setup your game. But the more important fix is understanding the difference between an object and an instance. Search through the forums for a post by @FrostyCat called Objects vs Instances or something like that for a thorough explanation of what you are doing wrong.
 
A

AtomicToilet

Guest
Ah, nuts. I find most of my gamemaker problems are these 'can't see the wood for the trees' type situations; I understand that objects are the 'template' and instances are the 'copy', just in this case I completely failed to realise what I was doing with the targets. Cheers, RefresherTowel!

I tweaked all my obj_rock references into instance_nearest, and the rocks still vanished (once the workers collided with the base and were set back to state = "mine") - and then I realised it was this bit of code hidden in the default move script:

Code:
//delete target when we meet it then set unit to idle state
    if (position_meeting(x,y,target))
    {
    with (target) instance_destroy();
    state = 'idle';
    }
So I removed this (and replaced it with a simple collision event with obj_target = destroy obj_target) and now it all works great!
 
Top