Sunday, April 13, 2014

Hooray for Open Source

Today I started investigating how I want to handle the mini-map. I still haven't completely settled on a design that I like. Some of the questions or factors that I need to think about are:

  1. The minimap needs to be smart enough to (at least mostly) build itself from my level data, without me having to go back and build a big minimap by hand.
  2. I want to minimize the effort involved -- I neither want to have to add a bunch of meta-data to my maps to give them hints about displaying themselves on the minimap, neither do I want to have to write a ton of code for the build process to make it build the minimap.
  3. How much detail do I want to show on the minimap? In Anguna, the dungeons were just wireframes of the rooms (which is closer to a Super Metroid-style map), but the overworld was actually just the image of the overworld map scaled down to any extremely tiny size.
Super Metroid's wireframe map. Robo-Ninja's world is about as big as the "Brinstar" section of Super Metroid.
(bonus points for those of you that can point to Brinstar on this map without looking it up)


I'm leaning toward doing scaled down images (in answer to #3), so I started looking into a simple scriptable way to dump an image file from my map, using the Tiled editor. Turns out, they have a command-line utility for dumping them. The only problem: it omits any map layer with the name "collision" (why they hardcoded that is beyond me), which is the name I use for the primary layer in my maps!

Luckily, it's open-source! It took about an hour to:
  • Find the place in their code where it omits "collision" (actually, I didn't realize that's why my collision layer wasn't getting exported until I searched through their code!)
  • Change the command-line utility to take an argument flag to tell it whether to omit that flag
  • Compile, test
  • Send a message and a pull request to the maintainer, in case they're interested in using the changes.
So now I can dump out my images of my maps in an easily scripted method. Hooray for open-source!

Now I just need to decide about #1 and #2 above. My map files theoretically can figure out how they're all connected to each other, based on the "exit" hotspots, that warp you from one map to another when you get to a certain edge. But the maps don't really know their absolute position in the overall world map (which was just poor design/planning on my part).  So I really need to decide between computing each map's position by tracing through all the connections between maps (from a known start point), vs going back and adding metadata to each map to tell it what its position is in the global map. I'll have to think on that some more, I guess.

Wednesday, April 9, 2014

Back to the Ninja

Well, the Dart coding was fun. I ended up spending a few weeks-worth of coding-with-one-hand-while-holding-a-baby-in-another playing with it. My verdict: I'm not sure I was any more efficient working in it (particularly with the combined pain of learning a new language/framework, lack of documentation, and lack of 3rd party libraries), it was definitely less painful than javascript or other traditional ways of doing web development. I'll be interested to see if it goes anywhere. Being a Google technology, I don't have my hopes up.

So this week, I'm back at Robo-Ninja. I think the trick to getting me to finish a development project is to have a fan. Having Aaron pester me about it is a good motivation!

So during approximately 10 minutes last night, and 15 tonight, I managed to get the consumable slow-motion powerup working. It was one of those happy times where everything fits smoothly into your design without bumping into any nasty corners.

I also realized from testing that my icons for cycling through your abilities were too small. It was fine on the computer with the mouse, but once I had my hands on the screen, blocking my view, it was really hard to tap the right spot quickly between manically tapping the screen to time my jumps and slides. So I've increased the size. Hopefully that will help, but I haven't had a chance to test on my actual phone again yet.
The icon on the left is after the size increase. The consumable items on the right are how big they were originally. 

Next steps: the wall cling ability, and the minimap.

Monday, March 17, 2014

Lack of UI libraries in Angular Dart

So I'm still slowly chugging along playing with Angular Dart.

The thing that's bothering me now is, because the it's such a new language/framework, is the lack of decent UI stuff. I needed a pretty date picker for my test project. I could either use the HTML5 date picker which isn't supported in half the browsers out there, or write my own.  I guess I could alternatively import all of jQuery and figure out how to get Angular Dart to talk to a jQuery widget. Ugh.  I finally found someone that had written one using WebUI, a deprecated system for making widgets in Dart, and managed to port it over to Angular. (if you are reading this and need one, email me!)

Tonight it was an autocompleter that I needed. Again, I ended up spending awhile converting a WebUI widget. Which is great practice for learning a language and framework, so I'm not complaining too much. But it certainly cuts down on the productivity.

The way components in Angular Dart are written, I can envision a world with a huge library of simple-to-use UI components. It's MUCH MUCH MUCH cleaner than trying to pull in javascript libraries for a widget. But I guess there's just not any real community or momentum behind the project yet.

Friday, March 14, 2014

Oops

Huh, that's what I get for not proofreading my last post. Didn't realize Blogger was incapable of escaping my HTML for me, so it mangled my code. It's corrected now.

And so after playing with Angular Dart for a while longer, I'm really annoyed at the Dart to Javascript conversion. Plenty of stuff works wonderfully in Dart proper, but then fails with cryptic error messages once converted to Javascript. I'm not sure if that's just immaturity in the environment, but if not, it's a pretty big show-stopper. This platform only works if the compilation to javascript is relatively seamless.

Tuesday, March 11, 2014

A week with Angular Dart

So I'm taking a (hopefully) short break from RoboNinja. With the baby, I have a couple hours in the evening where I hold her as she's winding down.  By that time, and with the one-and-a-half-hands that I have available, I just can't bring myself to try to do any serious work on it.

So instead, I decided to spend a little time fooling around learning a new web framework (Since with a new technology, you spend as much time reading as you do actually typing!) I think I've mentioned before on there that I'm always looking for new web frameworks that try to make web programming not suck. (And the vast majority fail miserably). So this time I decided it was time to try Angular Dart.

Dart is a new language from Google that attempts to replace Javascript. It's not perfect, but it's a whole lot more "normal" -- it uses class-based OO, reasonable scoping rules, etc.  Since basically no browsers support it, it can compile down to javascript. So theoretically it can run anywhere.

Angular is originally a clever javascript framework (one of the few that, when I looked at it, I said "Oh wow, neat!" instead of "huh, more ugly javascript"). So now the folks at Google have been working at porting the Angular framework to Dart. It's pretty new, and still in flux, but it sounded fun to play with.

The general idea of it is that, instead of writing a ton of event listeners, DOM-modifying code, etc, etc, you write a view with HTML plus a few magic attributes, and it takes care of automatically keeping your view and your model in sync. The simplest example is something like:

<span ng-if="person.name != null">{{person.name}}</span>
<input ng-model="person.name" />
In this case, it's all operating on the "person" model, which is an object that I'm assuming exists. As soon as you start typing in the input, the span will magically appear (since person.name is no longer null), and the span will contain the person's name. As you type. Without setting up listeners or registering callbacks or using CSS selectors to find the span's DOM object. It's neat.  You also have a controller object sitting behind the view that takes care of getting the model object, doing any business logic (ie "onSave"), etc.

Then, to make it better, you can build your own new HTML element tags, which let you easily make your own components on page. So you can do stuff like make a new date-picker element that you can use all over the place as easily as:

<date-picker ng-model="person.birthday"></date-picker>

Which, without additional wiring, will update the person's birthday field as you modify it.

So I've been fooling around for the last week with trying to put together a fairly simple webapp with it. So far, it's been really fun and interesting (as opposed to most webapp projects!), although it hasn't yet been fast. The biggest problem so far has been a lack of documentation. Angular Dart just isn't very mature yet, and there's very little in the way of documentation.  Learning a new framework and language is always a slightly time-consuming process, and it's even trickier with a lack of resources.

Debugging has also been challenging. Because all the magic data-binding and DOM manipulation happens magically by the framework stuff, it's almost impossible to tell what's going wrong when the problem is with your HTML view. Dart has decent debugging facilities, but they really just apply to your Dart code itself, and not all the Angular magic. (unless you want to slowly step through the all the Angular libraries).

That all being said, it's been really fun and interesting to work through. I can't yet judge how productive overall the framework is, but it's definitely more pleasant and interesting than slogging through javascript event listeners and DOM manipulation.


Saturday, February 1, 2014

New Baby

So, I just came here to say that our 3rd child, another girl, was just born!

That may slow things down a little. Or maybe, during the couple weeks I'm taking off work, where I spend hours holding a baby on my lap, unable to do much but sit still, I might actually make some progress. We'll see, we'll see. For now, enjoy a picture of my new little girl with a birthday cupcake that she can't eat.


Sunday, January 26, 2014

Portable Checkpoint

It turns out I'm chattier when I'm more excited about the project. I'm still making progress, but was slogging through some code that was designed poorly, so it wasn't any fun. So I've been pretty quiet.

Fairly early on, I had decided a wanted a consumable "portable checkpoint" item that you drop right before a really hard section, so you wouldn't go crazy having to do a whole level over. Unfortunately, my item design had focused on the main character abilities, and didn't work well with consumable items. I finally slogged through that, when I realized that my checkpoint/respawn design also didn't work well with having a secondary respawn point.

So I ended up doing a ton of work, when I should have done significantly less if I had thought through my design better in the first place. 

The good thing is that I've been continuing to make progress on maps/levels in parallel. When I'm not in the mood to write code, I can turn off my brain and rough out a level map. Or use my brain and design the specific spike/jump/enemy patterns for that level.  Or if I'm sick of making levels, it's back to code.  So that works well.

So now I've got the portable checkpoint item working, along with a nice little icon. (Thanks Rob, for the icons!) And a couple more maps.

Now I need to actually properly test on my phone, which I haven't done in a few weeks. That always reveals new bugs that weren't obvious testing just on my computer. Not looking forward to that.

NES Anguna

Well, I had a little bit of time still, while Frankengraphics is finishing up her game Project Blue, to have a little downtime on Halcyon, s...