GameMaker 2.2* => 2.3 Update fix arrays

1.5k Views Asked by At

In new GameMaker 2 update there are so many major changes: https://help.yoyogames.com/hc/en-us/articles/360011980018

We develop our game (https://store.steampowered.com/app/733460/First_Feudal/) on this engine for 3 years. There was no other way to handle state before: only arrays. No structures and model objects.

So we have really many arrays in our game. We use 1d and 2d arrays. From now GML have only 1d arrays, and 2d or other multidimensional arrays - are 1d array of 1d arrays.

For now after update from 2.2 to 2.3 GameMaker your arrays may work ok. But there are some issues. First of all some array functions will deprecate in next versions. And some of them (like array_height_2d) may work in different way if you mix 1d and 2d logic.

So, how to update 2d arrays to new 2.3 format, and don't use obsolete functions later?

2

There are 2 best solutions below

0
On

Firstly I want to do it using some script (on vbs or powershell), but this idea wants to eat a lot of time because of issues with best way of open and rewrite file. There may be issues with file code format after rewrite. + time to research regexp in them. And also some logging system develop (to know which files and how changes). We cannot use just GMS, because of no regexp search.

So the best way for me was Notepad++ (https://notepad-plus-plus.org/downloads/).

Firstly, replace all [i,j] to [i][j]

  • Open Notepad++
  • Drag'n'drop project folder
  • RMB on folder in workplace > Find in Files..
  • Find in files tab
  • Find what: ([\w])(\[\s*)([^\]\[]+)(\s*,\s*)([^\[\]]+)(\s*\])
  • Replace with: \1\[\3\]\[\5\]
  • Filters: *.gml
  • Regular expression radio button
  • In all subfolders checkbox
  • Find All button
  • Research all finded places, if all ok Replace in Files button.

Then think about fix [[i][j],k] to [[i][j]][k]:

  • Same as before but
  • Find what: ([\w])(\[\s*)([^\]\[]+\]\[[^\]\[]+\])(\s*,\s*)([^\[\]]+)(\s*\])
  • Replace with: \1\[\3\]\[\5\]
  • May be issues if you have difficult logic

Secondly, replace all array_height_2d to array_length

  • Same as before but
  • Find what: array_height_2d\(
  • Replace with: array_length\(
  • Check array_height_2d existence

Thirdly, replace all array_length_2d to array_length

  • Same as before but
  • Find what: (array_length_2d\(\s*)([^\(]+)(\s*,\s*)([^\)]+)(\s*\))
  • Replace with: array_length\(\2\[\4\]\)
  • Check array_length_2d existence (it may be if you use scripts inside array_length_2d check)

And finally, replace all array_length_1d to array_length

  • Same as before but
  • Find what: array_length_1d\(
  • Replace with: array_length\(
  • Check array_length_1d existence

It also may be some issues with 2d array creation. If you use accessors, then you should fully init array before access to property. (before, accessor was increased array size by itself)

Then fix other corner cases.

1
On

For the most part you don't have to do anything - old-style 2d accessors will work just fine:

var a2d; a2d[1, 2] = 3;
show_debug_message(a2d[1, 2]); // 3
show_debug_message(a2d[1][2]); // 3
a2d = [[], [0, 0, 4]];
show_debug_message(a2d[1, 2]); // 4
show_debug_message(a2d[1][2]); // 4

As you have noticed yourself, array_height_2d does not work correctly with 1d arrays as there is no longer a difference between a 2d array and an array with arrays in it. For my purposes I was able to get around this by introducing a script that returns height only if the array contains other arrays inside:

function array_height_2d_fixed(arr) {
    var n = array_height_2d(arr);
    if (n == 0) return 0; // empty / not an array
    for (var i = 0; i < n; i++) if (is_array(arr[i])) return n;
    return 1; // no arrays inside
}

and so

var a1d = [0, 1];
show_debug_message(array_height_2d(a1d)); // 2 - wrong!
show_debug_message(array_height_2d_fixed(a1d)); // 1 - right
show_debug_message(array_height_2d(a2d)); // 2
show_debug_message(array_height_2d_fixed(a2d)); // 2