The game of Spite and Malice, written in Python using the Pygame engine!
IMPORTANT: Everything in this repository EXCEPT for the contents of assets/card_backs and assets/card_faces, including all code, is hereby released under the MIT license. The contents of assets/card_backs and assets/card_faces have been previously released under different licenses, detailed in the "Asset Credits" section below.
Spite and Malice, also known as Skip-Bo, is a two-player card game usually played with two decks of standard playing cards where the object of the game is to get rid of all the cards in your payoff pile before the other player. To do this, players use four shared build piles to count from 1-12 (A, 2-10, Jack, Queen), using cards from their hand, personal discard piles and payoff pile. The top card of the payoff pile will determine who goes first (highest rank). At the beginning of their turn, if they have no cards, a player draws 5 cards from the draw pile to their hand and proceeds to stack cards in the build piles starting with aces and working their way up to queens. When a queen is placed on the build pile, that pile is reshuffled back into the draw pile. A player ends their turn by placing a card from their hand onto one of their four personal discard piles. Kings are wild cards and can substitute for any other ranked card. Suits do not matter in this game. Jokers are also not used. The first player to have no cards left in their payoff pile wins. If the number of draw pile cards run out before both payoff piles have been emptied, the winner is determined by who has the lowest amount of cards left on their payoff pile. If both payoff piles have the same number of cards left, the game is a stalemate.
- Play with two players over the internet or on your local network
- Server port, number of playing card decks and number of payoff pile cards configurable on the server
- Auto-reshuffling when a queen (or a wild king substituting for a queen) is placed on a build pile
- Automatic drawing of 5 cards when it's the players turn and they have no cards in their hand
- Stack value displayed below build piles during gameplay in case a king is on the top of the pile
- Multiple card back colors configurable on the client
- Custom player names configurable on the client
- Shuffling and drawing sounds in-game (You can also turn these off in the client)
- Ability to challenge your opponent to a re-match after the conclusion of a game (both players must select yes to proceed)
If you would prefer to run single executables of the client and server with all dependencies included, check out the releases page here!
This repository contains two main scripts, the server script (spite_and_malice_server.py) and the client script (spite_and_malice_client.py). The server script is a command line application while the client script contains the main game GUI that each player will require to play the game. If you downloaded executables from the link above, you will instead have two executables, one for spite_and_malice_server and another for spite_and_malice_client.
The server script requires the following files/directories and modules to run (you can skip this if you downloaded an executable above):
- pygame-ce (
pip install pygame-ce) - numpy (
pip install numpy) - card.py
- socket_utils.py
- path_utils.py
- assets/card_faces directory
The client script requires the following files/directories and modules to run (again, you can skip this if you downloaded an executable above):
- pygame-ce (
pip install pygame-ce) - pygame-gui (
pip install pygame-gui) - numpy (
pip install numpy) - card.py
- socket_utils.py
- path_utils.py
- assets/card_backs directory
- assets/dealing_cards.wav
- assets/shuffle_cards.wav
- theme.json
The typical configuration to run this game is one server component running and serving two client instances. Both players will also require a mouse to move cards on their instances of the client while playing the game.
The server component will require either a local host or dedicated/shared server (either on a local network or in the cloud) with a firewall configured to allow inbound IPv4 traffic on an ephemeral port between 32768 and 65535. The chosen port is passed to the server script/executable on first run and stored in a config file. If setting up for multiplayer gameplay over the internet (or just on a local network), the host running the server component must have an IPv4 address that is visible to both players.
After setting up a python virtual environment, installing the dependencies listed above and running the server script (or simply running the all-in-one server executable from the releases page), you will be presented with the following prompt:
This is the ephermeral port number mentioned earlier that should be opened for inbound IPv4 traffic on your server. Enter your chosen ephermeral port number and press Enter.
You will then see the following:
This is the number of standard playing card decks the game will use for each game. Standard games of Spite and Malice use 2 decks, but use 4 or more if you don't want to run out of draw pile cards during a game. Enter a number between 2-6 and press Enter again.
You will then see yet another user prompt:
This is the number of cards to use for each payoff pile. Standard games of Spite and Malice use either 20 or 30, but you can enter any value between and including 20 and 30. Enter a number and press Enter once again to complete the initial configuration.
You should then see a notification that a configuration file (config.toml) was written to a local directory path and that the server has begun listening for traffic. Configuration files are written by the server to the following locations depending on the platform of the host:
Windows: C:/ProgramData/jscdev909/spite_and_malice_server
MacOS/Linux: $HOME/.config/spite_and_malice_server
These files are fully editable but if any wrong information is read from them during startup of the server you will receive the setup prompts again to re-write the file with valid information.
Initial server configuration is now complete. The entered information will be remembered for all subsequent runs of the server. To get the initial user setup prompts again, simply delete the config file.
For the client, after setting up a python virtual environment, installing the dependencies listed above and starting the client script (or simply starting the all-in-one client executable from the releases page), you will be presented with the following empty configuration screen:
Player name can be any name up to 8 characters in length. The server IP is the visible IPv4 address of the server (or 127.0.0.1 if hosting locally) and the port is the ephemeral port configured on the server earlier. The game options control the color of the card backs seen in the GUI and if any shuffling or dealing card sounds should be played during the game. These can be adjusted as necessary. After pressing OK, all of these settings will be stored in a config.toml file at the following path depending on the host platform:
Windows: C:/ProgramData/jscdev909/spite_and_malice_client
MacOS/Linux: $HOME/.config/spite_and_malice_client
The configuration file is automatically re-written each time you press OK in the client. To get a blank client setup screen again, simply delete the configuration file.
Press OK to connect to another client to play the game. You should see connection status notifications on the client and the server should start outputting status messages for the players as well. At this point two running and properly-configured clients should be able to connect to each other and play the game.
Enjoy!
If you have any questions or concerns with the game functionality, don't be afraid to open an issue and let me know!
- Playing cards (by Byron Knoll, open source/public domain license): https://opengameart.org/content/playing-cards-vector-png
- Colored card backs (by jeffshee, Creative Commons 3.0 license): https://opengameart.org/content/colorful-poker-card-back
- Icon used for Windows/macOS release executables (by Everaldo, LGPL Open Source license): https://www.iconarchive.com/show/crystal-clear-icons-by-everaldo/App-Card-game-icon.html
- Stack Overflow and its many contributors, for tons of answers of relevant Python questions and for providing the source code for the get_path and recv_all helper functions used in path_utils.py and socket_utils.py, respectively
- DigitalOcean, for hosting the cloud agent I used to test the server component of this project with
- My Mom, for playing Skip-Bo with me which inspired this whole project
- My friend Anthony, for play-testing the development versions of this game with me, helping to squash bugs and giving me feature suggestions