22
9
In a desolate, war-torn world, where cities have been overrun by thugs and thieves, civilization has reinvented itself in the form of small, isolated, industrial cooperatives, scattered throughout the previously uninhabited landscape. The existence of these communities is reliant on teams of mercenary workers called "scrappers", who search the untamed territory for valuable materials to sell to the coops. As these materials have grown more scarce, scrapping has become an ever more difficult and dangerous profession. Fragile human workers have mostly been replaced with remote robotic stand-ins, called “bots”, and a typical mercenary is more likely to be a skilled programmer than an armed welder. As the human presence in scrapping has declined, so too has the respect between mercenary groups for one another. Bots are equipped not only to collect scrap, but to defend it, and in some cases take it by force. Bot programmers work tirelessly devising new strategies to outsmart rival scrappers, resulting in increasingly aggressive bots, and yet another danger for humans who venture outside the walls of their communities.
(yeah, the logo gets cropped hilariously)
Welcome to Scrappers!
This is an early version of Scrappers in which scrap collection and factories have not been implemented. It’s basically a “shoot ‘em up”.
You are a mercenary programmer tasked with creating a program to remotely conduct your bots to victory over rival scrapper groups. Your bots are spider-like machines consisting of power and shield generators at their core, surrounded by many appendages equipped with gripping, cutting, and attacking implements. The power generator is capable of producing 12 power units (pu) per tick (a scrapper's unit of time). You are in control of how this power is distributed amongst a bot's three primary needs: movement, shields, and firepower.
Scrapper bots are exceptionally agile machines, and can easily move over, under, and around any obstacles they encounter. Thus, collision is not something that your program needs take into consideration. You are free to allocate all, some, or none of the 12pu available to your bot for movement, as long as you deal in whole numbers. Allocating 0pu to a bot's movement functions would render it immobile. Allocating 2pu would enable a bot to move 2 distance units (du) per tick, 5pu would result in 5du/tick, 11pu would result in 11du/tick, and so on.
Your bots’ shield generators project a bubble of deflective energy around their body. A shield can deflect up to 1 damage before popping, thus leaving your bot exposed until it's shield generator builds enough power to snap the shield back into place. You are free to allocate all, some, or none of the 12pu available to your bot towards it’s shield. Allocating 0pu to a bot's shield means that it will never generate a shield. Allocating 2pu would allow a bot to generate a new shield 2 out of 12 ticks, or once every 6 ticks. 5pu would result in shield regeneration 5 out of every 12 ticks, and so on.
By building up a charge in their welding lasers, your bots can fire damaging beams over short distances with fair accuracy. Like shield generation, your bots’ rate of fire depends on the power allocated to their lasers. Allocating 0pu to a bot's lasers means that it will never fire. Allocating 2pu would allow a bot to fire 2 out of every 12 ticks, and so on. A bot’s laser will travel until it encounters an object or disperses into uselessness, so be mindful of friendly fire. Although your bots are quite accurate, they aren’t perfect. You should expect +/- 2.5 degrees of variance in accuracy. As the laser beam travels, its particles are incrementally deflected by the atmosphere until the beam becomes effectively harmless with enough distance. A laser does 1 damage at point blank range, and 2.5% less damage every bot-length it travels. In other words, the closer you are to your target, the more likely you are to hit it, and the more damage you will cause.
Scrapper bots are autonomous enough to handle basic functions, but rely on you, their programmer, to make them useful as a group. As a programmer, you may issue the following commands for each individual bot:
- MOVE: Specify coordinates towards which a bot will move.
- TARGET: Identify a bot to aim at and fire at when power allocation allows.
- POWER: Redistribute power between movement, shields, and firepower.
Technical Game Details
There are three programs that you'll need to be familiar with. The Game Engine is the heavy lifter and provides a TCP API that the player programs connect to. The player program is what you'll write, and I've provided some examples with binaries here. Finally, the Renderer processes the output from the Game Engine to produce a GIF of the battle.
The Game Engine
You can download the game engine from here. When the game is launched, it will begin listening on port 50000 (currently not configurable) for player connections. Once it receives two player connections, it sends the READY message to the players and begins the game. Player programs send commands to the game via the TCP API. When the game is over, a JSON file named scrappers.json (also, currently not configurable) is created. This is what the renderer uses to create a GIF of the game.
The TCP API
Player programs and the game engine communicate by passing newline-terminated JSON strings back and fourth over a TCP connection. There are just five different JSON messages that can be sent or received.
Ready Message
The READY message is sent from the game to the player programs and is only sent once. This message tells the player program what its player ID (PID) is and provides a list of all the bots in the game. The PID is the only way to determine which Bots are friendly vs enemy. More info on the bot fields below.
{
"Type":"READY", // Message type
"PID":1, // Player ID
"Bots":[ // Array of bots
{
"Type":"BOT",
"PID":1,
"BID":1,
"X":-592,
...
},
...
]
}
Bot Message
The BOT message is sent from the game to the player programs and is sent when a bot's attributes change. For instance, when shields are projected, or health changes, a BOT message is sent. The Bot ID (BID) is only unique within a particular player.
{
"Type":"BOT", // Message type
"PID":1, // Player ID
"BID":1, // Bot ID
"X":-592, // Current X position
"Y":-706, // Current Y position
"Health":12, // Current health out of 12
"Fired":false, // If the Bot fired this tick
"HitX":0, // X position of where the shot landed
"HitY":0, // Y position of where the shot landed
"Scrap":0, // Future use. Ignore.
"Shield":false // If the Bot is currently shielded.
}
Move Message
The MOVE message is a command from the player program to the game (but think of it as a command to a bot). Simply identify the bot you want to move, and the coordinates. It's assumed that you are commanding your own bot, so no PID is necessary.
{
"Cmd":"MOVE",
"BID":1, // Bot ID
"X":-592, // Destination X coordinate
"Y":-706, // Destination Y coordinate
}
Target Message
The TARGET message tells one of your bots to target some other bot.
{
"Cmd":"TARGET",
"BID":1, // Bot ID
"TPID":0, // The PID of the bot being targeted
"TBID":0, // The BID of the bot being targeted
}
Power Message
The POWER message reallocates the 12pu available to your bot between movement, firepower, and shields.
{
"Cmd":"POWER",
"BID":1, // Bot ID
"FPow":4, // Set fire power
"MPow":4, // Set move power
"SPow":4, // Set shield power
}
The Competition
If you're brave enough to explore the untamed lands, you'll be entered into a double-elimination tournament against your mercenary peers. Please create an answer for your submission and either paste your code or provide a link to a git repo, gist, etc. Any language is acceptable, but you should assume I know nothing about the language and include instructions for running your program. Create as many submissions as you like, and be sure to give them names!
The sample player programs will be included in the tournament, so I highly recommend testing your bot against them. The tournament will commence roughly two weeks after we get four unique program submissions. Good luck!
--- Winner's Bracket ---
** Contestants will be randomly seeded **
__________________
|___________
__________________| |
|___________
__________________ | |
|___________| |
__________________| |
|________________
__________________ | |
|___________ | |
__________________| | | |
|___________| |
__________________ | |
|___________| |
__________________| |
|
--- Loser's Bracket --- |___________
|
___________ |
|___________ |
___________| |___________ |
| | |
___________| | |
|___________ |
___________ | | |
|___________ | |___________|
___________| |___________| |
| |
___________| ___________|
Other Important Info
- The game runs at 12 ticks/second, so you will not receive messages more frequently than every 83 milliseconds or so.
- Each bot is 60du in diameter. The shield takes up no additional space. With the +/- 2.5% accuracy, the odds of hitting a bot at a certain distance are represented by this graph:
- The decay of laser damage over distance is represented by this graph:
- A bot's accuracy and laser decay combine to calculate its average damage per shot. That is, the average damage a bot will cause when it fires from a certain distance. Damage per shot is represented by this graph:
- A bot's laser originates half way between the bot's center and its edge. Thus, stacking your bots will result in friendly fire.
- Enemy bots spawn roughly 1440du apart.
- The game ends if 120 ticks (10 seconds) pass without any damage dealt.
- The winner is the player with the most bots, then the most health when the game ends.
Understanding the Rendered Image
- Player 1 is represented by circles and player 2 by hexagons.
- The color of a bot represents its power allocation. More red means more power has been allocated to firing. More blue means more shield. More green means more movement.
- The "hole" in a bot's body represents damage. The larger the hole, the more damage has been taken.
- The white circles surrounding a bot are it's shield. If a bot has a shield at the end of the turn, it is shown. If the shield was popped by taking damage, it is not shown.
- The red lines between bots represent shots taken.
- When a bot is killed, a large red "explosion" is shown.
Comments are not for extended discussion; this conversation has been moved to chat.
– Dennis – 2017-07-20T05:26:33.870