Jump to content

Data modelling in JS


mariogarranz
 Share

Recommended Posts

I'm working on a game, where I have many different game objects which, in essence, have the same behaviour. They are all defined by the same class. Yet, depending on their type, they will have a different sprite and the game logic will act differently according to the combination of objects of different type.

 

So far, I had always used some sort of "Enum" to define these types, like this:

 

colors = {NONE: 0, BLUE: 1, GREEN: 2, YELLOW: 3, PURPLE: 4},states = {IDLE: 0, RUNNING: 1, JUMPING: 2, SLASHING: 3}

That way I could just tell the type of an object according to its "color", for example.

 

For this game, however, I'm going to have more than 50 different types, each with its own sprite associated, so that I don't have to code a huge "switch" instruction to get the correct sprite for each type of object.

So I would like to make a more complex data structure, with type name, sprite string, etc.

Which would be the best practice to model this data structure? JSON file maybe? Do you know which is the most common method used for this?

Thanks in advance for your help :)

Link to comment
Share on other sites

Just a couple of thoughts:

 

In most cases using "Enums" like that in JavaScript isn't a very good idea. Objects are key-value pairs in JavaScript, so I don't think you gain anything by doing it that way, you only make your code harder to read. For example:

if (object.color == 'yellow')

isn't going to be any slower than

if (object.color == colors.YELLOW)

Sure, in the first case you are comparing strings, in the second case you are comparing numbers. But to determine what the value of colors.YELLOW is, the JavaScript engine will have to look up the "YELLOW" string in the colors properties at runtime. This is more complex than it seems, because the "YELLOW" could be stored in the object keys, or in the object's prototype keys. If anything, this is going to be marginally slower than the other approach.

 

There are some exceptions (when arrays are involved), but at the end of the day, the performance difference is going to be minimal. I would suggest that you should go with whatever approach makes your code easier to read and maintain.

 

Regarding the data structure, yeah JSON is the most natural choice, since it doesn't have to be parsed, i.e. a JSON object is also a JavaScript object, there's no need to translate or rearrange the data.

Link to comment
Share on other sites

Just a couple of thoughts:

 

In most cases using "Enums" like that in JavaScript isn't a very good idea. Objects are key-value pairs in JavaScript, so I don't think you gain anything by doing it that way, you only make your code harder to read. For example:

if (object.color == 'yellow')

isn't going to be any slower than

if (object.color == colors.YELLOW)

Sure, in the first case you are comparing strings, in the second case you are comparing numbers. But to determine what the value of colors.YELLOW is, the JavaScript engine will have to look up the "YELLOW" string in the colors properties at runtime. This is more complex than it seems, because the "YELLOW" could be stored in the object keys, or in the object's prototype keys. If anything, this is going to be marginally slower than the other approach.

 

There are some exceptions (when arrays are involved), but at the end of the day, the performance difference is going to be minimal. I would suggest that you should go with whatever approach makes your code easier to read and maintain.

 

Regarding the data structure, yeah JSON is the most natural choice, since it doesn't have to be parsed, i.e. a JSON object is also a JavaScript object, there's no need to translate or rearrange the data.

 

Thanks for your help Gio. As you can see I come from OOP languages and I'm still not very into Javascript.

 

So would it be a bad practice to do it that way? Imagine a classic blocks game. All blocks have the same behavior, but different colors. I would have different sprites depending on the state and color of the block. I thought about doing a structure like this and saving it into a JSON file:

 

blockTypes = {    green: {        a:'greenAsprite',        b:'greenBsprite'    },    blue:{        a:'blueAsprite',        b:'blueBsprite'    }}

Would that be a wrong approach to the data model?

Link to comment
Share on other sites

There is no wrong approach, if it works for you that's all that matters :)
 

I have a classical OOP background too (I still use C languages on a daily basis), and I understand it's tempting to use JavaScript as a C-style language... it's so flexible that it lets you do that! But just because it's so flexible, there may be many other ways of doing the same things.

 

In your particular case, I think it's personal preference really, but if you're going to use a consistent naming convention for your sprites, then the JSON data structure is almost redundant. Now you would be doing:

var sprite = blockTypes[myType][myState];

but you could also get rid of the data structure altogether and do:

var sprite = myType + myState + 'sprite';

I'd personally prefer the latter, since there would be one less file to worry about (and if you are creating that file by hand, there's also an extra opportunity for some typos or copy and paste errors).

 

Unlike classical OOP languages, string operations in JavaScript are really fast. Or rather, since many things (object property names for example) are actually strings, using string operations in most cases isn't slower than using any other methods, but it can be a lot more convenient.

Link to comment
Share on other sites

Really :)

 

I accept that if you're iterating over all your states and types hundreds of times per frame and don't care about IE, there may be a good reason to choose the 'enum' approach over the other. But that wasn't really my point... (Incidentally, your tests are valid and interesting, but also show that the 'string' pattern is easier for browsers to understand and optimize; it'd be very interesting to see if that extends to code minifiers such as closure compiler).

 

Coming from a classical OOP background and being used to compiled languages, you naturally wouldn't use strings, because they can be much (much!) slower and don't make your life any easier. My point was that in a general usage case, in JavaScript the performance difference is small enough that it doesn't matter at all. If you're doing something very intensive with these enums, that may be different. If you're making an html5 game, I really doubt you'll ever see any difference, so I normally prefer simpler code that's easier to maintain.

Link to comment
Share on other sites

First up thanks heaps for making me look at this, I just assumed that the object way would be faster aswell coz I come from pascal (I was hopeless at it ;) ) and was taught that allocating and deallocating memory COSTS and strings do it alot.

Ive never made a game (still havent even used Phaser yet) but I would have thought that speed would always count, even in the little things.

Personally Im a little obsessed with objects in JS, its one of the things that made me love it and yeah I might resort to them too quick sometimes....maybe.

 

 it'd be very interesting to see if that extends to code minifiers such as closure compiler

 

 

I did some tests on a couple of minifiers once and both of them slowed the code down, they might make code smaller but sometimes by turning things into their slower cousins (noticed that one thing they converted too was something I had already been shown as slow, so did the tests).  Have no idea about closure.  Ive always wondered why people dont use things like the compactor on this page more....

http://jsutility.pjoneil.net/

...do a safe minify then that gets smaller results anyway.

If only there was a mutator that could actually speed things up ;).

 

Heres another perf that relates.....

http://jsperf.com/strings-vs-enums/2

 

Really I guess it would depend on what hes using this for and how, he didnt really supply enough info to know that.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...