Item Removal and Hxcpp Debugging

Hey Folks! I'm happy to report that today just about made up for yesterday's lack of progress.

First of all, I believe I have item code working now. It's crude. It's going to need some cleaning up to make it more maintainable. It's even lacking features. But it works.

Basically, I added some more code to handle situations where items have no parent item or crew, such as items on the floor of a ship. If an interaction says to remove self, the parent item/crew/ship will do so when the interaction executes. My test case was for a hungry Mal to query the ship for any food, walk to where a food packet was lying on the floor, "SeekFood" on it, and it replied with "SeekFoodAllowDirect," delivering StatFood to Mal while deleting itself from the ship.

I also added a special item to the game called "[us]". Like the same phrase in NEO Scavenger, the game will replace [us] with whomever is acting. So if "YellowFoodPacket" has an interaction that removes "[us]", that interaction replaces "[us]" with "YellowFoodPacket" on-the-fly. This way, one interaction can be used for multiple items or crew members, instead of needing one specific interaction per item/crew type.

HXCPP Debugging

Today's other major breakthrough was being able to debug a Haxe Windows app (generated by HXCPP) using MS Visual Studio Express (MSVC).

I use FlashDevelop to write Haxe code. Partly, it's because I'm so familiar with FD from my Flash programming days. But also, it's one of the few IDEs with decent Haxe integration.

However, one of the drawbacks of FD is that it cannot directly debug a C++ (CPP) app. (It was designed to debug Flash AS3 code, which it does well.) It writes Haxe code, which gets converted to C++, AS3, HTML5, or whatever target you're aiming for. If I want to compile my app to Windows, FD actually uses a library called HXCPP to generate C++ files, talk to MSVC and compile them into a .exe. Setting a breakpoint in FD does nothing in the C++ app.

Enter MSVC. Also enter the always-helpful Lars Doucet, who pointed me in the right direction. (Thanks, Lars!)

MSVC has the ability to "attach to process", which basically means it'll start monitoring a running app. Provided that app has debug info/hooks, MSVC can trigger breakpoints (pause the app), examine variable values at that moment, step forward, and show a host of useful information about what the app is currently doing.

And fortunately, HXCPP generates these debug hooks!

In practice, one just has to F5 compile their Haxe Windows app, wait for it to launch, then tell MSVC to attach to that app's process. Then, one can use MSVC to open any .cpp file in the generated C++ code, toggle a breakpoint by clicking the sidebar, let the Haxe app run, and MSVC will pause/step forward/show locals/etc.!

Specific steps:

Spoiler: Highlight to view
  • Open FlashDevelop.
  • Open the .hxproj Haxe project in need of debugging.
  • Using the dropdowns at the top of FlashDevelop, select "Debug" and "Windows" from the available options. (Ctrl+F5 and Ctrl+F6 also toggle these.)
  • Hit F5 to compile the project for Windows. Wait a few seconds to a few minutes (depending on project size and whether it's been compiled before) until the application finishes compiling and launches.
  • Open MS Visual Studio Express.
  • Look for a green arrow at the top that says "Attach..." and press it (or use menu Debug->Attach to Process...)
  • At the bottom of the resulting "Attach to Process" dialog, search the "Available Processes" list for the Haxe project, and select it.
  • Click "Attach"
  • Open Windows Explorer and navigate to the Haxe project's "bin/windows/cpp/obj/src" folder.
  • Drag a the .cpp file in which you want a breakpoint into MS Visual Studio Express. (You can alternately just open the .cpp file from MSVC's File menu.)
  • Search for the line of code at which you want to insert a breakpoint.
  • Click to the far left of the line of code. A red dot should appear.
  • Switch back to the running Haxe app. (Depending on where your breakpoint is set, you may need to trigger something in the Haxe app to reach that point in code. An easy place to start is a per-frame update method.)
  • Begin using debugging tools. F10 and F11 to step through the code, hover mouse over variables for value info, examine call stack and locals, etc.
  • When done, you can either hit the red "Stop" button at the top of MSVC, or close the app if it's accessible.

Now, fair warning: it's ugly. The generated C++ code isn't as human-readable as the raw Haxe code. A lot of the same var and function names are in there, but you'll also find a lot of generically-named temp variables to wade through. Fortunately, HXCPP injects a lot of debug info that can help humans map between raw Haxe code and the generated C++. E.g. you'll see a lot of "HX_STACK_LINE" calls with line numbers that correspond to the Haxe code. So prepare to alt-tab between MSVC and FD quite a bit.

Still, being able to break, inspect locals, step into and out of functions was a real help for me today as I was debugging the item interactions. So hopefully, typing all this out will help someone else in my situation down the road!

I'm actually pretty excited about reaching this point. Not only do I have rough item logic in the prototype now, which is a milestone in itself, but also now I have a powerful tool for debugging non-Flash output from Haxe!

Next week might get interesting...