Rebble Hackathon-001 - ROCK! The Vote
Table of Contents
To start, I have to say it: the Pebble smartwatch doesn’t deserve the fate it got. In my dream world, we’re on the tenth generation of the Pebble watch and I’m listening to my Spotify weekly playlist on my Pebble Core. For those who don’t know, the Pebble smartwatch is a now discontinued smartwatch that was initially entirely funded through a Kickstarter campaign from April 11th, 2012. In the span of its fundraising goal, it raised 10.3 million dollars earning the project the, then, title of most funded project in Kickstarter history. source
But since this isn’t a blog post about the history of the Pebble smartwatch, I’ll keep things brief. Ultimately, things didn’t work out and the Pebble is now just a memory of what could of been. Luckily, I’m not the only one who still feels this way about the legacy of the Pebble, and so it lives on with the community project, Rebble. Rebble aims to preserve the Pebble and keep it living on as long as the hardware works. Thanks to their team, users are still able to create, upload, and use old and new watchfaces and watchapps to this day! They’ve even created a project to replace the stock OS, known as RebbleOS.
Oh hey and look, I’ve even contributed to it, how neat!

Hey look, that's me!
Thanks to great channels like the Rebble Discord, the Rebble community continues to be active to this day. So when they announced the first official Rebble Hackathon, I knew this was something I had to be a part of.
But what did I create, what’s my story? This post will be purposefully verbose as I aim to cover topics from the Hackathon itself to how I conceptualized, designed, and implemented my entry. I hope this can be a useful aid for anyone out there on the fence about joining an in-person or online hackathon!
The Hackathon:
A complete overview of the event can be seen by the blog post made by Rebble team member Will Murphy here. I highly recommend you take a look at it to get an idea of the format of the hackathon weekend.
One tool from the hackathon I want to shoutout was the hackathon VM that came pre-loaded with the, now, notouriously difficult to install and unmaintained Pebble SDK. This absolutely sped up my development time, as I had everything ready to go out of the box. Thank you so much for that Will!
Another aspect I really need to highlight and compliment from the hackathon was the structure of the hackathon channel put together on the Rebble Discord. Using Discord’s thread feature, each hackathon project entry go its own dedicated “mini-channel” that the user could use to update everyone on their progress and make announcements.
This was such a creative and great way to post my progress, as well as see the progress of everyone else. It made the event all the more fun and helped shrink the seemingly large wall the internet can place on interaction between people.
But enough about the event, let’s talk about my entry.
Conceptualization
As I started brainstorming, I created a goal of the types of technologies my app would use. I wanted to challenge myself to incorporate the following:
- a multiplayer interactive game leveraging the internet
- a REST based API
- a simple to understand and simple to program GUI
The most important aspect to keep in mind was the scope of the project. It’s easy to let your imagination go wild, but when you only have one weekend to complete the project (and an already busy one at that!) it’s important to create a goal that’s obtainable in that time.
After going back and forth in my head for a concept and spit balling some ideas with my wife, I finally had an idea.
Inspiration

The Everybody Votes Channel was a Wii Menu channel that allowed users to vote in simple opinion polls and compare and contrast opinions with those of friends, family and voters around the globe. source
It’s a perfect example of a Nintendo online application, voicing and listening to people on the internet with the safety rails of pre-determined prompts all the way up. However despite the limitation in communication, it still created a lot of fun and comradery. Like, who were those people who said pizza is better than calzones? I don’t know either, but I sure as hell know their opinion is wrong. Am I right fellow calzone lovers?
After thinking about it some more, and talking about how I would port this experience to the Pebble, I knew I had a fun project that people would enjoy while hitting all of my personal technology goals I wanted to incorporate:
- a multiplayer interactive game leveraging the internet
- Players would be able to cast votes that would be tallied on a public server and made available to view results.
- a REST based API
- I would need to invoke actions, like casting player votes and downloading the current day’s prompt, by using ajax requests and Pebble’s AppMessage API.
- a simple to understand and simple to program GUI
- I will leverage the powerful Pebble window and drawing API to help create a game that is easy to pick up, and hard to put down.
Outlining
The Plan: Create an online interactive poll based off of simple prompts
Now that I had my vision, it was time to start the work. I started by creating a simple flow diagram on paper of what the user experience would look like.
Let’s go through it real quick: First, I wanted the user to be greeted with a fun welcoming animation, a splash screen of sorts, stating the name of the app.
Next would come our first decision tree: has the user voted already or not? This would be determined by asking the server through one of my REST API calls. But how would I determine if a user has already voted or not, how could I give a unique identifier to every single user that uses the app? I mean, I’m not afraid of people cheating (I don’t think it should be taken that seriously), but this does seem like a pretty low bar to cross over. Luckily, I didn’t have to spend too much time thinking about it, because the people at Pebble had thought about it for me! Turns out, each Pebble watch comes with a UUID that can be accessed using the UUID API of the Pebble SDK. Great, I’ll have the user send over their UUID to authenticate every vote, and keep track of it to prevent duplicate votes. So, if it’s determined a user has already voted they’ll be informed on another window and be told to check back in tomorrow. They’ll be able to access a menu that let’s them see the current and previous day’s question, as well as the current and previous day’s votes.
What if a user hasn’t voted yet? If a user hasn’t voted yet, they’ll be taken to a window that’ll inform them of the type of question the question of the day is. I decided on three different types:
- Would You Rather?
- Who Would Win?
- This or That?
(Notice how each question is made up of three words, more on why I made this decision later!)
After the user was informed of the question type, next would come the prompt for a response. There will be two options stacked on top of each other. When the user selects one using the top or bottom watch buttons, the vote will be sent to the API server. From there they will be taken to the same window as the post-already voted branch where they could see the current and previous day’s question, as well as the current and previous day’s votes.
Implementation
Creating the back-end
To me, back-end development comes naturally, it’s a lot more straight forward. The design was simple, I needed a way for my Pebble app front-end to communicate with a server over the internet. That’s trivial with the Pebble JS ajax commands which gives me easy access to REST verbs. Additionally, I’ll need a persistent storage base containing the list of people who’ve voted that day, and the amount of votes for each answer. Sounds like a SQLite database should fit fine!
As of lately, Rust has been my language of choice both at home and at my job. I have a lot of experience with these concepts listed in Rust, so I already had libraries in mind. For my simple REST endpoints, I used rocket. For an SQLite library, I used rusqlite.
I scoped out my endpoints for the functionality I needed, and came up with the following:
Endpoint Path | REST Type | Description |
---|---|---|
/increment_red/<voter_uuid> | POST | API endpoint for POST-ing vote for red choice. Takes Pebble UUID as argument to add to responders table. |
/increment_blue/<voter_uuid> | POST | API endpoint for POST-ing vote for blue choice. Takes Pebble UUID as argument to add to responders table. |
/has_user_voted/<voter_uuid> | GET | API endpoint for GET-ing if user has already voted for current day’s prompt. Takes Pebble UUID as argument to search the responders table for that entry. |
/latest_question_and_results | GET | API endpoint for GET-ing current day’s prompt and poll results. |
/previous_question_and_results | GET | API endpoint for GET-ing previous day’s prompt and poll results. |
Creating the front-end
By far, I am no expert in user interface or experience design. In general, I like to go off this simple principle: if I like it, odds are there’s going to be an amount of people who like it as well. That being said, the one “philosophy” I like to employ with UI comes from a common programmer mindset: keep it simple and re-use as much as possible. Using this mindset, I finalized my UI using two designs, what I like to call: Three Letter Fullscreen and Split-Screen Prompt. Creating a window skeleton for both was simple.
The Three Letter Fullscreen window is simple in its construction: three textlayers stacked on top of each other on a window stack. After that, I created a function that took arguments for the window’s background color and the first, second, and third text layer and created a new window stack from there. It’s amazing what you can convey in three words, take a look at what I was able to do:

App Splash Screen

New daily Vote user prompt

Would you Rather user prompt (See? I told you those three letter questions would come into play later...)

Vote is In! user prompt

This vote's Results prompt shown after user has voted

Last vote's Results prompt shown after user has voted
You may have noticed that for the Three Letter Fullscreen windows I alternated between CAPS lowercase CAPS. For whatever reason, I feel like this just looked better.
The Split-Screen Prompt was a little more complex than the Three Letter Fullscreen, but still straightforward. Using this Pebble SDK tutorial, I drew two colored rectangles on top of a window stack. They meet halfway, one colored red the other blue. Why red and blue? Well why not? It seems the war of red versus blue is one that’s been going on for quite some time now. From there I put a textlayer on top of both rectangles and an actionbarlayer to the right of the window so users knew the app was waiting for their prompt.
Again I created a function that took arguments for the window’s top and bottom textlayer text. These were used to display the question of the day’s two prompts, and then later numbers that corriponded to the team’s color when the user had already voted:

Split-Screen Prompt base

Split-Screen Prompt with example text
Putting it all together
I won’t go into detail on how I setup my front-end to back-end communication, mostly because I entirely used the example code grabbed from this Pebble SDK tutorial on reaching out to the internet on your Pebble via Pebblekit JS.
Things went as expected and without drama. When I sent a GET request to my /latest_question_and_results endpoint, I got my JSON of the latest red prompt, blue prompt, question type, and red and blue vote count.

Likewise, sending a POST with the Pebble’s UUID to /has_user_voted/[Pebble UUID] successfully got the back-end searching the responders table and returning whether it found the UUID or not. Very simple, and very effective, both signs of a well (enough) designed API!
Testing
Testing took place on my local network with my old reliable Raspberry Pi 1 hosting the Rust REST API server. For a lot of the testing, I was able to get away with using the Pebble SDK’s official QEMU emulator.
I have to take a moment to compliment just how amazing the testing tools that come with the SDK are. There’s so much the emulator is able to do, that even if you don’t have the actual hardware you could easily make a full application while still incorporating API like the accelerometer and compass by creatively pairing your phone.
I conducted my first vote, and viola! I showed up in the responders table:
Deployment
When it was all said and done, it was time to put my app through the most rigorous testing of all, public release. Like I said before, when Pebble was first shutting down the app store as we knew it was in jeopardy. However, thanks to the amazing work from the Rebble team, not only was the store in its entirety preserved, but there’s a new interface for uploading and managing new watchface and watchapp entries. Using your Rebble account, you can manage pre-existing entries and new ones. Now that’s pretty amazing. I headed over to dev-portal.rebble.io and uploaded ROCK! the Vote, you can find it on the store today here!
After I uploaded my app, and had my server running on the Raspberry Pi it was time to sound the alarm. I made an announcement in my project’s thread on the Rebble Hackathon channel, and the response was almost instant!

After one night, I took a look at the database. People had been voting. After the week of the hackathon, engagement continued for a short while too:

Wow, people are voting!
Aftermath
Hey look at that, a letter and official Rebble logo stickers signed by Katherine Berry! Thanks so much!
All in all, I’d describe the hackathon as a success on all levels. Personally, I had a great time participating in my first online hackathon. I learned a lot about the Pebble product and software lifecycle as a whole. It was really enjoyable to speedrun the design process in one weekend, something that can take months or years when working in a company. Additionally, it seemed to be great for the Rebble community as well. Inspiring a lot of fun watchfaces, apps, and games to be created!
I hope to see a Rebble Hackathon #002 soon, and I know I’ll be one of the first to sign up.