{"id":14895366,"url":"https://github.com/morganpage/ic-gamekit","last_synced_at":"2025-09-22T06:33:02.046Z","repository":{"id":247842183,"uuid":"824642939","full_name":"morganpage/ic-gamekit","owner":"morganpage","description":"A GameKit for the Internet Computer","archived":false,"fork":false,"pushed_at":"2024-09-10T17:07:48.000Z","size":217,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-09-22T06:05:53.996Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/morganpage.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-05T15:24:05.000Z","updated_at":"2024-09-10T17:07:52.000Z","dependencies_parsed_at":"2024-07-10T23:46:08.431Z","dependency_job_id":"8fc421f1-5f22-4a4b-bea9-ec82219e85c8","html_url":"https://github.com/morganpage/ic-gamekit","commit_stats":null,"previous_names":["morganpage/ic-gamekit"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganpage%2Fic-gamekit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganpage%2Fic-gamekit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganpage%2Fic-gamekit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/morganpage%2Fic-gamekit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/morganpage","download_url":"https://codeload.github.com/morganpage/ic-gamekit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233831439,"owners_count":18737061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-22T06:00:59.345Z","updated_at":"2025-09-22T06:32:56.712Z","avatar_url":"https://github.com/morganpage.png","language":"JavaScript","funding_links":[],"categories":["Game Development"],"sub_categories":["Protocols"],"readme":"# The IC GameKit\n\n## Design and GameKit architecture\n\nThe IC GameKit is drop-in solution for adding achievements, game and user data saves. The GameKit consists of 2 main canisters, a back-end canister that persists all the data associated with the achievements, game saves etc and the front-end that is a react web app that can be used to manage this data. Additionally a demo game canister is included that shows how a typical game canister can make use of the GameKit. All data relevant data is held in stable memory and hence will persist across upgrades.\n\nMultiple games can be created inside a single GameKit back-end canister hence it is envisaged that a game studio may only need one canister deployed to cater for all their games. Additionally, multiple admins can be added to the GameKit canister to enable easy management across a team. Each game that wants to utilise the GameKit should have its own canister and that canister should be added as an admin too.\n\nThe front-end react web app enables you to:\n- Add / remove admins\n- Create a new game\n- Specify achievements associated with that game\n- Save game data viewing\n- User data viewing\n\n### Game Specific Data\nData can be stored against each game set up in the IC GameKit. For instance you may want to have a list of pets that can be randomly earned in the game and that you can add to easily without redeploying your game. You can set up multiple key/value pairs, both are held as strings so you can store your list of pets in json format and retrieve them in-game as needed. This would look like:\n```bash\n# Pets\nKey       Value\nrewards  { \"pets\" :\n[\n  { \"name\": \"Mouse\", \"url\" : \"https://roguefoxguild.mypinata.cloud/ipfs/QmXXba3DLd8y6DyM7rri1aQap5p8LTtcTaz7TLN4wS846B\" },\n  { \"name\": \"Cat\", \"url\" : \"https://roguefoxguild.mypinata.cloud/ipfs/QmNPhRKoQPppkQ6GxbiUniyyUkjY9Tht7Vyn1pvQ1DDEiY\" },\n  { \"name\": \"Dog\", \"url\" : \"https://roguefoxguild.mypinata.cloud/ipfs/QmecJRNGz44hvvMQLayQH6tDM2BQgYP7dDLGprMbd4o6Kt\" }\n]\n          }\n```\n### Player Specific Data\nThis is where you can store data about a player that is consistent across all your games. This will most likely be profile data like social links, display name etc.\n\n### Game Save Data\nSpecific to a player within a game, game saves can be used to store the progress that a player has made in a particular game.\n\n## Admins\nOnly Admins can create games and add achievements. You can add a wallet principal as an admin with:\n\n```bash\n# Adds a new Admin\ndfx canister call ic-gamekit-backend addAdmin '(principal \"ns7tc-nfpjp-wggqg-o5bag-feolr-dlb5q-3zcdz-vcavb-hyw2u-ypiwj-7ae\")'\n```\nThe deploying identity automatically becomes an Admin.\n\n## Installing the project locally\n\nInstall dfx by following [these](https://internetcomputer.org/docs/current/developer-docs/getting-started/install/) instructions.\n\n```bash\n# Install mops (npm i -g ic-mops) , the motoko package manager and install dependencies with\nmops install\n# Install all other dependencies with\nnpm install\n```\n\n## Running the project locally\n\nIf you want to test your project locally, you can use the following commands:\n\n```bash\n# Starts the replica, running in the background\ndfx start --background\n\n# Build, to be on the safe side ;-), deploy does this anyway\ndfx build\n\n# Deploys your canisters to the replica and generates your candid interface\ndfx deploy\n```\nIf you get an 'assetstorage.did doesn't exist' just retry the deploy and it should work (or do the build step first)\n\nOnce the job completes, your application will be available at `http://localhost:4943?canisterId={asset_canister_id}`.\n\nIf you have made changes to your backend canister, you can generate a new candid interface with\n\n```bash\nnpm run generate\n```\n\nat any time. This is recommended before starting the frontend development server, and will be run automatically any time you run `dfx deploy`.\n\nIf you are making frontend changes, you can start a development server with\n\n```bash\nnpm start\n```\n\nWhich will start a server at `http://localhost:8080`, proxying API requests to the replica at port 4943.\n\n## Running locally - Continued...\nI would suggest running the ic-gamekit-frontend first, so click on either link listed after you do a dfx deploy. You should get a browser window up that shows the IC GameKit with a Clicker Game panel. If at this point your click on the Click button you will get a message saying you are not an admin and it will handily show the Game Canister Principal that you need to copy and paste into the following command:\n```bash\ndfx canister call ic-gamekit-backend addAdmin '(principal \"Enter-the-Game-Canister-Principal Here\")'\n```\nNow when you hit the Click button it should increment and start unlocking achievements!\n\n\n# Testing\nYou will need to run the following command to add the test Admin user before running the tests.\n\n```bash\n# Adds a test Admin\ndfx canister call ic-gamekit-backend addAdmin '(principal \"rwbxt-jvr66-qvpbz-2kbh3-u226q-w6djk-b45cp-66ewo-tpvng-thbkh-wae\")'\n```\nThen run the tests with:\n```bash\n# Runs test\nnpm run test\n```\n\n### Unity Login - The unity-login folder\nTo enable logging in to a Unity game via Internet Identity, I have included an example login page. A Unity application can load this login page into an iframe and when the login process is complete, this page will create a delegation chain that it passes to the Unity application via a postMessage. To enable testing in the Unity Editor, this page also supports sending the delegation chain via websockets. An example Unity game that utilises this can be found [here](https://github.com/morganpage/ic-clicker-game). For more information on delegtaion chains checkout the official ICP documentation [here](https://internetcomputer.org/docs/current/references/ii-spec#introduction).\n\n\n### Writing your own game contract\nWhen you have finished checking out the example clicker game you will probably want to start creating your own game contract. This is general process for doing this...\nCreate a new folder inside the src folder (something like mycool-game!). Inside that folder, create a file (something like mycoolgame.mo). Import the IC GameKit canister with:\n```bash\nimport ICGameKitCanister \"canister:ic-gamekit-backend\";\n```\nThen amend dfx.json, adding the following\n```bash\n{\n  \"canisters\": {\n    \"mycool-game\": {\n      \"dependencies\": [\n        \"ic-gamekit-backend\"\n      ],\n      \"main\": \"src/mycool-game/mycoolgame.mo\",\n      \"type\": \"motoko\"\n    },\n```\nThen run (only need to do this once):\n```bash\ndfx canister create mycool-game\n```\nThen try building your canister with:\n```bash\ndfx build mycool-game\n```\n### Useful IC GameKit Functions\nAlthough you can add games, achievements etc through the ic-gamekit-frontend. The preferred way is doing a one-off setup of your game in your smart contract. Here is some example code to get you going:\n```js\nawait ICGameKitCanister.createGame(\"Your game name\", \"Your game description\");\nawait ICGameKitCanister.createAchievement(\"Your game name\",\"Achievement Name\",\"Description\", 1, false, false);\n//The 4th param is the maxProgress, 1 in this case, a single increment will earn it!\n//Last 2 bool params are secret, hidden\n//secret = You can omit to show these to a player to keep them... secret\n//hidden = You can have achievements hidden until they are ready to go live\n```\nNow that you have created a game and an achievement, during gameplay you can unlock an achievement by:\n```js\nawait ICGameKitCanister.incrementPlayerAchievement(\"Achievement Name\", \"playerId here\",1);\n//The 3rd param is how much to increment by, in this case 1, hence progress becomes progress+1 \n//If progress = maxProgress the achievement is considered earned!\n```\nUpdating player profile data is nice and easy:\n```js\nawait ICGameKitCanister.updatePlayerData(\"playerId here\", \"profileName\",\"Bob\");\nawait ICGameKitCanister.updatePlayerData(\"playerId here\", \"profileBio\",\"I'm a game dev!\");\n```\nAnd saving game data is straight forward too:\n```js\nawait ICGameKitCanister.createGameSave(\"Save01\",\"Your game name\",\"playerId here\", \"Game data here\");\n```\nYou will probably want to save your game data in JSON format which is nice and flexible. See the [clickergame.mo](https://github.com/morganpage/ic-gamekit/blob/main/src/clicker-game/clickergame.mo) code for an example of how this can be done.\n\nAnother useful feature of the IC GameKit is saving game specific data. This can be useful for adding new features to a game without redeploying the game. In the click game example, the rewards are held this way so that additional rewards can easily be added after deployment.\n```js\nawait ICGameKitCanister.updateGameData(\"Your game name\",\"Game data key\",\"Game data value\");\n```\n\n### Note on frontend environment variables\n\nIf you are hosting frontend code somewhere without using DFX, you may need to make one of the following adjustments to ensure your project does not fetch the root key in production:\n\n- set`DFX_NETWORK` to `ic` if you are using Webpack\n- use your own preferred method to replace `process.env.DFX_NETWORK` in the autogenerated declarations\n  - Setting `canisters -\u003e {asset_canister_id} -\u003e declarations -\u003e env_override to a string` in `dfx.json` will replace `process.env.DFX_NETWORK` with the string in the autogenerated declarations\n- Write your own `createActor` constructor\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorganpage%2Fic-gamekit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorganpage%2Fic-gamekit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorganpage%2Fic-gamekit/lists"}