LTU Forge Global Games Jam

Participated in my first games jam a couple weeks ago, the LTU Forge Global Games Jam. Super fun, a little stressful at times, but it was so exciting to be able to do it in such a welcoming environment. Coming out of it, I feel inspired and more experienced for having done it. I really want to do another; a feeling similarly expressed by my friends.

Carl Escape is a narritive/dialog based game, so naturally that was the first system we worked on.

Multiple dialog bubbles with focus on the currently talking character was the implementation we went with after a few iterations. Blukat worked on the data structure that backed this one.
While the final game had only two characters, it allowed for dynamic names, backgrounds, and choices in the dialog tree.

As the art and storyline came in from JD, JabberJaws, and BearAxe, Blukat and I plugged in the assets into the API, everyone coming together when things needed final tweaks. Half way through, the dialog front end was mostly complete so I switched over to working on the minigames.

Powered by

ConEmu and cmder fix for saving current working directory

ConEmu and tools built on it like cmder are awesome for Windows development. I can’t see myself ever going back to conhost.exe with its lack of color, unicode-support, buffered-scrolling, tabs, configuration, sane hotkeys… ConEmu does come with a set of annoyances though.

The biggest ConEmu annoyance for me is it not properly persisting the current working directory in Git Bash. Long story short you need to add this snippet to your .bashrc.

1
2
3
4
5
6
7
8
9
#ConEmu Integration
if [[ -n "${ConEmuPID}" ]]; then
#For WSL and cygwin/msys connector (which ConEmu will use for Git bash). It
#sends an operating system command (OSC) to cygwin/msys connector to update the
#cwd on PS1 print (the \$PWD in the below string, \w will not work).
#https://conemu.github.io/en/ShellWorkDir.html#connector-ps1
#https://github.com/Maximus5/ConEmu/issues/1752
PS1="\[\e]9;9;\"\$PWD\"\007\e]9;12\007\]$PS1"
fi

ConEmu by default does not know when Git Bash changes its working directory. This breaks features like tab cloning (hotkey WinS), %CD% in tasks, and workspace persistence. To notify ConEmu of changes, you have to send an operating system command (OSC) using special control characters. The ConEmu documentation does describe how to set this up but I still found it buggy. After extensive testing, I found that only paths that contain the ~ character break it and submitted a bug for it. Using the above snippet I created implements the OSC described in the documentation and also fixes the bug.

This fixes tab cloning, %CD% in tasks, and workspace persistence for non-cmd shells. You can now use all of those features and do nifty things like using the same directory when opening a new task no matter what shell. All you need to do is add /dir %CD% to your “Task Parameters” so that when ConEmu starts that task, all commands will have %CD% as their current working directory.

Vue.js render() and $slots; Corrupt DOM

Just ran into an issue today when making a component with a custom render() function and messing around with vnodes passed in via $slots. A seemingly simple template produced really odd results where some DOM elements would disappear, some would be duplicated, some would be out of order, and others would have their inner content ripped out to their outside after a few rerenders. Small template tweaks would also produce vastly different output, sometimes seemingly correct output.

You can see an example in this codepen:

See the Pen Vue.js $slots with and without v-bind:key by Peter “Cobertos” F. (@cobertos) on CodePen.

Is WebAssembly faster than vanilla Javascript?

I keep seeing GitHub issues of people just like me trying to figure out what WebAssembly (Wasm) and previously asm.js mean for performance-related javascript (in my case, games). WebAssembly should introduce less abstraction between you and the hardware and so your code should in general run faster, right? In reality this question is harder to answer because WebAssembly runs in a Javascript VM-like environment and was not made directly motivated for performance. I’ll be putting aside the misinformation and anecdotes to hopefully find out if and how applying Wasm might make your projects more performant.

A bit of background on Wasm

Wasm was originally created for so much more than just performance. Wasm is about providing a proper compile target for native code to get into the browser. In the earlier stages of the development cycle, Wasm was actually asm.js, a unofficial JavaScript standard that only supports strict subset of JavaScript to allow native code to compile and run in a JavaScript VM. Wasm is also about providing an environment where multiple sources of code can run safely at a low level where things like memory management and control flow structures (jumping and loops) matter. Already Wasm is doing a ton of things that previously were infeasible or a real pain to do in the browser. (Sourcing a lot of this from this blog post by Adrian Colyer. It’s good to keep this in mind while we ask performance only questions.

Wasm loads much quicker than Javascript code in pretty much all cases I’ve seen that is not really a topic that’s up for debate so I’ll skip over load performance and focus on runtime performance.

Chemistory Level and Net Code

Chemistory over the past couple weeks got a few new features, the biggest being an actual level and client/server networking code (or at least the start of it).

There’s a separate build for client (Browser) and server (NodeJS), both of which run THREE.js and Oimo.js, though the server doesn’t actually render anything. It took a switch to Gulp from Grunt, a pull request to WWOBJLoader2, and heavy use of ifdef-loader but it all actually talks to each other. Next steps are to add boilerplate for RPCs and member syncing and test out a little bit of multiplayer.

I really hope this goes quickly! I want to get back to game play and UI so I can start play-sharing it with my friends.

A Simpler Blender Development Environment

After accidentally running Blender from a native console, I realized a much easier way to setup Blender for iterating over features/bug development. My old Blender Python module reloader was becoming too unreliable in my codebase so it was a welcome discovery.

To easily reload Blender for development:

  1. Set up the Blender UI to your liking to test your add-on. Mine happens to be the scripting interface but instead of the notepad on the left, I have the User Preferences view with the add-on tab open.
  2. Save this as your startup file for Blender
  3. Run ./blender.exe from cmd, bash, or Git bash to capture error output in the console without having to toggle it manually every startup.
  4. Optionally, run while :; do ./blender.exe; done from bash or Git bash instead to continuously rerun Blender when it exits automatically.

HelloWorld Games Jam Outcome

My current company, HelloWorld, hosted a small games jam after hours. Over the course of 5 days, James (another dev at HW) and I put together two small concepts utilizing a networking engine one of my other coworkers wrote

The original concept for my game was platformer where the player must escape a pool of rising lava and race her friends to some sort of goal. The first step was intergrating the networking engine with THREE.js and physics to get 3D aesthetics and correct movement. The actual gameplay is quite shaky due to integration problems and time limitations. Once the boilerplate was as complete as it could be, I spent a bit of time throwing together a test level and playtested it with James. For some added spice, I tried my hand at adding an animated model for the player. THREE.js and Sketchfab made this easier than I expected though I had to use the converted GLTF format SketchFab provides (THREE.js’s THREE.FBXLloader doesn’t support animations and has other corner case issues). Given the time constraints this is as far as I got but I say for an 8 hour game jam that’s not too bad.

Super exciting and I’m looking forward to the next time I get to participate in a games jam. I’ve been keeping my eye on the The Forge to see if Lawrence Tech will host in 2019 where maybe a few people from HelloWorld can participate.

Bobskater - A Python obfuscation Library

Using: pythonv3.5

Recently I had the need to obfuscate/minify some Python files before I distributed them. Coming from the Javascript world of ES6 where transpilers and processors are plentiful, I figured there would be a mature, well maintained library similar to UglifyJS in the Python ecosystem. It turns out that this isn’t the case.

I decided to code and package my own, called bobskater. It turned out to be surprisingly easy with Python’s ast library, the invaluable documentation at GreenTreeSnakes, and a little library called astunparse. Being completely AST based, it won’t die on weird syntax or require special formatting. All obfuscation decisions are based on AST node type. There are a few limitations as of now but they’re all documented in the repository.

There do exist a lot of libraries/techniques out there (free and pay) that perport to do this, with mixed results:

  • Compile to .pyc using compile(). Even at the highest optimization you can still extract the original code, variable names, and docstrings with uncompyle6 in literally just one command.
  • Encrypt your modules and hook the import functionality to decrypt them when loading them at runtime. Too simple to reverse in my opinion.
  • Compile your modules using Cython, which removes Python bytecode though introduces it’s own set of problems, like not being able to call using named kwargs (see this citrisbyte article for more details). I could see this not playing nicely with Blender’s import system.
  • opy - For a Regex-based obfuscator it worked surprisingly well except for one or two corner cases. Doesn’t scale well though as all external identifiers that shouldn’t get obfuscated need to be manually entered. Requires specific source code formatting but isn’t an issue if your code is based on Python’s recommendations
  • pyminifier - An unmaintained, hybrid regex/token-based obfuscator. 80 open issues and seemingly errors in very basic cases.
  • pyobfuscate - Last updated in 2013, not particularly well documented and non hopeful open issues.
  • mnfy - Python minifier but no obfuscation.
  • and a few others.