0. Preface

This repository introduces an intact "building & crafting & tower-defense/siege" game with "remotely persisted profile" as well as "pull-based progress update management".

It supports a wide variety of features as shown in the intro videos listed below, yet not currently integrated into a single entry scene. If you find some features "too hidden to enable", please leave a message in Github issues.

It's strongly recommended that you start playing with this repository with the "frontend-only tower-siege game", i.e. at <proj-root>/frontend/assets/scenes/OfflineStageMap.fire.

We decided to open source this project due to lack of resource to maintain it, therefore new feature proposal, bug report or pull-request might not be handled in time -- and we'll try our best.

Redis-server is no longer necessary to start the backend of this project, though a redis-server instance could still be used to limit API call rate, i.e. the "v1.Player.CallLimitController", which is now made optional.

1. Database Server

The database product to be used for this project is MySQL 5.7.

We use skeema for schematic synchronization under <proj-root>/database/skeema-repo-root/ which intentionally doesn't contain a .skeema file. Please read this tutorial for more information.

You can use this node module (still under development) instead under Windows10, other versions of Windows are not yet tested for compatibility.

The following command(s)

### Optional.
user@proj-root/database/skeema-repo-root> cp .skeema.template .skeema

###
user@proj-root/database/skeema-repo-root> skeema diff

is recommended to be used for checking difference from your "live MySQL server" to the latest expected schema tracked in git.

1.1 Database-related-items checklist before pushing to a collaborative branch

Before pushing to, say the "master" branch, you should be very careful about the preconfigured tables in SQLite. Mostly they're tables to be dumped into "MySQLServer tables with the same names" respectively, e.g. "SQLite table buildable" will be dumped into "runtime MySQLServer table buildable" upon server process(es) launch (using <proj-root>/battle_srv/env_tools/load_pre_conf.go), and in turn loaded to instances of in-RAM model class Buildable defined in <proj-root>/battle_srv/models/buildable.

In a "clean commit", you should make sure that each table involved in ToSyncSQLFiles

  • <proj-root>/battle_srv/configs.template/*.sqlite
  • <proj-root>/database/skeema-repo-root/*.sql
  • <proj-root>/battle_srv/models/*.go

is made "git-pullable", such that a colleague who pulls your commit is able to launch the server process(es) if he/she at least overwrites the runtime environment with all the ToSyncSQLFiles of the current commit.

2. Building & running

2.1 Golang1.11

See https://github.com/genxium/Go111ModulePrac for details.

2.2 MySQL

On a product machine, you can install and manage MySQL server by these scripts.

2.3 Required Config Files

2.3.1 Backend

  • It needs <proj-root>/battle_srv/configs/* which is generated by cd <proj-root>/battle_srv && cp -r ./configs.template ./configs and necessary customization.

2.3.2 Frontend

  • It needs CocosCreator v2.2.1 to build.
  • A required "CocosCreator plugin i18n" is already enclosed in the project, if you have a globally installed "CocosCreator plugin i18n"(often located at $HOME/.CocosCreator/packages/) they should be OK to co-exist.
  • It needs <proj-root>/frontend/assets/plugin_scripts/conf.js which is generated by cd <proj-root>/frontend/assets/plugin_scripts && cp conf.js.template conf.js.

2.4 Different "ServerEnv"s for the runtime of backend service

本游戏具备账号系统且主要注册方式为"Phonenum+SMSCaptcha",考虑到开发者和公司内部测试的需要,服务器将提供以下的"ServerEnv"s供在runtime of backend service按需采用。

2.4.1 ServerEnv == PROD (如不指定ServerEnv则默认为PROD)

user@proj-root/battle_srv> make run-prod

将不允许使用“测试账号”。

2.4.2 ServerEnv == TEST

user@proj-root/battle_srv> make run-test

将允许使用“测试账号”,详见 https://shimo.im/docs/Q7wqNHlvyYQu0nYP 说明。

以下两个ServerEnv可以使用"iPhone游客登录"方式试玩,此开关在battle_srv/configs/global_conf.jsonanonymousPlayerEnabled中配置。

2.4.3 ServerEnv == AnonymousPlayerEnabledTest

user@proj-root/battle_srv> make run-anonymous-test

2.4.4 ServerEnv == AnonymousPlayerEnabledProd

user@proj-root/battle_srv> make run-anonymous-prod

For clearing certain hardcoded test accounts (in <proj-root>/battle_srv/cli_scripts/player_test.go), try the following one-liner.

For updatePlayerCookBinding started_work_at test (in <proj-root>/battle_srv/cli_scripts/player_test.go), now this script will update all playerCookBinding started_work_at,if you want update one playerCookBinding started_work_at,you can add WHERE("player_id": playerId) at <proj-root>/battle_srv/cli_scripts/player_test.go test UpdatePlayerCookBindingStartedWorkAt

For updatePlayerWallet gold,energy,daemon test (in <proj-root>/battle_srv/cli_scripts/player_test.go), this script will update playerId in scripts's playerIds ,if you want update your test player player_wallet, you can add update at <proj-root>/battle_srv/cli_scripts/player_test.go UpdatePlayerWallet() playerIds

user@proj-root/battle_srv> cp -r ./cli_scripts.template ./cli_scripts

## Then customize the parameters in ./cli_scripts/*.go for your convenience, e.g. the TestEnv player IDs.
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run DeletePlayer
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run InitKnapsack
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run InitKnapsackForExistedUser
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run IngredientProduce --args -cancel=true
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run IngredientProduce --args -cancel=false
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run SynthesizeToIngredientProgress --args -cancel=true
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run SynthesizeToIngredientProgress --args -cancel=false
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run SynthesizeToManuallyCollectableIngredientProgress --args -collect=true
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run SynthesizeToManuallyCollectableIngredientProgress --args -collect=false
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run MassiveCrafting
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run HqConcurrentQueues
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run SmsCaptchaLogin
user@proj-root/battle_srv> ServerEnv=TEST go test --count=1 -v server/cli_scripts -run WsConnectAttackFirstVictim

3. More about development

3.1 db2struct

user@shell> go get github.com/roowe/db2struct
user@shell> db2struct -d cuisine --package models --t <table_name> --user <db_name> --password <db_passwd> --struct <struct_name> --sqlx --json

See db2struct for more information

3.1 json2strust

user@shell> go get https://github.com/ChimeraCoder/gojson
user@proj-root/battle_srv/common/> gojson -name constants -pkg common -input ./constants.json -o ./constants_struct.go 

4. Building to iOS project

Due to possibly a bug in CocosCreator's custom building pipeline, after successfully building by the cmd above, you might have to manually add "/build/jsb-link/frameworks/runtime-src/Classes/*" into the "XCode project virtual directory named Classes". Refer to this note for screenshot demo.

4.1 Removing the use of IDFA in libcocosanalytics.a

Please read this note for details. I've removed the import of CAAgent from <proj-root>/frontend/build-templates/jsb-link/frameworks/runtime-src/proj.ios_mac/ios/AppController.mm, but you should follow the note to removed the dependence on libcocosanalytics.a BEFORE building the archive.

4.2 Switching between different CocosCreator versions

Please make sure that you've removed <proj-root>/frontend/build/ thoroughly before rebuilding the project by a different CocosCreator version. Otherwise JSB2.0 module registration procedures will be contaminated and you might get symbols undefined (e.g. XMLHttpRequest) upon launch.

5. Building to WechatGame

5.1 Configuring the correct appId and WechatServer endpoint

  • /battle_srv/configs/wechat.json
  • /frontend/assets/plugin_scripts/conf.js

5.2 Configuring the "REMOTE_SERVER" and uploading to corresponding remote dir

Set REMOTE_SERVER_ROOT = "https://mineralchem.lokcol.com/wechat-game/" in the build panel, and then upload by the following command(s).

shell> scp -r ./frontend/build/wechatgame/res/* ubuntu@mineralchem.lokcol.com:/var/www/html/MineralChem/wechat-game/res/
&
shell> rm -rf ./frontend/build/wechatgame/res/*

5.3 Total count of HTTP requests v.s. single large file

Either an overwhelming "count of HTTP requests" or a "single large file" will jam the download of resources at runtime. We can tune the balance in the building panel, please check/uncheck the followings.

  • Inline all SpriteFrames
    • We've already compressed the textures using TexturePacker, thus this field doesn't affect much.
  • Merge all JSON that Start Scene
    • Unchecking this field might result in too many "JSONIndexFile requests" (avoided by the approach stated below), whilst checking this field might result in a single large file.
    • By loading the "WechatGameLogin" scene first, we want to be able to level & parallelize the time spent in downloading & parsing "JSONIndexFile(s)" among different scene.
  • MD5 cache (√)

According to http://docs.cocos.com/creator/manual/en/scripting/load-assets.html#how-to-dynamically-load, "all files under the resources folder, as well as any external file they depend on", will be written into "JSONIndexFiles" after project being built (delivered only via the mainpackage). To reduce the size of such "JSONIndexFiles" for WechatGame platform, we should put as few files under resources folder as possible, e.g. for those to be called by cc.loader.loadRes(...).

6. Building and deploying to Web

shell> scp -r ./frontend/build/web-mobile/* ubuntu@idlegame.lokcol.com:/var/www/html/MineralChem/web-mobile/

7. Building to ByteDanceMiniGame

7.1 Use CLI to build the project

- <proj-root/frontend> ./build_to_platform.sh bytedance 

7.2 Uploading to corresponding remote dir

shell@proj-root> python ./frontend/uploader_scripts/upload_to_qiniu.py -d ./frontend/build/wechatgame/res/ --prefix="wechat-game" -a <MyAppKey> -s <MySecretKey> 
shell@proj-root> rm -rf ./frontend/build/wechatgame/res/*