[12.7] How can I define a multidimensional array?

The above approach for tables can be extended to any number of dimensions, but it gets pretty unwieldy. I'd probably suggest using fixed-size arrays wherever possible (they don't have to be of fixed fixed size, you can specify width, height etc in parameters to the birth handler).

Anyway, here's an alternative (rather outlandish) approach allowing arrays of arbitrary dimension (maybe they're trees really, but whatever...)

    -- parent script "array object"
    
    property array
    
    on birth me
      set array = []
      return me
    end birth
    
    on setVal me, coordList, val
      -- check we've got a proper set of coordinates
      if (not listP(coordList)) then return #badCoord
      if count(coordList) = 0 then return #badCoord
      
      -- if there's only the one coordinate, set that value in our array
      if count(coordList) = 1 then
        setAt array, getAt(coordList, 1), val
        
      -- otherwise, either create a new sub-array at our coordinate or use one
      -- that's already there, and get it to set the value at the place
      -- specified by the rest of the coordinate list
      else
        -- identify our coordinate, and delete it from the list
        set thisCoord = getLast(coordList)
        deleteAt coordList, count(coordList)
        -- see if there's an array there already
        set subArray = 0
        if count(array) >= thisCoord then set thisVal = getAt(array, thisCoord)
        -- if not, create one
        if not objectP(subArray) then
          put birth(script "array object") into subArray
          setAt array, thisCoord, subArray
        end if
        -- do the recursive call
        setVal subArray, coordList, val
        -- rebuild the coordinate list
        add coordList, thisCoord
      end if
      
      -- return a value to say that it worked
      return #ok
    end setVal
    
    on getVal me, coordList
      -- check we've got a proper set of coordinates
      if (not listP(coordList)) or count(coordList) = 0 then return #badCoord
      
      -- if there's only one coordinate, return the value of that in our array
      if count(coordList) = 1 then
        put getAt(coordList, 1) into thisCoord
        if count(array) >= thisCoord then return getAt(array, thisCoord)
        else return 0
      end if
      
      -- otherwise, check that there's an object at thisCoord, and summon the
      -- value from it, or return 0 for undefined
      put getLast(coordList) into thisCoord
      if count(array) < thisCoord then return 0
      put getAt(array, thisCoord) into subArray
      if not objectP(subArray) then return 0
      deleteAt coordList, count(coordList)
      -- do the recursive call
      put getVal(subArray, coordList) into retVal
      -- repair the coordList
      add coordList, thisCoord
      -- et voila
      return retVal
    end getVal
To create your array, use:
  put birth(script "array object") into myArray
and get and set values with:
  setVal myArray, [1,2,3], blah
  put getVal(myArray, [1,2,3]) into blah
(note: while this allows the creation of arrays of arbitrary dimension, it's important to always use coordinates of the same dimension within any single array. eg, setting x[1] = 1 and then x[2,1] = 2, you'll lose the value of x[1], because it will have become an array to contain all values x[n,1])