Poker Poker Magic (Puyo puyo-like)

Hello everyone!

While working on improving my map editor for DuckBlur, I decided to port and finish an old game of mine. It's a Puyo Puyo-style puzzle game with somewhat poker rules. Falling blocks are cards, and you need to match 3 or more of a kind, create a straight, or achieve a flush to make them disappear.

Here's how it currently looks:
masterful

The story unfolds in a school of card tricks. You can play as either Caroline, a lively but clumsy girl who needs to master magic tricks to avoid failing her exam, or as her bird, Columbus.

The game experiences some lag on devices when the boards are full. I didn't expect to have to optimize a puzzle game, but the number of sprites is increasing fast :sweat_smile:.

11 Likes

I made some profiling and the main slowdowns were caused by the high number of sprites (up to 87 per side + 6 layers for the background + 6 for the magic ball) and by the earthquake effect when chips are sent by the opponent.

I found a way to optimize those two points at the same time: when a card is placed in the board, I now remove the sprite and draw its image on the board itself. That makes the number of updated sprites way lower.

Here is the game showing only the card sprites for the left player. Cards are removed when they reach the ground:
only cards

Earthquakes are also much faster now because only one sprite is moving instead of more than 50 at the same time.
all

It was a bit trickier to handle the disappearance of a card. I have to clear the image from the board and every other cards on its top and add the corresponding sprites back in the sprite list.

Here is the game showing only the board sprite. You can see how row of cards disappear during a combo:
only board

An other thing I did was to flatten the background to 2 layers but it didn’t changed anything much.

2 Likes

Before each battle, the characters talks in short dialogue scenes. As these scenes will represent a significant part of the game, I wanted to include support for multiple languages in the game system. I expected encoding issues (and wasn't disappointed!), so I wanted to incorporate this early in the development.

In English, no surprises, everything displays correctly:
english

However, I started encountering some display issues with accents in French. I noticed that the len argument of the method playdate->graphics->drawText(const void* text, size_t len, PDStringEncoding encoding, int x, int y) is in fact not the number of bytes to display but the number of characters. So when I passed strlen(line) (i.e. the buffer length), it displayed a few extra characters.

Fortunately, I have some knowledge of UTF-8, and was able to quickly write a method to count the number of characters in a sentence:

uint32_t MELUTF8StringCodePointCount(const MELChar * _Nullable source, int length) {
    if (source == NULL) {
        return 0;
    }
    uint32_t count = 0;
    for (uint32_t index = 0; index < length && source[index] != '\0'; index++) {
        const uint32_t entry = source[index] & 0xFF;
        if (entry <= 127) {
            // ASCII
            count++;
        }
        // isUTF8Wagon is ((source[index] & 0xFF) >> 6) == 2
        else if (entry >> 5 == 6 && isUTF8Wagon(source, index + 1)) {
            // 2 bytes
            count++;
            index++;
        } else if (entry >> 4 == 14 && isTrailedByCountUTF8Wagon(source, index, 2)) {
            // 3 bytes
            count++;
            index += 2;
        } else if (entry >> 3 == 30 && isTrailedByCountUTF8Wagon(source, index, 3)) {
            // 4 bytes
            count++;
            index += 3;
        } else {
            // Encoding error
            playdate->system->logToConsole("Unable to count UTF-8 characters: encoding error, invalid UTF-8 value.");
        }
    }
    return count;
}

french

Supporting Japanese wasn't as straightforward as I imagined.
First problem: the font. Fortunately, others have been there before me. A big thanks to @matt and @hunty for the Japanese fonts.

Second problem: Japanese doesn't have spaces!
In English and French, the text reflow was handled by looking for the next space or the end of the sentence. If the displayed text size + the next word exceeded the width of the screen, the word would move to the next line. But in Japanese, it displayed nothing because the sentence didn't fit in width. So now, I display letter by letter when the language is Japanese.

The len argument also took its revenge! Naturally, the one in playdate->graphics->getTextWidth(LCDFont* font, const void* text, size_t len, PDStringEncoding encoding, int tracking) is also in the number of characters and not in the number of bytes, but I had forgotten to modify the code here as well >_<

japanese

2 Likes

This looks great! Good variation on a theme. Makes me want to make a tetris/puyo puyo variant.

1 Like

This week, my focus was on developing a grid view component to handle menus.

Since the game is made in C, using the Lua implementation from CoreLib wasn’t possible. I had 3 choices: find a C library for this, port Panic code to C, or build one from scratch. I chose the latter because it didn’t seemed that hard (spoiler: I was wrong). Maybe you have already read this meme: "We do this not because it is easy, but because we thought it would be easy". That’s exactly me right now.

So here it is, in various use cases:

  • a row of save files
  • the new game form (which will be gone soon)
  • a story selection grid

navigation

I also tried to replicate how scrolling works in the system. If you keep pressing a button, it will keep scrolling after a little delay:

scrolling

I still need to implement sections to make it possible to have rows with a custom column count.

The current result is a bit ugly though. Design is next.

You don’t know how much I respect the team doing menus in Persona games. They could make a game with nothing other than menus and I would still buy it.
I have to start playing Persona 5 to study how they make menus both look and feel fantastic!

This is a bit of fun

1 Like

I started playing Persona 5 Royal. The game menus are really well-designed, I love them. However, I didn't have enough time to think about menu design or code this week.

Fortunately, I was still able to make progress. I tried GarageBand on iOS during my commute, and I was pleasantly surprised. It is full-featured and very capable. For Kuroobi, I used a MIDI keyboard (Roland FP-10) alongside the macOS version of GarageBand to create the music, but the virtual piano on the iPhone screen was good enough to work.

I wrote a few tracks. The forum doesn’t allow attachment of mp3 files so I will look for an other way to share them.

Music creation isn't my specialty, but I find it very enjoyable. It feels great to start by humming something and later to have a 'real' version of the track.

The Kuroobi soundtrack was my first composition. Listening to Cabel explain the process of composing the B360 theme in the Playdate podcast made me want to try and write something as well.

I'm glad I tried. Thank you, Panic!

1 Like

The game is out! It was officially released on Catalog on September 10, 2024. You can check it out here:

When I started in December, I had an optimistic goal of finishing by March 2024. But, as always, game development had its surprises!

Time Breakdown: The Top 10 Tasks

I did a bit of a retrospective by looking at the git commits, and here are the top ten tasks that ended up taking the most time:

  • Intro and title screen: 6 weeks
  • Bug fixes and fine-tuning the game: 4 weeks
  • Writing the story: 3 weeks
  • Translating to English and Japanese: 3 weeks
  • Porting the game engine from Swift: 2 weeks
  • Coding the dialog scenes: 2 weeks
  • Making the CPU build combos: 2 weeks
  • Coding the "Learn to play" mode: 2 weeks
  • Developing a tool to convert the story dialogs from Markdown to C: 1 week
  • Drawing character artworks with multiple expressions for the dialogs: 1 week

As you can see, the most time-consuming aspects involved the intro, title screen, and fine-tuning the game. I tend to work slowly when it comes to drawing animations or writing stories. However, since Poker Poker Magic has no scoring or multiplayer modes, these elements were very important to ensure the game felt complete. My goal was to make the game long and fun enough so that players wouldn't regret their purchase.

Experimenting with Art and Animation

I already knew that I don't excel at drawing fast so I tried various techniques to speed up or improve the artworks:

Drawing only a shadow of the character!

It's easy to do, the drawings are quicker to make too, and you can even make a few mistakes without it being too obvious. I love it, using it too often may seem cheap.

Rotoscoping!

I filmed my daughter doing a little dance and traced Caroline over the video. It was time-consuming to go over each frame, but the result was worth it.
danse

Not actually animating the drawings!

Inspired by intros I love, I realized that instead of animating characters, I could animate the background to still give a sense of action. This technique saved time and I think it looks great.
onlybg

A few words

Releasing Poker Poker Magic has been a long journey, filled with unexpected challenges and creative solutions. From porting the engine to crafting the story and experimenting with different artistic techniques, each step of the process taught me something new. While development took longer than I initially planned, I'm really proud of the final result and I hope players enjoy the game as much as I enjoyed making it.

Thank you to everyone who supported me during this process, whether through playtesting, offering feedback, or simply showing interest in the game. It means the world to me!

2 Likes

Congratulations on the release and thanks for the development tips. I really like your anime style graphics!

We are probably in the same boat as I also want to make games with everything done by myself. Playdate is such a good platform for one-man team like us :smiley:

1 Like

Thank you! Glad that you like my style, it’s inspired by both manga and by French comics. In fact, a lot of recent bande dessinée in France have a style mixing both :sweat_smile:.

And I agree, the Playdate is awesome for solo developers and I love it!

Excited to see what you are working on after PocketBM!

1 Like