1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

Question - Code What is the correct way to declare 'object' style variables

Discussion in 'GameMaker Studio 2 Community Tech Support' started by Starlight, Mar 28, 2019.

  1. Starlight

    Starlight Member

    Joined:
    Mar 28, 2019
    Posts:
    5
    I was on version 2.2.1.3 and using the below code in multiple places without a problem

    Code:
    move = "EnemyIdle";
    move.state = states.idle;
    
    return move;
    
    This worked and I've used it across my game

    After updating to 2.2.2.4 I can no longer do this, and get the following error
    Code:
    FATAL ERROR in
    action number 1
    of Create Event
    for object object_tempEnemy:
    
    unable to convert string "EnemyIdle" to int64
     at gml_Object_object_tempEnemy_Create_0 (line 19) - move.state = states.idle;
    Is this a bug or regression in the update?

    If not, I don't mind updating my code, but what is the correct way to define a variable that functions this way?

    Ex. How do I declare 'move' so that I can use move.var1, move.var2, move.var3 etc. and return the entire structure

    What is the variable type I was seemingly implicitly creating before?
     
  2. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    4,689
    Resource IDs are not strings, stop treating them like one.

    If EnemyIdle is an object ID or instance ID, get it out of the quotes so that you work with a live ID.
    Code:
    move = EnemyIdle;
    move.state = states.idle;
    
    If that isn't what you want, you would need to work out what you actually wanted and redo every piece of code that contains the same mistake.

    Your code shouldn't have worked in the first place, if it ever did it's because you were unlucky enough to have it forgiven badly. Because 2.2.1 and below used to cast non-castable types to 0 when a numeric value is warranted (which the left side of a dot is for an object or instance ID), this whole time you have been creating instance variables for the first object in your resource tree. If there's an instance of that, you wouldn't get an error as 0 would then be a legal target to try assigning variables for, but the absence of an error doesn't mean everything's alright.

    This is not a bug or regression in 2.2.2, this is new 2.2.2 behaviour pointing out a problem in your code that 2.2.1 used to incorrectly sweep under the rug.
     
    Starlight and IndianaBones like this.
  3. Starlight

    Starlight Member

    Joined:
    Mar 28, 2019
    Posts:
    5
    EnemyIdle is not an object ID or instance ID. It is literally a string used as a string for debugging to display what state an object is in. It just so happened to also work to declare 'move' for me so I can declare properties on it (Or whatever they are when referenced by thing.varName)

    I appreciate the condescending tone though. If you note in the OP, I was fully prepared for this to be wonky unintended behaviour, and asked how I should do this properly.

    This is the actual information I needed to know to understand what was happening. Makes sense, thank you.

    Is there a correct way to declare move, so that I can do for example:

    Code:
    move.name = "EnemyIdle"
    move.state = states.idle
    
    return move
    
    Or is this simply not a thing in gamemaker and I just need to refactor how I'm approaching this?
     
    Last edited: Mar 29, 2019
  4. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    4,689
    There are 2 ways in which you can do it the way you described.

    The first is creating a new automatically self-deactivated object type to serve as a carrier for instance variables.
    Code:
    // obj_data_unit Create
    instance_deactivate_object(id);
    
    Code:
    // Your script
    var move = instance_create_depth(0, 0, 0, obj_data_unit);
    move.name = "EnemyIdle"
    move.state = states.idle
    return move;
    
    The second is using an array with an enum. Note that the enum declaration should only appear once in your project.
    Code:
    // Put this in a new script that's never called anywhere
    enum data {
      name,
      state
    }
    
    Code:
    // Your script
    return ["EnemyIdle", states.idle];
    
    Then you would index the returned array using the enum (e.g. arr[data.name]).
     
    Starlight likes this.
  5. Starlight

    Starlight Member

    Joined:
    Mar 28, 2019
    Posts:
    5
    This is what I was thinking and then you replied. Just refactored everything by changing move to an enum

    Code:
    var frameMove = [];
    frameMove[move.name] = "EnemyIdle"
    frameMove[move.state] = states.idle;
    
    return frameMove
    This gives me the behaviour I wanted, albeit a bit more verbose.

    Thank you!
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice