@rbxts/utility-ai
v0.0.3
Published
A small Utility Ai Framework
Readme
Utility Ai
A small Utility Ai Framework
Install
npm install @rbxts/utility-aiUsage
import { UtilityAi } from "./index";
interface EnemyEntity {}
interface PlayerEntity {
isStuck(): boolean;
distanceTo(enemy: EnemyEntity): number;
gunEmpty(): boolean;
nextCoverDistance(): number;
isInCover(): boolean;
}
interface WorldData {
player: PlayerEntity;
enemy: EnemyEntity;
}
const utility_ai = new UtilityAi<WorldData>();
// define your actions e.g "Move to Enemy", "Fire at Enemy", "Move to Cover", "Reload Gun"
utility_ai.addAction("Move to Enemy", (action) => {
// pre-conditions for actions, if not fulfilled all actions will be skipped
action.condition(({ player }) => {
if (player.isStuck()) return false;
// explicit return of true needed to fulfill condition
return true;
});
// each score expects a number as return value, the higher the better the action will be weighted
action.score("Distance to Enemy", ({ player, enemy }) => player.distanceTo(enemy));
action.score("Gun is not loaded", ({ player }) => player.gunEmpty() && -100);
});
utility_ai.addAction("Fire at Enemy", (action) => {
action.score("Proximity to Enemy < 50", ({ player, enemy }) => player.distanceTo(enemy) < 50 && 75);
action.score("Cannot make it to cover", ({ player }) => player.nextCoverDistance() > 25 && 50);
action.score("Gun is not loaded", ({ player }) => player.gunEmpty() && -125);
});
utility_ai.addAction("Move to Cover", (action) => {
action.score("Is not in cover", ({ player }) => !player.isInCover() && 50);
action.score("Proximity to Cover < 50", ({ player }) => player.nextCoverDistance() < 50 && 50);
});
utility_ai.addAction("Reload Gun", (action) => {
action.score("Gun is not loaded", ({ player }) => player.gunEmpty() && 75);
action.score("Is in Cover", ({ player }) => player.isInCover() && 50);
action.score("Gun is loaded", ({ player }) => !player.gunEmpty() && -125);
});
const data: WorldData = {
player: {
isStuck() {
return false;
},
distanceTo(enemy) {
return 0;
},
gunEmpty() {
return false;
},
nextCoverDistance() {
return 0;
},
isInCover() {
return false;
},
},
enemy: {},
};
// starts the evaluation of a given world state and returns its best action
const result = utility_ai.evaluate(data);
// e.g. result = { action: "Move to Cover", score: 100 }