Well, the time has now come that I've been dreading. I need to figure out how to come up with some icons to represent each of Robo-Ninja's powerup abilities. I can probably find some free art resources for the general template of these icons, but I'll still need to do a bunch of graphics work to make the icons themselves. And come up with a consistent look between them.
This is going to get ugly.
So if anyone out there feels inspired to help me make some icons, let me know.
I started by blogging the process of porting my homebrew game Anguna from the Gameboy Advance to the Nintendo DS. Now, my random thoughts on development and chronicling whatever hobby project catches my fancy.
Monday, December 23, 2013
Saturday, December 21, 2013
And sometimes things are easy.
Occasionally it turns out that my code design is actually decent, which means that on those rare occasions, adding things is easy.
Halfway through my cave level, I decided it needed boulders dropping from a hole in the ceiling that you had to dodge (by timing jumps when they go by). I didn't have any code in place yet for moving obstacles, although I had vague ideas about eventually including them, so luckily I had at least designed for the possibility.
Turned out, it was REALLY easy. It took about 15 minutes to find, download, and edit a Creative-Commons licensed boulder sprite. About 20 minutes to write the code for the boulder itself. Then about 15 minutes to write the code for initializing the boulders from the tile-editor level definition. BAM, the whole feature was working in less than an hour.
That felt good, after wasting so long reworking my collision code the other night.
Next I'll work on the 2nd cave room, which includes the first major ability powerup item. So I'll have to write the code to handle the UI for switching abilities. And I need to hurry and do that, because Aaron has been pestering me all day to hurry up and add a new ability. Well, when he's not running around the house jumping over things and pretending to be Robo-Ninja.
Halfway through my cave level, I decided it needed boulders dropping from a hole in the ceiling that you had to dodge (by timing jumps when they go by). I didn't have any code in place yet for moving obstacles, although I had vague ideas about eventually including them, so luckily I had at least designed for the possibility.
Turned out, it was REALLY easy. It took about 15 minutes to find, download, and edit a Creative-Commons licensed boulder sprite. About 20 minutes to write the code for the boulder itself. Then about 15 minutes to write the code for initializing the boulders from the tile-editor level definition. BAM, the whole feature was working in less than an hour.
That felt good, after wasting so long reworking my collision code the other night.
Next I'll work on the 2nd cave room, which includes the first major ability powerup item. So I'll have to write the code to handle the UI for switching abilities. And I need to hurry and do that, because Aaron has been pestering me all day to hurry up and add a new ability. Well, when he's not running around the house jumping over things and pretending to be Robo-Ninja.
Friday, December 20, 2013
And this is why I do level design early.
So I started on a harder cave level, with some pretty hard and messy jumps and collisions.
And realized my collision code wasn't good enough.
I had originally gone for an overly simple collision model, which I hoped would be good enough: check for collisions at each corner of Robo-Ninja, and deal with whichever is the "most important" collision. Well, as Robo-Ninja is taller than a single 16x16 "block", I was running into instances where the head would go above the block without colliding, then the feet would collide with the block from beneath, and all sorts of brokenness would ensue. This also got me into trouble when I put ramps too close to other collisions, as it would get confused about what is colliding where.
So tonight I overhauled and reworked the collision system. Which, once again, leads me to my previous statement: Ramps are weird. It only took me about 30 minutes to get the basic collisions working with my new model (checking multiple points around the perimeter of the bounding box, processing each point's collision separately).
Then another 2 hours to get ramps working. Now I'm tired. The good news is that the ramps work more smoothly than before. Previously, going down a ramp, you'd run too far ahead, your feet would leave the ground, then you'd bounce down a bit, then run too far ahead again, and so forth. Which was bad, because it made it really hard to jump while running down a ramp. (you had to time it perfectly when your feet hit the ground). Now, your feet lock to the ramp on the way down.
So now I can continue on with my hard cave level. It took me about 25 tries to get through it while testing. My son was extremely excited about the existence of this cave level, but was rather unhappy that it was so hard.....
Wednesday, December 18, 2013
Working on some early level design
So I decided to put the actual programming on pause at this point, and do some early level-design. Mainly because I don't actually enjoy the details of level design very much. I really enjoy drawing a big rough map of the world, and planning out the overall gameplay. But the details of each little level? It's tedious.
Which is weird because when I was a kid that dreamed of making video games, I loved drawing out each level in minute detail on paper. Now that just bores me. Maybe because when you are 8 years old and drawing levels, you don't have to pay attention to making them the appropriate difficulty level, and interesting to look at, at the same time.
Anyway, so I've started on the first couple of "real" levels/rooms in the game. The first is pretty simple, without many things that can kill you. The second is full of death. And I'm realizing it's going to take a lot of work to make the challenge level right for this game. I'm not yet good enough at my own game to know which jumps and arrangements are going to be hard, and which are going to be easy, and which are just impossible to get through. There's one spot that I had to put in a checkpoint/save-point just for testing, so I could play it over and over again just to see if there was any way to get through it (yes, there is. It's not easy though).
So I've got a couple of possibly-finished levels (out of about 50). But that's why I started now. If I finished all the programming, and just had level design to do, I'd get so bored. So I need to pace myself: work on a few levels, then go back to coding. Work on some levels, then back to coding.
My current plan is to make the levels up until the first major ability item, then actually add the UI code for managing items. Then I need to write the code for the minimap. Which, I learned from Anguna, is a giant pain. Hopefully I'll be smarter in how I write it this time around.
I also found yet another bug with my ramp code. Robo-Ninja can't jump while running down a ramp. Because I depend on the game's gravity to lower you down the ramp, it thinks you are in a freefall, so it won't let you jump. Oops.
Which is weird because when I was a kid that dreamed of making video games, I loved drawing out each level in minute detail on paper. Now that just bores me. Maybe because when you are 8 years old and drawing levels, you don't have to pay attention to making them the appropriate difficulty level, and interesting to look at, at the same time.
Anyway, so I've started on the first couple of "real" levels/rooms in the game. The first is pretty simple, without many things that can kill you. The second is full of death. And I'm realizing it's going to take a lot of work to make the challenge level right for this game. I'm not yet good enough at my own game to know which jumps and arrangements are going to be hard, and which are going to be easy, and which are just impossible to get through. There's one spot that I had to put in a checkpoint/save-point just for testing, so I could play it over and over again just to see if there was any way to get through it (yes, there is. It's not easy though).
So I've got a couple of possibly-finished levels (out of about 50). But that's why I started now. If I finished all the programming, and just had level design to do, I'd get so bored. So I need to pace myself: work on a few levels, then go back to coding. Work on some levels, then back to coding.
My current plan is to make the levels up until the first major ability item, then actually add the UI code for managing items. Then I need to write the code for the minimap. Which, I learned from Anguna, is a giant pain. Hopefully I'll be smarter in how I write it this time around.
I also found yet another bug with my ramp code. Robo-Ninja can't jump while running down a ramp. Because I depend on the game's gravity to lower you down the ramp, it thinks you are in a freefall, so it won't let you jump. Oops.
Monday, December 9, 2013
Silly Mistakes
So I'm realizing that with this project, I don't have as interesting things to talk about as I did with Anguna. Anything that takes more than 30 minutes to implement in Robo-Ninja is usually because I made a silly mistake, not because I have to do cool stuff to make it work.
Tonight I was working on handling the back button on the Android build. I wanted it to pop up a simple exit-confirmation type of menu. LibGDX provides a nice handler for catching the back button (see the docs and this post on Stack Overflow), and it was pretty easy to pop up the menu. Quitting the game or canceling the menu were both no problem, but I kept having trouble whenever I'd use the "Main Menu" button.
I could get it to take me back to the Main Menu without issue, but the next time I'd hit the back button, the menu wouldn't appear. I spent a good 30 minutes stepping through with the debugger before I figured out my mistake:
When I started the game over, I instantiated a new UI/menu overlay object that controls all the on-screen popups (the Hud object). My back button handler, which I didn't re-instantiate, was holding on to a reference to the old Hud, which wasn't being displayed anywhere. So the old Hud, off in limbo-land, was trying it's hardest to show me a menu, it's too bad I wasn't actually DRAWING the old Hud.
Tonight I was working on handling the back button on the Android build. I wanted it to pop up a simple exit-confirmation type of menu. LibGDX provides a nice handler for catching the back button (see the docs and this post on Stack Overflow), and it was pretty easy to pop up the menu. Quitting the game or canceling the menu were both no problem, but I kept having trouble whenever I'd use the "Main Menu" button.
No, this is not the final visual design for the menu. Yes, that button says Robo-Nina. Oops. |
I could get it to take me back to the Main Menu without issue, but the next time I'd hit the back button, the menu wouldn't appear. I spent a good 30 minutes stepping through with the debugger before I figured out my mistake:
When I started the game over, I instantiated a new UI/menu overlay object that controls all the on-screen popups (the Hud object). My back button handler, which I didn't re-instantiate, was holding on to a reference to the old Hud, which wasn't being displayed anywhere. So the old Hud, off in limbo-land, was trying it's hardest to show me a menu, it's too bad I wasn't actually DRAWING the old Hud.
LibGDX
Ok, I'm trying again to talk about LibGDX.
When I got it in my head that I was going to make a new game, I wanted to make my life easy, and actually have hope of getting it done in some reasonable amount of time, which meant using an existing game framework/library.
On Anguna, it was a lot of fun building everything from scratch, but I spent A LOT of time just doing the basics: animating sprites, building characters out of multiple sprites, getting backgrounds to scroll properly, etc. On an device like the GBA, learning the weird tricks to do all that was a lot of fun. This time, on a modern smartphone platform, I just wanted to spend my time focusing on the game.
So I started evaluating different tools. Unity and Marmalade (which used to be called Airplay, which I originally started using for the iPhone port of Anguna) are the two that seem to have the most use, but are also a bit expensive these days for a hobby project that might never get finished.
So then I stumbled upon LibGDX. It's a free open-source framework. You write your code in Java, and then it can be deployed to Android, Desktop, Html5, and iOS (using RoboVM). While Java has its warts, it's easier to be productive in than straight C or C++, which are often the alternatives. And doing my daily development on the JVM is really nice, as I've still never found a better platform for debugging code. Being able to hot-swap code during a debug session, then drop back to the stack frame and re-test makes some things SO much easier to get right.
Some other things I liked about LibGDX:
- It's open source, and has a pretty friendly and decent community. I like the idea of open source, particulary for hobby projects. But some open source communities and personalities are downright obnoxious. This one seems to be pretty cool. And they do a decent job of documentation.
- There's good support for existing tools (ie loaders for Tiled and other map editors), so I don't have to spend as long figuring out how to massage my assets to get them into the game.
- Like many of these other platforms, it is set up for 3d support, but has a pretty easy 2d api for people like me that just want to make a simple 2d game without worrying about 3d graphics math.
- Although most of the projects in gallery look pretty janky and homemade (like mine!), there are a few examples (Ingress) of "real" games that are using it. So at least it's mature enough for a real game.
So now that I've decided to use it for my project, I haven't really hit too many warts yet. That's a good sign. I ran into one place where the default Tiled map loader was pretty inefficient for large but sparse maps. Being open source, that was easy to fix. Overall, though, I've been pretty happy. It gets out of the way and lets me write my game.
When I got it in my head that I was going to make a new game, I wanted to make my life easy, and actually have hope of getting it done in some reasonable amount of time, which meant using an existing game framework/library.
On Anguna, it was a lot of fun building everything from scratch, but I spent A LOT of time just doing the basics: animating sprites, building characters out of multiple sprites, getting backgrounds to scroll properly, etc. On an device like the GBA, learning the weird tricks to do all that was a lot of fun. This time, on a modern smartphone platform, I just wanted to spend my time focusing on the game.
So I started evaluating different tools. Unity and Marmalade (which used to be called Airplay, which I originally started using for the iPhone port of Anguna) are the two that seem to have the most use, but are also a bit expensive these days for a hobby project that might never get finished.
So then I stumbled upon LibGDX. It's a free open-source framework. You write your code in Java, and then it can be deployed to Android, Desktop, Html5, and iOS (using RoboVM). While Java has its warts, it's easier to be productive in than straight C or C++, which are often the alternatives. And doing my daily development on the JVM is really nice, as I've still never found a better platform for debugging code. Being able to hot-swap code during a debug session, then drop back to the stack frame and re-test makes some things SO much easier to get right.
Some other things I liked about LibGDX:
- It's open source, and has a pretty friendly and decent community. I like the idea of open source, particulary for hobby projects. But some open source communities and personalities are downright obnoxious. This one seems to be pretty cool. And they do a decent job of documentation.
- There's good support for existing tools (ie loaders for Tiled and other map editors), so I don't have to spend as long figuring out how to massage my assets to get them into the game.
- Like many of these other platforms, it is set up for 3d support, but has a pretty easy 2d api for people like me that just want to make a simple 2d game without worrying about 3d graphics math.
- Although most of the projects in gallery look pretty janky and homemade (like mine!), there are a few examples (Ingress) of "real" games that are using it. So at least it's mature enough for a real game.
So now that I've decided to use it for my project, I haven't really hit too many warts yet. That's a good sign. I ran into one place where the default Tiled map loader was pretty inefficient for large but sparse maps. Being open source, that was easy to fix. Overall, though, I've been pretty happy. It gets out of the way and lets me write my game.
Wednesday, December 4, 2013
Blogger app for Android (don't use it!)
Hmm, so I started typing a long post about LibGDX, using the Blogger android app. That was a mistake. While typing, I toggled over to a web browser to check something. When I came back, it had deleted my entire post. Turns out that wasn't a one-time thing, that's just how it works. I guess whoever at Google made the thing didn't read their own document about the Android Lifecycle. Ah well. Maybe I'll try again tomorrow.
Tuesday, December 3, 2013
Ramps are weird
So I've got most of the real core of Robo-Ninja complete. Not that that means I'm anywhere near complete. The basic core (map loading, characters moving and animating, collisions, etc) is the easy (and fun) part. The details are what takes all the time.
Anyway, after getting the basics of collisions working, I suddenly decided (for reasons I haven't really figured out) that I needed to add ramps. I wish I would have been smart enough to think of that earlier, as my design for collisions didn't really take ramps into account. And ramps are weird.
Overall, wall collisions are pretty easy, although slightly harder in a game like Robo-Ninja than they were in Anguna. In Anguna, you just check for collisions, and revert the character's position if he collided with a wall. There were a few other gotchas, (type of wall, since you can sometimes walk over water. Or checking vertical collisions separate from horizontal so you could "slide" diagonally across a wall), but it was easy. In Robo-Ninja, vertical collisions need to work similarly (walls above you will suddenly stop any upward velocity. Walls below will stop downward velocity). But horizontal collisions will make your guy suddenly switch directions.
Now ramps. Now we've got a collision that, being a diagonal ramp, is suddenly a vertical AND horizontal collision at the same time. And it should not only change your vertical velocity (stopping downward momentum), but also your position (as it needs to nudge you up vertically if you are moving left, but not send you jumping up in the air). And the tiny magic intersection tile between ramp tiles is really a normal tile. Which meant if Robo-Ninja moved a tiny bit too far forward in each frame, he'd collide with THAT tile instead of the actual ramp tile, and decide to turn around and run the other way.
Anyway, none of that should actually be hard. But it would have been a whole lot easier if I had decided I wanted ramps BEFORE implementing the rest of my collision code, so I would have actually designed with that in mind. Oh well. It works now.
Now I'm on to items/powerups, and the UI associated with them.
Anyway, after getting the basics of collisions working, I suddenly decided (for reasons I haven't really figured out) that I needed to add ramps. I wish I would have been smart enough to think of that earlier, as my design for collisions didn't really take ramps into account. And ramps are weird.
Overall, wall collisions are pretty easy, although slightly harder in a game like Robo-Ninja than they were in Anguna. In Anguna, you just check for collisions, and revert the character's position if he collided with a wall. There were a few other gotchas, (type of wall, since you can sometimes walk over water. Or checking vertical collisions separate from horizontal so you could "slide" diagonally across a wall), but it was easy. In Robo-Ninja, vertical collisions need to work similarly (walls above you will suddenly stop any upward velocity. Walls below will stop downward velocity). But horizontal collisions will make your guy suddenly switch directions.
Now ramps. Now we've got a collision that, being a diagonal ramp, is suddenly a vertical AND horizontal collision at the same time. And it should not only change your vertical velocity (stopping downward momentum), but also your position (as it needs to nudge you up vertically if you are moving left, but not send you jumping up in the air). And the tiny magic intersection tile between ramp tiles is really a normal tile. Which meant if Robo-Ninja moved a tiny bit too far forward in each frame, he'd collide with THAT tile instead of the actual ramp tile, and decide to turn around and run the other way.
I can't tell you how many times I kept bouncing off that highlighted tile until I stopped being dumb and fixed my code. |
Now I'm on to items/powerups, and the UI associated with them.
Wednesday, November 27, 2013
An unexpected turn of events
So one thing I didn't count on is my 5-year old son become interested in the process of making this game.
The other day while he was bored, I was letting him play with my phone, and he discovered a new game in the games folder, Robo-Ninja. And even though there were only 2 short levels, and they were pretty hard, he loved it.
This morning he wanted to play it again, and asked why it was so short (he didn't realize it was a game I was in the process of making). So I explained that I was making it, and could make some more levels for him. (and some easier ones). Then I had the realization that the level editor was easy enough that HE could make levels. That REALLY got him excited.
So we spent a good while this morning letting him design some levels. They're a bit...um...random. But he loved it. And I loved helping him do it.
But now I have a dilemma. He's going to want to play his version on my phone. But I'm going to want my version on there to show off, mess with, etc. So I ended up adding a menu item in the game to let you choose between Aaron's version and the real version.
Eventually, if I ever get close to finishing this thing, I'll probably have to pull his content out (there's no way I can distribute a game with the Ninjago Theme Song as background music, which is the case with his levels). But it's pretty fun to have my son excited about the process right now.
That may end up slowing down my development a bit (it did today!), but realistically, if it's between having fun doing this with my son and actually finishing, I'll take the former any day.
The other day while he was bored, I was letting him play with my phone, and he discovered a new game in the games folder, Robo-Ninja. And even though there were only 2 short levels, and they were pretty hard, he loved it.
This morning he wanted to play it again, and asked why it was so short (he didn't realize it was a game I was in the process of making). So I explained that I was making it, and could make some more levels for him. (and some easier ones). Then I had the realization that the level editor was easy enough that HE could make levels. That REALLY got him excited.
So we spent a good while this morning letting him design some levels. They're a bit...um...random. But he loved it. And I loved helping him do it.
In case you can't tell, that's supposed to be a forest in the top-half of the screen. |
But now I have a dilemma. He's going to want to play his version on my phone. But I'm going to want my version on there to show off, mess with, etc. So I ended up adding a menu item in the game to let you choose between Aaron's version and the real version.
Eventually, if I ever get close to finishing this thing, I'll probably have to pull his content out (there's no way I can distribute a game with the Ninjago Theme Song as background music, which is the case with his levels). But it's pretty fun to have my son excited about the process right now.
That may end up slowing down my development a bit (it did today!), but realistically, if it's between having fun doing this with my son and actually finishing, I'll take the former any day.
Starting a new game
Well, I'm finally starting a new game.
Actually, I've been working on it off and on for a couple months now, but I've been hesitant to talk about it, as I'm not sure I'm mentally committed to finishing it. I'm still not sure I'm ever going to finish it, but I have trouble not talking about things. So despite the fact that I hate yapping about things that I'm not sure I'll ever finish, here goes.
Like Anguna, I'm attempting to make a game that I want to play. (See my discussion of where I failed to achieve that mark for Anguna)
So I'm working on a cheesy little game called "Robo-Ninja." The main character, is in fact, a robot ninja.
So what I really want to make, a large metroidvania-style adventure game, generally requires better input mechanisms than a phone provides. There's a reason there's 8 million tap-to-jump games (Like The Impossible Game, which did it the best, and Wind Up Knight, which got tons of attention but was ultimately incredibly boring). Like I've talked about on this blog before, I really love the exploration part of a simple but large 2d world. So I started thinking about ways to make a metroidvania game work on a phone.
I really also like incredibly frustrating games where you die. A Lot. (See the Impossible Game, above). I was completely blown away by VVVVVV, which is both incredibly frustrating AND a metroidvania-style game.
I also have to limit the scope of the game. I don't want to spend 3 years working on this like I did Anguna.
So I set out to combine all of those, and decided on the gimmick: a metroidvania game where the only controls are the crazy tapping-to-jump mechanism. (well, to jump or do an alternative action depending on what items you have -- I was picturing some sort of Ninja dude as I was brainstorming), You could also tap on a corner to cycle through your inventory of items. To make it harder, your dude never stops running forward. Except when he hits a wall, then he turns around and runs the other way. (thus the Robot part, because he's dumb and just runs) So you have to work your way through a frustrating world of pits and spikes and frustrating timing, exploring and choosing routes by forcing your guy to bounce off the right walls or jump through the right holes.
So far, it's been a lot of fun. I had to pick a framework/game engine (LibGDX, which I'll talk about some other time), find art resources (there's quite a bit of free art out there, the hard part was finding enough that matched up to get some sort of consistent style to the game), figure out what tools I wanted to use (Tiled for mapping, I think), and then start coding!
Now that I've finally broken down and admitted I'm working on this, I'll plan on posting more thoughts about the game as it progresses (or stalls out and dies if I get bored).
Although, for now, I will say that my 2 testing levels are hard enough to frustrate me as I test it. That's a good sign in my book. ;-)
Actually, I've been working on it off and on for a couple months now, but I've been hesitant to talk about it, as I'm not sure I'm mentally committed to finishing it. I'm still not sure I'm ever going to finish it, but I have trouble not talking about things. So despite the fact that I hate yapping about things that I'm not sure I'll ever finish, here goes.
Like Anguna, I'm attempting to make a game that I want to play. (See my discussion of where I failed to achieve that mark for Anguna)
So I'm working on a cheesy little game called "Robo-Ninja." The main character, is in fact, a robot ninja.
So what I really want to make, a large metroidvania-style adventure game, generally requires better input mechanisms than a phone provides. There's a reason there's 8 million tap-to-jump games (Like The Impossible Game, which did it the best, and Wind Up Knight, which got tons of attention but was ultimately incredibly boring). Like I've talked about on this blog before, I really love the exploration part of a simple but large 2d world. So I started thinking about ways to make a metroidvania game work on a phone.
I really also like incredibly frustrating games where you die. A Lot. (See the Impossible Game, above). I was completely blown away by VVVVVV, which is both incredibly frustrating AND a metroidvania-style game.
I also have to limit the scope of the game. I don't want to spend 3 years working on this like I did Anguna.
So I set out to combine all of those, and decided on the gimmick: a metroidvania game where the only controls are the crazy tapping-to-jump mechanism. (well, to jump or do an alternative action depending on what items you have -- I was picturing some sort of Ninja dude as I was brainstorming), You could also tap on a corner to cycle through your inventory of items. To make it harder, your dude never stops running forward. Except when he hits a wall, then he turns around and runs the other way. (thus the Robot part, because he's dumb and just runs) So you have to work your way through a frustrating world of pits and spikes and frustrating timing, exploring and choosing routes by forcing your guy to bounce off the right walls or jump through the right holes.
Here's an example of me falling in a pit, about to die. I do that a lot in my tests. |
So far, it's been a lot of fun. I had to pick a framework/game engine (LibGDX, which I'll talk about some other time), find art resources (there's quite a bit of free art out there, the hard part was finding enough that matched up to get some sort of consistent style to the game), figure out what tools I wanted to use (Tiled for mapping, I think), and then start coding!
Now that I've finally broken down and admitted I'm working on this, I'll plan on posting more thoughts about the game as it progresses (or stalls out and dies if I get bored).
Although, for now, I will say that my 2 testing levels are hard enough to frustrate me as I test it. That's a good sign in my book. ;-)
Friday, November 15, 2013
Pebble New SDK
Well, go figure.
A week after I finish writing my medsAlarm, Pebble releases their new version of their SDK. Which isn't backwards compatible. And has new better ways of doing everything that I'm doing. I guess I need to rework a number of the bits of functionality in the app now.
A week after I finish writing my medsAlarm, Pebble releases their new version of their SDK. Which isn't backwards compatible. And has new better ways of doing everything that I'm doing. I guess I need to rework a number of the bits of functionality in the app now.
Tuesday, November 5, 2013
Pebble MedsAlarm
So I previously mentioned the Pebble Alarm Clock App that I've been working on. I just came here to say that I think it's finally finished. If anyone is interested in helping me test it, let me know, as it's probably full of all sorts of bugs.
And just to clarify, MedsAlarm (my terrible name for it), is an alarm clock app for pebble that lets you manage up to 10 "complex" alarms. The alarms are all configured using a simple web interface on the server component. Each has a name, and can be set to go off either at a certain time each day, or repeat every X amount of time throughout the day, and each alarm can have a different "snooze time" setting. The watch syncs (via httPebble) with the server app when it is available (But attempts to function independently when it isn't, so it can be used in situations where cell phones aren't allowed). In the evening you can optionally press a button to put the watch "to sleep" so that repeating alarms will not continue to go off through the night, until you awaken the watch in the morning.
When no alarm is going off, the watch app shows the current date and time, as well an indicator telling what the next alarm to go off will be, and how long until it goes off.
Anyway, again, let me know if anyone is interested in helping test (or using the watch app once it's fully tested and any remaining bugs are sorted out)
And just to clarify, MedsAlarm (my terrible name for it), is an alarm clock app for pebble that lets you manage up to 10 "complex" alarms. The alarms are all configured using a simple web interface on the server component. Each has a name, and can be set to go off either at a certain time each day, or repeat every X amount of time throughout the day, and each alarm can have a different "snooze time" setting. The watch syncs (via httPebble) with the server app when it is available (But attempts to function independently when it isn't, so it can be used in situations where cell phones aren't allowed). In the evening you can optionally press a button to put the watch "to sleep" so that repeating alarms will not continue to go off through the night, until you awaken the watch in the morning.
When no alarm is going off, the watch app shows the current date and time, as well an indicator telling what the next alarm to go off will be, and how long until it goes off.
Anyway, again, let me know if anyone is interested in helping test (or using the watch app once it's fully tested and any remaining bugs are sorted out)
Sunday, October 6, 2013
CSS
So a lot of what I do at work ends up being targetted for the web. Despite me thinking web programming is a blight on humanity. Realistically, I've managed to abstract away the web-ness of most of it behind some decent libraries, so I can pretend it's not the web. But occasionally I have to actually write some HTML and CSS. And let me tell you, my opinion is that CSS is AWFUL.
Here's why:
1. It's unintuitive and inconsistent.
I'm not talking about the general concept, or the block model. Sure, you have to learn those. But they aren't hard. I'm talking about stupid stuff like vertical-align, which means two completely different things depending on the context. In a table cell, it means one thing. In an inline element, it means something completely different.
Or absolute positioning. One would think positioning of "absolute" instead of "relative" means positioning the element absolutely. Instead, it's just a different type of relative, technically: "In the absolute positioning model, a box is explicitly offset with respect to its containing block" ...or in other words, it's relative to some parent above it. (W3Schools states it as "An absolute position element is positioned relative to the first parent element that has a position other than static.")
It also kills me that specifying a width of 100% for an element gets really messy if there's a margin or padding. Because the padding is included in the 100%, but the margin isn't. Or maybe it's the other way around? I'm sure CSS junkies remember. Normal humans don't. All I know is that percentage widths break down when margins and padding are around.
Now I know people that are used to CSS will defend many of these things, but having used a large number of other layout toolkits in other programming environments, none of them make me scream and pull my hair out like CSS does.
2. No grid layout.
Why, oh why, isn't there a grid layout? Maybe because the table html element already exists, which is a perfectly good grid layout. Oh wait, all presentation-related code is supposed to be moved to css, and tables should only be tables of data. Unfortunately, there's no real replacement for tables for grid-based layouts. So for a layout that should naturally be a grid (ie a form of labels and text fields), you end up with a mess of absolutely sized nested divs or other ridiculous workarounds.
People have come up with all sorts of hacks and frameworks to get around this issue. Great, we can hack our way past it. It's still terrible design.
3. It replaces one set of hacks and problems for another set.
When people first got all excited about separating content from presentation, it seemed like a good idea. Unfortunately, HTML and CSS are terrible at letting you actually do so for any vaguely interesting design. So either your presentation bleeds into the content (37 divs for a piece of content, just so the header, header corners, edges, etc, can all fit together to make it look right), or you end up with all sorts of hacks and nastiness in CSS and Javascript frameworks to try to trick your browser into doing something it wasn't designed to do.
So what can we do about it? Not much, unfortunately. The web is what it is. All sorts of CSS and javascript framework are written to try to make it easier. I guess you can use one of those. Or maybe just avoid web programming in general, that seems more pleasant.
Here's why:
1. It's unintuitive and inconsistent.
I'm not talking about the general concept, or the block model. Sure, you have to learn those. But they aren't hard. I'm talking about stupid stuff like vertical-align, which means two completely different things depending on the context. In a table cell, it means one thing. In an inline element, it means something completely different.
Or absolute positioning. One would think positioning of "absolute" instead of "relative" means positioning the element absolutely. Instead, it's just a different type of relative, technically: "In the absolute positioning model, a box is explicitly offset with respect to its containing block" ...or in other words, it's relative to some parent above it. (W3Schools states it as "An absolute position element is positioned relative to the first parent element that has a position other than static.")
It also kills me that specifying a width of 100% for an element gets really messy if there's a margin or padding. Because the padding is included in the 100%, but the margin isn't. Or maybe it's the other way around? I'm sure CSS junkies remember. Normal humans don't. All I know is that percentage widths break down when margins and padding are around.
Now I know people that are used to CSS will defend many of these things, but having used a large number of other layout toolkits in other programming environments, none of them make me scream and pull my hair out like CSS does.
2. No grid layout.
Why, oh why, isn't there a grid layout? Maybe because the table html element already exists, which is a perfectly good grid layout. Oh wait, all presentation-related code is supposed to be moved to css, and tables should only be tables of data. Unfortunately, there's no real replacement for tables for grid-based layouts. So for a layout that should naturally be a grid (ie a form of labels and text fields), you end up with a mess of absolutely sized nested divs or other ridiculous workarounds.
People have come up with all sorts of hacks and frameworks to get around this issue. Great, we can hack our way past it. It's still terrible design.
3. It replaces one set of hacks and problems for another set.
When people first got all excited about separating content from presentation, it seemed like a good idea. Unfortunately, HTML and CSS are terrible at letting you actually do so for any vaguely interesting design. So either your presentation bleeds into the content (37 divs for a piece of content, just so the header, header corners, edges, etc, can all fit together to make it look right), or you end up with all sorts of hacks and nastiness in CSS and Javascript frameworks to try to trick your browser into doing something it wasn't designed to do.
So what can we do about it? Not much, unfortunately. The web is what it is. All sorts of CSS and javascript framework are written to try to make it easier. I guess you can use one of those. Or maybe just avoid web programming in general, that seems more pleasant.
Saturday, October 5, 2013
Debugging on Pebble
So I'm currently working on a fancy alarm clock app for Pebble for a friend of mine. It allows up to 10 independent alarms, with different schedules (and different types of schedules, ie "every day at 9am" or "every 2 hours"), and the ability to sync (using HttPebble) with a web app so that the alarms can be managed from a web page, and to synchronize their status (since there's no persistence on the pebble itself).
Let me just say, this has been harder than I expected.
The first draft, to get the alarm functionality working, was actually pretty straightforward. I wrote the code, pushed it to the watch, and, with a couple obvious tweaks, it just worked. When does that ever happen?
The next step was to use the HttPebble protocol to sync stuff (yes, my friend uses iOS) This has been the painful part. Let me count the ways:
1. I have to do a fair bit of string manipulation in passing data back and forth. Anyone who's done much with C knows how primitive the string manipulation functions are. To top it all off, Pebble's limited environment doesn't even include all the standard C string functions, so I had to rewrite a simple implementation of a few of them.)
2. There's just no real testing/debugging tools for Pebble. During the kickstarter project they said there'd be an emulator, but it's pretty clear that they promised more than they could provide. When it doesn't work, it's really hard to tell why.
3. I've had some weird network issues at home that have made it even harder to test, because I'm never sure if it's my code or if my phone just can't talk to my test server.
Ugh.
I think I'm finally getting close. The watch properly (via the phone) sends the status of any repeating alarms to the server, which saves them and can echo them back to the pebble. The only thing I need to fix is the pebble parsing and understanding the alarm definitions that the server sends, which it's currently failing to do.
Let me just say, this has been harder than I expected.
The first draft, to get the alarm functionality working, was actually pretty straightforward. I wrote the code, pushed it to the watch, and, with a couple obvious tweaks, it just worked. When does that ever happen?
The next step was to use the HttPebble protocol to sync stuff (yes, my friend uses iOS) This has been the painful part. Let me count the ways:
1. I have to do a fair bit of string manipulation in passing data back and forth. Anyone who's done much with C knows how primitive the string manipulation functions are. To top it all off, Pebble's limited environment doesn't even include all the standard C string functions, so I had to rewrite a simple implementation of a few of them.)
2. There's just no real testing/debugging tools for Pebble. During the kickstarter project they said there'd be an emulator, but it's pretty clear that they promised more than they could provide. When it doesn't work, it's really hard to tell why.
3. I've had some weird network issues at home that have made it even harder to test, because I'm never sure if it's my code or if my phone just can't talk to my test server.
Ugh.
I think I'm finally getting close. The watch properly (via the phone) sends the status of any repeating alarms to the server, which saves them and can echo them back to the pebble. The only thing I need to fix is the pebble parsing and understanding the alarm definitions that the server sends, which it's currently failing to do.
Monday, August 26, 2013
Pebble review revisited
Well, it's been a few months since my rather negative review of my Pebble. So now that they've released a couple versions of the SDK, it's time to restate my opinions.
First, please note that I'll be specifically referring to using the Pebble with an Android phone. Due to the developer restrictions in the iOS world, my coworkers and I haven't found iOS apps that interface with the watch to make it do cool things. There's a primitive http tunnel app (HttPebble) that lets watch apps communicate with specially coded websites. But that's all I've seen. (if anyone knows of any, please let me know!) Until things change, I wouldn't bother with a Pebble if you use iOS -- you can't do much more than you could when I wrote my last review. Sure, there are a few watchapps that don't require communication, but those are of limited functionality. And the HttPebble tunnel is limited enough to keep it from being a general solution for integrating with many external websites.
But in the Android world, people have jumped in and written apps to make the Pebble start to fulfill the promise of the "smart" watch. First, I'm still rather unimpressed with the software created by Pebble itself. It takes the development of these 3rd party apps to accomplish what I expected Pebble to actually come up with in the first place.
That being said, there are 2 Android apps that deliver a pretty good "smart watch" experience: Glance for Pebble and Canvas. for Pebble
First, please note that I'll be specifically referring to using the Pebble with an Android phone. Due to the developer restrictions in the iOS world, my coworkers and I haven't found iOS apps that interface with the watch to make it do cool things. There's a primitive http tunnel app (HttPebble) that lets watch apps communicate with specially coded websites. But that's all I've seen. (if anyone knows of any, please let me know!) Until things change, I wouldn't bother with a Pebble if you use iOS -- you can't do much more than you could when I wrote my last review. Sure, there are a few watchapps that don't require communication, but those are of limited functionality. And the HttPebble tunnel is limited enough to keep it from being a general solution for integrating with many external websites.
But in the Android world, people have jumped in and written apps to make the Pebble start to fulfill the promise of the "smart" watch. First, I'm still rather unimpressed with the software created by Pebble itself. It takes the development of these 3rd party apps to accomplish what I expected Pebble to actually come up with in the first place.
That being said, there are 2 Android apps that deliver a pretty good "smart watch" experience: Glance for Pebble and Canvas. for Pebble
Glance for Pebble
Glance is the first of the two that I discovered and tried, and the first Pebble app that made my Pebble useful. It has a few options for the display, which includes things like weather, missed calls, missed email, etc. The other nice thing about it is that is has quite a bit of interactivity. You can send pre-written text messages, launch tasker scripts, etc. Overall, it's pretty nice, although the main watch face isn't extremely configurable.
Canvas for Pebble
If being configurable is what you are looking for, Canvas for Pebble is amazing. It features an on-screen designer (on your phone) to customize your watchface. You can add layers, move them around, hook into phone sensors, tasker variables, weather, etc. And it features a plugin system so you can write your own layer types. I've been using a custom watchface that shows date, time, weather, missed phonecalls, number of unread emails, my next appointment on my calendar, and a small noitfication if my phone and watch disconnect from each other (ie if I left my phone somewhere). I have vague plans to add a few custom plugin layers, if I ever get around to it, but we'll see.
While it doesn't have any interactive features (you can't control things from the watch, it's merely a watchface), it's amazing as far as getting your watch to look the way you want.
So that all said, I finally feel like the Pebble is neat. My watch is "smart" now, whatever that means.
There are some problems still. I get random disconnects every few days, that usually require me to turn off bluetooth and turn it back on before it will reconnect. The music control and display feature built into the watch doesn't work well with Pandora. Battery life is shorter with these smarter watchfaces (usually 5 or 6 days instead of the 7-10 I was getting). But overall, it's not a bad product at this point. Although I'm still not convinced it's worth the price.
Wednesday, March 13, 2013
Tasker
Ok, I have to rave about my favorite thing for Android -- Tasker. If you own an Android phone, and you enjoy the process of fiddling about to make it more and more useful, then Tasker is the best thing ever. It's an app that lets you basically attach various actions (changing settings, playing notifications, launching apps, etc) to various triggers (locations, times of days, phone sensors, phone calls/texts -- just about anything you can think of) in all sorts of interesting and complicated ways. It's relatively expensive for an Android app (around $6), but worth every penny.
The only problem is the user interface -- it has a goofy unintuitive UI that makes it pretty cumbersome setting up complex profiles. I'd pay another $6 for a decent editor on my actual computer. (It's tempting to write one, as tasker saves and loads its profile scripts as xml).
That all being said, here's the things that I currently use it for:
The only problem is the user interface -- it has a goofy unintuitive UI that makes it pretty cumbersome setting up complex profiles. I'd pay another $6 for a decent editor on my actual computer. (It's tempting to write one, as tasker saves and loads its profile scripts as xml).
That all being said, here's the things that I currently use it for:
- When headphones (without a microphone) are inserted, and there's no media already playing, immediately launch my last music player and resume the last song.
- Mute the phone on sunday during church time, and restore the volume afterwards.
- Mute the phone if it's being charged after 10pm. (I always charge it while sleeping, so I figure if I'm up after 10, I want it to ring until I put it on the charger. And if I'm charging during the day, I want to hear it).
- It checks my work calendar, and automatically mutes if it's during the time that I have a meeting scheduled (and restores the volume afterward)
- If Sara's calling, it vibrates with a crazy different pattern, to make it more obvious that it's her.
- If I get a call that's a non-217 area code, and not in my contact list, it's a different ringtone (I've gotten a lot of phone spam recently, so this makes it obvious it might be spam)
- If I get a call from a number I've previously marked as spam, it doesn't even ring.
- If I text a secret code to my phone (or Sara's), it turns to full volume, and rings like crazy (to help find the phone if we've misplaced it, or if I know Sara muted her phone and I need to get her attention)
- If I receive a text message, and I'm in the car (based on being connected to the bluetooth device in my car), it reads the text aloud over the audio.
- If I get a text message, and I'm not at my desk at work, it forwards the text on to my pebble watch. (If I'm at my desk, I get the text notification on my computer, so I don't want it to bother with my watch). To check whether I'm at my desk, it does a web query to a URL I set up on my work machine that simply reports the time since the last input. If that number is bigger than a few minutes, it assumes I'm not at my desk.
- I haven't finished setting this up, but I want to do the same thing with gmail -- if I'm not at my desk, forward the message summary (First few lines) on to my pebble watch.
That's just a tiny sample of what this thing can do. There's a thread here on Reddit with people listing cool things they've made it do, and some other interesting samples on Tasker's site. Like I said, if you have an Android phone and you enjoy futzing around to automate your life, Tasker is absolutely worth it.
Tuesday, March 5, 2013
My Pebble Review
Since everyone and their uncle is talking about their brand new Pebble, I guess I can chime in with my review of the current state of the Pebble. I've had the Pebble for a few days now, so I've had some time to play with it and see what it has to offer.
First, the physical appearance and feel (the unimportant stuff). It's a little bigger than I'd really like, but still fits comfortably on my wrist. The included watch band feels a bit rubbery and cheap, although it's a standard band and easily replaceable, so I'm not too concerned about that (as a side: the Pebble makers seem awfully proud on their twitter stream about the fact that the band is customizable. Maybe that's because nothing else on the watch is customizable yet?) It's held a charge well so far (I charged it 4 days ago), so it will easily last a long weekend, which is my cutoff for real use (I don't want to haul along a watch charger for a weekend trip!) So overall, the physical package is decent, although nothing amazing or mind blowing.
That leads to the next part: the built-in software. The pebble was supposed to come with a set of built-in functionality, as well as feature an SDK and the ability to load custom apps. All of the promotional information about the pebble talked about integration with things like RunKeeper, ifttt, golf range finder apps, etc. Unfortunately, none of those apps actually exist. Pebble claimed that the SDK would be released before the watch was shipped, but there's been no sign of an SDK yet, no apps, and worse: no announcements about any sort of timeline for it. Without a timeline or any announcements, one has to assume that we might not see any custom software for a long, long time. So we're stuck reviewing what the pebble can do out of the box. And unfortunately, the answer is: not much.
The Pebble currently has a small handful of watchfaces. One of them, a text-based face, is well designed and nice looking. Most of the others aren't as nice looking, or are relatively gimmicky (such as a binary watch). So while it's fun to be able to switch watch faces, many users will only have one or two that they are actually happy with using day to day.
The other two things the pebble can do are control music on your phone, and receive notifications. The notification system is the best part (or only redeeming part) of the Pebble so far. When I get a text message, it appears on my watch. The watch vibrates and shows caller id when I receive a call (And I can reject the call from the watch). It's also supposed to support email notifications, but for some reason, those don't actually work right now from gmail on many Android phones (including mine). So until those work, I don't really count that as a feature. It also claims to forward facebook notifications to the watch, but I don't have Facebook installed on my phone, so I can't test it. It DOES support google voice notifications, which I'm really happy about (as I do all my texting through google voice).
The music control is neat, and actually works. If you select the music app (a surprisingly cumbersome task requiring you to back out of your current watchface, dig through a list of all the watchfaces you've installed, and select the music player), it shows what song is currently playing on your phone, and provides the standard Bluetooth controls for play/pause, forward, and back. It's relatively cool, and works well, although to get back to your watch, you have to once again navigate through the menu to find your preferred watchface. If there's a shortcut to go back to watch mode, I haven't found it. The clunky interface deters me from using it as often as I might otherwise.
And so far, that's all it can do. To help a little, some smart person has written a 3rd party app for Android that lets you forward any notification from your phone to the watch, not just the few that Pebble officially supports. (I wonder why Pebble didn't just build that functionality in?) Still, there's no ability to actually control anything from the Pebble other than your music. And doing that requires navigating a relatively clunky interface.
I'm still excited about the future prospect of the Pebble. If the SDK gets released soon, it could end up being an exciting product. Or at least actually fulfill the "smart" part of the "Smart Watch" idea. Unfortunately, the longer they wait to release, or even officially announce a timeline for the SDK, the worse and worse the Pebble looks as a product. I love the theoretical future idea of the Pebble, but I'm not very impressed with the hunk of plastic currently on my wrist.
Pebble has said they first focused on getting the hardware right, and now they can focus on software. So if I think in terms of it being an unfinished product that they plan to finish later, it makes more sense. Because the watch currently on my wrist isn't by any means a finished product. I just wish they were more communicative about the timeline for finishing it.
I guess this quote from an article on TechCrunch about smart watches sums up my opinion about it:
First, the physical appearance and feel (the unimportant stuff). It's a little bigger than I'd really like, but still fits comfortably on my wrist. The included watch band feels a bit rubbery and cheap, although it's a standard band and easily replaceable, so I'm not too concerned about that (as a side: the Pebble makers seem awfully proud on their twitter stream about the fact that the band is customizable. Maybe that's because nothing else on the watch is customizable yet?) It's held a charge well so far (I charged it 4 days ago), so it will easily last a long weekend, which is my cutoff for real use (I don't want to haul along a watch charger for a weekend trip!) So overall, the physical package is decent, although nothing amazing or mind blowing.
That leads to the next part: the built-in software. The pebble was supposed to come with a set of built-in functionality, as well as feature an SDK and the ability to load custom apps. All of the promotional information about the pebble talked about integration with things like RunKeeper, ifttt, golf range finder apps, etc. Unfortunately, none of those apps actually exist. Pebble claimed that the SDK would be released before the watch was shipped, but there's been no sign of an SDK yet, no apps, and worse: no announcements about any sort of timeline for it. Without a timeline or any announcements, one has to assume that we might not see any custom software for a long, long time. So we're stuck reviewing what the pebble can do out of the box. And unfortunately, the answer is: not much.
The Pebble currently has a small handful of watchfaces. One of them, a text-based face, is well designed and nice looking. Most of the others aren't as nice looking, or are relatively gimmicky (such as a binary watch). So while it's fun to be able to switch watch faces, many users will only have one or two that they are actually happy with using day to day.
The other two things the pebble can do are control music on your phone, and receive notifications. The notification system is the best part (or only redeeming part) of the Pebble so far. When I get a text message, it appears on my watch. The watch vibrates and shows caller id when I receive a call (And I can reject the call from the watch). It's also supposed to support email notifications, but for some reason, those don't actually work right now from gmail on many Android phones (including mine). So until those work, I don't really count that as a feature. It also claims to forward facebook notifications to the watch, but I don't have Facebook installed on my phone, so I can't test it. It DOES support google voice notifications, which I'm really happy about (as I do all my texting through google voice).
The music control is neat, and actually works. If you select the music app (a surprisingly cumbersome task requiring you to back out of your current watchface, dig through a list of all the watchfaces you've installed, and select the music player), it shows what song is currently playing on your phone, and provides the standard Bluetooth controls for play/pause, forward, and back. It's relatively cool, and works well, although to get back to your watch, you have to once again navigate through the menu to find your preferred watchface. If there's a shortcut to go back to watch mode, I haven't found it. The clunky interface deters me from using it as often as I might otherwise.
And so far, that's all it can do. To help a little, some smart person has written a 3rd party app for Android that lets you forward any notification from your phone to the watch, not just the few that Pebble officially supports. (I wonder why Pebble didn't just build that functionality in?) Still, there's no ability to actually control anything from the Pebble other than your music. And doing that requires navigating a relatively clunky interface.
I'm still excited about the future prospect of the Pebble. If the SDK gets released soon, it could end up being an exciting product. Or at least actually fulfill the "smart" part of the "Smart Watch" idea. Unfortunately, the longer they wait to release, or even officially announce a timeline for the SDK, the worse and worse the Pebble looks as a product. I love the theoretical future idea of the Pebble, but I'm not very impressed with the hunk of plastic currently on my wrist.
Pebble has said they first focused on getting the hardware right, and now they can focus on software. So if I think in terms of it being an unfinished product that they plan to finish later, it makes more sense. Because the watch currently on my wrist isn't by any means a finished product. I just wish they were more communicative about the timeline for finishing it.
I guess this quote from an article on TechCrunch about smart watches sums up my opinion about it:
A solid platform needs compelling applications. The promise of the smart watch is fine but, in actuality, it will take a while for this promise to come to fruition. By that time, I suspect, the mass of Pebbles will be lying at the bottom of a dresser drawer.My friend who has a pebble has already stashed his in a desk drawer and gone back to a normal watch. I'm still wearing mine, hoping the novelty lasts long enough until the SDK is actually released, the promised apps arrive, and a finished product materializes.
Subscribe to:
Posts (Atom)
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...
-
So I've recently purchased DosBox Turbo , the best (as far as I can find) implementation of DosBox for Android, and have been playing th...
-
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...
-
When I'm too tired/frustrated to work on my NES game, I've been playing around with ideas for another hobby project that I've he...