Legacy GM [Solved] Some code crashes with YYC, other code isn't run at all...

J

JealousOfCrows

Guest
So I tried to compile my game with the YYC today and once I got it working (i.e. the game actually running), to my dismay, certain parts of my game were just acting weird, some tweening wasn't running and my pause menu crashed the game. Here is the error on the crash:

FATAL ERROR in
action number 1
of Step Event0
for object oPause:

Unable to find any instance for object index '0'

No idea what object index '0' is, any thoughts? The pause menu code works fine when not compiled with YYC. Also I am using the tween GMS by 8bit warrior from the marketplace and I have my character tween when it jumps and lands, this just isn't working with the YYC (no errors though).

When I try and compile with C:\Program Files (x86)\Windows Kits\8.0 and C:\Program Files (x86)\Microsoft Visual Studio 11.0 I get the below error.

LINK : fatal error LNK1181: cannot open input file 'wininet.lib'
C:\Users\Adam\AppData\Local\gm_ttt_25048\gm_ttt_11350\Sci_fi_Platformer_Alpha.manifest : general error c1010070: Failed to load and parse the manifest. The system cannot find the file specified.

It does work however with windows kit 8.1 and either VS 11 or 12. So I am using these instead. Any help or suggestions would be greatly appreciated!
 
J

JealousOfCrows

Guest
Ok. Here it is. Please let me know if you need any clarification! I know the code is a little odd but it works... outside the YYC that is. I also call the oPause object from my game controller oController when the escape key is first pressed (this controller object is the first object in my resource tree and likely the object instance '0' causing issues but I don't know why). I really feel their should be a formal guide from Yoyo about what can and can't be done when compiling with the YYC. Anyways, hopefully this information is enough to get me on the right track and hopefully people find it useful! (either to help them compile with YYC or even to make pause menu!).

Here is the pause menu in action. Ignore that green screen stuff, gif cam gets weird when you have green things in your video for some reason (not sure why).
http://imgur.com/a/RCF4m

Here is the code for the oController:
Code:
///Pause the game
    if ((room == rmStartScale) or (room == rmStartScreen))
        {
        game_end();
        }
    else if !(instance_exists(oPause))
        {
            instance_create(0,0,oPause);
        }
Create Event:
Code:
///Pause the game  
   
    screen = -1;  
    State = 0;
    nav = 0;
    press = 0;
    mouse_press = 0;
    PauseMenu = 0;
    numsprite = sprite_get_number(spr_pause_menu) - 1;
    /*
    0 = resume
    1 = options
    2 = exit  
    */
   
    //Set up variables
    var w, h, xx, yy;
    w = view_wview;
    h = view_hview;
    xx = view_xview[0] + (view_wview/2);
    yy = view_yview[0] + view_hview;

    //Set shader uniforms
    upos = shader_get_uniform(shd_motion_blur, "pos");
    usize = shader_get_uniform(shd_gaussian_blur, "size");

    //Inactivate particle systems
    part_system_automatic_update(global.pSystem_fg, false);
    part_system_automatic_update(global.pSystem_mfg, false);
    part_system_automatic_update(global.pSystem_mbg, false);
    part_system_automatic_update(global.pSystem_bg, false);
   
    //Inactivate all instances
    instance_deactivate_all(true);
   
   
    if !(instance_exists(oPauseMenu)) {
        //Create the number of objects equal to # of sprites of the menu
        for (var i = 0; i <= numsprite; i++){
            //array should have values 0-2          
            PauseMenu[i] = instance_create(xx, yy, oPauseMenu);
           
            with(PauseMenu[i])
                {
                yyy = view_yview + view_hview*((i+2)/6); //this centers the sprites, slicing the screen into 6 parts
                image_index = i; //assigns appropriate image
                Selected = false;
                image_speed = 0;
                SelectScale = 0.5;
                Scale = 0.24;
                image_xscale = Scale;
                image_yscale = image_xscale;
                TweenFire(self, y__, EaseOutBack, TWEEN_MODE_ONCE, false, 0, 15, y, yyy);
                TweenFire(self, image_xscale__, EaseInOutCubic, TWEEN_MODE_ONCE, false, 0, 15, image_xscale, Scale);
                TweenFire(self, image_yscale__, EaseInOutCubic, TWEEN_MODE_ONCE, false, 0, 15, image_yscale, Scale);  
                }
        }  
       
    }
       
    if !(surface_exists(screen)){
        screen = surface_create(w, h);
        surface_copy(screen, 0, 0, application_surface);
    }
Step Event:

Code:
    nav = 0;
    nav -= max(keyboard_check_pressed(vk_up), keyboard_check_pressed(ord('W')), 0);
    nav += max(keyboard_check_pressed(vk_down), keyboard_check_pressed(ord('S')), 0);
   
   
    press = max(keyboard_check(vk_enter), keyboard_check(vk_space), 0);
   
    if (nav != 0){
        //Change the state based on the key presses (nav) to move up or down
        State += nav;  
        if (State < 0)                                  {State = array_length_1d(PauseMenu) - 1;}
        if (State > (array_length_1d(PauseMenu) - 1))   {State = 0;}
    }
   
       
    for (var i = 0; i <= numsprite; i++){
        //If the state is equal to i, then with the specific instance, Selected = true
        if (State == i) {  
            with (PauseMenu[i]){
                if (!Selected){
                    TweenFire(self, image_xscale__, EaseInOutCubic, 0, false, 0, 15, image_xscale, SelectScale);
                    TweenFire(self, image_yscale__, EaseInOutCubic, 0, false, 0, 15, image_yscale, SelectScale);
                    Selected = true;
                }
            }
        }
        //else Selected = false and tween back to normal
        else if (State != i){
                with (PauseMenu[i]){      
                    if (Selected){
                        TweenFire(self, image_xscale__, EaseInOutCubic, 0, false, 0, 15, image_xscale, Scale);
                        TweenFire(self, image_yscale__, EaseInOutCubic, 0, false, 0, 15, image_yscale, Scale);
                        Selected = false;
                    }
                }
            }
       
    }
   
    //Check to see what state we are in (i.e., which option is selected)
    switch (State)
        {
        case 0: // resume
            if (mouse_press) or (press)
                {
                event_perform(ev_keypress, vk_escape);
                }
            break;
        case 1: //restart
             if (mouse_press)  or (press)
                {
                event_perform(ev_keypress, vk_escape);
                if (room != rmStageSelect)
                    {
                    room_restart();
                    }
                else room_goto(rmStartScreen);
                }
            break;
        case 2: //quit
            if mouse_press  or press
                {
                event_perform(ev_keypress, vk_escape);
                if (room != rmStageSelect)
                    {
                    room_goto(rmStageSelect);
                    }
                else game_end();
                }
            break;                  
        }
Key Press Escape:

Code:
    if (surface_exists(screen)) {surface_free(screen);}
    if (instance_exists(oPauseMenu)) {
        with(oPauseMenu)
            {instance_destroy();}
    }
    instance_destroy();
    instance_activate_all();
    part_system_automatic_update(global.pSystem_fg, true);
    part_system_automatic_update(global.pSystem_mfg, true);
    part_system_automatic_update(global.pSystem_mbg, true);
    part_system_automatic_update(global.pSystem_bg, true);
 
What value is numsprite set to?

Edit - I also noticed the use of self. I've never actually used it so I'm unsure of how it works in the YYC, but I'd take a look at that as well.
 
Last edited:
J

JealousOfCrows

Guest
Hey BattleRifle BR55, thanks for the response. In the create event, numsprite = sprite_get_number(spr_pause_menu) - 1. This is essentially the number of sprites in the menu (resume, option, ext, etc...). I will look into the self issue, the reason I use it is to access the specific instance to tween and not the object because then they will all tween. Now that I think about it, the tween isn't working on my player character after landing and it also uses 'self'.

This also doesn't seem to be the cause of the error, which involves the object index '0'. I see no reference to my oController object in the oPause object, the only connection is that the controller object spawns the pause obejct... so still not sure what is the issue here.
 
J

JealousOfCrows

Guest
Wow. That fixed everything. Pause menu works now, the character tweening works as well and my game is definitely faster (still need to optimize draw calls though). Thank you very much FrostyCat (preferred your old name of GameGeisha, seemed more authoritative ;)).

I do find it odd the error message I was getting though and how I was supposed to figure out the issue with that information was beyond me ( I was digging through my pause and controller code as I figured that was the reference throwing the error). I think Yoyo should write tech blog on optimizing code for YYC and what types of things just don't work, this was not very intuitive for me and I am sure other users have had similar issues as well. Just to confirm before I mark as solved, should 'self' always be replaced by 'id' for YYC?
 

FrostyCat

Member
I do find it odd the error message I was getting though and how I was supposed to figure out the issue with that information was beyond me ( I was digging through my pause and controller code as I figured that was the reference throwing the error). I think Yoyo should write tech blog on optimizing code for YYC and what types of things just don't work, this was not very intuitive for me and I am sure other users have had similar issues as well. Just to confirm before I mark as solved, should 'self' always be replaced by 'id' for YYC?
For instance IDs stored for later use, self should always be replaced by id, and so should other by other.id.

In the standard VM, self is always -1 and other is always -2, the actual instance used is determined by the context where it is referenced. You can easily see how this can get taken out of context and cause the symptoms you described. If I left a note saying "comb my hair" and you followed its instructions, I wouldn't be surprised if you combed your own hair instead of mine. For you as the reader, "my" is yourself. That wouldn't have happened if the note was "comb FrostyCat's hair" instead.

The situation gets more complicated with YYC, which has a simpler instance scoping mechanism than the standard VM for speed. There was a bug report around the inception of YYC about how the behaviour of self was inconsistent (now closed from access), and YoYo decided to deprecate it instead of fixing it. There was no motivation to fix it because there were virtually no use cases where using a straight instance ID would be unattainable. With GMS 2, they may have changed IDs to be interpreted as unsigned integers, in which case -1 might get casted to 0 and cause the error you described.

As I said, this is all speculation because self is a deprecated feature that's buggy when YoYo abandoned it, there is no telling what it wants to do. Avoid it at all costs from now on and you'll be fine.
 
J

JealousOfCrows

Guest
Thank you for the response. I'm using 1.4.x and not gms2. I only use self and other in the context of with statements and collisions (from which I thought it was ok, and is with the VM... But not with the YYC). Solved.
 
Top