The rigors of OCTGN development

I must have spent 16 hours a day on the weekend coding my netrunner plugin and yesterday I stayed until 5am coding the latest features. I don’t know why, but this kind of thing is addicting to me. I just can’t tear away from my computer while my code is still not working. If I don’t get to a working state, I won’t go to bed. And given the sorry state of the OCTGN debugger, something that I think will have fixed in 20 minutes, ends up taking 1.5 hours. Of course my wife is none too impressed by this, since I end up telling her that I’ll be going to bed “soon” and when I get there, it’s not even in the same timezone as “soon”.

WTF is this shit?!

And speaking of  a debugger, can I rant about the one, or rather lack of one in OCTGN 3 for a moment? Dear gawds I want to rip someone’s head out at times. It is so bad that the only thing I get is a python syntax check when I try to install a new version of the plugin, and even then, when it finds unexpected sytax (eg, a missing closing parenthesis, a bad indentation etc) it will report the correct issue, but then point to the wrong line of code! You can see that in the screenshot on the right, where I removed a colon after a loop opened, so it got confused by the line break. It then reported a line 30 lines above it! it seems that the more deep in the code the error is, the larger the offset of the line reported. This makes finding syntax errors an absolute pain in the cohones. But this is nowhere near as bad as how non-existent runtime debugging is.

If an error appears during runtime (e.g. trying to read a variable that doesn’t exist, like a typo), the only thing I get is a python aborting error that mentions the very first function I called in OCTGN. So if I have a complex structure where the first function can call upwards of 20 others, included nested calls etc, then imagine one script failing with this error. There is absolutely no clue where to begin looking! I used to have to manually enter short pop-up windows in the code, that would inform me where I’m at in the code, so that I can begin to even track the issue. Tracking a small case-sensitive typo could take from 5 to 20 minutes, depending on how much code I wrote in between. Now? I’ve written my own “soft” debugger inside the python script, which accepts levels of verbosity and spits out messages such as which function I am entering/leaving, and what the result of regex commands are. It’s not perfect, but at least it narrows down my search considerably, and I don’t have to repackage the plugin just to insert some error tracking code.

Why would I repackage the whole plugin to test a line of code, you ask? Fool! A sane development environment of course provides some way to alter code on the fly, not to mention a runtime debugger. But OCTGN is no same development environment. If anything, it’s actively taxing your sanity as you spend 10 minutes for the 1000th time, trying to track which of the 10 variables in a function failed to receive a value somewhere. But if that wasn’t enough, the lack of a way to modify your code while in the game, means that the only way to make small changes in order to try and fix issues is to:

  1. Exit the game you’re currently in.
  2. Make your changes in the python code and save the file.
  3. This is what you get if you try to install a new version of a plugin with the same filename as the previous version.

    Re-add the python file into your .o8g file (a simply .zip, renamed). I use 7zip’s handy function to remember the previous names of files you’ve compressed into, so I just select the relevant directory, “compress to” and then select the name. So it adds and replaces to the existing .o8s files with the same name in the current directory. But make sure the .o8g file you’re putting it into does not have the same name as the .o8g file you used last time! Since OCTGN always keeps the current plugin files open in the system, if you try to reinstall a file with the same name, it will fail. So what I do is keep two .o8g in the folder, Netrunner-OCTGN.o8g and Netrunner-OCTGNa.o8g, and every time add the latest changes to the other one.

  4. Go to the Game tab.
  5. Select “Install Game”.
  6. Find your new .o8g file and select it. This takes 2 extra clicks for me since for some reason Windows 7 or OCTGN, I don’t know which, refuses to remember the name of the previous directory I was in last time I installed a game.
  7. Press OK to install it. Hope you didn’t miss any syntax errors. If you did, you have to close the almost-useless error pointer, go back, fix the issue, and then start from step 2 again. But THIS time you have to use the same .o8g name you just used, as it didn’t actually install it, so it’s still using the old one. Make sure you remember that info, because this shit’s written nowhere…
  8. If you had no syntax errors, then it will allow the plugin to be updated after a confirmation dialogue (extra click there.)
  9. Once your plugin is updated, reinstall the sets, if I’ve made any changes to the autoscripts of the cards. Fortunately, those don’t lock the files, so I can re-use the same filenames and don’t have to keep track of which file I installed last time.
  10. OCTGN randomly decided to keep one file open. Why OCTGN? Whhhhhy?

    However, sometimes OCTGN will decide to keep one of your set files open anyway, usually because you looked at one of those cards last (although OCTGN is using an internal DB now). In case you see those lovely red errors when installing the sets, the quickest way to fix it is to restart OCTGN, including logging-in again. Mmmm, I loves me some time wasters…

  11. Go to the game Host/Join tab.
  12. Click “Host” to start a game lobby.
  13. Select the Game you will play from the list.
  14. Provide a lobby name (or click OK to accept the previous one.)
  15. Press Start.
  16. Wait 5 – 10 seconds for the board to load.
  17. Load my debugger (which I’ve conveniently coded so that it spawns 6 cards with abilities I’d like to check and the environment to use them in. In the past I had to always load a deck, use the Setup function, and then fish for the cards I wanted to check.)
  18. Test the new code.

My now I’ve gotten so proficient at this, that I can do this whole procedure in under a minute. However I need to do this for everything. From the smallest typo, to the biggest code blunder in the universe. Can you imagine the overhead of this? I can tell you, it’s absolutely ludicrous. I would code 50 times faster, if I could make code changes and re-run the same code WITHOUT FRIGGING EXITING, REPACKAGING,REINSTALLING and RESTARTING MY GAME EVERY TIME! The fuck!

So imagine doing all that, and then realizing you didn’t fix the issue at all. Imagine you don’t even know where to being looking for the error, so you have to do this whole process 2 or 4 times, just to enter enough messages and error hooks in the places you suspect the problem is, just so that can begin to track it down. I’ve spent hours in issues that would have normally taken me seconds, just because I couldn’t track it easily (think: regression bug) Fun!!!

Fuck you OCTGN! FUCK! YOUUUUUUUUUUUUUUU!

Oh yeah, did you see that wonderful error above. This is the totality of the console I have in the game. A lot of goddamn scrolling involved to perhaps get an idea where the error happened. As you can see, by default, it tells you fuck-all where the error would be. Not only that,  but the error will appear before ALL the notification you’ve put in the code, because python processes the code faster than OCTGN puts out notifications. So first you see the error, and then you see your debugging messages you’ve inserted into the code. Talk about mindfuck.

Oh sure, you see that it was the “useAbility()” function, but that’s just where the rabbit hole starts. In fact, this particular error was caused by a regex which I hadn’t configured to process numbers in the text of special Autoscripted announcements. So one group in the regex results was empty. This was the 10th function or so called from useAbility()…It took me half an hour to track that down, and that was WITH my custom-made debugger spitting out the actual last function used until now. Good fucking luck figuring that out just from that message…

You need to be a goddamn zen coder to not be ripping your testicle hairs out with OCTGN. You need to be able to write flawless code the first time around, because if you don’t, you’d better write your own debugger first before you even begin to write any sort of advanced plugin. And then you’d better have the patience of a Go grandmaster…

Why yes, I have asked the developers for more debugging tools, more than 4 months ago, multiple times, why do you ask..?

Phew! Glad that’s out of my system

However, for all its failings, OCTGN is still top of the line among card game engines, primarily because of its integration of Iron Python. It has its quirks (some of them quirkier than others) but the flexibility and power of using python in the backend just can’t be topped. Other card games like GCCG also support some sort of scripting, but then you have to learn its own internal syntax, which is definitely not as advanced as the capabilities of python. This is why, for all its failings and frustrations, I still stick with OCTGN. It’s the first engine that allowed me to fully realize my vision for how a card game engine online should work (i.e. automation up the arse!).

Hopefully the new version that’s in development will have *something* better than this sorry situation. But I swear if they have to break my existing python code in 20 different ways due to a new interpreter (like what happened when moving from OCTGN 2 to OCTGN 3) without giving me a proper debugger, I’m going to cry…Imagine having to debug 3000 lines of code times 4 plugins…

Aaaanyway, it is what it is. Still, through the fire and flames, I’ve still created a plugin I am proud of, and soon I’ll be using the existing code to implement Android: Netrunner. So why don’t you give the current plugin a run and let me know what ya think. You don’t want to let all that past frustration go to waste, do you? Do you?

Bastard.