• 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!

Help with control actions and "other"

R

Ray

Guest
I have the following problem:

I am trying to create a simple "lights off" clone without scripting. But the control actions don't properly fill in the other variable it seems.

I am trying to replace a neighboring object instance.

I have tried: "Check Collision" and "Check Object" without success.

In the debugger the action is called "action_if_collision"

I tried Solid, not solid vs. other, self in all combinations
I am using: v1.4.1757 r41000

Here is a debugger screenshot: http://i.imgur.com/oH5eTVy.png

Please tell me what I am doing wrong...
 
A

Aura

Guest
You can create a "lights off" game pretty easily using GML as explained here:

https://www.yoyogames.com/blog/386

Either way, if you want to continue using D&D, please post all the relevant information, what exactly you're trying to do and what it actually does. To do that, you can use the Show Information button in the object properties and copy-paste everything here. It would make it easier for us to help you.
 
R

Ray

Guest
First, thanks for your response!

Yes I saw that tutorial, but it is far from easy.
Yes I can copy and paste tons of code, but I would not understand a thing and would need to learn a ton of ds_grid functions.

I think it should be possible to create a simple game like Lights Off without the need of GML.

The question is not can I use GML, the question is why is the other keyword variable not filled in correctly after the use of action_if_collision ?
 
A

Aura

Guest
Either way, if you want to continue using D&D, please post all the relevant information, what exactly you're trying to do and what it actually does. To do that, you can use the Show Information button in the object properties and copy-paste everything here. It would make it easier for us to help you.
 
R

Ray

Guest
Information about object: o_wall
Sprite: wall
Solid: true
Visible: true
Depth: 0
Persistent: false
Parent:
Children:
Mask:
No Physics Object
Mouse Event for Left Pressed:
if relative position (-64,0) gives a collision with All objects
for other object: change the instance into object o_clown, not performing events
if at relative position (-64,0) there is object o_wall
for other object: change the instance into object o_clown, not performing events

( And no, the actions do not cancel each other out, I tested both ways alone and stepped through the debugger )

And here is my room:
https://i.imgur.com/Jc2y2ky.png
 

FrostyCat

Redemption Seeker
Stop believing that collision checking functions give other a meaning, only with blocks and actual collision events give other a meaning.

What you need to do is to find the colliding instance ID and then apply the action to it. If you are checking a specific point, that would be either instance_position() or collision_point(). Drag-and-drop doesn't support applying actions to instance IDs, so the only recourse is GML.
Code:
var other_wall = instance_position(x-64, y, o_wall);
if (other_wall != noone) {
  with (other_wall) instance_change(o_clown, false);
}
 
R

Ray

Guest
Thanks for the response.

However it is hard to stop believing that since the documentation gave me that impression and searching the web and docs using index and keyword showed no results for action_if_collision.

In fact, based on my observations in the debugger I started a new wiki page for action_if_collision here: http://gamemaker.wikia.com/wiki/Action_if_collision yesterday since it was missing.

And now I will update it, sadly, saying that the function does not properly set the other keyword variable, which would make a lot of sense if it did...
 

FrostyCat

Redemption Seeker
However it is hard to stop believing that since the documentation gave me that impression and searching the web and docs using index and keyword showed no results for action_if_collision.

In fact, based on my observations in the debugger I started a new wiki page for action_if_collision here: http://gamemaker.wikia.com/wiki/Action_if_collision yesterday since it was missing.

And now I will update it, sadly, saying that the function does not properly set the other keyword variable, which would make a lot of sense if it did...
The Manual said no such thing, stop believing that nonsense.
The Manual's entry for other said:
The special keyword other has two different ways that it can be used to reference a specific instance: when used in a with function (explained here) or when used in acollision event, which is what this section is going to explain.
It specifically said "collision event" with a link to what it meant by that. Nothing here says other should be set by collision checking functions or actions such as "check collision". You are putting words into the Manual's mouth.

While you should say that it doesn't set other, you have no business adding the "properly" to it. It was never built that way, nor was it ever meant to be.
 
R

Ray

Guest
Why do you defend something that is obviously flawed ?
Why on earth wouldn't the function set the other variable ?
It is completely counter intuitive.
Especially since every DnD action has an option to select other.
Why can you select other if it is "never" filled.

(Well I do not hope it is never... )
 

jo-thijs

Member
I was writing the below response, but when I double checked what I was saying,
it appears the latest update of GM:S changed behaviour of self and other to no longer be constants,
but to directly hold the id of the instances they refer to and to hold 0 if no instance is applicable instead.
This isn't documented anywhere though (as far as I found), so I'm guessing this is just a bug and can get fixed in later updates,
so I'll leave my response I wrote below:

How is it flawed?
Perhaps you just don't understand how it works?
"other" isn't a variable, it's a keyword and it behaves exactly like a constant with value -2.
Whenever you write other.varName, it gets replaced by -2.varName and this is left to the executing instance to interprete.
How it will interprete this, is by looking if the code it's executing is called by a with structure.
If so, it will look for the variable in the instance that called the with structure.
Otherwise, it will look for the variable in itself.
The reason you can use other in collision events is because you can treat collision events to be internally called through with structures in GameMaker:
Code:
// Collision event of obj1 with obj2
// This happens inbetween the step and end step events
// It is a simplified version though, as e.g. solid behaviour isn't taken into account
with obj2
    if place_meeting(x, y, other)
        with other
            event_perform(ev_collision, obj2);
Now that that's explained, it would actually be counter intuitive if functions (and scripts) could set the value for "other".
This means that every time you execute a function, you can expect "other" to be something different and not necessarilly useful.
For example, someone creating a script could use collision functions and forget that they change the value of "other", leaving the value of "other" on something undefined,
which can cause various bugs that are hard to find.
Meanwhile, those functions could have just returned their result (what you think "other" should contain) and left the GameMaker user with more control and cleaner code.
This is the way GameMaker does its collision functions and it is the way it should be done.

Now, as to why every DnD action has an option to select "other", it's meant to use in collision events
to e.g. destroy the colliding instance or to subtract hp from it (letting both instances do this themselves can cause synchronisation issues, as the destroying might happen first and dealing damage might never happen).

Other does get "filled" when using "with structures" or collision events.

And on a final note, making other not be a constant would actually take away functionality,
as you can now do everything it could do otherwise by using (other.id).varName
and you can do more by saving special references in datastructures for example.

The only unfortunate thing, is that you can't stack multiple "other"s like this: other.other.varName.

Now, I also just realized, the reason you're thinking other should behave differently, is because you're only using DnD.
The use of "other" is indeed pretty limited there.
However, if you're coding in GML, it makes a lot more sense.
So, I'd suggest you simply try out coding instead of DnD and you'll probably see what we're all talking about.

And on a final note, you shouldn't be using or documenting the action_* functions.
They're not meant to be used, they just exist because DnD gets converted to them.
Those functions aren't documented and have better equivalents in GML.
 
Last edited:
R

Ray

Guest
I appreciate your response. I have no problem with scripting in general,
but it is kinda frustrating to get so far with DnD and then suddenly miss that single little feature with the other variable being set
to be able to complete the game.

Related question: would I be able to write a DnD Gamemaker extension action which would behave like action_if_collision but would set other ?
 

jo-thijs

Member
No, but you can very easilly do it in code.
This part:
Code:
action_set_relative( 1 );
#...
var __b__;
__b__ = action_if_collision( -64, 0, 1 );
if __b__
{
{
with( other )
{
action_change_object( o_clown, 0 );
}
}
}
would become:
Code:
with all
    if place_meeting(x + 64, y, other)
        instance_change(o_clown, false);
Though, I have to say that's quite a wierd code to execute.
You should never use functions that check for "collision with any object".
 
Top