A web-based game with programmable bots (in Javascript). Live demo here.
- Choose the bots you want to fight (and you can add custom bots via URL)
- If you want to use a different ruleset, add it via the box at the bottom
- Press
Start. - Hit the space bar to pause.
- Crusher
- Destroyer
- Dumbo: very simple bot
- Teleporter: for use with teleport ruleset
- SampleBot: empty bot
- Xavier
- default
- demo1: smaller bots, set obstacles, set initial placement, various parameter tweaks
- demo2: completely redone drawing code
- demo3: faster bullets, different look, CSS 3D transform
- conveyor: different strips of the world move bots up or down
- expulsion: adds teleportation circle in center of world, varying bot radii
- orbit: bots orbit around the center point
- teleport: adds "teleport" command (see the Teleporter bot)
- walls: moving walls, larger world
All bots inherit from the parent Bot class in bots/bot.js. A bot script will be instantiated a number of times, depending on the ruleset.properties.bots.botsPerTeam value.
- name: team name
- id: numeric id
- x, y: coordinates of the bot's current location
- color: the assigned team color (from the ruleset)
- angle: the bot's current angle in radians
- radius: size of bot
- health: from 0 to 100
- alive: boolean
- weapons: object with number of remaining ammo for each weapon type
- canShoot: boolean
- waitFire: number of clicks to wait before firing
- collided: boolean
- hitByBullet: boolean
this.distanceToPoint(x1, y1, x2, y2): returns distance from point 1 to point 2this.myDistanceToPoint(x, y): returns distance from the bot to the pointthis.getDirection(target, threshold): basic pathfinding helper function. Uses fields to avoid obstacles.targetneeds to havexandyproperties (point, bot, etc.). A threshold of0.05works well. Returns an object:- response.command: the bot command needed to move closer to the target
- response.angle: the angle to the target
The minimum code required for a bot:
var NewBot = function() {};
NewBot.prototype = new Bot();
server.registerBotScript("NewBot");
If you want your bot to be named something different from the class name you've used, pass a second parameter to the server.registerBotScript function:
server.registerBotScript("NewBot", "Noob");
The game engine calls each bot's setup() function at the beginning of the game.
NewBot.prototype.setup = function() {
// Do stuff here
};
And then each click, it calls the bot's run() function. This is where the bulk of the bot logic should go.
NewBot.prototype.run = function() {
return { command: 'wait', team: {} };
};
The run() function returns an object with two properties:
command: the bot's command for this round (a string). Default commands (rulesets may add or modify commands):forwardbackwardleftrightfireminestrafe-leftstrafe-rightwaitself-destruct
team: an object that will get sent to the other bots on the team. You can access it viathis.state.payload.
A list of properties available under this.state:
world: a copy ofruleset.properties.world. In general, there arewidthandheightproperties that let you know how big the world is.bots: an array of all the currently living bots.id: bot's unique ID (integer)name: bot's team namexandy: bot's locationangle: angle the bot is pointinghealth: the current health of the bot (0–100)
obstacles: an array of all the obstacles. Each obstacle has the following properties:xandy: coordinates for the upper left corner of the obstaclewidth: width of obstacleheight: height of obstacle
items: an array of all the items. Each item has the following properties:xandy: coordinates for the center of the itemradius: radius of itemtype: type, currently onlyhealthandammoare supported (but rulesets may add new items)
weapons: an array of all the weapons currently in play. Each weapon has the following properties:xandy: weapon's locationangle: angle the weapon is pointingowner: ID for the bot who fired the weapontype: string, currently onlybulletandmineare supported (but rulesets may add new weapons)
payload: object passed in via theteamproperty returned from the bot's run() command
Custom rulesets allow you to modify game parameters and dynamics.
Minimum code required for a custom ruleset:
var ruleset = new Ruleset(server);
ruleset.name = "customrulesetname";
// Ruleset tweaks go here
server.setRuleset(ruleset);
Anything in the ruleset is tweakable. For example, to change existing properties or add new ones:
// Tweaking an existing property
ruleset.properties.botsPerTeam = 5;
// Adding a new property
ruleset.properties.confundusCharm = 10;
To add a new command (see teleport):
// Adds "pulse" as a command available to bots
ruleset.commands.pulse = function(bot) {
// Do things
}
And since it's an HTML/CSS game, you can also include DOM changes (see demo2):
$("body").css("background", "#f00"); // Don't do this
propertiesweaponsitems
commands- If a command moves a bot, it should return a position object; otherwise it need not return anything.
resetGame(): called at the beginning of a new gameregisterBotScript(teamNum, botScript, name): registers a new bot script (you generally won't want to change this)generateObstacles(): returns array of obstacles (objects withx,y,width, andheightproperties)generateItems(): returns array of items (objects withx,y,radius, andtypeproperties)initializeBot(bot, id): initialize bot (you generally won't want to change this)postInitBot(bot): post-init per-bot setup hooksetInitialPlacement(bot): setsbot.xandbot.yat the beginning of each gameinitializeGame(): game init hookstartRound(clicks): called at the beginning of each roundresetCollisionFlags(bot): resets collision flagsupdateFlags(bot): updates bot flags and countersupdateBot(bot, pos): hook to allow the server to move bots (see orbit, conveyor)parseCommand(command, bot): parses command (you generally won't want to change this)checkCollisions(bot, newPosition): checks for collisionspostProcess(bot): called after each bot is processedendRound(): called at the end of each roundgameOver(): returns true or false depending on if game over conditions have been metgetWinner(): returns name of the team who wongetHealth(): returns array of combined health for each team
These are part of ruleset. To add new functions, modify draw.world().
draw.world(): draws everything in order (clear, backgroundLayer, health, obstacles, bots, weapons, particles, foregroundLayer)draw.clear(): clears the canvasdraw.backgroundLayer(): draws the background layer (default ruleset draws a grid)draw.foregroundLayer(): draws the foreground layer (default is nothing)draw.obstacles(): loops through obstacles and callsdraw.obstaclefor each one (you probably won't need to modify this)draw.obstacle(obstacle): draws an obstacledraw.items(): loops through items and calls their callbacksdraw.bot(x, y, angle, color, radius, health): draws a botdraw.weapon(x, y, angle, type, owner, obj): draws a weapon (bullet, mine, etc.)draw.particles(): loops through particles, runs the decay on each (TODO: move this out of drawing code), and callsdraw.particlefor each one (you probably won't need to modify this)draw.particle(particle, newPos): draws a particledraw.health(): modifies the HTML elements that store the healthdraw.paused(): draws the paused state (dark overlay, white pause icon)draw.endgame(winner): draws the endgame state
These are part of ruleset.
draw.width: if you modifyproperties.world.width, modify this as welldraw.height: if you modifyproperties.world.height, modify this as welldraw.ruleset: makes the ruleset object available to drawing codedraw.server: makes the server object available to drawing code