---
title: 'From Cats to Pokémon: Building PokeBattle Arena with Replit, Expo, and Grok'
authors: Raj Kumar
published: April 9, 2025
categories: Users
tags: Replit, vibe coding, Grok, AI app development, AI apps, Expo Go
---

I never thought a ‘**Random Cat Generator**’ tutorial by Matt Palmer would set me on a Pokémon path, but that’s exactly what happened. I guess you could call it _“**vibe coding**”_—there was no strict plan; I just kept building things that felt fun until a full-blown PvE battleground emerged.

[Tweet](https://x.com/mattppal/status/1890053960209404264)

So I created **PokéCatcher**, a quick fetch-and-display app for random Pokémon—just for fun.

**But it didn’t stop there.**

[Tweet](https://x.com/rajkstats/status/1891171734021353537)

I figured that was it—until I saw a suggestion in the comments that I turn it into a PvE battleground. Next thing I knew, I was deep in battle logic, and PokeBattle Arena was born.

To be honest, I had no clue how to build a PvE battleground when I started. Once I decided to go beyond just catching Pokémon, I realized I needed a plan— especially for turn-based battle logic, AI moves, and all the little details that make fights exciting. With the idea of a PvE battleground in mind, I decided to keep it simple at first: one Pokémon vs. another, taking turns until someone faints.

[Tweet](https://x.com/rajkstats/status/1894184017433694566)

My first thought was, ‘**_Where do I even begin with turn-based battles?_**’ So I hopped onto X and tried out __Grok 3’s deep research.__

![Grok 3](https://cdn.sanity.io/images/9r24npb8/production/e3e002915c216ea4103b6299136668835b584ad0-1050x942.png)

It gathered everything relevant about Pokémon battle mechanics and condensed it into something I could actually use. That let me create a simple one-on-one system where each Pokémon has HP, a few moves, and a basic turn cycle.

## Building the Home Screen with Expo + Replit

With the logic mapped out, I figured the first step was to give players something to see and do—so I started building the home screen in **Expo**.

I jumped into this [Expo template on Replit](https://replit.com/@replit/Expo?v=1&utm_source=twitter&utm_medium=video&utm_campaign=matt#README.md). Just hit **“Remix Template”** and it spun up a basic React Native environment right in my browser—no local setup required.

![Expo and Replit](https://cdn.sanity.io/images/9r24npb8/production/93baf43628de4d0d941d5b4cc0d23f1e33614c18-1912x936.png)

## PokeBattle Arena: Home Screen

I split my app into two pages:

- **`index.tsx`**: Lists 20 random Pokémon from the [PokéAPI](https://pokeapi.co/) (huge thanks to them for making all this possible!); users just scroll through the randomly fetched list and tap one to select.
- **`battle.tsx`**: The actual battle screen where attacks, HP, and animations play out.

It’s super minimal—just enough to be fun. And thanks to [**Expo Go**](https://expo.dev/go), I could check it all on my phone in real time, as easy as scanning a QR code

![Pokemon Battle Arena: Home Screen](https://cdn.sanity.io/images/9r24npb8/production/5c34385e5e92718856ab5655d5a3fc27fbe24d52-391x828.png)

With the scrolling list in place, the next step was to wire up navigation to the battle screen. And as soon as the user picks a Pokémon, I store its data—like **name**, **stats**, and **image** in **local storage**—and pass it along to the next screen. That way, it’s all ready for the upcoming turn-based showdown.

As soon as that screen loads, it fetches the chosen Pokémon from storage, then randomly picks an opponent Pokémon from the PokéAPI. I added a quick **‘VS’** animation for flair, and set up two HP bars—one for the player and one for the opponent.

## Bringing the battle to life

At this point, I just had to **wire in the actual damage calculations** and **figure out who attacks first.** Grok 3’s deep research mode gave me the groundwork for a simplified Pokémon battle. Then I translated those findings into `battle.tsx`, complete with damage calculations, animations, and a combat log.

## The damage formula

This code decides how much HP is lost when one Pokémon attacks another. It looks at how strong each monster is (**Attack**, **Defense**), how powerful the move is (**power**), and assumes everyone is **Level 50**:

```javascript
function calculateDamage(attackerStats, defenderStats, power) {
  if (!power || power <= 0) return 0;
  const level = 50;
  const raw =
    (((2 * level) / 5 + 2) * power * (attackerStats.attack / defenderStats.defense)) /
    50 +
    2;
  return Math.max(1, Math.floor(raw));
}
```

No fancy **type weaknesses** or **critical hits**. If the defender’s still alive after the hit, they get to use the same function against you. This keeps battles straightforward but still fun.

## Turn Order, Animations, and Logs

I wanted the game to feel rewarding, but not punishing. So I decided the player always goes first. If the opponent’s HP isn’t zero, it responds with a random move.

Every attack logs a message in a **scrollable combat log**, color-coded so you can see who did what at a glance.

With each turn, you see a quick line like

> **_‘omanyte used bind! It dealt 7 damage!’_** (in green).

If the opponent fights back with something like

> **‘butterfree used gust! _It dealt 9 damage!_’ (**in red)

**To show the impact of each attack**, I display a quick message and update the HP bar right away.

It’s a small detail, but helps turn a simple exchange of numbers into a mini story

![Battle screen](https://cdn.sanity.io/images/9r24npb8/production/5e20594c85a6984f56a6d6550a81f83f30c3158d-398x831.png)

### Adding a rematch option

One small feature I added was a **Rematch** button at the end of each battle. Once a Pokémon faints, the battle ends and players see a “Rematch” prompt. Tapping it:

- Resets both Pokémon’s HP to full
- Clears the combat log
- Either reuses the same matchup or fetches a new opponent

That way, you can jump right back into the action without returning to the home screen.

![Rematch](https://cdn.sanity.io/images/9r24npb8/production/1d19ef7d1ed7ad7f58f432dca04411984bcc5a56-376x791.png)

## The Grok, Replit, Expo combo

- **Grok** gave me the **damage formula** and logic concepts via deep research and boiler plate code for battle, saving me from hours of forum-hopping.
- [**Replit**](https://replit.com/) served as my **all-in-one dev workspace**—I remixed the Expo template online, used the built-in assistant for quick debugging, and deployed my **web version** as a static page with just a couple of clicks.
- Meanwhile, **Expo** powered **both the web and Android builds** from the same codebase. I may not have published the Android version on the Play Store, but being able to test it on my phone via **Expo Go** was a game-changer—tweak some code, scan a QR code, and boom, new features on the go!

## Where to next?

**PokeBattle Arena** is a neat little project, but I’m only scratching the surface. Imagine adding:

- **Type Matchups** (Fire vs. Water? That’s classic Pokémon!)
- **Speed Stats** (who gets the first move?)
- **Status Effects** (poison, burn, sleep—lots of fun)
- **Real-Time PvP** (challenge your friends!)

Check out the **live web version** here: [http://poke-battle-arena.replit.app/](http://poke-battle-arena.replit.app/)

Or, if you want to mess with the code yourself, just remix the [Expo template on Replit](https://replit.com/@replit/Expo), sprinkle in some Grok research, and you’ll have a mini Pokémon adventure running on your phone in no time.

**Big thanks to [PokéAPI](https://pokeapi.co/)**— Without their database, none of this would have been possible.

**And of course, thanks for reading!**

If you have questions or ideas on how to level this up, feel free to reach out.

**Have fun battling!**