Hooks for AI integration

I’ve written a bunch of AIs for board games (games with AI) and they have pretty spartan interfaces. Does VASSAL have any way to communicate with another program sending information about the board and sending changes back? My framework is written in C++ so integrating it somehow as a module would be challenging given VASSAL is in Java.

Just wondering if anyone else has done something like this or has any info related.

Vassal has, unfortunately for what you want to do, a data format that grew out of a UI. The sort of immediate access to properties of things in the game state that you’d want for AI is just not there in V3. Supposing that you had a way for your program to access the game state, you’d find that you also wouldn’t have any generic way to tell whether it’s your turn, how to manipulate the game state, etc. You could modify individual modules to have, say, a button that signaled to the AI that it could go, but you’d have to do this on a module-by-module basis; there’s no general way to handle it. You’d be stuck writing code to handle each module individually.

The above applies to V3 only, however. We’re just at the beginning of redesigning for V4. One of our goals is to have a sensible data format handled by a backend that’s not coupled to our purpose-built UI. I’d be interested to hear what your desiderata are for a format your AI programs would be consuming.

Ah Ludii would be good to look at for that. It does allow you to design your own third-party AIs. That said its in-house one is pathetic.

Also I believe the Ludii API for AI may have a design flaw. It seems not to hide information from an AI player that that player should not have.

There is a bit of history here though. Ludii is somewhat inspired by an older system called “Zillions of Games”, that did have a really good AI. But Zillions of Games had the advantage of working only with combinatorial games where game states can be coded in efficient ways and brute force analysis was possible.

My framework is geared towards complex board/card games (although I have implemented 2 abstract type games too).

The output of my framework is literally a list of all the options the player can take. The input is then the choice out of those options. The engine generates all legal moves based on the current game state and user choice. That’s the super duper simple way it works. It does support network play, replay files, and all kinds of other stuff, but at its core that’s all it is. It generates what is legal, and the human player chooses an action. The AI does the same, but those choices can go through different algorithms, like minmax w/ ab pruning, monte carlo, etc. This is all internal to the framework.

The only interactions outside of the program is getting human player input, and sending game state for updating any UI present.

When I add a UI on top, there’s a very small interface for sending the actions and game state (for viewing the board, etc) and getting the user’s input. In some games the UI I have allows for interacting with the board w/ a mouse, etc. For example, if a human player moves a piece on the board, I can check that move against the list of actions available and choose it. In some cases, that isn’t possible so the list of actions is also presented (actually it is always presented, but can be bypassed by interacting with the board in these cases).

My age of steam implementation has a very spartan UI. Just shows the actions taken, current actions for the human player and a few key pieces of game state for the player. To view track, goods table, etc function keys bring up those.

My dreamblade implementation (think Magic the Gathering meets chess) has a much more elaborate UI in addition to a text based on. This is the text based interface:

console Dreamblade

This one is written in wxWidgets, and where if you drag a piece it will select the appropriate action. The actions aren’t shown in this picture, but they would be right under the “game has ended” text. The above part is the information statements that are also present in the Age of Steam pic above.

wxWidgets Dreamblade

This particular interface is quite clean and has worked for the many games I have implemented.

So, for my needs, I’d like to see a way to communicate with another program (or somehow link it in) from VASSAL to get the game state and actions and then to send back an action chosen. A way to utilize the game state within VASSAL to update the board, and other parts of the game would be needed as well.

Does this make sense? I’ve never had to explain how my stuff works. :slight_smile:

How do you handle games that have thousands of legal moves in the current game state?

Thankfully, the games I’ve implemented don’t get into the thousands, but they do get into the few hundreds in a few cases, this is somewhat rare though. My implementation of Band of Brothers has this issue as there are so many options for movement, unit selection etc. Same for Hold the Line (although not as bad). If integrated into something like Vassal, the goal would be to avoid showing the actions unless absolutely necessary and allow interacting with the game components or widgets would cover it instead.

In the above screenshot for Age of Steam you can see some of that. The values in brackets show that information (The [1:2:number] after the message). The first number is the index of the action taken, the 2nd number is the total number of actions, the third is the random seed value for this action. This is a case of filtering as the AI could take 10 shares if they wanted to. I limit it to 2 early in the game to cut down on options.

The way I deal with that is for the human player with the console based UI, pressing certain keys filters based on the type of action. e.g. for Band of Brothers, can filter on move, fire, mark op fire, etc. The actions are also sorted on specific values to make it easier (for instance unit id, then sort on destination hex, etc).

The AI actions are sometimes pruned before evaluation based on some basic logic or even just random select to give a more human feel.

If there is a UI component mapping to the action, the presentation of that many actions can be mitigated by interaction with the board as I mentioned I do for Dreamblade.

There is one exception, and that is my implementation of Feudal (a chess like game). The user inputs manually the move they want to make, and that is verified, and then mapped to an action generated and is executed. This is due to, as you mentioned, the volume of options available. In something like VASSAL, dragging a piece would accomplish this. Only other type of action here is the Archer shooting.

feudal

I not sure this is a design flaw. Computer game AI’s reached sentience years ago, but all they’ve managed to achieve so far is cheating at Civilization :wink:

1 Like

I think it is definitely a design flaw if you are building a generic AI, and your AI does not in anyway take account of what it has a right to know. We are talking here about an product that is geared towards abstract games.

It may be a more acceptable compromise if you are building a more commercial non-abstract AI especially if you are struggling with limited hardware and your primary goal is creating an engaging experience for the player.

It’s not a design flaw. The onus is on the writer of the AI not to cheat. Putting that restriction on the AI designer instead of building it into the language lets them make the language much simpler.