GMS 2 Phantom Step Event or Script Trigger - help! [SOLVED]

P

Pandemicsnowman

Guest
Hello! It's pleasure to be a part of the GMC. I'm new to GMS2 but am familiar with game design and programming in general. I'm running into a strange problem I was hoping to get some help on from some of the GMS vets out there.

TL;DR
Basically the issue is there is a specific script that is running every tick (as if from a step event) that I can't for the life of me figure out what is triggering it. Please read on for the full details:

ISSUE:

I have an empty default room named rm_mapView with a single object instance placed in it. The object, called obj_dungeonController has no parents or inheritance. It is set to visible, but no other settings are set to it. It has only one event:

* Create - sets up some instance variables, and then executes a script called "scr_generateDungeonData" at the end.

The scr_generateDungeonData script is a 580 line script that generates a dungeon. It runs a secondary script at the end of it, called scr_setDungeonData which loops through and randomizes certain data elements.

When I run the game, this is what happens, in order.
  1. The Main Menu is loaded, awaiting user input
  2. I click the test button that runs room_goto(rm_mapView);
  3. The room rm_mapView is loaded.
  4. The Create Event of the Dungeon Controller is executed successfully.
  5. scr_generateDungeonData is executed, and then runs scr_setDungeonData on the last line.
  6. scr_setDungeonData is executed successfully.
  7. After the last line of code for the scr_setDungeonData, the game then attempts to run a non-referenced script called "collision_multiple" every tick. This causes a fatal error because that script is expecting arguments that are undefined when called.

Here is the code error message:

Code:
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of Create Event
for object object94:

instance_place argument 3 incorrect type (undefined) expecting a Number (YYGI32)
 at gml_Script_collision_multiple (line 16) -     var hit = instance_place(x1, y1, obj);
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_collision_multiple (line 16)
called from - gml_Script_scr_generateDungeonData (line 580) -        script_execute(scr_setDungeonData())
called from - gml_Object_object94_Create_0 (line 36) - script_execute(scr_generateDungeonData()) ;
The error makes it seems like this collision_multiple script is being called from the scr_setDungeonData script, but there's not a single reference to it. What is very interesting though, is if I comment out the first script execution (scr_generateDungeonData) from the Create Step code, the problem goes away. Commenting out the execution of scr_setDungeonData on like 580 of scr_generateDungeonData does not however.

Here's the code for the Create Step for the dungeon controller:

Code:
// run at the start of each dungeon level.
// ------------------------------------------------------------------------------------------------------------------------------------
//
// GENERATION SETTINGS
//
//------------------------------------------------------------------------------------------------------------------------------------
maxDungeonX = 22 ;
maxDungeonY = 14 ;
dungeonX = 22 ;
dungeonY = 14 ;
roomSeedMax = 3 ;

var baseRoomCount = 38 ;
var extraRoomCount = 12 ;

global.stage = 0;

// ------------------------------------------------------------------------------------------------------------------------------------

randomize() ;
global.stage++ ;
maxRooms = baseRoomCount + irandom( extraRoomCount ) + (global.stage*4)

roomList = ds_list_create() ;
dungeonData = ds_grid_create(dungeonX, dungeonY) ;
ds_grid_clear(dungeonData, -1) ; // the grid will store indices of speicific rooms ds_maps. Clear all cells with -1

generateDungeon = true ;
script_execute(scr_generateDungeonData()) ;  // commenting this line out stops the collision check from happening. Why?

I'm also not sure how this collision_multiple script is running every tick. Unless I'm missing something fundamental, isn't all of this script code running under the Create Event of the object? I thought the Create Step occurs only once per object. Any ideas on what I should look at next?

Other Notes:
* The collision_multiple script is an included asset with engine I purchased. It is required to make the main game engine work properly without fatal errors. The main game engine works fine on its own.
* I suspected this script was possibly being run from a persistent object, but the only object that has any persistence at all is an object called objControl, an included asset. However, all it really does is handle keyboard and Xbox360 inputs. No collision steps, or even any script executions.
* There are a bunch of parent objects and entity objects with code that does collision checks. However, these are completely unrelated to the obj_dungeonController.
* Collision_multiple runs every tick after the Create Event "finishes". I verified this by commenting out all code in the script and just showing a show_message dialog at top of it.

Any help is greatly appreciated! Thanks guys.
 

obscene

Member
TLDR. Sorry if I missed something important, but...

The error is in the create event. Not sure why you think it's in the step event.

FATAL ERROR in
action number 1
of Create Event <-----
for object object94:

instance_place argument 3 incorrect type (undefined) expecting a Number (YYGI32)
at gml_Script_collision_multiple (line 16) - var hit = instance_place(x1, y1, obj);

So for obj are you trying to pass -4 in?
 

FrostyCat

Member
Do you know the difference between the following?
Code:
script_execute(scr_generateDungeonData);
Code:
script_execute(scr_generateDungeonData());
If not, consider yourself a typical washout from the Spalding/HeartBeast school of teaching. Someone qualified to do a dungeon explorer should know the difference, and with that the proper procedure for calling a script.

If you want to run a script that you know the identity of at compile time, DO NOT use script_execute(). Run it using the standard bracket syntax. Even if the script takes no arguments, you still need to put in () after the name. That sets the difference between running the script and referencing the script ID.
Code:
scr_generateDungeonData();
Only when the script's identity is dynamically determined at runtime (e.g. script-based FSMs) should you use script_execute() to run it. And when that happens, DO NOT use the bracket syntax on the value inside unless it's a function or script that returns a script ID.
Code:
arbitrary_script = scr_generateDungeonData;
Code:
script_execute(arbitrary_script);
 
P

Pandemicsnowman

Guest
Do you know the difference between the following?
Code:
script_execute(scr_generateDungeonData);
Code:
script_execute(scr_generateDungeonData());
If not, consider yourself a typical washout from the Spalding/HeartBeast school of teaching. Someone qualified to do a dungeon explorer should know the difference, and with that the proper procedure for calling a script.

If you want to run a script that you know the identity of at compile time, DO NOT use script_execute(). Run it using the standard bracket syntax. Even if the script takes no arguments, you still need to put in () after the name. That sets the difference between running the script and referencing the script ID.
Code:
scr_generateDungeonData();
Only when the script's identity is dynamically determined at runtime (e.g. script-based FSMs) should you use script_execute() to run it. And when that happens, DO NOT use the bracket syntax on the value inside unless it's a function or script that returns a script ID.
Code:
arbitrary_script = scr_generateDungeonData;
Code:
script_execute(arbitrary_script);
Thank you FrostyCat for the quick response and info. What you said totally makes sense, and switching it to a function call fixed the issue. I presumed scr_generateDungeonData() was only the script reference/id, not a function I could call directly. I should've searched a bit more on the forums for examples. It explains why the collision_multiple was executed after the Create but before the Draw step, since that script had a index of 0 which was being returned after scr_generateDungeonData() executed. It was basically running two scripts.

And yeah I can't stand HeartBeast either. Never heard of the Spalding though. I'd rather learn by experimentation and reading from developers on the forums. Thanks again!
 

TheouAegis

Member
As Frosty said.

What should result is the game will then run whichever script has the same ID as whatever value scr_generateDungeonData returns. So if the script returns a value of 3, then the 4th script in your resource tree would be run afterward. If your dungeon generation script doesn't return any value, then the very first script in your resources tree should be run afterward.

Not sure why the error is for instance_place as a result of this. Could just be one of those quirks. Or in your version of gamemaker it doesn't return a value of 0 by default.
 

obscene

Member
Let's hate on people who make free tutorials to teach people how to get into game maker because they are evil. Sure.

I'm making my game because of Shaun Spaulding. No number of know-it-all, pretentious coders on internet forums bothered to take time out of their lives to make easily accessible introductory videos showing the basics of GameMaker that allowed me to take those first steps towards what is becoming my career, but Shaun Spaulding did.
 

arirish

Member
I'm making my game because of Shaun Spaulding. No number of know-it-all, pretentious coders on internet forums bothered to take time out of their lives to make easily accessible introductory videos showing the basics of GameMaker that allowed me to take those first steps towards what is becoming my career, but Shaun Spaulding did.
I feel like if you are committed to trying to make games with GM, but had no prior coding experience (hello!), those kinds of tutorials are ideal. You learn a little (maybe not the best way to do things, but the easiest to understand), plough on, then learn better, more optimized ways of doing the same thing, and so on, and so on. I've seen forum posts on here that use advanced math and completely unrelatable variable names that are extremely clever, do the same thing faster, and in less code, but are completely alienating to a new learner. The only real issue with those kinds of tutorials are the requirement on the part of the learner to recognize their limitations, and then work past them.

EDIT: Sorry for off-topic post.
 
P

Pandemicsnowman

Guest
Whoa, easy guys! Wasn't trying to be uncivil here. As someone new to GMS, there is definitely a lot of value in tutorial series for someone starting out. I'm currently referencing one about how to handle aspect ratios and resolutions in GMS, since GMS is pretty different in that regard than what I'm used to. My point is you only see one person's approach that way, where-as the forums have much more going on in them, often including more optimal ways of coding that help cement in how GMS works under the hood. To me, that's where the real value is. As someone with previous experience working on games and other software, I'm personally just more interested in the advanced and optimal way to do stuff even though I'm new to GMS. I know what it's like to be months into a new project and just hit a wall, knowing that a lot of the development could've been done better because of some steep learning curve with the platform. In my experience, it's best to do as much research as possible early to avoid hitting those setbacks.

The instance_place occurred on a line of in the collision_multiple script, as it attempted to dynamically create an instance of an object that was passed in as an argument. The arguments were not getting set into vars due to my prior ignorance, which is why that specific error appeared. All that makes sense to me. The only thing I couldn't figure out is, why was the code engine continuously executing the collision_multiple script every tick. Assuming I had written:

execute_script(0) ;

I would expect the collision_multiple script (which has an index of 0) to be run once, not continuously, especially since all of the code was contained in the Create Step.

It's a pleasure to be here guys, and thanks again for the info.
 
Top