Skip to content

Instantly share code, notes, and snippets.

@timetocode
Created August 4, 2019 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timetocode/5c069d0865f5fda6598ade1e77d2944e to your computer and use it in GitHub Desktop.
Save timetocode/5c069d0865f5fda6598ade1e77d2944e to your computer and use it in GitHub Desktop.
nengi bot example using multiple cpus
const glue = require('./glue')
const nengi = glue.nengi.default
const nengiConfig = glue.nengiConfig.default
const PlayerInput = glue.PlayerInput.default
// bots need to all share the same protocols
const protocolMap = new nengi.ProtocolMap(nengiConfig, nengi.metaConfig)
//var address = 'ws://localhost:8001'
const address = null // put some url here
let numberOfBots = 10 // just a default, actual amount set by parent process
const bots = new Map()
// process communication
process.on('message', msg => {
if (msg.address) {
address = msg.address
}
if (msg.count) {
numberOfBots = msg.count
}
if (msg.start) {
for (let i = 0; i < numberOfBots; i++) {
setTimeout(() => {
connectNewBot(i)
}, i * 250)
}
}
if (msg.stop) {
bots.forEach(bot => {
if (bot.websocket) {
bot.websocket.terminate()
}
})
}
})
process.on('SIGINT', function () {
console.log("childBot caught interrupt signal, cleaning up websockets")
bots.forEach(bot => {
if (bot.websocket) {
bot.websocket.terminate()
}
})
process.exit()
})
// creating a bot
function connectNewBot(id) {
const bot = new nengi.Bot(nengiConfig, protocolMap)
bot.id = id
// may not need this depending on the game
bot.controls = {
w: false,
a: false,
s: false,
d: false,
space: false,
sprint: false,
primary: false,
secondary: false,
reload: false,
rotationX: Math.random() * Math.PI * 2,
rotationY: Math.random() * Math.PI * 2,
rotationZ: Math.random() * Math.PI * 2,
delta: 1 / 60
}
bot.onConnect(response => {
console.log('Bot attempted connection, response:', response)
bot.tick = 0
})
bot.onClose(() => {
bots.delete(bot.id)
})
bots.set(bot.id, bot)
bot.connect(address, {})
}
function randomBool() {
return Math.random() > 0.5
}
const loop = () => {
bots.forEach(function botLoop(bot) {
if (bot.websocket) {
// releases memory!! also returns snapshots, if you want the bots to intelligently play the game
bot.readNetwork()
// randomly hitting keys and changing controls - will vary for your game
if (Math.random() > 0.95) {
bot.controls = {
w: randomBool(),
a: randomBool(),
s: randomBool(),
d: randomBool(),
space: false, //randomBool(),
sprint: false,
primary: false, //randomBool(),
secondary: false,
reload: false,
rotationX: Math.random() * Math.PI * 2,
rotationY: Math.random() * Math.PI * 2,
rotationZ: Math.random() * Math.PI * 2,
delta: 1 / 60
}
}
// actually creating and sending the input to the server
const input = new PlayerInput(
bot.controls.w,
bot.controls.a,
bot.controls.s,
bot.controls.d,
bot.controls.space,
bot.controls.sprint,
bot.controls.primary,
bot.controls.secondary,
bot.controls.reload,
bot.controls.rotationX,
bot.controls.rotationY,
bot.controls.rotationZ,
bot.controls.delta
)
if (Math.random() > 0.7) {
// another type of command periodically?? up to you
// bot.addCommand(new FireCommand(500, 500, Math.random()))
}
bot.addCommand(input)
bot.update()
bot.tick++
}
})
}
setTimeout(() => {
setInterval(loop, 16) // simulated client tick rate
}, 100)
require = require('esm')(module/*, options*/)
module.exports.nengi = require('nengi')
module.exports.nengiConfig = require('../common/nengiConfig')
/* from here on your needs will vary per game, use your games commands */
module.exports.PlayerInput = require('../common/command/PlayerInput')
const { fork } = require('child_process')
/*
// example of creating ONE child
const forked = fork('./game/bot/childBot.js')
forked.on('message', (msg) => {
console.log('Message from child', msg)
})
forked.send({
address: 'wss://asia-pacific-3.example.io/1',
count: 10,
start: true
})
*/
// sending 10 players each to servers wss://asia-pacific-3.example.io/1 thru wss://asia-pacific-3.example.io/10
for (var i = 1; i <= 24; i++) {
const forked = fork('./game/bot/childBot.js')
forked.send({
address: `wss://asia-pacific-3.example.io/${i}`,
count: 10,
start: true
})
}
process.on('SIGINT', function () {
console.log("multiBot caught interrupt signal")
process.exit()
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment