This is a bot for bot.generals.io.
- In the
./src/
directory, create aconfig.js
file with the following structure:
export default {
GAME_ID: '{theNameOfTheGameToJoin}',
BOT_NAME_1: '[Bot]botName',
BOT_USER_ID_1: '{userIdFromLocalStorageFromIncognitoWindow}',
BOT_VARIANT_1: 'MurderBot',
BOT_NAME_2: '[Bot]botName',
BOT_USER_ID_2: '{userIdFromLocalStorageFromIncognitoWindow}',
BOT_VARIANT_2: 'EnigmaBot',
// Set up multiple usernames/IDs so you can open a second tab and go to
// /play/2, /play/3, etc. and have multiple bots join a game and play each other.
...
}
NOTE: Do not commit the config file, or anyone could use your bot's identity
- Open
bot.generals.io/games/{GAME_ID}
, and set desired game settings. - Run
npm install
andnpm start
. - Open
localhost:3000/play/{botIdNumber}
, and the corresponding bot will join the game. - Click the force_start option in the bot UI and the lobby UI to start the game.
Features:
- Base game configuration, eventing, and intelligence is calculated in the client and passed to all bot variants
- Ability to load multiple bot variants
- Game logic runs entirely in the client browser
- Sticky game settings on a per-bot basis
- Unit tests ensure that calculations run as expected
- IN-PROGRESS: Test bed, where AI can be tested step-by-step in deterministic scenarios
- IN-PROGRESS: Live updating map that can also be used to send attack/defend commands to the bot
- ESLint, Prettier, & pre-commit hooks (sorry it took so long, other developers)
To-Do List:
- Efficient army consolidation, when discovered by a more powerful opponent
- Ruthless declaration of war, if an opponent with a known general location suddenly becomes vulnerable
- Ability to abort extended operations, if field conditions suddenly change
- Targeted exploration, not just random movement
- Add teammate recognition and ping generation and acknowledgement
- Send game logs to log section, instead of console
- On turn 50, consolidate all newly-generated troops and either attack, expand, explore, or defend
- Fuzzy recursive logic for army consolidation
- Identify location of target
- Only use the top x% armies
- Identify the path the goes through the most other armies
- If you have grabbed x% of desired armies, bail out early and execute
Stages of Development Replays:
- [most recent failure]
- https://bot.generals.io/replays/rgjawPwsF (top of the leaderboard the whole game, with aggressive city and general attack algorithm, missing defense strategy)
- https://bot.generals.io/replays/rgTpm28ot (1st 3-player win)
- https://bot.generals.io/replays/rl-2BbHiY (1st legitimate win, with initial general attack algorithm)
- https://bot.generals.io/replays/BltYNsCKY (1st near-win, with 2 captures, without any specific city or general attack targeting or army gathering implemented)
- https://bot.generals.io/replays/rgRdQY0tY (hyper-aggressive creep reclamation)
- https://bot.generals.io/replays/HgErmdnFt (fast creep queue added)
- https://bot.generals.io/replays/BlkI7vOYY (improved decision-making)
- https://bot.generals.io/replays/SerSfIDYF (1st bot win, fast attack with quick expansion)
- https://bot.generals.io/replays/BgvSl-mtK (2x speed, now explores without backtracking so much and uses most-recent army when possible)
- https://bot.generals.io/replays/SlYu2rhuY (now conquers cities, stupidly)
- https://bot.generals.io/replays/SeHYrHndY (doesn't just shift armies back and forth)
- Emphasize capture of empty spaces (opening 6 turns are optimal)
- Parse game state into actionable data, avoids attacking mountains
- Minimize looping and halt execution on game completion
- Separate socket logic from AI logic
Pieces of data to consider tracking
let dataToTrack = { foreignPolicy /* mode */: 'CREEP|TURTLE|EXPLORE|EXPAND|DEFEND|CONSOLIDATE|GATHER|MURDER|DECOY|ATTACK|GAMBIT', itemsOfInterest: { availableCities: [ { color: 'NEUTRAL', location: undefined, totalArmies: undefined, } ], easiestTarget: {}, biggestThreat: {}, enemies: [ { color: undefined, disposition: 'NEUTRAL|AGGRESSIVE|INVADING|SUICIDAL', generalLocation: undefined, generalStrength: undefined, knowsMyGeneralLocation: false, totalFriendlyArmiesKilled: undefined, totalArmies: undefined, totalLand: undefined, } ], pointsOfAttack: [ ] } }