arc-agents
Version:
A library for creating and deploying gaming agents at scale
104 lines (96 loc) • 3.26 kB
JavaScript
class AutonomousAgentWrapper {
constructor(model, config={}) {
this.model = model
this.frameDelay = config.frameDelay ?? 15
this.forcedHold = config.forcedHold ?? 4
this.holdActions = config.holdActions ?? []
this.pressActions = []
this.forceHoldActions = config.forceHoldActions ?? []
this.complementaryActions = config.complementaryActions ?? {}
this.model.inputs = {}
this.inputCooldown = {}
this.previousHoldActions = {}
this.holdCooldown = {}
Object.keys(model.config.actionMetadata).forEach((actionGroup) => {
model.config.actionMetadata[actionGroup].order.forEach((action) => {
this.model.inputs[action] = false
this.inputCooldown[action] = 0
if (this.holdActions.includes(action)) {
this.previousHoldActions[action] = false
this.holdCooldown[action] = 0
}
else {
this.pressActions.push(action)
}
})
})
}
applyPressCooldown(inputs, action) {
if (this.inputCooldown[action] > 0) {
inputs[action] = false
this.inputCooldown[action] -= 1
}
else {
if (inputs[action]) {
this.inputCooldown[action] = this.frameDelay
}
}
}
applyHoldCooldown(inputs, action) {
const forceHoldBool = this.forceHoldActions.includes(action)
const complementaryAction = this.complementaryActions[action]
if (!this.previousHoldActions[action]) {
if (
complementaryAction !== undefined &&
(
this.previousHoldActions[complementaryAction] ||
this.inputCooldown[complementaryAction] !== 0
)
) {
inputs[action] = false
}
if (this.inputCooldown[action] > 0) {
inputs[action] = false
this.inputCooldown[action] -= 1
}
else if (inputs[action] && forceHoldBool) {
this.holdCooldown[action] = this.forcedHold
}
}
else {
if (this.holdCooldown[action] > 0 && forceHoldBool) {
inputs[action] = true
this.holdCooldown[action] -= 1
}
else if (!inputs[action]) {
this.inputCooldown[action] = this.frameDelay
}
}
}
applyFrameDelay(inputs) {
this.pressActions.forEach((action) => {
this.applyPressCooldown(inputs, action)
})
this.holdActions.forEach((action) => {
this.applyHoldCooldown(inputs, action)
})
}
trackPreviousHoldInputs(inputs) {
this.holdActions.forEach((action) => {
this.previousHoldActions[action] = inputs[action]
})
}
selectAction(features, selectionFunction) {
this.trackPreviousHoldInputs(this.model.inputs)
let inputs
if (selectionFunction !== undefined) {
inputs = selectionFunction.call(this, features)
} else {
inputs = this.model.selectAction(features)
}
this.applyFrameDelay(inputs)
this.model.inputs = inputs
return inputs
}
}
module.exports = AutonomousAgentWrapper