• 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 Can't stop character movement

W

Wild_West

Guest
I'm going through my project and trying to make sure my character can't be allowed to move whenever certain things are going on like item menu being shown, or speaking to NPC characters, and for some reason it's only working half the time.

For example when I speak to ONE NPC I can't move until I'm done talking to them, like I want. But for the others it doesn't work.

I set character_parent.can_move to false in the NPC's code once a conversation starts.

Code:
if( start_conversation )
{
   world_inventory_manager.visible = false;
   character_parent.can_move = false;
}
else{ character_parent.can_move = true; }
Then the next instance is with my inventory. I have a variable I turn on and off for displaying the character's current list of actions in battle and another showing my inventory, both of these conditions should stop my movement but only the inventory's does.

Code:
 if( show_actions ){ can_move = false; }
I've tried moving these to the end step event but nothing changes. Why is this happening?
 

chamaeleon

Member
I'm going through my project and trying to make sure my character can't be allowed to move whenever certain things are going on like item menu being shown, or speaking to NPC characters, and for some reason it's only working half the time.

For example when I speak to ONE NPC I can't move until I'm done talking to them, like I want. But for the others it doesn't work.

I set character_parent.can_move to false in the NPC's code once a conversation starts.

Code:
if( start_conversation )
{
   world_inventory_manager.visible = false;
   character_parent.can_move = false;
}
else{ character_parent.can_move = true; }
Then the next instance is with my inventory. I have a variable I turn on and off for displaying the character's current list of actions in battle and another showing my inventory, both of these conditions should stop my movement but only the inventory's does.

Code:
 if( show_actions ){ can_move = false; }
I've tried moving these to the end step event but nothing changes. Why is this happening?
Probably too little code to easily say what is going wrong, but in a case like this, perhaps just sprinkle in some show_debug_message() calls just before setting can_move anywhere, plus just before if statements that check it to see whether the expected setting and testing takes place?
 
W

Wild_West

Guest
Probably too little code to easily say what is going wrong, but in a case like this, perhaps just sprinkle in some show_debug_message() calls just before setting can_move anywhere, plus just before if statements that check it to see whether the expected setting and testing takes place?
Why would I need that when I can physically see that my character is still able to move? I don't have much more going on than what's shown.
The only places I make can_move true again is after whatever sets it to false is no longer true.
 
W

Wild_West

Guest
Probably too little code to easily say what is going wrong, but in a case like this, perhaps just sprinkle in some show_debug_message() calls just before setting can_move anywhere, plus just before if statements that check it to see whether the expected setting and testing takes place?
well I displayed the variables in the debugger and they're getting set right like I assumed. So there's still no explanation for this
 

chamaeleon

Member
Why would I need that when I can physically see that my character is still able to move? I don't have much more going on than what's shown.
The only places I make can_move true again is after whatever sets it to false is no longer true.
*shrug* I don't really care what you do. If you have code logic that depends on the state of a flag it just seems obvious to me to have a track record of all relevant things going on so I can analyze it in conjunction with the code rather than imagining the state in my head. What I see on the screen is irrelevant when it comes to debugging. I prefer to have the computer tell me exactly what the state is at the points I desire it.
 

chamaeleon

Member
well I displayed the variables in the debugger and they're getting set right like I assumed. So there's still no explanation for this
Well, not a single line of code shown relates to movement. So either you have Schrodingers variables that are both true and false at the same time, or you're not setting them right, or the logic to respond to them is not right..
 
W

Wild_West

Guest
*shrug* I don't really care what you do. If you have code logic that depends on the state of a flag it just seems obvious to me to have a track record of all relevant things going on so I can analyze it in conjunction with the code rather than imagining the state in my head. What I see on the screen is irrelevant when it comes to debugging. I prefer to have the computer tell me exactly what the state is at the points I desire it.
and I did that, all it says is the variables are set to true of false exactly when they should be. so how does that help me?
 
W

Wild_West

Guest
Well, not a single line of code shown relates to movement. So either you have Schrodingers variables that are both true and false at the same time, or you're not setting them right, or the logic to respond to them is not right..
I mean what do you want the whole of every script that has these lines in it ? I figured THAT would be more waste of time. If I thought I was omitting something vital I'd have included it.
 

chamaeleon

Member
I mean what do you want the whole of every script that has these lines in it ? I figured THAT would be more waste of time. If I thought I was omitting something vital I'd have included it.
I'm just pointing out that there's nothing in the lines shown that has anything to do with x and y.. Presumably movement involves changing those. If they change, and the change is guarded by your various boolean variables, clearly the boolean must not have the right value, or you're performing movement without the proper test of the boolean somewhere. If you move when you shouldn't, either the boolean is wrong at some point or you're not respecting its value by omitting a test or test incorrectly.
 
W

Wild_West

Guest
I'm just pointing out that there's nothing in the lines shown that has anything to do with x and y.. Presumably movement involves changing those. If they change, and the change is guarded by your various boolean variables, clearly the boolean must not have the right value, or you're performing movement without the proper test of the boolean somewhere. If you move when you shouldn't, either the boolean is wrong at some point or you're not respecting its value by omitting a test or test incorrectly.
I'm telling you I checked this stuff 3 ways from sunday, it's not like I ran into the problem and instantly came here. Everything works the way it should save for this ONE instance where I speak to the second NPC character. Not the first one, just the second. And it does not make any sense.
 

chamaeleon

Member
I'm telling you I checked this stuff 3 ways from sunday, it's not like I ran into the problem and instantly came here. Everything works the way it should save for this ONE instance where I speak to the second NPC character. Not the first one, just the second. And it does not make any sense.
Since you use the word "parent" in variable names, any missing event_inherited()?
 
W

Wild_West

Guest
I'm just pointing out that there's nothing in the lines shown that has anything to do with x and y.. Presumably movement involves changing those. If they change, and the change is guarded by your various boolean variables, clearly the boolean must not have the right value, or you're performing movement without the proper test of the boolean somewhere. If you move when you shouldn't, either the boolean is wrong at some point or you're not respecting its value by omitting a test or test incorrectly.
Since you use the word "parent" in variable names, any missing event_inherited()?
No the parent doesn't even do anything with movement it's just to group party characters together for specific events.

If you really need to see then fine but I'm telling ya there's nothing here that's complex

Code:
if not( gamepad_is_connected(0) )
{
   if( can_move )and( world_party_manager.current_leader == id )
   {       
       if( keyboard_check(vk_right) or ( keyboard_check( ord("D") ) ) )
       {
         if( place_free(x+10, y) )
         { x += 10; }
       }       
       
       if( keyboard_check(vk_left) or ( keyboard_check( ord("A") ) ) )
       {
         if( place_free(x-10, y) )
         { x -= 10; }
       }       
   
       if not( place_free(x,y+1) )and( keyboard_check_pressed(vk_space) )
       { vspeed = -60; }
   }
}
else
{
   /*Controller settings*/
}
if( world_party_manager.current_leader == id ){ exit; }
else
{
   if( instance_exists(world_party_manager.current_leader) )
   {
      if( world_party_manager.current_leader.x > x + 200 )
      { x += 10; }
       
      if( world_party_manager.current_leader.x < x - 200 )
      { x -= 10; }
   }
}
That's literally all there is for movement anything else I have just turns it on and off when I'm viewing inventory actions or speaking to other characters.
 

chamaeleon

Member
That's literally all there is for movement anything else I have just turns it on and off when I'm viewing inventory actions or speaking to other characters.
Are you saying that x and y are in fact modified in the block protected by the can_move variables and not the bottom part, and that can_move is false when it is inside that block?
 

chamaeleon

Member
Are you saying that x and y are in fact modified in the block protected by the can_move variables and not the bottom part, and that can_move is false when it is inside that block?
Oh, one thing.. You use vspeed.. It would modify y without running your code, if it has a value other than 0..
 
Last edited:
W

Wild_West

Guest
Are you saying that x and y are in fact modified in the block protected by the can_move variables and not the bottom part, and that can_move is false when it is inside that block?
The bottom part only applies if the character in question is a party member not in the lead position. so they follow the lead character it doesn't apply to if my character is alone. and once again, the code I'm trying to get right works for one npc not with 2 so there's something going wrong that doesn't fit as far as just trying to apply it to a second npc object. That's all that I can't work out nothing else is wrong.
 

chamaeleon

Member
The bottom part only applies if the character in question is a party member not in the lead position. so they follow the lead character it doesn't apply to if my character is alone. and once again, the code I'm trying to get right works for one npc not with 2 so there's something going wrong that doesn't fit as far as just trying to apply it to a second npc object. That's all that I can't work out nothing else is wrong.
When can_move is supposed to have a specific value, true or false, does character_parent represent the proper instance that can_move refers to as an instance variable in the movement code?
 

samspade

Member
No the parent doesn't even do anything with movement it's just to group party characters together for specific events.

If you really need to see then fine but I'm telling ya there's nothing here that's complex

Code:
if not( gamepad_is_connected(0) )
{
   if( can_move )and( world_party_manager.current_leader == id )
   {      
       if( keyboard_check(vk_right) or ( keyboard_check( ord("D") ) ) )
       {
         if( place_free(x+10, y) )
         { x += 10; }
       }      
      
       if( keyboard_check(vk_left) or ( keyboard_check( ord("A") ) ) )
       {
         if( place_free(x-10, y) )
         { x -= 10; }
       }      
  
       if not( place_free(x,y+1) )and( keyboard_check_pressed(vk_space) )
       { vspeed = -60; }
   }
}
else
{
   /*Controller settings*/
}
if( world_party_manager.current_leader == id ){ exit; }
else
{
   if( instance_exists(world_party_manager.current_leader) )
   {
      if( world_party_manager.current_leader.x > x + 200 )
      { x += 10; }
      
      if( world_party_manager.current_leader.x < x - 200 )
      { x -= 10; }
   }
}
That's literally all there is for movement anything else I have just turns it on and off when I'm viewing inventory actions or speaking to other characters.
It's been a long time since I've used them, but I'm nearly positive that vspeed, hspeed, and speed all work automatically. In other words, if any are not zero, you will move assuming nothing stops you. You're only setting speed here, but these variables are also tied to direction. So if you use direction anywhere you could be transferring movement to hspeed.

A second possible problem is I see an if (can_move) for the keyboard checks, but I don't see that for the controller. And I also see it for the final if block which also affects x. This appears to be automatic movement though. So probably isn't the problem.

This is also a great problem for the debugger to solve. Or copious show_debug_messages.
 
W

Wild_West

Guest
It's been a long time since I've used them, but I'm nearly positive that vspeed, hspeed, and speed all work automatically. In other words, if any are not zero, you will move assuming nothing stops you. You're only setting speed here, but these variables are also tied to direction. So if you use direction anywhere you could be transferring movement to hspeed.

A second possible problem is I see an if (can_move) for the keyboard checks, but I don't see that for the controller. And I also see it for the final if block which also affects x. This appears to be automatic movement though. So probably isn't the problem.

This is also a great problem for the debugger to solve. Or copious show_debug_messages.
well there's no hspeed or direction anywhere. I don't know how many more times I can say it works in one case but not the second. If it works at all it should be working for the second npc stopping me moving but it doesn't.
 

chamaeleon

Member
well there's no hspeed or direction anywhere. I don't know how many more times I can say it works in one case but not the second. If it works at all it should be working for the second npc stopping me moving but it doesn't.
"Should work" has been said many times about code.. Just visually observing behavior is quite often not a substitute for actual debugging, as annoying as that may be. Why are you so reluctant to actually adding show_debug_messag() to create a trace of what the state of the important variables are?
 

samspade

Member
well there's no hspeed or direction anywhere. I don't know how many more times I can say it works in one case but not the second. If it works at all it should be working for the second npc stopping me moving but it doesn't.
I agree. Given that you aren't working with esoteric functions or doing anything at all unusual, the chance that you have a bug is virtually non-existent. That means that there is something wrong with your code. Which is we are asking you to show your code and suggesting possible (not guaranteed) issues and that you use the debugger and report what happens either that you found the solution or what you did that failed to find a solution.
 

TheouAegis

Member
Sorry, I'm going to skip over this wall of posts. lol

Code:
if( start_conversation )
{
   world_inventory_manager.visible = false;
   character_parent.can_move = false;
}
else{ character_parent.can_move = true; }
Where is that called from? Just the End Step event of the NPC objects? While there is no issue with what's inside the brackets, the issue I have is that else. Depending on where the code is, it's going to set character_parent.can_move to true ALL THE TIME unless there are other conditions at work preventing any of this code from even running. If NPC 1 is in the room and NPC 2 is in the room and this code is in the Step Event or similarly repeated open event, then NPC 1 will set can_move to true after NPC 2 tried setting it to false.

Remove the else part (and its related code) and set can_move to true when the dialogue gets closed.
 
W

Wild_West

Guest
I agree. Given that you aren't working with esoteric functions or doing anything at all unusual, the chance that you have a bug is virtually non-existent. That means that there is something wrong with your code. Which is we are asking you to show your code and suggesting possible (not guaranteed) issues and that you use the debugger and report what happens either that you found the solution or what you did that failed to find a solution.
well I messed around with pretty much every instance of me setting can move to true and false, I drew the variables to the screen even with different text to see when it changed and everything is fine with the npcs variables but they aren't changing the player's.
even the PLAYER itself isn't changing them.

I click to open the actions list and I can still move, I go to talk to npc 2 I can still move I open my inventory and I can't move I talk to npc 1 and I can't move.
then I try to change screens with the actions list open and I can't move. I've tried changing the step events the code is in to end, begin normal.
Like none of it is making sense for what's going on.

One weird thing is that when I remove the else part of this
Code:
if( start_conversation )
{
   world_inventory_manager.visible = false;
   character_parent.can_move = false;
}
else{ character_parent.can_move = true; }
then I can't move period, even if I haven't spoken to an npc yet. also makes no sense since none of their variables are set to true until I talk to them which like I said, I already drew to the screen to see.

So here this is literally every bit where I do anything with can_move true / false

Code:
//In player end step event
if not( instance_exists(world_battle_manager) )and not( world_inventory_manager.visible )
{
    if( keyboard_check_released( ord("Q") ))
    {
       if not( show_actions )
       { show_actions = true; }
       else{ show_actions = false; }
    }
}
if( show_actions ){ can_move = false; }

Code:
//In NPC end step event
someone_to_talk_to = collision_line(x-100, y-sprite_height/2, x+100, y-sprite_height/2, character_parent, false, true);
if( someone_to_talk_to != noone )
{ able_to_talk = true; }
else
{ able_to_talk = false; }
if ( place_meeting(x, y, character_parent) )
{ able_to_talk = false; }
//Moving the emote bubble
direction += 10;
emote_position_y += lengthdir_y( 10, bbox_top + direction);
if( able_to_talk )
{
   if( keyboard_check_released( vk_enter ) )
   {
      start_conversation = true;
      current_conversation_point += 1;
      if( current_conversation_point > 4 )and not( can_recruit )
      {
          start_conversation = false;
          current_conversation_point = 0;
      }
      if( current_conversation_point > 5 )and( can_recruit )
      {
         world_party_manager.character_2 = id;
         start_conversation = false;
         current_conversation_point = 0;
      }
   }
}
  
//Decline new party member recruit
if( keyboard_check_released( vk_backspace ) )
{
   start_conversation = false;
   current_conversation_point = 0;
}
//Change into the new character Object
if( world_party_manager.character_2 == id)
{ instance_change( character_gemma_obj, true ); }
if( start_conversation )
{
   world_inventory_manager.visible = false;
   character_parent.can_move = false;
}
else{ character_parent.can_move = true; }

Code:
if( visible ){ character_parent.can_move = false; }

if( visible )and( inventory_area_x1 == view_xview[0]+view_wview[0]-380 )
{
    /*a bunch of code for scrolling through the inventory*/
}
else
{
   if( instance_exists(world_battle_manager) )and not(world_battle_manager.battle_is_active)
   { character_parent.can_move = true; }
}
That's it
 
W

Wild_West

Guest
"Should work" has been said many times about code.. Just visually observing behavior is quite often not a substitute for actual debugging, as annoying as that may be. Why are you so reluctant to actually adding show_debug_messag() to create a trace of what the state of the important variables are?
It's not reluctance I did it already I even said it didn't show anything useful.
 

chamaeleon

Member
It's not reluctance I did it already I even said it didn't show anything useful.
How can it not, unless you are missing a critical location for such a message (not counting any use of implicit movement based on speed, vspeed, hspeed, direction or physics based movement)? Again, if the movement is made in a block protected by a flag, the flag must be true. A show_debug_message() issue that block is necessary, and anywhere x or y is modified. Every setting of the flag, without exception, should have a show_debug_message(). A good prefix to uniquely identify each source code location is necessary. Can you show a trace of this and it still indicates movement without the flag allowing it? And please remember to ensure all relevant instance ids are included in the output in case a mismatch involving that is possible.

You don't have to do this or course, but as for me I'm not going to guess blindly about root causes.
 
Here's the problem:

Code:
if( start_conversation )
{
   world_inventory_manager.visible = false;
   character_parent.can_move = false;
}
else{ character_parent.can_move = true; }
This piece of code is run by every NPC instance in each step. If one of the NPCs start_conversation is set to false, it sets character_parent.can_move to true. Player movement is pretty much a question of the NPCs instance order at the moment.
 
Last edited:

samspade

Member
Well, I'm not sure I have the answer but I do have a couple more suggestions. The code is helpful. Before my specific suggestions though, here are some general ones (just in case the specific one is wrong).
  • It sounds like you're drawing variables to debug. While this is a good idea in some cases, here I would say not a good idea. As drawn variables only show the state at draw time and here you want to know what it is during one specific code block. I would be using the debugger or show debug itself here and stepping through the code.
  • You should comment out all of your movement code without changing anything else and see if it is possible to still move. This is unlikely to be very helpful but it would (in most cases) confirm that that movement code needs to run, and therefore is running.
  • In a similar vein, I would put a show debug message in all movement code to determine if it is running, I've included some standard debug messages I have as scripts below.
  • Logically, only one of a few things can be true. 1) You have other code that moves your player than the code you showed us. 2) can_move is true despite you setting it to false for that moment.
  • I assume that all the can_move code you posted you found with a control + shift + f search (or whatever it is in GMS 1) and you weren't relying on your memory. Also, in GMS 1 I don't know if the search pulls up room code (code done in the room editor) if you have any of that or have any assets which might have done that, you should search for that code as well.

Here are my specific suggestions. Your player end step code seems wrong. Specifically it says:

if( show_actions ){ can_move = false; }

Which means that if show_actions is EVER true can_move is false and nothing switches it back. Taken with the likely incorrect else statement TheoAegis pointed out and that might be the entire answer including as to why it only sometimes happens. If show actions is set to true, can move is false. But nothing sets it back to true. Except that incorrect else statement running every step. So one mistake corrected the other. The reason some NPCs are fine and some are not is that assuming this code is in the NPC step event, which I think you said it was, then the order the step events are run makes a difference. If the NPCs step event is run before the players, then can_move is true for the player's step event and set to false in the end event (so it would draw to the screen as false). If the NPC ran after the player then the players end step event would flip can move to false.

My guess is removing the else statement as suggested and adding an else statement here would fix the problem, but I don't actually know the rest of your code well enough to be sure.

I don't remember how macros work for GMS 1 so you'd have to convert that portion if you want to use the macro element. Otherwise, you could call the script directly. But in GMS 2 the macro element makes it shorter to type and gives it the macro color which is nice.

Code:
///scr_here
#macro HERE scr_here()
show_debug_message("HERE");

///scr_here
#macro A scr_a()
show_debug_message("A");

....repeat as many times as you like
 

chamaeleon

Member
Here's the problem:

Code:
if( start_conversation )
{
   world_inventory_manager.visible = false;
   character_parent.can_move = false;
}
else{ character_parent.can_move = true; }
This piece of code is run by every NPC instance in each step. If one of the NPCs start_conversation is set to false, it sets character_parent.can_move to true. Player movement is pretty much a question of the NPCs instance order at the moment.
I very much agree with this assessment, and just want to add that having show_debug_message() in there should show the switching of the value back and forth as different npcs execute their step event.
 

TheouAegis

Member
Supposedly you showed all the places where you set can_move. ...But where is the create event where you set it to true by default to begin with? You need to set it to true somewhere by default and that default setting needs to be not in an NPC.
 
Top