An R package containing an R6 class to simulate simplified gameplay elements of the Safari Zone sub-area from Pokémon Blue (1998) with OOP.
The first generation of Pokémon games were developed for the Nintendo Game Boy by Game Freak and published by Nintendo. Pokémon as a property is owned by The Pokémon Company.
This project is a demonstration of the {R6} package and the R6-class for object-oriented programming in R. It’s purely for learning purposes. You can read a blog post about it.
Install from GitHub with remotes::install_github("matt-dray/safar6")
.
The game is text-based and takes place entirely in the console. Start a
game like x <- safar6::safari_zone$new()
. Be warned: it’s tricky. But
then so was the original.
Use x$step()
to take a step through the tall grass of the Safari Zone.
There’s a chance you’ll encounter a wild Pokémon; perhaps it will be a
rare one at a high level. You’ll be prompted to throw a Safari Ball to
try and catch it, with the option to throw bait or a rock to influence
its catchability. Try to catch as many Pokémon as you can before you run
out of steps or balls.
Use x$pause()
to ‘pause’ the game and see your current stats. You can
boot up x$bills_pc
to see which Pokémon you’ve caught so far.
For help with fields and methods see ?safar6::safari_zone
.
Expand for (contrived) example gameplay 👾
> library(safar6)
# {safar6}
# Start game: x <- safari_zone$new()
# Take a step: x$step()
> x <- safari_zone$new()
# ------------------------
# First, what is your name?
# NEW NAME (1)
# BLUE (2)
# GARY (3)
# JOHN (4)
# ------------------------
# Select 1, 2, 3 or 4:
> 1
# Your name:
> THEW
# Welcome to the SAFARI ZONE!
# For just P500, you can catch all the
# Pokemon you want in the park!
# Would you like to join the hunt?
# ------------------------
# MONEY: P500
# YES (1) or NO (2)
# ------------------------
# Select 1 or 2:
> 1
# That'll be P500 please!
# ------------------------
# MONEY: P0
# ------------------------
# We only use a special POKe BALL here.
# THEW received 30 SAFARI BALLs!
# We'll call you on the PA when you run out of time or SAFARI BALLs!
> x$step()
# 499/500
> x$step()
# 498/500
> x$step()
# 497/500
# Wild VENONAT L22 appeared!
# ------------------------
# BALLx30 (1) BAIT (2)
# THROW ROCK (3) RUN (4)
# ------------------------
# Selection:
> 3
# THEW threw a ROCK.
# Wild VENONAT is angry!
# ------------------------
# BALLx30 (1) BAIT (2)
# THROW ROCK (3) RUN (4)
# ------------------------
# Select 1, 2, 3 or 4:
> 1
# THEW used SAFARI BALL!
# Wobble...
# Darn! The POKeMON broke free!
# Wild VENONAT is angry!
# ------------------------
# BALLx29 (1) BAIT (2)
# THROW ROCK (3) RUN (4)
# ------------------------
# Select 1, 2, 3 or 4:
> 1
# THEW used SAFARI BALL!
# Wobble... Wobble... Wobble...
# All right!
# VENONAT was caught!
# Do you want to give a nickname to VENONAT?
# ------------------------
# YES (1) or NO (2)
# ------------------------
# Select 1 or 2:
> 1
# Nickname:
> Tajiri
# Tajiri was transferred to BILL's PC!
> x$pause()
# 497/500
# BALLx28
# Transferred to BILL's PC: 1
> x$bills_pc
# nickname species level
# 1 Tajiri VENONAT 22
Here’s a screenshot of the game in action using the gamelad RStudio theme and the VT323 font.
The Safari Zone is an enclosed area separate from the rest of the game. Game mechanics are different here: you’re allowed 500 steps and 30 balls to capture Pokémon. Also, wild encounters don’t result in a ‘battle’; instead you can ‘bait’ or ‘throw a rock’ to influence the catch rate of the target. I chose to simulate this area due to its relative simplicity compared to other areas of the game, which use a more complex battle mechanic.
The fields in the SafariZone
class are ‘overworld’ counters,
basically: the number of steps and balls remaining, and the number and
identity of captures you’ve made.
Methods are:
$new()
to initialise the class and start the game$step()
, which moves your ‘player’ and may result in an encounter$pause()
(a copy of the$print()
method) to simulate the pause screen from the game, showing the current number of steps and balls remaining
The $step()
method does the hard work. It contains code that:
- decides whether you encountered a target, based on the encounter rate of the Safari Zone (~12%)
- selects a wild Pokémon based on the relative encounter-rate slots
for the Safari Zone Center Area particular to Pokémon Blue
(e.g. 20% for a level 22 Nidoran Female through to 1% for a level 23
Chansey; see
safar6::pokemon
for details) - generates individual variation in the selected Pokémon’s speed and HP (IV values), which influence catchability
- prompts you interactively for an action: throw ball, bait, throw rock, run
- adjusts the ‘angry’ and ‘eating’ values of the target and modifies catch rate and run probability as a result (a rock doubles the catch rate and the flee chance; bait halves the catch rate, but makes it four times less likely to run)
- calculates whether the Pokémon will be caught or will run away
- terminates the game if steps or balls are depleted
To keep things (much!) simpler than the original, this implementation doesn’t include a number of features from the original game. Some missing elements are:
- visuals (everything is printed in the console)
- movement around a map (all steps are treated as though you’re moving through tall grass)
- all areas of the Safari Zone (only the Center area is used here)
- finding items (they have no use in this context)
- fishing and use of different rod types
- species catch and encounter rates from the other Gen 1 versions (e.g. Scyther is in Red rather than Pinsir; and Yellow has some catch-rate changes)
Information about game mechanics and values are relatively tricky to come by. I used the following resources:
- Bulbapedia for Pokémon stats and game mechanics
- The Cave of Dragonflies for game mechanics
- the Pokémon Slots website for encounter rates
- the pret/pokered GitHub repo for a disassembly of the games
I also referred to a post I wrote about using {R6} to simulate an Automatic Bell Dispenser from Nintendo’s Animal Crossing: New Horizons (2020).
Please note that the {safar6} project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.
I do not condone throwing rocks at any creature, let alone catching and imprisoning them.