procemon 1.5.3
Procedurally generated trading card game
License: MIT
Keywords: image pokemon card procgen

<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 source code under a truck so I leaked it online. You can use it to create your own unique decks.

***

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

# Installation

1. [Get Python3](https://www.python.org/downloads/)
2. **`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`

**Result:** You will create a unique deck of cards.

# 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 Dex has a `region` name, generated via [markov chains](https://github.com/jsvine/markovify) of Japanese cities and prefectures scraped from Wikipedia and US county names scraped from [pycopora](https://github.com/aparrish/pycorpora)
- 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) as well as:
  - A list of `nouns` which will be used to generate monster names. MonsterTypes and their nouns were collected in several ways:
    - Reorganized from 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)
  - A list of `verbs` and a list of `adjectives`. These are used to create names of moves. See `procemon/data/moves/srcs.txt` for a list of sources. Verbs and adjectives are assigned to each monster type by running `procemon/wv.py`  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). Words are assigned to monster types 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"]}` 
 - A given number of Monsters are generated per MonsterType.
  - 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,
  - There is also a list of generic "attack verbs" that any type can use and prefer if the move deals damage. These verbs are a very short distance away from the words like `"attack"`, `"battle"`, etc. These are calculated and cached via a word vector model when you run `procemon/wv.py` (see above).
  - 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 monsters 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 gets a list of nouns (the same list used for generating monster names). Using a randomized subset of that list, the Dex tries to get the corresponding Wikipedia page. It then uses Beautiful Soup to scrape the page for image URLs. If there aren't any image URLs, the Dex stores this noun in `data/images/no_images.txt` so we don't try it 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

[Changelog](doc/changelog.md)