Oboy, there have been updates to the Bot Playtesting Toolkit. The additions have been triggered both by games I’m simulating and by things I just wanted to improve anyway. The most important parts are summarized below.
Object filters
I realized that I often needed to write complex if-statements to check if an in-game object matches certain criteria, and often I needed to run these if-statements on lists of objects to select or remove matching objects. Since version 1.2 this can be done by the ObjectFilter class, which has seen substantial improvements in 1.3 and 1.4.
The ObjectFilter is used to create and store complex conditions, which are then applied either to a single object (returning true or false), or to arrays of objects (returning the matching objects). The three examples below are from the online documentation.
Getting all agents on the blue team:
let blueTeam = new ObjectFilter({team: ‘blue’}).applyOnArray(gameState.agents);
Selecting all spaces on a track (i.e. chess board) where the colour is black and there is no piece:
let mySpaces = new ObjectFilter().addEqualsCondition({colour: ‘black’}).addEqualsCondition({piece: false}).applyOnArray(gameState.track.board.spaces);
Taking out all cards that are spades or twos:
let myCards = new ObjectFilter().or().addEqualsCondition({colour: ‘spades’}).addEqualsCondition({value: 2}).removeFromArray(gameState.decks.myDeck.cards);
Having the ObjectFilter class has already helped me a lot.
Functions for caching expensive objects
Since the script runs through Google spreadsheets there is a limit on 30 seconds execution time. This puts some pressure on using the clock cycles wisely. Since version 1.3 there are setCache and getCache functions available, used to store objects that are expensive to create so they can be reused between game iterations. (My own use for this was some extensive analysis of a game board, calculating and storing a lot of useful data based on distances and whatnot.)
Since version 1.4 it is also possible for modules to have a postBuild function, called after the game state has been set up but before the first game iteration. The purpose of this function is to make any heavy calculations that only need to be made once, and store them in the cache.
New functions for tracks/boards/grids
The Track class has seen some useful additions. Now it is not only possible to create complex grid boards, finding the shortest path between two spaces, finding all spaces a certain number of steps away and (since v. 1.1) checking if there is a line of sight between two spaces; but also functions to get all spaces within a certain distance from a point and also by default connect spaces based on proximity.
The ObjectFilter class now also makes it easier to work with both simple and complex conditions in combination with spaces on a board.
Other improvements
There are a number of other improvements as well.
- There is now a template that comes with the Bot Playtesting Toolkit, significantly shortening the time it takes to actually have a working simulation in place. It has a large number of example code that can be uncommented and remixed to work with a specific game (or just to learn from in general).
- It is now possible to pass any extra arguments to the simulation() function, and these will be sent to the module being used. This allows for quickly switching between different variants of the simulation.
- A Table class has been introduced, to make it easier to print a representation of a game board (or something else) to the log.
The project can, as always, be found at https://github.com/Itangalo/Bot-Playtesting-Toolkit. It is, as always, open source. Feel free to use, study, share and improve.
Recommend0 recommendationsPublished in Prototyping
Responses