I'm writing a kinda long, kinda complex API script for a game I'm about to start, and I'm running into a problem with some data mysteriously vanishing from the state variable I've set up. In a nutshell, the script assigns players to one of four quadrants on
the board (one of which is shown to the left), then populates those quadrants with graphics that represent
their abilities and pools, which they can interact with. Most
interactions are done via "bins", which are regions defined by grid
coordinates that trigger different functions when counters or other
things are dragged onto them. Both the photo and the skull symbol in the image at left have been registered as
"bins", and the three rows of trait dots can be dragged & dropped
onto them for various effects. Problem: For some reason, whenever I restart the sandbox, my quadrant assignments will sometimes not persist. This makes little sense to me, because the quadrants are stored very simply. For example, if I check the state variable immediately before restarting the sandbox, I'll get this: state.DotTracker.Quadrants = {
TL: "-KjgjouPXDxIwG3XCa34", // (character IDs linked to that quadrant)
TR: "-KjMWf6MutGjCwewZaEh",
BR: "-KjcGCjeuUXgT7cutPga",
BL: "-KjmbIllYx5_RjfmiiyN"
} ... but, when I log the same state info to the console as the very first step after restarting the sandbox, I'll get this: state.DotTracker.Quadrants = {
TL: "-KjgjouPXDxIwG3XCa34", // (character IDs linked to that quadrant)
TR: "-KjMWf6MutGjCwewZaEh",
BR: "-KjcGCjeuUXgT7cutPga"
} It seems to only affect the last assignment I made, which is strange because I can't figure out what makes the last assignment any different from the assignments that came before---they all use the same function. I've considered that it might be a reference/pointer issue (as I know references to objects/functions don't persist), but I've tried everything to exclude this possibility---most recently peppering my code with random "state.DotTracker.Quadrants = _.clone(state.DotTracker.Quadrants)". My last thought is that the state variable might have a limit on how much data it can store? The method I'm using to keep track of my bins involves a very large 2-dimensional array, and I'm wondering if that might be making the state variable... unstable... or something? I've included the relevant parts of my code below; hopefully it's enough, I pruned out everything I thought irrelevant but wanted to keep the main formatting intact in case there's a scope problem or something. Thanks in advance for any help you can provide! var DotTracker = DotTracker || (function () {
'use strict';
//--- SNIP ---// (a bunch of variable declarations and utility functions)
var cleanupObjectReferences = function () {
/* First "substantial" function run when sandbox starts up: declares variables, deletes unlinked graphics, etc.
big props to Aaron C for a lot of this (though I'm sure I've mangled it in ways that physically hurt him) :) */
state.DotTracker = state.DotTracker || {};
state.DotTracker.Chars = _.omit((state.DotTracker.Chars || {}), ["null", null, "undefined", undefined]);
state.DotTracker.Quadrants = _.omit((state.DotTracker.Quadrants || {}), function (value) {
return !_.isString(value);
});
state.DotTracker.Bins = state.DotTracker.Bins || {};
state.DotTracker.Bins.XYMap = state.DotTracker.Bins.XYMap || [];
state.DotTracker.Bins.Index = state.DotTracker.Bins.Index || {};
/* These "Bins" are graphic objects on the board that you can drag other objects into, to trigger various functions.
When an object is dragged, it checks its new position (in grid coords) against Bins.XYMap (a 2-dimensional array of X/Y grid coordinates).
If a bin occupies that position, XYMap will return its binName (string); otherwise, returns undefined.
E.g. object's grid position is (12, 75), it looks up Bins.XYMap[12][75] to see if there's a binName there.
If so, accesses all the bin's details via Bins.Index[binName]. */
//--- SNIP ---// (wacky code to clear unlinked objects and solve problems from crashing; not relevant
// to my problem, as the error occurs before this point.
};
var assignQuadrant = function (quad, charID) {
/* This is the main function to set a character up on one of the four quadrants on the board. It creates a stat block, name, photo, and other graphical elements specific to that character and the system I'm running. */
// First, clear out any characters currently in that quadrant, as well as the quadrant iself:
state.DotTracker.Chars = clearCharacter(charID); // returns _.omit(state.DotTracker.Chars, charID)
state.DotTracker.Quadrants = clearQuadrant(quad); // returns _.omit(state.DotTracker.Quadrants, quad)
// Create a template object for the character, referencing the various objects and stats...
state.DotTracker.Chars[charID] = { vitality: {}, willpower: {}, spite: {}, shadeSymbol: "", quadrant: quad }; // Assign the charID to the Quadrants lookup object: state.DotTracker.Quadrants[quad] = charID;
// ... and then construct the graphical objects and bins for the character in this quadrant:
_.each(["vitality", "willpower", "spite"], function (trait) {
state.DotTracker.Chars[charID][trait] = makeDotLine[trait](charID);
});
state.DotTracker.Chars[charID].shadeSymbol = makeShadeSymbol(charID);
restoreAllValues(charID); // grabs current values of stats from character sheet
};
var handleInput = function (msg) {
/* Event Handler: Chat Input (pruned to include only the relevant parts) */
var args = msg.content.split(/\s+/);
switch (args.shift()) {
case '!dt':
switch (args.shift()) {
case 'assign':
var quad = args.shift();
var token = getObj("graphic", msg.selected[0]._id);
var id = token.get("represents");
//--- SNIP ---// (just some error-catching code)
assignQuadrant(quad, id);
break;
//--- SNIP ---// (a bunch of other commands, not really relevant)
default:
showHelp(who);
break;
}
break;
}
};
var checkInstall = function () { // And right here is when I check the status of the Quadrants object, and find entries missing.
log("SUPER EARLY: " + JSON.stringify(state.DotTracker.Quadrants || {});
log("");
log("*********** INITIALIZING ************");
cleanupObjectReferences();
};
var registerEventHandlers = function () {
on('chat:message', handleInput);
};
return {
RegisterEventHandlers: registerEventHandlers,
CheckInstall: checkInstall,
};
}());