Circuit Dude [2.1] - Awesome Puzzle Game With 50 Levels!

(Curtis Ovard) #21

Me too, level 14 is damn hard.

(Holmes) #22

Oof! That one is brutal!

Level 14 Hint
  1. Left side
  2. Top few rows
  3. Right side
  4. Middle square

After 14, there are a lot of new tiles being introduced, so the following few levels are substantially easier. :wink:

(Curtis Ovard) #23

Thanks for the hint, I was getting close. Should be able to move on now :slight_smile:


Ya I have passed the level 14 ! :laughing:

(Tobias) #25

I really like the game, but could you please save the sound options?
Having to turn off the sound with that peep sound, over and over, is just annoying.
How am I supposed to play during lesson, if it makes sounds? :smiley:

(Holmes) #26

In the next release, I will include this. :wink:

(Scott) #27

For a quick fix, I think you should be able to change the line near the start of the sketch:

boolean soundon = true;


boolean soundon = false;

The game will then always come up muted. You will have to turn it on each time you want sound, instead of having to turn it off when you don’t.

(Kevin) #28

This game is epic! I love it. 50 levels? I would have never believed it possible! @crait is a monster!

(Holmes) #29

Thanks, man! :slight_smile:

(Matthew Coburn) #30

Great game @crait! I used to love the game Chip’s Challenge (does anyone remember it?) and the mechanics of Circuit Dude is making me nostalgic! Well done brother!

(Holmes) #31

Thanks a bunch, @crowbar crowbar! Whenever I finished the first playable demo for this game, I showed it to my roommate and he flipped out telling me that it reminded him of Chip’s Challenge. We went through old screenshots looking for inspiration for new mechanics and such. I had never heard of it before that!

I would say the biggest inspiration I got from the game was the story! My roommate tried to tell me the crazy storyline for Chip’s Challenge, but it was so zany and crazy. If you complete all 50 of Circuit Dude, you’ll get to see the exciting conclusion to the (almost non-existent) storyline that I came up with! :smiley:

(Holmes) #32

I’ve had some people tell me that level 6 and level 14 were just too hard! So, I went ahead and moved them down to level 22 and level 23, respectively.

This little change will move the game from 1.0 to 1.1.

(Holmes) #33

Hey, everyone! :slight_smile:

I updated Circuit Dude to 2.0! It includes a lot of new features and better Aesthetic s . Here’s the changelog:

  • Switched over to the Arduboy2 library! (Shout out to @MLXXXp!)
  • Busted out the audio to the Playtunes library
  • Added the ability to quit the level with A+B
  • Expanded the help section to include all of the tiles
  • Compressed most images to save some space (Shout out to @igvina!)
  • Sound on/off is now saved in the global EEPROM location
  • Updated some screens to include better graphics
  • Packed everything into a .arduboy package
  • Included the Screen Mirror feature

(Scott) #34

Nice work @crait! :clap:

I know you spent time refactoring the code for program size. You’ve managed to (barely) squeeze it into the space available but here’s some suggestions to free up some more space (maybe for more levels or more detailed help, like “what does mirroring do?”). None of these changes should affect game play.

  1. The ArduboyPlaytune library handles sound muting itself, so you don’t need to test if sound is enabled before calling tunes.tone() in the sound() function. Since that’s all the sound() function does, you really don’t need it at all.

  2. You’re using only the tone() function of ArduboyPlaytune. Unless you plan to add background music in the future (probably not, since there’s no space left), you can save some space by switching to the ArduboyTones library. The tone() functions in each library are compatible so it’s quite easy to switch. Just create an ArduboyTones object instead of an ArduboyPlaytune object and remove the ArduboyPlaytune initChannel() and toneMutesScore() function calls in setup().

  3. The sketch generates a number of compiler warnings. (You may have to set Show verbose output during compilation and Compiler warnings to All, in the Arduino IDE preferences, to see them. The warnings are due to the mismatched use of signed and unsigned variables. Changing char to byte and int to unsigned int where you get the warnings will eliminate then. It also reduces code size, probably because it takes less code to work with unsigned values.

All in all, I was able to free up 1318 bytes of code space by making the above changes. For reference, I put my changed version in a gist on GitHub:

EDIT: gist removed as per the author’s code use requirements.

(Holmes) #35

Thanks for that update, @MLXXXp! I was planning on switching the audio library, but as I mentioned before, there’s some compatibility issues with it. Loading the code that you have on your GitHub will produce weird audio artifacts. It sounds muffled/scratchy/inconsistent. I was hoping to get a detailed example of this so we can pinpoint the cause of the issue. I think it has something to do with the use of the LED’s and audio in the same sketch, but as I said, I haven’t confirmed it, just yet.

Whenever I get that solved, there are some more things I can refactor to save some more space. I’m hoping to include another frame or two to the story and a way to re-watch the secret ending without needing to beat Level 50, again. :slight_smile:

(Scott) #36

No, that’s not the problem. In fact, the ArduboyPlaytune library uses timer 1, which is the timer used to PWM the red and blue RGB LEDs. When ArduboyPlaytune is used you can’t properly control the brightness of these two LEDs.

If you look at the red LED when you hold the A button in a level, you’ll notice that it just stays at a single brightness and then jumps to fully on at the end, instead of the brightness increasing as the temperature rises. This is because ArduboyPlaytune is messing with timer 1.

ArduboyTones uses only timer 3, so all the RGB LEDs work properly with it. You can see this with the red LED when using my Circuit Dude changes to use ArduboyTones.

As for the sound scratchiness using ArduboyTones:
Is it only during the ascending tone sequence played while the temperature rises when holding the A button? If so, then I’m pretty sure the “noise” is caused by the speed at which you’re changing tones. ArduboyTones sets both speaker pins back to low when each tone stops, even if it’s due to forcing it to change to a new tone. I did this to make sure that both pins are low when idle. (ArduboyPlaytune may not do this, which is why it isn’t scratchy.) This setting of the pin(s) low could happen in the middle of a frequency cycle, especially if the tone is forced to stop by starting a new tone while it’s playing. By changing tones rapidly, these partial cycles are heard as noise.

ArduboyTones wasn’t really intended play a glissando by rapidly playing tones of incrementing or decrementing frequency. In Circuit Dude, you can improve things somewhat by allowing each tone to play longer and compensating by increasing the frequency more for each tone. For instance, you can change the line:

sound.tone(100 + temperature * 10, 100);


if (!(temperature % 4)) {
  sound.tone(100 + temperature * 10, 100);

so that you only change the tone every 4th time through the loop and increase the frequency by 4 times more each time. If the frequency changes sound too distinct, you can try temperature % 2 but that will increase the scratchiness.

The scratchiness of the tone sequence that plays after the temperature reaches maximum is due to the same problem. You could change it so that you only start each distinct tone once and leave it playing for the desired duration. A better solution would be to let ArduboyTones play all the end tones as a single sequence, which it can do (unlike ArduboyPlaytune’s tone() function, which can only play a single tone).

(Holmes) #37

That’s very helpful, but I don’t think it reliably solves the problem. As you mentioned, the explosion noise as well as the temperature escalation are scratchy, but scrolling through the levels does not create a consistent noise, either.

I could add some lines of code to try to adjust that, but it would mostly be trial-and-error. Meanwhile, that problem would still exist for others trying to have a fluid-sounding repetition of beeps or a glissando of varying notes.

I tried changing up some code to make it sound more fluid, but after playing with this specific library for a few hours, I couldn’t get anything that sounded as good as using the PlayTunes library.


Best game i have played so far currently on level 25…

(Holmes) #39

Keep going! I think you’re closest to getting to the secret ending! :smiley:

(Scott) #40

The sound when scrolling through levels is the same problem. You’re continually and rapidly starting a new tone while one is currently playing. In this case, the new tone is the same frequency as the old tone. With ArduboyTones, whenever a new tone is started while one is playing the possibility exists that you’ll get a small glitch from the resetting of the pins. If each tone plays for a reasonable amount of time and the next one changes in frequency, then this glitch is practically unnoticeable. However, if you change tones too fast, or start a new tone of the same frequency, then it shows up as noise or a very short interruption.

For the level scrolling sound, you could fix it by starting a tone of infinite duration (by leaving off the duration argument or setting it to 0), and then stop the tone when the scrolling stops using noTone(). However, instead of a continuous tone while scrolling, personally I would prefer to hear continuous evenly spaced beeps. This is easy to accomplish with ArduboyTones by using a two tone sequence, where the second tone is a silent rest, and waiting for the sequence to complete before playing it again.

In addition to the problems you’ve mentioned, I also found the conveyor (spelled conveyer in the code) sound to have the same problem as with level scrolling. The solution is the same; either sound a single tone for the duration of travel or change it to a series of beeps. Again, I find the second option sounds better to me and was an easier code change.

For the explosion noise, as I already said, you can just make that a single sequence and let it play on its own.

So, the temperature escalation glissando is the only difficulty. As I said before, the only solution I can come up with is to “quantize” the gliss into a series of longer tones. This greatly reduces the noise but sounds more like a glissando created on a piano than one created with a slide trombone. Whether one technique sounds better than the other for the rising temperature is a matter of artistic opinion.

I’ve updated my CircuitDude.ino gist with the above changes EDIT: gist removed as per the author’s code use requirements. I used high volume for the explosion tones for emphasis. The sketch size is 27292 bytes. You can decide if any deficiencies in sound outweigh the code space savings from using ArduboyTones.

If you decide that ArduboyTones still isn’t acceptable, I suggest you switch from using ArduboyPlaytune to just the Arduino tone() function. This will save you over 300 bytes and sound the same as before. Also, the RGB LED will work properly. To do this, you just have to remove the inclusion and setup of ArduboyPlaytune and change the sound() function to:

void sound(int pitch, unsigned int duration) {
  if ( {
    tone(PIN_SPEAKER_1, pitch, (unsigned long)duration);

The duration parameter is changed from a long to an unsigned int so that each call to sound() only has to generate and pass 2 bytes for the duration instead of 4, saving another 102 code bytes. (None of the durations in the sketch is longer than the 65.5 seconds that you can pass as an unsigned int)

Yup, but again that’s not the intended purpose. And, be aware that the ArduboyPlaytune API doesn’t guarantee this either. It just happens to work that way today, but future changes to fix bugs or improve efficiency could cause ArduboyPlaytune to exhibit the same problems as ArduboyTones and still remain true to the documented API. If you want to easily create glissandi, arpeggios and other interesting sound effects, consider using ATMlib.