Final Fantasy Legend Level Editor Update

Jesse Warden - Oct 7 '23 - - Dev Community

Progress on Final Fantasy Legend level editor.

My biggest frustration was how to deal with multidimensional Array’s in Elm. In JavaScript, if you want to build a 2D grid, you just put Array’s in Array’s like so:

grid = [
  [ 0, 0, 0 ],
  [ 0, 0, 0 ],
  [ 0, 0, 1 ]
]
Enter fullscreen mode Exit fullscreen mode

And to see if a tile is walk-able (e.g. 0), you just do a nested Array access:

walkbleTile = grid[0][0] // 0
unWalkableTile = grid[2][2] // 1
Enter fullscreen mode Exit fullscreen mode

Then when creating level editors, you simply set a tile’s value the same way:

// make last tile walk-able again
grid[2][2] = 0
Enter fullscreen mode Exit fullscreen mode

However, Elm doesn’t have null pointers because it doesn’t have null. Any time there is a value that might not exist, it’s a Maybe. This means all code now has 2 paths. For 90% of these 2D games, the tiles don’t change. It makes your code super nasty because you’re doing if statements when there is no point. For such a powerful type system, there HAD to be a better way.

So I asked around on the Elm Discourse and got a few alternatives. I started playing with the Vector library today, and it’s awesome. No Maybes; you just use the Vector size you need, and viola!

You’ll notice, however, when I click on the tiles, there “off”. This is because knowing where you clicked I haven’t gotten correct yet. There is where you clicked + where the Canvas actually is + what the offset of the tiles is + any CSS & box model adjustments + any zoom level. When I zoom in, you can see how bad the math is, lol.

However, still a major victory to have such a wonderful API now to access and update tile maps without Maybes everywhere.

Here’s the Array get and set API:

vs the Vector get and set:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .