Code Monkey home page Code Monkey logo

terraform-aws-palworld's Introduction

Palworld Dedicated Server Terraform Module

Palworld Server Infrastructure Terraform module.

Donate

I do this in my free time. Consider donating to keep the project going and motivate me to maintain the repo, add new features, etc :)

Support on Patreon

Support on Patreon

Support on By Me A Coffee

Support on BuyMeACoffee

Subscribe

Subscribe on YouTube

About

This module allows you to quickly deploy an Palworld server on AWS.

Key Features

  • Palworldrunning on Ubuntu
  • The ability to use an existing PalWorldSettings.ini
  • PalWorldSettings.ini settings are configurable inputs for creating a brand new configuration
  • Ability to store backups in S3 at a defined interval
  • Ability to start from existing save data
  • AWS SSM or SSH connectivity

How to Use

Prerequisites

You must have the following to use this Terraform module:

Usage

  1. Create a file named main.tf
  2. Add the following as a minimum. See all available inputs in the "Inputs" section of this README. Inputs not defined will use their default values.
module "palworld" {
  source  = "TheSudoYT/palworld/aws"

  instance_type                 = "t3.xlarge"
  create_ssh_key                = true
  ssh_public_key                = "../../palworld_public_key.pub"
  server_name                   = "palworld-on-aws"
  server_player_max_num         = 32
}
  1. Choose your inputs - PalWorldSettings.ini inputs use default values unless you provide a value OTHER than the default value. Palworld will use the settings from a custom PalWorldSettings.ini file if you choose to use one. Modifying an input that is a PalWorldSettings.ini setting while also using a custom PalWorldSettings.ini file will result ONLY the values in your custom .ini file being used.

Warning

Any of the inputs that are also settings in the PalWorldSettings.ini file will be ignored if use_custom_palworldsettings = true. For example, if you say exp_rate = 3.0 and also say use_custom_palworldsettings = true then the value in your custom PalWorldSettings.ini will be used and the value of exp_rate will be ignored.

  1. Initialize Terraform - Run terraform init to download the module and providers.
  2. Create the Palworld server and Infrastructure - Run terraform apply to start deploying the infrastructure.

Accessing the Server

Warning

As of Jan 23, 2024 users are reporting a bug preventing servers from appearing in the community servers list or search filter. If this happens you can still connect to the server using the EC2 instance IP address and the public_port you have set (default 8211)

Note

In testing it takes approximately 10 minutes on a t3.xlarge for steam to download and configure Palworld.

The terraform apply will complete, but the server will not appear in the server list until this completes. You can SSH into your server ssh -i my_palworld_key.pem [email protected] and use journalctl -xu cloud-final to monitor the install. See the troubleshooting section of the README if you continue to have problems.

Note

In testing it takes approximately 3 to 5 minutes for your server to appear on the community server list after installation is complete.

Backups

This module offers an optional backup feature, designed to safeguard your Pal/Saved/SaveGame directory by periodically copying it to an Amazon S3 bucket. When enabled, the backup feature automatically archives the specified directory to a designated S3 bucket at intervals defined by a cron expression. The retention period of these backups in S3 is controlled by the s3_bucket_backup_retention parameter, allowing for cost-effective storage management.

Note

Enabling this creates an additional S3 bucket. In testing, this adds an additional 0.10 USD ( 10 cents ) a month on average depending on the duration of backup retention, how often you backup, and how often you restore from backup. https://calculator.aws/#/addService

2 Files will be created on the Palworld server; palworld_backup_script.sh on install and palworld_backup_log.log AFTER the first backup job runs.

The backup should be visible in the AWS S3 bucket after the first specified backup interval time frame passes.

Using an Existing PalWorldSettings.ini

You can use an existing PalWorldSettings.ini so that the server starts with your custom settings. The following inputs are required to do this:

Warning

Any of the inputs that are also settings in the PalWorldSettings.ini file will be ignored if use_custom_palworldsettings = true. For example, if you say exp_rate = 3.0 and also say use_custom_palworldsettings = true then the value in your custom PalWorldSettings.ini will be used and the value of exp_rate will be ignored.

Input Description
use_custom_palworldsettings = true Must be set to pass a custom PalWorldSettings.ini to the server on startup
custom_palworldsettings_s3 = true Cannot be set when custom_palworldsettings_github = true. Set to true if you would like to upload an existing PalWorldSettings.ini to an S3 bucket during terraform apply. Setting this to true will create an S3 bucket and upload the file from your PC to the S3 bucket. It will then download the file from the S3 bucket on server startup. You MUST also set palworldsettings_ini_path as a path on your local system relative to the terraform working directory. It is easiest to just place PalWorldSettings.ini in the root of your terraform working directory and just provide palworldsettings_ini_path = PalWorldSettings.ini.
palworldsettings_ini_path = "path/on/my/pc" A path on your local system relative to the terraform working directory. It is easiest to just place PalWorldSettings.ini in the root of your terraform working directory and just provide game_user_settings_ini_path = PalWorldSettings.ini. Only used when custom_palworldsettings_s3 = true.
custom_palworldsettings_github = true Cannot be set when custom_palworldsettings_s3 = true. Set to true if you would like to download an existing PalWorldSettings.ini to the server from a GitHub URL. Must also provide custom_palworldsettings_github_url = "https://my.url.com with a valid URL to a public GitHub repo.
custom_palworldsettings_github_url = "https://my.url.com A valid URL to a public GitHub repo to download an existing PalWorldSettings.ini from onto the server during startup. Must have custom_palworldsettings_github = true and use_custom_palworldsettings = true to use.
  • Using the S3 option will instruct terraform to create an S3 bucket along with an EC2 instance profile that will have permissions to assume an IAM role that is also created. This role contains a policy to allow only the EC2 instance to access the S3 bucket to download PalWorldSettings.ini. This also instructs the user_data script that runs when the server starts to download PalWorldSettings.ini from that S3 bucket and place it in /palworld-server/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini

  • Using the GitHub option will simply instruct the user_data script that runs when the server starts to download PalWorldSettings.ini to the server and place it in /palworld-server/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini

Starting From Existing Save Data, Restoring From Backups, or Migrating Servers

This guide outlines essential processes for starting from existing save data, restoring from backups, or migrating servers using this Terraform module. It emphasizes the importance of the DedicatedServerName setting and provides instructions for using both local and S3 bucket backups.

Prerequisites

Before proceeding with backup or restoration processes, you must obtain the DedicatedServerName value from your old Palworld server's GameUserSettings.ini file. This value is crucial as it corresponds to the directory name containing your .sav files on the old server.

[!DANGER] It is mandatory to provide the DedicatedServeName from the old Pal/Saved/Config/LinuxServer/GameUserSettings.ini file. This is also the name of the directory from the old server that contained your .sav files.

Note

Using this modules enable_s3_backups = true option will backup the GameUserSettings.ini file to S3 as well in the event the server is lost.

Using You Own S3 Bucket ( Bring Your Own )

Set backup_files_storage_type = "s3" if you have an AWS s3 bucket somewhere with the backups files already in it. Please note the warning below about the REQUIRED file structure of the bucket. Terraform and user_data are opinionated in how they retrieve and place these files, so you must adhere to this structure.

Warning

When backup_files_storage_type = "s3" using The objects in the S3 bucket must not be compressed and must be in the root of the S3 bucket. The bucket's file structure MUST match the picture below. It will be synced to the SaveGame/0/<dedicated_server_name> directory.

Required S3 Structure

Using Local Files

Set backup_files_storage_type = "local" if the save files are on your local host PC. Please note the warning below about the REQUIRED file structure of the bucket. Terraform and user_data are opinionated in how they retrieve and place these files, so you must adhere to this structure.

Warning

When backup_files_storage_type = "local" using The objects/files in the directory you specify with backup_files_local_path must not be compressed. Terraform will iterate through each file in that directory and upload it to the root of an S3 bucket it creates. It will do this for backup_files_local_path/Players as well.

Required local file structure

Required Local File Structure

  • backup_files_storage_type = "local" will instruct terraform to create an S3 bucket named palworld-bootstrap-local-saves-<region>-<accID> and upload the save files from your local PC backup_files_local_path directory specified to that bucket. The user_data script on the EC2 instance will download the files from that S3 bucket when the server starts and place them in the /palworld-server/Pal/Saved/SaveGames/0/<dedicated_server_name_hash> directory.

  • backup_files_storage_type = "s3" Is informing terraform that you have an existing S3 bucket somewhere that contains the save game data. The EC2 user_data script will attempt to sync the root of that S3 bucket with the SaveGames/0/<dedicated_server_name_hash> directory. It will also attempt to sync the S3 buckets Players folder to SaveGames/0/<dedicated_server_name_hash>/Players That is why it is important that the objects be uncompressed and in the proper structure.

Warning

When backup_files_storage_type = "local" using The objects/files in the directory you specify with backup_files_local_path must not be compressed. Terraform will iterate through each file in that directory and upload it to the root of an S3 bucket it creates.

Usage - Restore From Local Files

Relevant inputs:

  start_from_backup         = true
  backup_files_storage_type = "local"
  dedicated_server_name_hash = "FA8C44A6FA46436AAAE4D414C4214B25"
  backup_files_local_path   = "../../assets"

Usage - Restore From an Existing S3 Bucket ( Bring Your Own S3 Bucket)

Relevant inputs:

  start_from_backup         = true
  backup_files_storage_type = "s3"
  dedicated_server_name_hash = "FA8C44A6FA46436AAAE4D414C4214B25"
  existing_backup_files_bootstrap_bucket_arn  = "arn:aws:s3:::palworld-existing-s3-bucket-bootstrap"
  existing_backup_files_bootstrap_bucket_name = "palworld-existing-s3-bucket-bootstrap"
  • If start from backup = true then dedicated_server_name_hash is required

Using SSM Instead of SSH

AWS Systems Manager Session Manager is a web based way to connect to an instance from your browser instead of over SSH. It is more secure than enabling port 22 and SSH. Use the input enable_session_manaer = true to enable it.

Note

SSH and SSM can be used together is you wish.

Starting, Stopping, and Restarting Palworld

Action Command
Stop Palworld systemctl stop palworld
Start Palworld systemctl start palworld
Restart Palworld systemctl restart palworld

Updating Palworld

Palworld will update the next time the service is restarted with systemctl start palworld or systemctl restart palworld or if the server restarts.

Troubleshooting

  • Monitoring the installation - You can view the user_data script that ran by connecting to your server via SSH using the public key you provided, ubuntu user, and the IP address of the server. Example: ssh -i .\palworld_public_key [email protected]. Once on the server you can view the progress of the user_data script that installs and configures palworld using the command journalctl -xu cloud-final. Use the space bar to scroll through the output line by line or shift+g to scroll the end of the output. If there is an obvvious reason that palworld failed to install or start in the way you expect, you can most likely find it here.

  • Checking the palworld service is running - You can run systemctl status palworld to view the status of the palworld server. The service should say Active: active (running). If it does not, then the palworld server failed to start or has stopped for some reason.

Examples

Possible and Known Bugs

Memory leak? https://www.reddit.com/r/Palworld/comments/19bdsrn/dedicated_server_ram_usage/

Requirements

Name Version
terraform >= 1.5.0
aws >= 5.0.0

Providers

No providers.

Modules

Name Source Version
palworld_backup ./modules/backup n/a
palworld_compute ./modules/compute n/a
palworld_vpc ./modules/networking n/a

Resources

No resources.

Inputs

Name Description Type Default Required
active_unko Activate UNKO setting bool false no
admin_password Admin password string "RockwellSucks" no
ami_id The AMI ID to use. Not providing one will result in the latest version of Ubuntu Focal 20.04 being used string null no
auto_reset_guild_no_online_players Auto reset guild when no online players bool false no
auto_reset_guild_time_no_online_players Time for auto reset guild when no online players number 72 no
backup_files_local_path Path to existing save game files relative to your Terraform working directory. Will be uploaded to the server. Required if backup_files_storage_path = local string "" no
backup_files_storage_type The location of your save game files that you wish to start the server with. Supported options are local or s3'. localmeans the save game files exist somewhere on the host you are running terraform apply from.s3 means the files exist in an s3 bucket. string "local" no
backup_interval_cron_expression How often to backup the ShooterGame/Saved directory to S3 in cron expression format (https://crontab.cronhub.io/) string "0 23 * * *" no
backup_s3_bucket_arn The ARN of the s3 bucket that you would like to use for ShooterGame/Saved directory backups string "" no
backup_s3_bucket_name The name of the S3 bucket to backup the ShooterGame/Saved directory to string "" no
ban_list_url URL of the ban list string "https://api.palworldgame.com/api/banlist.txt" no
base_camp_max_num Maximum number of base camps number 128 no
base_camp_worker_max_num Maximum number of base camp workers number 15 no
build_object_damage_rate Build object damage rate number 1 no
build_object_deterioration_damage_rate Build object deterioration damage rate number 1 no
can_pickup_other_guild_death_penalty_drop Can players pick up other guild's death penalty drop bool false no
collection_drop_rate Collection drop rate number 1 no
collection_object_hp_rate Collection object HP rate number 1 no
collection_object_respawn_speed_rate Collection object respawn speed rate number 1 no
coop_player_max_num Maximum number of players in coop mode number 32 no
create_backup_s3_bucket True or False. Do you want to create an S3 bucket to FTP backups into bool false no
create_ssh_key True or False. Determines if an SSH key is created in AWS bool true no
custom_palworldsettings_github True or False. Set true if use_custom_palworldsettings is true and you want to download them from github. Must be a public repo. bool false no
custom_palworldsettings_github_url The URL to the PalWorldSettings.ini file on a public GitHub repo. Used when custom_palworldsettings_github and custom_game_usersettings both == true. string "" no
custom_palworldsettings_s3 True or False. Set true if use_custom_palworldsettings is true and you want to upload and download them from an S3 bucket during installation bool false no
day_time_speed_rate Day time speed rate number 1 no
death_penalty Death penalty setting. 0 = None : No lost, 1 = Item : Lost item without equipment, 2= ItemAndEquipment : Lost item and equipment, 3= All : Lost All item, equipment, pal(in inventory) number 1 no
dedicated_server_name_hash The DedicatedServerName= value from the old servers GameUserSettings.ini. Will be set on the new server to ensure data properly loads with backup data. string "" no
difficulty Game difficulty setting string "None" no
drop_item_alive_max_hours Maximum hours a drop item is alive number 1 no
drop_item_max_num Maximum number of drop items number 3000 no
drop_item_max_num_unko Maximum number of UNKO drop items number 100 no
ebs_volume_size The size of the EBS volume attached to the EC2 instance number 40 no
enable_aim_assist_keyboard Enable aim assist for keyboard bool false no
enable_aim_assist_pad Enable aim assist for pad bool true no
enable_defense_other_guild_player Enable defense against other guild players bool false no
enable_fast_travel Enable fast travel bool true no
enable_friendly_fire Enable friendly fire bool false no
enable_invader_enemy Enable invader enemy bool true no
enable_non_login_penalty Enable penalty for non-login bool true no
enable_player_to_player_damage Enable player to player damage bool false no
enable_rcon Is RCON enabled bool false no
enable_s3_backups True or False. Set to true to enable backing up of the ShooterGame/Saved directory to S3 bool false no
enable_session_manager True or False. Determines if SSM Session Manager is enabled or not bool false no
enable_ssh True or False. Determines if SSH and port 22 are enabled or not bool true no
enemy_drop_item_rate Enemy drop item rate number 1 no
exist_player_after_logout Does player exist in game after logout bool false no
existing_backup_files_bootstrap_bucket_arn The ARN of an existing S3 bucket with Palworld save game data. Files will be downloaded to the server. Objects must be in the root of the S3 bucket and not compressed. string "" no
existing_backup_files_bootstrap_bucket_name The Name of an existing S3 bucket with Palworld save game data. Files will be downloaded to the server. Objects must be in the root of the S3 bucket and not compressed. string "" no
existing_ssh_key_name The name of an EXISTING SSH key for use with the EC2 instance string null no
exp_rate Experience rate number 1 no
force_destroy True or False. Set to true if you want Terraform destroy commands to have the ability to destroy the backup bucket while it still containts backup files bool false no
guild_player_max_num Maximum number of players in a guild number 20 no
instance_type The instance type to use string "t3.large" no
is_multiplay Is the game in multiplay mode bool false no
is_pvp Is the game in PvP mode bool false no
is_start_location_select_by_map Is start location selected by map bool false no
night_time_speed_rate Night time speed rate number 1 no
pal_auto_hp_regen_rate Pal auto HP regeneration rate number 1 no
pal_auto_hp_regene_rate_in_sleep Pal auto HP regeneration rate in sleep number 1 no
pal_capture_rate Pal capture rate number 1 no
pal_damage_rate_attack Pal damage rate on attack number 1 no
pal_damage_rate_defense Pal damage rate on defense number 1 no
pal_egg_default_hatching_time Default hatching time for pal eggs number 72 no
pal_spawn_num_rate Pal spawn number rate number 1 no
pal_stamina_decrease_rate Pal stamina decrease rate number 1 no
pal_stomach_decrease_rate Pal stomach decrease rate number 1 no
palworldsettings_ini_path Path to PalWorldSettings.ini relative to your Terraform working directory. Will be uploaded to the server. Required if use_custom_palworldsettings = true and custom_game_usersettings_s3 = true. string "" no
player_auto_hp_regen_rate Player auto HP regeneration rate number 1 no
player_auto_hp_regen_rate_in_sleep Player auto HP regeneration rate in sleep number 1 no
player_damage_rate_attack Player damage rate on attack number 1 no
player_damage_rate_defense Player damage rate on defense number 1 no
player_stamina_decrease_rate Player stamina decrease rate number 1 no
player_stomach_decrease_rate Player stomach decrease rate number 1 no
public_ip Public IP address string "" no
public_port Public port number number 8211 no
rcon_port RCON port number number 27025 no
region Server region string "" no
s3_bucket_backup_retention Lifecycle rule. The number of days to keep backups in S3 before they are deleted number 7 no
server_description Server description string "Running On AWS" no
server_name Server name string "AWSWorldTest" no
server_password Server password string "RockwellSucks" no
server_player_max_num Maximum number of players on server number 32 no
ssh_ingress_allowed_cidr The CIDR range to allow SSH incoming connections from list(string)
[
"0.0.0.0/0"
]
no
ssh_key_name The name of the SSH key to be created for use with the EC2 instance string "palworld-ssh-key" no
ssh_public_key The path to the ssh public key to be used with the EC2 instance string "~/.ssh/palworld_public_key.pub" no
start_from_backup True of False. Set true to start the server from an existing palworld save. Requires existing save game files. bool false no
subnet_availability_zone The AZ of the subnet to be created within the VPC string "us-east-1a" no
subnet_cidr_block The CIDR block of the subnet to be created within the VPC string "10.0.1.0/24" no
use_auth Use authentication bool true no
use_custom_palworldsettings True or False. Set true if you want to provide your own PalWorldSettings.ini file when the server is started. Required if game_user_settings_ini_path is defined bool false no
vpc_cidr_block The CIDR block of the VPC to be created string "10.0.0.0/16" no
work_speed_rate Work speed rate number 1 no

Outputs

Name Description
backup_s3_bucket_name The Name of the S3 bucket created to store backups if enabled
custom_ini_s3_bucket_name The ID of the S3 bucket that was created if use custom ini with s3 was configured.
palworld_server_public_ip The public IP address of the Palworld server to connect on.
palworld_server_public_port The public port to connect to the Palworld serer on
palworldsettings_s3_content The contents of the palworldsettings.ini ( experimental ).
session_manager_enabled Is AWS SSM Session Manager enabled or not.

terraform-aws-palworld's People

Contributors

josh-tracy avatar semantic-release-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

terraform-aws-palworld's Issues

I Can't run terraform init

the error said this:

Error: Failed to download module

│ on main.tf line 1:
│ 1: module "palworld" {

│ Could not download module "palworld" (main.tf:1) source code from
│ "git::https://github.com/TheSudoYT/terraform-aws-palworld?ref=03668dc8fcd22be2ef78e3df0740e65e72537cb7":
│ error downloading
│ 'https://github.com/TheSudoYT/terraform-aws-palworld?ref=03668dc8fcd22be2ef78e3df0740e65e72537cb7': git
│ must be available and on the PATH.

can you help me how to fix this?

How can I create the EC2 on a local zone to reduce latency?

What is your Question?
How can I create the EC2 on a local zone to reduce latency?

Can you Provide Context?
I live in Dominican Republic and the smallest ping is a local zone in atlanta "us-east-1-atl-1a" so I would like to create the ec2 in there, I have the local zone activated in my account already (its where I run my other servers) my question would if your module supports to deploy in a local zone. Thanks for the great work.

Error: Failed to download module

What is your Question?
I was trying to follow your youtube video and got to the terraform init part, but received an error.

"Failed to download module

│ on main.tf line 1:
│ 1: module "palworld" {

│ Could not download module "palworld" (main.tf:1) source code from
│ "git::https://github.com/TheSudoYT/terraform-aws-palworld?ref=5e3223be6ab41a7b7189acccd6960ee2d8510dba": error downloading
│ 'https://github.com/TheSudoYT/terraform-aws-palworld?ref=5e3223be6ab41a7b7189acccd6960ee2d8510dba': git must be available and on the PATH."

Can you let me know what I'm doing wrong? Thanks for the in-depth guide!

image

How do I restore from S3 backup?

Hi there!
Hacker came into my server and started trolling wiping people's bases out.

How do I replace the worldsettings.ini file, and the level.sav and player folder with the backups in S3?

PalWorldSettings.ini Changes Not Reflected in Game

Describe the bug
None of the inputs shown in PalWorldSettings.ini are actually implemented in game.

To Reproduce

  • Pick up a rock +1 EXP with EXP rate set to 9
  • /AdminPassword results in error "Admin password not set for this server"

Expected behavior
Changes in PalWorldSettings.ini to reflect in game.

New Feature Request: An Input to Install Mods During Server Creation

Is your feature request related to a problem? Please describe.
There is no input that allows for mods to be uploaded to the server at this time.

Describe the solution you'd like
An input that allows mods to be uploaded to the server upon server creation.

Describe alternatives you've considered
Copying mods to the EC2 instance using SCP manually after server creation

Additional context
A feature that allows users to provide an input such as enable_mods = true and a mechanism to get mods onto the server.

A possible solution is to have users create an S3 bucket out of band of the Terraform code and provide the bucket name and ARN as inputs. The EC2 instance user_data script could then download the mods from the S3 bucket to the EC2 instance during creation.

Another possible solution is allowing users to upload mod files from the local PC to an S3 bucket to keep everything within the terraform workflow and avoid resource creation outside of terraform. The downside to this approach is the side of the mod files is unknown and varies widely depending on the mod. This could have unintended consequences while terraform is upload the files to S3 depending on the time it takes for terraform to upload the mod(s)

creating EC2 Subnet

Describe the bug
InvalidParameterValue: Value (us-east-1a) for parameter availabilityZone is invalid. Subnets can currently only be created in the following availability zones: ap-northeast-1a, ap-northeast-1c, ap-northeast-1d.
Seem like availabilityZone value is hard coded.
To Reproduce
Steps to reproduce the behavior:

  1. set up $Env:AWS_REGION = "ap-northeast-1"
  2. terraform apply

Expected behavior
create success in ap-northeast

Palworld/Feature: Input for custom AMI ID

Add an input to allow users to provide a custom AMI ID.

  • user_data is only supported on Ubuntu at this time
  • Default to ubuntu LTS if custom_ami_id not provided by user

What is the preferable way to install mods?

What is your Question?
How can I access the EC2 instance and install mods? Can be done with terraform to keep the modifications saved?

Additional Context
I've tried with SCP command line but the key provided does not have sufficient permissions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.