A Cards Against Humanity clone for LAN play. Works on desktop and mobile. Supports custom cards in multiple languages.
A Cards Against Humanity clone for hosting on your home network.
This software is currently in beta. It may contain bugs that impact gameplay. |
---|
The game server consists of a NancyFx web server and WebSocket server. The web server dishes out the webapp to anyone accessing the game in a browser. The webapp then connects to the WebSocket server, connecting you to the game.
The root directory contains a few important folders.
/packs
: Contains all the decks/trophies that will go in your server./web_content
: Contains the webapp./CardsOverLan
: Contains the server code.Check out the Releases section of this repository for official builds of the server.
Just unzip and follow the included setup instructions. When you're ready, run CardsOverLan.exe to start the server.
Some people may want to build the game from source. If that's you, read on.
First, you need Visual Studio 2017 (or newer) and .NET Framework 4.7.2. Make sure these are installed before continuing.
Open the CardsOverLan
project in Visual Studio. Set the build configuration to Release and run the build (usually by pressing F6).
The build (found in CardsOverLan/bin/Release
) will contain copies of the packs
and web_content
folders.
It also contains a settings.json
file that contains the server settings. See below for how to configure this file.
It is recommended to copy the build files to a separate directory before running the server.
When finished, run CardsOverLan.exe to start the server.
Your firewall settings may prevent the game from working properly. Make sure that TCP port 80 (or whatever port you set in the host URL) as well as TCP port 3000 (or your chose WebSocket port) are whitelisted for the server.
The settings.json file contains a number of properties that control how the server and game behave.
Property | Type | Description |
---|---|---|
afk_recovery_time_seconds |
Integer | Number of seconds an AFK player must play within in order to not be AFK anymore. |
afk_time_seconds |
Integer | Number of seconds a player can be idle before becoming AFK. |
allow_duplicates |
Boolean | Specifies whether to allow multiple clients from the same IP address. |
allow_skips |
Boolean | Specifies whether players are allowed to skip black cards. |
blank_cards |
Integer | Number of blank cards given to each player. These are not counted by hand_size . |
bot_config |
Object | Configures bot behavior. See below. |
bot_count |
Integer | Number of bots to add to the game. |
bot_czars |
Boolean | Specifies whether to allow bots to be Card Czars. |
bot_names |
String[] | List of names to assign to bots. |
client_ws_port |
Integer | Sets the client-facing port of the WebSocket server that they will connect to. Useful if hosting behind a reverse proxy. |
discards |
Integer | The number of discards allowed per player. |
enable_afk |
Boolean | Specifies whether AFK timers are enabled. |
enable_bot_taunts |
Boolean | Specifies whether bot taunts are enabled. Overridden by enable_chat . |
enable_chat |
Boolean | Specifies whether in-game chat is enabled. |
enable_idle_kick |
Boolean | Specifies whether idle kicking is enabled. |
enable_game_ready_up |
Boolean | Specifies whether to enable Ready-Up for new games. |
enable_upgrades |
Boolean | Specifies whether cards can be upgraded. Disabling this feature will fully upgrade all cards. |
enable_trophies |
Boolean | Specifies whether players can earn trophies. |
exclude_content |
String[] | Array with content flag strings to exclude cards by. Use this to filter out specific types of cards. |
exclude_packs |
String[] | Array of pack IDs. Forces the server to not load any packs in this array. Overrides any included packs in use_packs . |
game_end_timeout |
Integer | Time, in milliseconds, to wait before starting a new game. |
hand_size |
Integer | Number of cards dealt to each player. |
host_url |
String | The endpoint that the webserver will listen on. |
judge_per_card_timeout_bonus |
Integer | Number of additional seconds per card added to czar's timeout when judging cards. |
max_blank_card_length |
Integer | Maximum number of characters allowed in blank cards. |
max_player_name_length |
Integer | Maximum number of characters that a player name can have. |
max_players |
Integer | Maximum number of players that the server can hold. |
max_points |
Integer | Points required for a player to win the game. |
max_rounds |
Integer | Maximum number of rounds before game ends. |
max_spectators |
Integer | Maximum number of spectators allowed. |
min_players |
Integer | Minimum required players in order for the game to start. |
perma_czar |
Boolean | One lucky winner is selected to be the Card Czar for the entire game. |
pick_one_only |
Boolean | Specifies whether to prevent black cards with multiple blanks from being drawn. |
player_per_card_timeout_bonus |
Integer | Number of additional seconds per card added to player's timeout when playing. |
require_languages |
String[] | Excludes any cards that don't support all of the specified language codes. Leave empty to disable. |
round_end_timeout |
Integer | Time, in milliseconds, to wait before starting the next round. |
server_name |
String | The server name displayed in on the join screen. |
server_password |
String | The password to the server. Leave blank to disable. |
use_packs |
String[] | Array of pack IDs. Forces the server to only load packs in this array. Leave empty to load all available packs. |
web_root |
String | The path to the webapp directory. Leave blank to default to ./web_content . |
ws_url |
String | The endpoint that the game's WebSocket server will listen on. |
winner_czar |
Boolean | When set to true , the Card Czar will always be the previous round winner. Overridden by bot_czars and perma_czar . |
All time properties are in milliseconds.
Property | Type | Description |
---|---|---|
play_min_base_delay |
Integer | Minimum baseline delay before bot plays. |
play_max_base_delay |
Integer | Maximum baseline delay before bot plays. |
play_min_per_card_delay |
Integer | Minimum additional delay per card played. |
play_max_per_card_delay |
Integer | Maximum additional delay per card played. |
judge_min_per_play_delay |
Integer | Minimum delay per play before bot picks winner. |
judge_max_per_play_delay |
Integer | Maximum delay per play before bot picks winner. |
judge_min_per_card_delay |
Integer | Minimum additional delay per card before bot picks winner. |
judge_max_per_card_delay |
Integer | Maximum additional delay per card before bot picks winner. |
min_typing_interval |
Integer | Minimum interval between keystrokes when typing chat messages. |
max_typing_interval |
Integer | Maximum interval between keystrokes when typing chat messages. |
I was bored and wanted a fun project to work on over winter break.
They're all good in their own way, and each of them has different strengths. Below is a (non-exhaustive) comparison table:
PYX | Azala | Cardcast | Cards Over LAN | |
---|---|---|---|---|
Desktop support | ✔️️️ | ✔️ | ❌ | ✔️ |
Mobile support | ❌ | ✔️ | ✔️ | ✔️ |
Self-hosting | ✔️ | ❌ | ✔️ | ✔️ |
Offline play | ❌ | ❌ | ❌² | ✔️ |
Discards | ❌ | ✔️ | ❌ | ✔️ |
Chat | ✔️¹ | ✔️ | ❌ | ✔️ |
Blank cards | ✔️¹ | ✔️ | ❌ | ✔️ |
Localization | ❌ | ❌ | ❌ | ✔️ |
Bots | ❌ | ✔️ | ✔️ | ✔️ |
Black card skipping | ❌ | ✔️ | ❌ | ✔️ |
Trophies | ❌ | ❌ | ❌ | ✔️ |
Multiple games | ✔️ | ✔️ | ❌ | ❌ |
License Type | BSD 2-Clause | Closed Source | Closed Source | MIT |
¹ Chat and blank cards only available in third-party PYX servers.
² Internet connection required to download Cardcast decks.
Yes, decks are written using a simple JSON format. Add them to the packs
folder before starting up the server.
Cards Over LAN is designed to cater to local small group/party settings to provide a controlled, reliable service that can be easily customized. Moreover, it makes it more suitable for situations where physical cards may be inconvenient, or Internet service might be unavailable (such as while travelling).
Here are some creative ways you can play CoLAN:
Yes! I recommend hosting behind a reverse proxy such as Nginx or Apache. Although the game server doesn't directly support HTTPS, you can forward HTTPS traffic to it using a load balancer or similar.
Isn't that the great thing about open source software?
Never.
Suggestions are welcome. Please submit an issue detailing what you're looking for.
Cards Against Humanity is licensed under a CC BY-NC-SA 2.0 license. As such, I cannot include the cards without placing all of my code under the same license. As Creative Commons is not designed for software, the simpler solution is to distribute the CAH packs in a different repository with separate licensing.
If you want the official CAH cards, you can get the packs right here.
You can use the exclude_content
property in your settings for this.
Example: if you hate all violence and sexual content, you can do this to exclude any cards mentioning such things:
"exclude_content": ["v", "s"]
If you only hate cards including both violence and sexual content, but are fine with one or the other, combine the flags in one string. The order doesn't matter.
"exclude_content": ["v s"]
Save your changes, relaunch the server and enjoy your ten-card deck!
Regarding code contributions, I will have guidelines for this up soon.
If you speak a language that isn't English and want to help me translate the cards, feel free to submit a pull request with your translations!
Cards Over LAN is a clone of Cards Against Humanity. The original game, available at cardsagainsthumanity.com, is available under a CC BY-NC-SA 2.0 license. This project is in no way endorsed or sponsored by Cards Against Humanity.
For project license information, see LICENSE.
For third-party licenses, see LICENSES_THIRD_PARTY.