The biggest problem when trying to do harder levels in CodeCombat is that players have only one way of debugging their code:
this.say("Rect is at " + rect.x + ", " + rect.y + " with size " + rect.width + " x " rect.height");
It took me 30 seconds just to type that out, and I made a syntax error. This is not okay. As a Hacker News commenter put it:
"Only the very darkest realm would deprive its wizards of the mighty printf spell! To what Silicon demon legion did you pledge fealty to summon this coding abomination upon an unsuspecting land? Winter is truly coming at last."
So why is debugging so bad? Well, for one, serializing things across the web worker boundary is imperfect--you can't pass most World objects because they'll point to Thangs and Vectors and such which contain functions--and very slow if you're sending strings for each step of your algorithm for each frame of the simulation. So not only do you get really boring and unhelpful log statements like "Rect is at [Object object]", but it's very easy to blow up the simulation performance, and you have to either add a better UI than this.say()
for seeing the messages or force the player to go to the browser console. We used to do this, but we shut it off.
We could solve most of these problems, but there is a better way. An amazing way. Just lurking, waiting for us to have time to implement it. CodeCombat's programming environment should allow us to build a time-travel debugging interface that combines the best of both breakpoint-based stepping debuggers and using log statements, but far better than either. It'll be quite Victorian. You'll just scrub back and forward through your code's execution history and hover over any variable to see its value at any point in time.
jsdares actually does something like this already:
![screenshot 2014-01-02 10 06 03](https://camo.githubusercontent.com/67fcf0dd3dffda0d90f08ccff3e36051b80827025a3cb48b1e0eee0593b3fd4e/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f39393730342f313833343230382f39326162323532302d373364382d313165332d383265622d3231663330373130393265322e706e67)
In its solution, each statement generates a step message, and when you over over that statement's frame number, it shows the step message below the statement. It also uses blue dots to show which statements were recently executed or will execute. Finally, on the left you can see it shows the values of all currently defined variables. @janpaul123's thesis discusses the interface and motivations in Chapter 3, although the implementation has advanced beyond the thesis since its writing. There is some discussion of how it's done in Chapter 4.
I was thinking of implementing something different. Instead of trying to show all variables and their values, I'd prefer to focus on one variable when the player hovers over it. CodeCombat variables are often complex objects like Thangs, so a simple string isn't going to be enough to get a good picture of their state. You might want to see a Thang's pos
property, or perhaps even its target.target.id
to see who its enemy is attacking. Clearly we're not going to serialize all that state for every variable for every frame for every Programmable method.
Instead, what I plan to do is to keep the simulated World around in the web worker thread, possibly more than one at various intervals to make things even faster, and resimulate up until the current call whenever this kind of debugging info is requested. Then we can use Aether to thoroughly inspect the state of all accessible properties, serialize everything we can, and send it over for custom presentation that's aware of our common types (like Thangs and Vectors).
![2014-01-02 11 30 16](https://camo.githubusercontent.com/82752b23e169d5ab1dc1d70a7ea4d5750917bf90bc4f8b0dd8fa6da9ad5a2d85/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f39393730342f313833343834362f62623436616237652d373365342d313165332d386539312d3932663266623637353431322e6a7067)
I think the delay should be just a split second on most levels--suitable for idly hovering over various variables in the code to check them out. Then when the player wants to see a variable change over time, she can just scrub the playback and watch the variable change. It should be especially fast scrubbing forward, since we'll already have the World simulated up until the current frame and can just get the next frame--but it shouldn't be too bad going backwards, either.
With some cleverness plus the insanity of Aether's control flow yielding, we should also be able to scrub/step forward and backward within the current function execution on a statement-by-statement basis. We probably can't use the main playback scrubber for this, but perhaps some keyboard shortcut or traditional step forward/back/over/out buttons for when one wants to get really fine-grained could do the trick. jsdares experimented with a second timeline sort of interface, since beginners are confused by stepping debugger buttons, but as I recall having two was also confusing.
To implement this, we'll also need to do a bunch of improvements over in the Aether project, where I've added a companion issue. This issue can track the progress on the front-end interface as well as the coordination of Aether state harvesting and World resimulation in the background thread.
If we can pull this off well (and polish up some other editor rough edges), it has the potential to turn CodeCombat into the best environment for solving programming challenges that the world has ever seen, since not only will be there a sweet visual interface to see what's going on and gameplay mechanics to make it fun, but the overly powerful debugging, live-coding, and co-op multiplayer should make it possible to solve harder algorithms than you'd be able to do in a traditional environment--programming without a blindfold on, as it were.