Yup, itâs simply an array with arrays in it. See the MDN JavaScript Array documentation if you need help with working with arrays or understanding the code below.
To create the array you can do:
<<set $schedule = Array.from({ length: 366 }, function () { return []; })>>
which will create an array of 366 elements (0 to 365), and each element will contain an empty array. (Note: Arrays always start at index zero.)
You can then access the elements of that array like this:
// Set the current day to day 20.
<<set $currentDay = 20>>
// Add an event object to the current day's schedule.
<<set _eventObject = { name: "Event name", description: "Blah, blah, blah..." }>>
<<set $schedule[$currentDay].push(clone(_eventObject))>>
// Get the current day's schedule.
<<set _daySchedule = $schedule[$currentDay]>>
// Get how many events there are for the current day.
<<set _eventCount = _daySchedule.length>>
// Get the name of the first event in today's schedule, if there is one.
<<if _eventCount > 0>>
<<set _eventName = _daySchedule[0].name>>
<<else>>
<<set _eventName = "(none)">>
<</if>>
Those are just examples, you donât need to do any of it exactly like that.
Now, just a quick primer on the difference between âobject data typesâ and âprimitive data typesâ and how they behave in Twine/SugarCube, for those who donât know, since you can get yourself into trouble if you donât understand how they work.
In the above code, where it does <<set _daySchedule = $schedule[$currentDay]>>
, after that, _daySchedule will act exactly the same as $schedule[$currentDay] (based on whatever value $currentDay had at that time) because theyâre now both referencing the same JavaScript Object. This means that you could do $schedule[$currentDay][0].name
instead of _daySchedule[0].name
above, and it would work exactly the same. It also means that if you change something within a value of one of those variableâs objects (e.g. <<set _daySchedule[0].name = "Xyz">>
), it will also change the value the same way in the other one, because both variables are referencing the same Array object.
Thatâs why I used the SugarCube clone() function above, to make a separate copy of the _eventObject object thatâs added to the array. That way, if you later modified a value within the _eventObject object, it wouldnât also change the value that had been added to the $schedule array earlier using the .push() method.
I should also note that, for SugarCube story variables, all JavaScript Objects (including Array objects) are cloned during passage transitions in Twine/SugarCube. So, even if $A holds a reference to an object of some sort and you do <<set $B = $A>>
, the two story variables will only point to the same object within that passage. In the next passage, each of those story variables will now contain references to separate copies of the original object.
For contrast, variables which are set to data types which are not objects (i.e. numbers, strings, Booleans, undefined
, and null
), which are known as âprimitive typesâ, store the value directly in the variable, as opposed to storing a reference to the data the way it would with an object data type. In other words, if $A is set to a value which is a primitive type, you do <<set $B = $A>>
, and then change something within the value of one of those variables, the change will not also occur in the other variable, because each variable gets their own copy of that value.
TL;DR: Primitives are stored in variables by value, while objects are stored by reference, though SugarCube breaks references upon each passage transition.
Hopefully that wasnât too confusing, but when youâre working with objects, itâs a good idea to have a basic understanding of the way that they work.
Have fun! 
EDIT: Fixed array creation code.