<p align="center">
<img src="https://github.com/subalterngames/procemon/raw/main/procemon/data/images/logo.png" />
</p>


***

**Proćemon** is a procedurally-generated trading card game from the exceedingly popular Proćemon media franchise. I found the original source code under a truck and I’ve decided to leak it online.

***

<p align="center">
<img src="https://github.com/subalterngames/procemon/raw/main/doc/images/cards.png" />
</p>

# Installation

**`pip3 install procemon`**

# Usage

1. Either [clone this repo](https://github.com/subalterngames/procemon) or [download this file](https://raw.githubusercontent.com/subalterngames/procemon/main/create_dex.py).
2. `cd path/to/the/file` (Replace `path/to` with the actual path to the repo or the directory where the downloaded file is located.)
3. Windows: `py -3 create_dex.py` OS X and Linux: `python3 create_dex.py`

# What it does

1. Create a "Dex" of a given number of "types" of Proćemon. Choose those "types" randomly. 
2. Generate Proćemon and assign them moves.
3. Save a JSON object describing the Dex to disk.
4. Get a sprite image for each Proćemon.
5. Generate a card image for each Proćemon and save it to disk.
6. Generate a temporary image of the back of a card.
7. Create a PDF zine of some of the images.

# How it works

[Read the API documentation here.](https://github.com/subalterngames/procemon/tree/main/doc/api)

- A [Dex](https://github.com/subalterngames/procemon/blob/main/doc/api/dex.md) is a compendium of [MonsterTypes](https://github.com/subalterngames/procemon/blob/main/doc/api/monster_type.md). Per MonsterType, the Dex generates a given number of [Monsters](https://github.com/subalterngames/procemon/blob/main/doc/api/monster.md).
- Each MonsterType is stored as a JSON object [here](https://github.com/subalterngames/procemon/tree/main/procemon/data/types). MonsterTypes are a few important keywords (such as the name of the type) and a list of `nouns` (which will be used to generate monster names). MonsterTypes and their nouns were scraped from the Internet in several ways:
  - Reorganized a [pycopora](https://github.com/aparrish/pycorpora) dictionary
  - Scraped from Wikipedia using [Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)
  - Extracted from [ImageNet synset hierarchies](http://image-net.org/download-API)
- Each Monster has 2 MonsterTypes. Each Monster's `name` is generated by combining part of a noun from the first MonsterType with part of a noun from the second MonsterType.
- Each Monster has a `description` i.e. the flavor text at the bottom of the card. To generate the flavor text, it scrapes Wikipedia pages (with Beautiful Soup) using its MonsterType keywords (see `MonsterType.wikipedia`) and its constituent nouns. It then creates a Markov chain model (using [Markovify](https://github.com/jsvine/markovify)) from this text and to generate a short sentence.
- Each Monster has a [`rarity`](https://github.com/subalterngames/procemon/blob/main/doc/api/rarity.md). This determines how "good" its stats are. In the Dex, each MonsterType has a certain percentage of card rarities (e.g. 20% of each monster type is Rare, and so on).
- Each monster has a `strong_against` which is just the type one to the right of its "primary type" in the Dex array of MonsterTypes. For example if the array is `["duck", "furniture", "fern"]` then all Monsters with the primary type `"duck"` are strong against `"furniture"`. (The order of this array is randomly shuffled whenever a new Dex is created.)
- Each Monster has 2 [Moves](https://github.com/subalterngames/procemon/blob/main/doc/api/move.md). Moves are generated using the Monster's first type (the "primary type").
  - When the Dex is first created, it loads a [Word Vector file](https://radimrehurek.com/gensim/models/keyedvectors.html). It then loads [a list of verbs and a list of adjectives](https://github.com/subalterngames/procemon/tree/main/procemon/data/moves). These lists were scraped from pycorpora and [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/List_of_moves). Then, the Dex assigns verbs and adjectives to each Move based on their distance to the type. For example, if the type is `flower` and the adjective is `floral`, the distance will be really short, so now the adjectives dictionary will look something like: `{"flower": ["floral"]}`
  - If you don't already have the expected word vector file, it is downloaded from [here](https://github.com/subalterngames/procemon/releases/download/wv/glove.zip) and extracted to `~/procemon_wv/` where`~` is your home directory.
  - There is also a list of "generic" verbs that any type can use. These verbs are a very short distance away from the word `"attack"`.
  - To get the `name` of a Move, a verb is first picked at random either from the "generic" verb list of the type-specific verb list. Then, sometimes a type-specific adjective is prepended to the `name`.
  - A `Move` has a certain `cost`. It might deal `damage` and it might have a `special` effect. The odds for how this is generated depends on the Monster's `rarity`.
- Once all of the monster have been generated, the Dex [can be saved as a JSON dictionary](https://github.com/subalterngames/procemon/blob/main/doc/api/dex.md#write_json).
- Generate cards of each Monster by calling [`Dex.create_cards()`](https://github.com/subalterngames/procemon/blob/main/doc/api/dex.md#create_cards)
  - A [color palette](https://github.com/subalterngames/procemon/blob/main/procemon/data/images/palette.npy) is loaded. This array was derived from [this image of the NES palette](https://en.wikipedia.org/wiki/List_of_video_game_console_palettes#/media/File:NES_palette.png). Each MonsterType is associated with a "color index" representing a column in the palette array.
  - For every MonsterType, the Dex looks for image URLs. It uses [this file](https://github.com/subalterngames/procemon/blob/main/procemon/data/images/imagenet_wnids.json) to look up "synset IDs" in [ImageNet](http://image-net.org/download-API) using the `MonsterType.imagenet` and `MonsterType.nouns`. It tests each URL. 
    - If it's a "good" URL (if an image is successfully downloaded), the Dex processes the image using [PIL](https://pillow.readthedocs.io/en/stable/) to make it look like a sprite and then adds it as an option for the next Monster of this MonsterTtype. The sprite is colorized using the color index in the palette.
    - If it's a "bad" URL (and they often are) it is added to [a list of known bad URLs](https://github.com/subalterngames/procemon/blob/main/procemon/data/images/bad_image_urls.txt) so it doesn't waste time trying again.
  - Once the images have been selected, a card per Monster is created and saved to disk using PIL.
    - The background is colorized using the color index in the palette.
    - Some [Perlin noise](https://github.com/pvigier/perlin-numpy) is applied to the background.
    - [This is the font.](https://github.com/subalterngames/procemon/blob/main/procemon/data/fonts/pokemon-classic.ttf) [This is where it's from.](https://fontstruct.com/fontstructions/show/1819053/pokemon-classic-6)
- Optionally, [a zine can be created of some of the cards in the Dex](https://github.com/subalterngames/procemon/blob/main/doc/api/zine.md). This script will:
  - Generate an image of the back of the card to use as the front and back cover of the zine. 
  - Start creating a PDF using [fpdf](https://pypi.org/project/fpdf/).
  - Randomly select some cards and add them as pages.
  - Write the PDF to disk.

# Changelog

## 1.0.1

- Fixed: Data files aren't included.