{"id":19080314,"url":"https://github.com/rchovatiya88/chessvr","last_synced_at":"2025-08-13T14:09:20.504Z","repository":{"id":54387768,"uuid":"311433806","full_name":"rchovatiya88/chessvr","owner":"rchovatiya88","description":"Open Source WebXR game using aframe.io Full Code available on this Github Page.","archived":false,"fork":false,"pushed_at":"2021-02-21T18:48:46.000Z","size":201,"stargazers_count":5,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-04T02:46:03.205Z","etag":null,"topics":["aframe","javascript-game","webvr","webxr-template"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rchovatiya88.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-11-09T18:46:28.000Z","updated_at":"2024-02-25T19:03:04.000Z","dependencies_parsed_at":"2022-08-13T14:10:33.542Z","dependency_job_id":null,"html_url":"https://github.com/rchovatiya88/chessvr","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rchovatiya88/chessvr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchovatiya88%2Fchessvr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchovatiya88%2Fchessvr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchovatiya88%2Fchessvr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchovatiya88%2Fchessvr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rchovatiya88","download_url":"https://codeload.github.com/rchovatiya88/chessvr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchovatiya88%2Fchessvr/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270254160,"owners_count":24552985,"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","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["aframe","javascript-game","webvr","webxr-template"],"created_at":"2024-11-09T02:18:44.730Z","updated_at":"2025-08-13T14:09:20.424Z","avatar_url":"https://github.com/rchovatiya88.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Setting up Multiplayer WebXR Chess Game\n\nOpen Source WebXR game using aframe.io (webVR framework) Full Code available on Github Page.\n\nLive [Demo](https://chessvr.glitch.me/) - https://chessvr.glitch.me/\n\n#### Pre-Requisties\n\n- Web Browser (Chrome)\n- Set up Glitch Account - www.glitch.com\n\n\n### How it Works\n\n- Add 3D models in GLTF or glb format in the asset folder. Also, you can add any Images, videos, materials in asset folder for reference (Check File Size limit)\n- Inside `/public` folder `index.html` is where all the code will go and `/js` folder for all javascript functions / components.\n\n## Goal\n\nLet's define our goal for the project and scene. In order visualize our concept, some of following assets we need\n\n- Environment\n- 3D Models of Chess\n\n- Controllers\n\n\n### Creating a Scene\n\nSimilar to normal Web HTML Pages. We have\n\n- `\u003chead\u003e` tag (To import all our dependencies)\n- `\u003cbody\u003e` tag(All entities and assets)\n\n### Step 1\n\n- Let's set up our floor / ground\n\nIn a-frame, we can define a `\u003ca-plane\u003e`\n\nFor example we can follow the docs from a-frame [Getting Started](https://aframe.io/docs/1.1.0/introduction/)\n\n```js\n\u003ca-plane\n  position=\"0 0 -4\"\n  rotation=\"-90 0 0\"\n  width=\"4\"\n  height=\"4\"\n  color=\"#7BC8A4\"\n\u003e\u003c/a-plane\u003e\n```\n\nWatch [Tutorial](https://www.youtube.com/watch?v=ktjMCanKNLk\u0026list=PL8MkBHej75fJD-HveDzm4xKrciC5VfYuV)\n\n\n- For our project we need a real ground, We decided use a [Ground texture](https://www.textures.com/browse/streets/97701)\n  ![Ground textured](https://cdn.glitch.com/97890fbd-889b-466f-a357-23627a83de50%2FTexturesCom_FloorStreets0064_2_M.jpg?v=1612300231287)\n\n```js\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003eChess VR - Let's play chess in WEBXR\u003c/title\u003e\n    \u003cscript src=\"https://aframe.io/releases/1.1.0/aframe.min.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    \u003ca-scene\u003e\n      \u003ca-assets\u003e\n        \u003cimg\n          id=\"ground\"\n          src=\"https://cdn.glitch.com/97890fbd-889b-466f-a357-23627a83de50%2FTexturesCom_Carpet0020_1_seamless_S.jpg?v=1612295412711\"\n        /\u003e\n      \u003c/a-assets\u003e\n\n      \u003c!-- Ground --\u003e\n      \u003ca-plane\n        material=\"color: #FFFFFFF; src: #ground; repeat : 5 5;\"\n        rotation=\"-90 0 0\"\n        scale=\"10 10 1\"\n      \u003e\n      \u003c/a-plane\u003e\n    \u003c/a-scene\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n![Step 1](https://cdn.glitch.com/97890fbd-889b-466f-a357-23627a83de50%2FScreen%20Shot%202021-02-02%20at%203.12.33%20PM.png?v=1612296769130)\n\n### Step 2\n\n- Let's add a open-source `aframe-environment compoment` from [Diego F. Goberna](https://github.com/feiss/aframe-environment-component/) to easily create background scene for us!\n\n![Scene Examples](https://github.com/feiss/aframe-environment-component/raw/master/assets/aframeenvironment.gif?raw=true)\n\nWe used a `environment=\"preset forest\"` forest envrionement but we can do a bit more to add more customization to match our scene. For example, adding and removing different aspects of the scene\n\n```js\n    \u003c!-- Environment --\u003e\n      \u003ca-entity\n        environment=\"preset:  forest;  playArea:  2;  active:  true;  seed:  8;\n                     skyType:  gradient;\n                     skyColor:  #ffffff;  // Change the color of the sky\n                     horizonColor:  #87CEEB;\n                     fog:  0.5;\n                     groundYScale:  4.18;  groundTexture:  squares;  groundColor:  #43994b;  //Change ground color\n                     groundColor2:  #43994b;  dressing:  trees;  dressingAmount:  500;\n                     dressingColor:  #43994b;  dressingScale:  1;\n                     gridColor:  #43994b\"\n      \u003e\u003c/a-entity\u003e\n```\n\n[View docs for more info](https://github.com/feiss/aframe-environment-component/)\n\n_A Tip to easily change parameters_\n\n- Use [A-frame Inspector](https://github.com/aframevr/aframe-inspector) Please `ctrl+alt+i` on a scene and it will open an inspector, then on the right side change the parameter. Copy the changes and paste it to your html.\n\n![Step 2](https://cdn.glitch.com/97890fbd-889b-466f-a357-23627a83de50%2FScreen%20Shot%202021-02-02%20at%204.26.32%20PM.png?v=1612301609061)\n\n\n### Step 3\n\n\n- Let's add 3d Objects, we can use models our custom assets or use [Sketchfab](https://sketchfab.com/feed)\n\nWe have a bench and our chess board, For WebVR we need `.gltf` or `.glb`file\n\nSimilar to the code from [aframe docs](https://aframe.io/docs/1.1.0/primitives/a-gltf-model.html#sidebar)\n\n```js\n\u003ca-scene\u003e\n  \u003ca-assets\u003e\n    \u003ca-asset-item id=\"tree\" src=\"tree.gltf\"\u003e\u003c/a-asset-item\u003e\n  \u003c/a-assets\u003e\n\n  \u003c!-- Using the asset management system. --\u003e\n  \u003ca-gltf-model src=\"#tree\"\u003e\u003c/a-gltf-model\u003e\n\n  \u003c!-- Defining the URL inline. Not recommended but more comfortable for web developers. --\u003e\n  \u003ca-gltf-model src=\"tree.gltf\"\u003e\u003c/a-gltf-model\u003e\n\u003c/a-scene\u003e\n```\n\n- By using the `Aframe inspector` we position each chess pieces into proper spaces\n\n![Step 3](https://cdn.glitch.com/97890fbd-889b-466f-a357-23627a83de50%2FScreen%20Shot%202021-02-02%20at%205.44.21%20PM.png?v=1612305923293)\n\n\n### Step 4\n\n- Adding Quest Controllers to move and Teleport in our scene\n\nWe import `aframe-teleport-controls` by Fernando Serrano [Github link](https://github.com/fernandojsg/aframe-teleport-controls)\n\nInside the `\u003chead\u003e` tag we simply copy and past this cdn script\n\n```\n    \u003cscript src=\"https://rawgit.com/fernandojsg/aframe-teleport-controls/master/dist/aframe-teleport-controls.min.js\"\u003e\u003c/script\u003e\n```\n\n**WARNING**\n`The implementation for quest controllers doesn't quite work from the github page.`\n\nLuckily [Takashi Yoshinaga](https://github.com/TakashiYoshinaga) create a great implementation and showed how to implement in his demo - `https://quest-demo.glitch.me`\n![Demo](https://im2.ezgif.com/tmp/ezgif-2-f1d0dd3fd324.gif)\n\nUsing Takashi implementation, since we already imported the `aframe-teleport` we add cameraRig entity\n\n```\n \u003ca-entity id=\"cameraRig\"\u003e\n            \u003ca-entity id=\"head\" camera wasd-controls look-controls position=\"0 1.6 0\"\u003e\n            \u003c/a-entity\u003e\n            \u003ca-entity id=\"ctlL\"\n                teleport-controls=\"cameraRig: #cameraRig; teleportOrigin: #head; startEvents: teleportstart; endEvents: teleportend\"\n                raycaster=\"objects: .collidable; far:1.2; \" oculus-touch-controls=\"hand: left\" input-listen\u003e\n                \u003ca-text value=\"Press and let go \\nX: to Move\" position=\"0 0.08 0\"\n                    rotation=\"-90 0 0\" scale=\"0.1 0.1 0.1\" align=\"center\" color=\"#FFFFFF\"\u003e\u003c/a-text\u003e\n              \u003ca-sphere radius=\"0.01\" position=\"0 0 -1.2\" color=\"#FFFFFF\"\u003e\u003c/a-sphere\u003e\n            \u003c/a-entity\u003e\n            \u003ca-entity id=\"ctlR\" raycaster=\"objects: .collidable; far:1.2; \" oculus-touch-controls=\"hand: right\" input-listen\u003e\n                \u003ca-text value=\"Use Grip to interact\"\n                    position=\"0 0.08 0\" rotation=\"-90 0 0\" scale=\"0.1 0.1 0.1\" align=\"center\" color=\"#FFFFFF\"\u003e\u003c/a-text\u003e\n              \u003ca-sphere radius=\"0.01\" position=\"0 0 -1.2\" color=\"#FFFFFF\"\u003e\u003c/a-sphere\u003e\n            \u003c/a-entity\u003e\n        \u003c/a-entity\u003e\n```\n\nAnd we need to add EventListener script\n\n```\n\u003cscript\u003e\n    AFRAME.registerComponent('input-listen', {\n        init:\n            function () {\n                //Declaration and initialization of flag\n                //which exprains grip button is pressed or not.\n                //\"this.el\" reffers ctlR or L in this function\n                this.el.grip = false;\n\n\n\n                //Grip Pressed\n                this.el.addEventListener('gripdown', function (e) {\n                    //Setting grip flag as true.\n                    this.grip = true;\n                });\n                //Grip Released\n                this.el.addEventListener('gripup', function (e) {\n                    //Setting grip flag as false.\n                    this.grip = false;\n                });\n\n                //Raycaster intersected with something.\n                this.el.addEventListener('raycaster-intersection', function (e) {\n                    //Store first selected object as selectedObj\n                    this.selectedObj = e.detail.els[0];\n                });\n                //Raycaster intersection is finished.\n                this.el.addEventListener('raycaster-intersection-cleared', function (e) {\n                    //Clear information of selectedObj\n                    this.selectedObj = null;\n                });\n\n                //A-buttorn Pressed\n                this.el.addEventListener('abuttondown', function (e) {\n                       //Start pointing position to teleport\n                    this.emit('teleportstart');\n                });\n               this.el.addEventListener('abuttonup', function (e) {\n                    //Jump to pointed position\n                    this.emit('teleportend');\n                });\n\n                //X-buttorn Pressed\n                this.el.addEventListener('xbuttondown', function (e) {\n                    //Start pointing position to teleport\n                    this.emit('teleportstart');\n                });\n\n                //X-buttorn Released\n                this.el.addEventListener('xbuttonup', function (e) {\n                    //Jump to pointed position\n                    this.emit('teleportend');\n                });\n\n                //console.log(this);\n            },\n\n        //called evry frame.\n        tick: function () {\n\n            if (!this.el.selectedObj) { return; }\n            if (!this.el.grip) { return; }\n\n            //Getting raycaster component which is attatched to ctlR or L\n            //this.el means entity of ctlR or L in this function.\n            var ray = this.el.getAttribute(\"raycaster\").direction;\n            //setting tip of raycaster as 1.1m forward of controller.\n            var p = new THREE.Vector3(ray.x, ray.y, ray.z);\n            p.normalize();\n            p.multiplyScalar(1.2);\n            //Convert local position into world coordinate.\n            this.el.object3D.localToWorld(p);\n            //Move selected object to follow the tip of raycaster.\n            this.el.selectedObj.object3D.position.set(p.x, p.y, p.z);\n        }\n    });\n\n\n\u003c/script\u003e\n```\n\n![Step 4](https://cdn.glitch.com/97890fbd-889b-466f-a357-23627a83de50%2Fdemogif.gif?v=1613756972311)\n\n### Adding Hands and phsyics\n\nSince we need to add hands and being able to pick up chess pieces we need `aframe-physics` and `hands` - @[Will Murphy](https://github.com/wmurphyrd) to the rescue with `aframe-super-hands-component`\n\nAlso - Kyle Baker helped us simplify the implementation - \u003e https://github.com/wmurphyrd/aframe-super-hands-component/issues/188\n\nPer Kyle instruction \n - Import the components in head \n    ```\n     \u003cscript src=\"https://unpkg.com/super-hands/dist/super-hands.min.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://cdn.jsdelivr.net/gh/n5ro/aframe-physics-system@v4.0.1/dist/aframe-physics-system.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://unpkg.com/aframe-event-set-component@^4.1.1/dist/aframe-event-set-component.min.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://unpkg.com/aframe-physics-extras/dist/aframe-physics-extras.min.js\"\u003e\u003c/script\u003e\n    ```\n    \n- Then add Script \n```\n\u003cscript\u003e\n      AFRAME.registerComponent(\"phase-shift\", {\n        init: function() {\n          var el = this.el;\n          el.addEventListener(\"gripdown\", function() {\n            el.setAttribute(\"collision-filter\", { collisionForces: true });\n          });\n          el.addEventListener(\"gripup\", function() {\n            el.setAttribute(\"collision-filter\", { collisionForces: false });\n          });\n        }\n      });\n    \u003c/script\u003e\n  ```\n  \n  - Add Mixin inside your `\u003cassets\u003e` tag \n  \n  ```\n    \u003ca-mixin\n          id=\"all-interactions\"\n          hoverable\n          grabbable\n          stretchable\n          draggable\n          event-set__hoveron=\"_event: hover-start; material.opacity: 0.7; transparent: true\"\n          event-set__hoveroff=\"_event: hover-end; material.opacity: 1; transparent: false\"\n          dynamic-body\n        \u003e\u003c/a-mixin\u003e\n\n        \u003ca-mixin\n          id=\"grab-move\"\n          hoverable\n          grabbable\n          draggable\n          event-set__hoveron=\"_event: hover-start; material.opacity: 0.7; transparent: true\"\n          event-set__hoveroff=\"_event: hover-end; material.opacity: 1; transparent: false\"\n          dynamic-body=\"shape: box; sphereRadius: 0.1\"\n        \u003e\u003c/a-mixin\u003e\n\n        \u003ca-mixin\n          id=\"physics-hands\"\n          physics-collider\n          phase-shift\n          collision-filter=\"collisionForces: false\"\n          static-body=\"shape: sphere; sphereRadius: 0.02\"\n          super-hands=\"colliderEvent: collisions;\n                              colliderEventProperty: els;\n                              colliderEndEvent: collisions;\n                              colliderEndEventProperty: clearedEls;\"\n        \u003e\u003c/a-mixin\u003e\n  \n  ```\n  \n  - Now we need to tell our models to get mixins\n  ```\n  \u003ca-gltf-model\n        mixin=\"all-interactions\"\n        class=\"collidable\"\n        src=\"#knight\"\n        scale=\"0.03 0.03 0.03\"\n        position=\"-0.38701 1.08131 -2.44533\"\n      \u003e\n      \u003c/a-gltf-model\u003e\n      \u003ca-gltf-model\n        mixin=\"all-interactions\"\n        src=\"#queen\"\n        scale=\"0.03 0.03 0.03\"\n        position=\"0.07661 1.08131 -2.44533\"\n      \u003e\n  ```\n  \n  - Lastly we need to mixin, hands and script to the CameraRig\n  \n  ```\n  \u003ca-entity\n          id=\"ctlL\"\n          teleport-controls=\"cameraRig: #cameraRig; teleportOrigin: #head; startEvents: teleportstart; endEvents: teleportend\"\n          raycaster=\"objects: .collidable; far:1.2; \"\n          hand-controls=\"hand: left\" \n          mixin=\"physics-hands\" \u003c-updated\n          input-listen\n          phase-shift \u003c- updated\n        \u003e\n  ```\n  \n  \n# TODO\n\n- Adding `aframe-physics` to interact with chess pieces\n- Multiplayer\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frchovatiya88%2Fchessvr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frchovatiya88%2Fchessvr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frchovatiya88%2Fchessvr/lists"}