{"id":13907292,"url":"https://github.com/javierbyte/clashjs","last_synced_at":"2025-04-06T22:07:40.524Z","repository":{"id":32969187,"uuid":"36587499","full_name":"javierbyte/clashjs","owner":"javierbyte","description":"Play by creating a javascript function to command your battleship.","archived":false,"fork":false,"pushed_at":"2022-05-03T08:09:58.000Z","size":10477,"stargazers_count":246,"open_issues_count":4,"forks_count":85,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-30T20:11:19.469Z","etag":null,"topics":["ai","battle-game","game","javascript","learning"],"latest_commit_sha":null,"homepage":"https://clashjs.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/javierbyte.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-31T04:15:35.000Z","updated_at":"2025-02-08T18:34:07.000Z","dependencies_parsed_at":"2022-08-19T07:40:59.837Z","dependency_job_id":null,"html_url":"https://github.com/javierbyte/clashjs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javierbyte%2Fclashjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javierbyte%2Fclashjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javierbyte%2Fclashjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javierbyte%2Fclashjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/javierbyte","download_url":"https://codeload.github.com/javierbyte/clashjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247557767,"owners_count":20958047,"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":["ai","battle-game","game","javascript","learning"],"created_at":"2024-08-06T23:01:52.576Z","updated_at":"2025-04-06T22:07:40.505Z","avatar_url":"https://github.com/javierbyte.png","language":"JavaScript","readme":"# [ClashJS.com](https://clashjs.com/)\n\n[![](public/clashjs-com.jpg)](https://clashjs.com/)\n\n[Demo Online](https://clashjs.com/)\n\nThis is an experiment. The idea is to create a battle game, where the participants code their AI, and then we make them fight! You can play by adding your own AI to the game!\n\n# How to run the demo.\n\nYou'll need nodejs [https://nodejs.org/en/download/](https://nodejs.org/en/download/), tested with current LTS version `12.x`.\n\n1. Clone the repo.\n\n```\ngit clone git@github.com:javierbyte/clashjs.git\n```\n\n2. Move to the repo directory, install dependencies.\n\n```bash\ncd clashjs\nnpm install\n```\n\n3. Run the repo!\n\n```\nnpm start\n```\n\nIt should open your browser with the `http://localhost:3000/` demo URL.\n\nThe current configured players will start to play right away, at this point you can edit them on `src/players/\u003cPLAYER_NAME\u003e.js` and the browser should refresh on save.\n\n# How to participate.\n\nAdd your player as specificed in [player definition](#player-definition) in\n\n```\n/src/players/YOU.js\n```\n\nAnd then require yourself in\n\n```\n/src/Players.js\n```\n\nAnd run the demo again. Have fun!\n\nRead the [game definitions](#game-definitions) to learn how to create your player. Have fun!\n\n# Game. Functional Spec.\n\n## Introduction.\n\nGames and coding are fun! So I want to make a game where we can confront AI vs AI in javascript.\n\nThe game is simple: we will put all the players in a battle arena, and then make them fight to death. There will be ammo in the arena so they can shoot each other. The last player alive wins!\n\n### Game Rules.\n\n- Every player will have a position and direction on the grid. A player can not go over the grid limits, and can only face north, east, south or west.\n- The game will be turn based. Every turn we will excecute the AI of every player passing as arguments:\n  - The state of the player.\n  - The state of all other players.\n  - A environment configuration option with:\n    - Grid size.\n    - The position of the ammo.\n- Every turn a player must execute one of the following actions:\n  - Move one step in its current direction. (`move`).\n  - Turn into any of the four directions. (`north`, `east`, `south`, `west`).\n  - Shoot. (`shoot`).\n- A player can shoot to try to destroy another player.\n- A player can collect ammo in the moment it steps over it. New ammo may appear in any moment of the game.\n\n## Game Definitions.\n\n### Player Definition.\n\nLet the _player definition_ (`playerDefinition`) be an object with the player info and its AI function.\n\n```js\n{\n  info: {\n    name: 'javierbyte',\n    style: 2 // one of the 6 styles (0 to 5)\n  },\n  ai: function(playerState, enemiesStates, gameEnvironment) {\n    // think...\n    return 'move';\n  }\n}\n```\n\nThe AI function will receive [`playerState`](#player-state), `enemiesStates` (array of all the other players `playerState`s), and [`gameEnvironment`](#game-environment) as arguments, and must return one of the following strings:\n\n- `move`: To move one tile in the current direction.\n- `north`, `east`, `south` or `west`: To turn to that direction.\n- `shoot`. To shoot if the user has enough ammo.\n\nAny other response, trying to move outside the arena size (`gameEnvironment.gridSize`) or trying to shoot without ammo, will result in a no-op.\n\n### Player State.\n\nLet the _player state_ (`playerState`) be an object with a player information like the following:\n\n```js\n{\n  position: `[\u003cnumber\u003e, \u003cnumber\u003e]`,\n  direction: `\u003cstring\u003e`, // One of 'north', 'east', 'south' or 'west'\n  ammo: `\u003cnumber\u003e`,\n  isAlive: `\u003cbool\u003e`\n}\n```\n\n### Game Environment.\n\nLet the _game environment_ (`gameEnvironment`) be a configuration object like the following:\n\n```js\n{\n  gridSize: [\u003cnumber\u003e, \u003cnumber\u003e],\n  ammoPosition: \u003carray of [\u003cnumber\u003e, \u003cnumber\u003e] arrays\u003e\n}\n```\n\n### Game State.\n\nLet the _game state_ (`gameState`) be an object with the array of all user states, and the game environment.\n\n```js\n{\n  playerStates: \u003carray of `playerStates`\u003e,\n  gameEnvironment: \u003c`gameEnvironment`\u003e\n}\n```\n\n# Game Technical Spec.\n\n## Problem.\n\nWe should make an app that can take functions provided by the users, execute them, and render the game as specified in the functional spec.\n\n## Constraints.\n\n- The game mechanics should avoid accidentally benefitting players by its random nature. The order of execution of the AIs should not favor any particular player. The position of newly created coins should be fair for all players.\n- Be safe. A player code should not be able to modify anything other than itself.\n- Be resilient as possible. If a player crashes or stop responding, the show must go on.\n\n## How this was made.\n\n### Architecture.\n\nWe can divide the problem in 3 big steps.\n\n- **AI Runner**. This will take all the user provided functions and the current game state, and execute every function.\n  - This will take care of catch errors on the functions, and stop non-responding functions to hang the window.\n- **Game Core**. This will take the responses that the AI Runners sends, and apply the game logic on them.\n  - Handle killed players.\n  - Move and turn players.\n  - Collect and count coins.\n  - Generate new coins if necessary.\n  - Set the paralized turns to players that shot.\n  - Count if too many inactive turns have passed.\n  - Stop the game when it ends.\n- **Render**. This will take the game state and render it nicely.\n\nThey will interact as follows:\n\n![](spec_assets/game-blackbox.png)\n\n\u003c!---\nsequenceDiagram\nAI Runner-\u003e\u003e Game Core: Array of objects\nNote left of Game Core: The AI runners sends \u003cbr/\u003e the results of \u003cbr/\u003eexecuting the code \u003cbr/\u003e of every player\u003cbr/\u003eon the current game\u003cbr/\u003estate.\nGame Core-\u003e\u003e Render: Game state\nNote left of Render: The core applies the\u003cbr/\u003eresults to the game,\u003cbr/\u003ecomputes the new\u003cbr/\u003estate, and sends\u003cbr/\u003eit to the render.\nNote left of Game Core: The Core sends the\u003cbr/\u003enew game state to\u003cbr/\u003ethe AI runner\u003cbr/\u003eto execute all\u003cbr/\u003efunctions again.\nGame Core-\u003e\u003eAI Runner: Game State\n\nhttp://knsv.github.io/mermaid/live_editor/\n--\u003e\n\n# AI Runner. Spec.\n\n## Problem.\n\nThe AI runner should execute all the functions that the players provided, with the current user state, all user states, and game enrivonment as arguments.\n\n## Constraints.\n\n- Isolate the user functions. They should not be allowed to modify any other code.\n- Catch executions errors, and simply return `null` as response to the Game Core.\n- Detect if any functions gets stuck in an infinite loop, and return `null` as response.\n\n## Hypothesis.\n\nWe can run the functions as WebWorkers because:\n\n- They can not access the dom and modify things.\n- Runs in a sandbox. If they crash or stop responding we can detect it.\n- Bonus: We can parallelise the excecution.\n\nThe game is designed to make irrelevant the order of execution of the AIs. We are safe in running all this asynchronously.\n\n## Solution.\n\nTo prevent the functions from taking too much time processing (probably because an infinite loop), we will create an array of `null`s, where we will put the responses of the workers as they arrive. If `X` seconds passes (enough processing time for almost everything, except infinite loops, of couse) then we will pass the `null`ified response of that worker, and the Game Core will kill that player.\n\n![](spec_assets/airunner-blackbox.png)\n\n\u003c!---\nsequenceDiagram\nGame Core-\u003e\u003e AI Runner: Game State\nNote left of AI Runner: Starts a countdown\u003cbr/\u003eof X seconds.\nAI Runner-\u003e\u003e Worker0: Arguments\nAI Runner-\u003e\u003e Worker1: Arguments\nWorker1-\u003e\u003e AI Runner: Response\nAI Runner-\u003e\u003e Worker2: Arguments\nWorker0-\u003e\u003e AI Runner: Response\nWorker2-\u003e\u003e AI Runner: Response\nNote left of AI Runner: When all the workers\u003cbr/\u003eresponds, or the\u003cbr/\u003ecountdown hits 0\u003cbr/\u003ereturn the values\u003cbr/\u003eto the Game Core.\nAI Runner-\u003e\u003e Game Core: Results\n\nhttp://knsv.github.io/mermaid/live_editor/\n--\u003e\n\n# Game Core.\n\n## Player Class.\n\nThis javascript class will recive a `playerDefinition` and return a player instance.\n\n### Arguments:\n\n- [`playerDefinition`](#player-definition).\n- [`evtCallback`] A callback that will receive the arguments `evt` and `data`.\n\n### Methods:\n\n- `getInfo`. Will return the player info.\n- `execute`. Will receive the following arguments:\n  - [`playerState`](#player-state). The current player state.\n  - `enemiesStates`. An array of all the other live players `playerState`s.\n  - [`gameEnvironment`](#game-environment). The game environment object.\n\n## CashJS Class.\n\nThis class will receive all the player definitions, generate the game states, and execute the players AIs.\n\n### Arguments:\n\n- `playerDefinitionArray`. An array of [`playerDefinition`](#player-definition) objects.\n\n### Methods:\n\n- `getState`. Will return the current [`gameState`](#game-state).\n- `nextStep`. Will execute a step for every player (all individual plys). Will return the game state.\n- `nextPly`. Will execute the AI for the player in turn. Will return the game state.\n\n# Render.\n\nReact.\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavierbyte%2Fclashjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjavierbyte%2Fclashjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavierbyte%2Fclashjs/lists"}