Is the array object completely broken?

Discussion and feedback on Construct 2

Post » Sun Jun 08, 2014 5:21 pm

Hi,

I've been using Construct 2 for several years now, but this week I had to deal with the Array object for the first time.

For some reason, I can't seem to get it to work right. Despite having experience with arrays from several programming languages, I can't seem to do so much as get a simple 3D array up and running without getting strange results or even complete browser freezes.

I've asked around on IRC and even made a topic containing an example but haven't had much luck getting a response.

I guess my question is, is the Construct 2 Array object working as it should, allowing you to insert values and iterate through it as you normally would in other languages? Or are there known issues?

You can check out the above mentioned topic for a specific example.

Any comments?
B
22
S
5
Posts: 107
Reputation: 2,354

Post » Sun Jun 08, 2014 5:59 pm

The definition of coincidence right here. I just decided (like 3 days ago) to create 3D Array Plugin that uses a named convention system (Dynamic Storage) for the exact same reason as working with the array plugin as it is wasn't working the way i would expected it to coming from a traditional programming languages.

The plugin is still beta but should work the way you expect. I have an example capx that I use for testing each feature that is list below. You should be able to quickly see how it works.

Heres the plugin
trblsm_dynamic_storage.zip


And heres the example capx i use to test its features as i add them
DynamicStorageExample.zip


A screen shot of what it looks like in use.
screenShot1.png


Hopefully this helps
You do not have the required permissions to view the files attached to this post.
Last edited by troublesum on Mon Jun 09, 2014 5:23 pm, edited 1 time in total.
B
20
S
7
G
1
Posts: 221
Reputation: 2,077

Post » Sun Jun 08, 2014 6:15 pm

Thanks for the response.

It's great to see that you're doing something about this, but unfortunately I'm coding a rigid engine for a future commercial project, and first and foremost I'd like to try to understand exactly what the issue is here before I decide to move on to third party solutions.

Do you have any insights into exactly what isn't working with the Construct 2 Array?
B
22
S
5
Posts: 107
Reputation: 2,354

Post » Sun Jun 08, 2014 6:23 pm

unfortunately no... I took one look at the array plugin and was "its like time to learn the SDK because this wont work for me" Sure enough the SDK is really easy if you have any JavaScript background (It sounds like you do) you could simply open up the array plugin and see what its doing vs what you'd expect. I have to assume its working the way its intended because im sure there are tons of people using it. It just didn't work the way I expected/wanted it to and I couldn't wrap my head around it i came up with this.
B
20
S
7
G
1
Posts: 221
Reputation: 2,077

Post » Mon Jun 09, 2014 12:25 am

I wish I could open up arrays and fill in initial data visually rather than through events, but I rarely have many issues with arrays.
@bearboxmedia
www.bearboxmedia.com

Nintendo Wii U Developer using Construct 2
B
79
S
12
G
7
Posts: 963
Reputation: 10,721

Post » Mon Jun 09, 2014 1:52 am

The array system is not broken it's just peculiar. I've worked with all 3 depth for it.

C2 stores the 3D arrays as XYZ.
X
Y
Z.

X is root.
Y is the sub of X
Z is the sub of Y.

now I'm sure you you already know this. heck I knew this before using C2 and I still had problems getting around C2's array. I still don't like C2 arrays and wish they worked as the variables work. However it doe work and you can work with them. GL though.
B
90
S
18
G
9
Posts: 2,455
Reputation: 15,018

Post » Mon Jun 09, 2014 9:56 am

What is wrong with the arrays? How do people expect them to work?
@bearboxmedia
www.bearboxmedia.com

Nintendo Wii U Developer using Construct 2
B
79
S
12
G
7
Posts: 963
Reputation: 10,721

Post » Mon Jun 09, 2014 4:57 pm

@AnD4D

The way arrays usually work in all programming languages is they are dynamically referable locations of memory. IE. Each level can be accessed by "string" name or variable. Imagine you create function and the first parameter happens to be the name of the dictionary you want to access (Not the key value but that actual dictionary. In C2 this currently not possible with out hard coding all possible dictionary's in advance. So you are limited to only having a single level of dynamic access which are the dictionary keys. (Notice you can dynamically access values in a dictionary but you cannot dynamically access the dictionary its self). This is the limiting factor of C2 where not being able build large complex structures like recursive functions or dynamic data algorithms (closed loop systems) like a game engine or operating system. Its just not possible.

Using my plugin here is an example of looping through the first level of fields just as if it were a dictionary. This will loop through every key in player 1 and print his attributes. Nothing special becuase dictionarys already support this.
foreachFieldScreen.png



But lets say I have 2 players and I want the score from each player (Each player would have his own dictionary for this. (this is simple example and I know there are ways of doing this in C2 but look at how simple it is with 2 levels of dynamic access). Instead of some grand method required I can do for each player key and get a list of the same item for each player in a single line of code. This is the power of multilevel dynamic data access and in truth is the foundation of all programming.
test.png


There are so many benifits to this its hard to explain them all but let me give one more screen shot to help prove the point. By keeping all my data in a single location I can also debug problems much faster. Here is a screen shot of the storage container in debug view. Notice how easy it is to keep track of.
debugScreen.png


Lastly as the plugin supports pushing and poping data as JSON objects I can send raw JSON strings back and forth via AJAX for communication with my server. And it can so much more. The problem is that since most of the people that use C2 are not traditional developers they have no idea what there missing by not having this crucial fundamental ability that is inherent to programming.
You do not have the required permissions to view the files attached to this post.
B
20
S
7
G
1
Posts: 221
Reputation: 2,077

Post » Mon Jun 09, 2014 7:12 pm

@Troublesum: You might want to "publish" your plugin in the adequate forum.

As for arrays, manual articles and tutorials are available as to the specificities of C2 and they work very well.
New to Construct ? Where to start

Image Image

Image Image

Please attach a capx to any help request or bug report !
Moderator
B
289
S
112
G
94
Posts: 7,333
Reputation: 69,293

Post » Mon Jun 09, 2014 8:27 pm

@troublesum,

troublesum wrote:The way arrays usually work in all programming languages is they are dynamically referable locations of memory. IE. Each level can be accessed by "string" name or variable.

Code: Select all
NOPE
An array, in traditional programming language (C/C++/C#, Java, Python,...) is a list of contiguous elements of the same size (in memory). No more, no less.
When saying "dynamically referable location" you probably mean that you can use a variable that can dynamically change to access any part of the array. And that's right.
However, you can access each element using an integer index. Not a string, only an integer.

For example, let say we have an array of 4bytes integers.
In C (let's get back to the bare basics) you would do
Code: Select all
 int myArray[10]; //create an array of 10 ints

This will exactly reserve 4*10 = 40bytes of memory.
if we were to represent the array in memory, we could imagine something like that:
Code: Select all
indices :   0    1    2    3    4    5    6    7    8    9
schema:    [int][int][int][int][int][int][int][int][int][int]
offsets  :  0    4    8    12   16   20   24   28   32   36   40 ...

So how does an array work its magic?
when you do myArray[7], the computer knowing that all element have 4bytes will look at the 7x4th byte from the start of the array
And indeed the int at index 7 is the one at the offset 28 byte.

That's how array works. No more, no less.

Now, there's something that might confuse people depending on how you use arrays in some programming languages.

Multi-dimensional arrays ARE NOT array of arrays!

A Multi-dimensional array is just an arithmetic trick. In memory, it's still a single line of contiguous data. However an Array of Array is an array of pointers to arrays spread over the memory.
In C, you declare a 2-dimensional array like this:
Code: Select all
int multiArray[2][3]; // initialise a 2D array. For clarity let say it has a height of 2 and a width of 3

here is what it looks like in memory:
Code: Select all
indices1:   0    0    0    1    1    1 
indices2:   0    1    2    0    1    2
schema:    [int][int][int][int][int][int]
offsets:    0    4    8    12   16   20   24...

if you want a value at index [1][2] you get the value at offset (indice1 * width + indice2) * size_of_int = (1 * 3 + 2) * 4 = 5*4 = 20

Now an array of array, in C is declared like this:
Code: Select all
int* arrayOfArray[3] // array of pointers to int. Or, for simplicity's sake: array of arrays of ints

The special character* means pointer to what is before it.
It means that you don't have an array of ints anymore, but an array of pointers to an int (yeah those iffy pointers is why people don't like C/C++).
For this short explanation, you just have to understand that an array of ints is under the hood a pointer to an int (the first of the array then you use the previously mentionned offset to traverse your memory). Then you can understand that as "array of pointers to an int", or more conceptually "array of arrays of ints"
in memory, it looks like
Code: Select all
indices :   0     1     2    3   
schema:    [int*][int*][int*]
offsets  :  0     4     8    12...

(yeah pointers often also take 4 bytes but it depends on the compiler)

So when you do
Code: Select all
arrayOfArray[2]

You basically get an array of int.
Obviously C allows you to get any value in this array as well, so you can do something like
Code: Select all
arrayOfArray[2][3]

But what happens isn't the same as with the 2D array. Here you don't do arithmetics per se, you directly go to were a second array of int is, and use it directly like a simple array. A bit like Matryoshka doll or like following a path.

One of the main differences between the two, in practice, is that the arrays of your array of arrays can have different sizes (jagged arrays). It allows you for example, to build triangular matrices.
Code: Select all
[[3,2,1],
 [2,1]
 [1]]

Using a multi-dimensional array, You you just always have the same width, height, depth,... So it's a good fit for square matrices.
Code: Select all
[1, 0, 0,
 0, 1, 0
 0, 0, 1]


Small note about javascript:
Arrays in javascript are very far away from C arrays. They actually aren't really arrays but objects that expose a behavior close to arrays. Nonetheless, you can't access their elements by strings.
Also, "true" multidimensional array in javascript, and also php are impossible. People talking about multidimensional array in those language are merely refering to how they use it. But make no mistake, they are indeed Array of arrays in all case.

C2 array object aims to emulate the behavior of a true multidimensional array, that's why your can't easily have jagged arrays.


troublesum wrote:accessed by "string"

What you were refering to is called by many names. "Hashtable","Hashmap","Dictionary","Records",...
[rant]Basically it's a datastructure which allows you to access a value indexed using a hash.
Well usually, you don't use the hash but something that can be hashed (let say for example,... a string).
The hash will correspond to an index in an array of "bucket" (another kind of datastructure) which contains all value whose key have the same hash (hash collision).
The corresponding value is then inserted in or retrieved from this bucket.
A hashtable is slightly slower than an array. Since read and write require more computation. But it often doesn't matter.[/rant]

C2 dictionnary is just a simple basic hashtable.

troublesum wrote: This is the limiting factor of C2 where not being able build large complex structures like recursive functions or dynamic data algorithms (closed loop systems)


You can build recursive function in C2.
Code: Select all
+ Function: "factorial"
  + Function: parameter 0 <= 1
    -> Function: set return value to 1
  + else
    -> Function: set return value to Function.param(0) * Function.call("factorial",Function.param(0) - 1)


Also, you can build complex datastructure as well with a few hacks, but since it involves passing and parsing JSON strings arround, it's very inefficient. And yeah there's no easy way to create things like circular linked list. It's not impossible, but it would require building a whole set of function interfaces to access some data a certain ways to simulate memory references. And safe is to say that we would move toward crippling efficiency. C2 is slow enough :D

I would advise to take a look at my JSON plugin. It's still in development but I'm using it at work and it simplify few things.

At home I already implemented the hability to load/save objects by reference. So you will be able to create any cyclic datastructure you want.
But since I have no cool ways to save that as json for debugging or saving, I'm still looking for a good solution.
Last edited by Yann on Mon Jun 09, 2014 10:06 pm, edited 2 times in total.
B
66
S
22
G
14
Posts: 1,484
Reputation: 16,511

Next

Return to Construct 2 General

Who is online

Users browsing this forum: No registered users and 9 guests