- Scripts of Tribute Project
- Setup
- Implementing AI Agent
- Tales of Tribute AI Competition
- References
- Legal Notice
Scripts of Tribute (SoT) framework is a Tales of Tribute simulator, implemented in C# .NET Core and allowing to write AI agents and play against them.
IEEE Conference on Games 2024 Tales of Tribute AI Competition has ended.
See the results and all competition data here.
Details regarding 2025 edition will be posted in in the first quarter of the year.
A short video describing the 2023 competition is available HERE (most info remain up-to-date).
To play against the existing bots, download the most recent GUI binary release for your OS.
To start developing your own AI agents, check the documentation in this section and download SoT-Core project.
Dockerfile for competition environment is available here
The paper describing the competition is on arXiv (also accepted at IEEE COG 2024).
Tales of Tribute is a deck-building game that launched with The Elder Scrolls Online High Isle expansion.
As a source of information about the game, we find the following links helpful (some information in the descriptions might be outdated due to the game patches):
- Introducing Tales of Tribute AI Competition, Section IV
- game rules
- list of cards and patrons (up-to-date)
- patron strategies
- deck guides
The current SoT release is compatible with Tales of Tribute from ESO PC/Mac Patch 9.2.10 (25.02.2024) and contains seven patrons (out of 11 currently available in ESO). All patron deck cards are fully upgraded.
Cards data used is available in the cards.json file.
Come to our Discord and talk to us.
Jakub Kowalski, Dominik Budzki, Damian Kowalik, Katarzyna Polak, Radosław Miernik (University of Wrocław, Institute of Computer Science).
As ScriptsOfTribute Engine is based on the .NET framework, we recommend using Windows as a developing platform.
You can download the source code of the SoT engine from this repository.
Any you like. If you choose Visual Studio, make sure that you choose Visual Studio 2022, which supports .NET 7.
Skip this if you've chosen Visual Studio.
To build our engine and create bots with it, you need to install .NET 7 SDK compatible with your operating system. Go to the official page Download .NET 7.0, download, and then install the latest version.
If you are using Linux - here is the link to the tested tutorial; just change the version in commands from 6.0 to 7.0.
You should familiarize yourself with them before implementing a bot.
-
AI.cs - abstract class from which your agent should inherit. You have to implement the
SelectPatron
andPlay
methods. In theEndGame
method, you can add code that should be run after the end of the game, and inLog
method you can add some logs. -
All files in Serializers folder - by using these classes you can gain access to all visible data of the game - board, hand, tavern, etc. You can start with the
GameState
class - the object of this class you get from thePlay
method.
Useful files if you want to get access to some important information (cost of a card, amount of power of the opponent, ...) and types of cards, effects, etc:
This section introduces some objects that are used in the engine and knowing them is important for understanding other sections.
EndGameState
– contains information about how the game ended. It has aReason
field that indicates why the game ended, which can, for example, beTURN_TIMEOUT
orINCORRECT_MOVE
. It also containsID
of the winning player (unless the game ended to a reason such as an internal failure) and a string containing additional context about why the game ended, for example, in case of an incorrect move, it contains the move and a list of all other correct moves that were possible and should have been played instead. API functions often returnEndGameState?
– in most cases it is null, but in case the player makes a mistake or his move ends the game, this object is returned to indicate this.Move
– represents a move that a player can make. It contains aType
field, which can be, for example,PLAY_CARD
,END_TURN
, orACTIVATE_PATRON
. Depending on the type, it also contains additional information, such as the card that is to be played in case ofPLAY_CARD
move. Moves can be created using static methods inMove
class, for example:Move.PlayCard(card)
.Choice
– represents a choice that the player has to make. It can be, for example, a choice of which card to discard. Either cards or effects can be chosen, depending on the card played. This object also contains some information about the choice, including all possible items to choose, how many items need to be chosen, or what the effect of the choice will trigger (for example: destroy the chosen cards).ChoiceContext
– this object lives inside theChoice
and holds additional context, including the card and effect, or the patron that triggered the choice.
-
Create a file in
ScriptsOfTribute-Core\Bots\src
folder e.g.MyFirstAgent.cs.
Please remember that your class (in this case,MyFirstAgent
) should inherit from AI abstract class. -
Implement the body of
SelectPatron
method. Arguments of this method are a list of available patrons and which round of selection of patron it is (first or second). Your method should returnEnum
object of the typePatronId
. -
Implement a body of
Play
method This method will be run in a loop until you don't return a move that will end your turn, or your bot will try to do not allowed move. The method receives aGameState
and a list of possible moves and should return one move from that list. -
[Optional] Implement the body of GameEnd This method is called after the game has ended. The purpose of this function is to allow the programmer to analyze the data from the
EndGameState
object as they wish. -
[Optional] Add logs To add logs to your bot, call the method
Log
with a string that you want to put in your log. Logs can be shown in the GUI during play. -
Compile your bot Just run
dotnet build
inScriptsOfTribute-Core\Bots
folder. ABots.dll
file should be created in the folder - you can use it to test your bot by copying that to theGameRunner
folder, where you can test your bot against our sample bots or your other bots.
There's a possibility to use different language than C# to create a bot thanks to ExternalAIAdadpter. For now engine is built to work with Python files, but enabling other languages is easy. In such cases please contact us.
If you plan to create a bot in different language you have to parse game state from stdin which will come in json format ending with EOT string as an "End of Transmission" sign. Forming this object is done in Game State class in SerializeGameState
method. To understand more how these objects look please check tests. In case of any problem fastest way to get help or any information is through our discord.
Feel free to study our example agents, to familiarize yourself more with the infrastructure of the project. You can also use code from them to create your own code.
Bots whose understanding can help you implement your own agents:
- RandomBot
- MaxPrestigeBot Focus on the usage of
gameState.ApplyMove()
- this function allows you to simulate a move. If you provide a seed, you can simulate a random playout based on that seed. When running this method without a seed you will receiveGameState
and available moves without any random events (like a card that you could draw, a new card in the tavern after buying/removing the card, etc.)
Game Runner is a command-line application that allows the user to load bots from DLLs and run games between them.
Usage: GameRunner <NameOfBot1> <NameOfBot2> <flags>
for example: GameRunner RandomBot RandomBot -n 1000 -t 2
will run 1000 games between two RandomBot
s using two threads
For more flags and usage help, run GameRunner -h
To run game with bot made in different language, for example python use file's full name (main file). For example: GameRunner RandomBot PythonBot.py -n 1000 -t 2
To test your bot, you can also use our application in the Unity framework.
Just download the built version for your operating system and copy .dll
file with your bots into
- for Windows:
ScriptsOfTribute_Data\StreamingAssets
- for Linux:
Linux_Data\StreamingAssets
(also make sure that you makeLinux.x86_64
executable), - for Mac:
Mac.app\Contents\Resources\Data\StreamingAssets
The deckbuilding card game Tales of Tribute is a special activity recently added to the massively popular multiplayer online role-playing video game The Elder Scrolls Online. Although the game remains small by CCG standards (about 120 cards and only a few keywords), it is interesting and challenging for humans, with a significant potential for being a good AI testbed.
The players start with the same base cards and build their decks during the game by buying cards from a shared resource pool called the Tavern (a concept similar to Dominion). Tales of Tributes encourages long-term strategic planning - to ensure the deck we build contains enough strong cards and is not clustered with weak ones. In the meantime, because of a huge randomness factor influencing e.g., which cards occur in the Tavern, it is usually hard to stick with a pre-made plan - so it also requires considerable adaptiveness.
Tales of Tribute AI Competition aims to fill the void after the Hearthstone AI Competition while being significantly more challenging than a toy problem covered by Legends of Code and Magic and the Strategy Card Game AI Competition.
The competition is running using ScriptsOfTribute, an open reimplementation of the original game in .NET framework designed especially for this event. It features the game manager that allows running AI agents implemented as C# classes against each other and a graphical user interface that support human vs. AI games.
Tales of Tribute AI Competition will be back with COG 2025.
The Tales of Tribute AI competition is organized by Jakub Kowalski, Dominik Budzki, Damian Kowalik, Katarzyna Polak, and Radosław Miernik (University of Wrocław, Institute of Computer Science).
Have any questions or suggestions? Feel free to contact us on Discord or send a mail.
Information about the previous Tales of Tribute AI competitions, including submitted agents, can be found here.
The Tales of Tribute AI Competition has been described in this article.
Please cite as follows:
@inproceedings{Kowalski2024IntroducingTales,
author = {Kowalski, J. and Miernik, R. and Polak, K. and Budzki, D. and Kowalik D.},
title = {{Introducing Tales of Tribute AI Competition}},
booktitle = {IEEE Conference on Games},
pages = {1--8},
year = {2024},
}
Initial version of the ScriptsOfTribute has been described in engineer's thesis.
@mastersthesis{Budzki2023ImplementingTalesOfTribute,
title={{Implementing Tales of Tribute as a Programming Game}},
author={Budzki, Dominik and Kowalik, Damian and Polak, Katarzyna},
type={Engineer's Thesis},
year={2023},
school={University of Wroc{\l}aw}
}
This competition is neither directly nor indirectly related to Bethesda Softworks, ZeniMax Online Studios, nor parent company ZeniMax Media, in any way, shape, or form.
It is based on the Scripts of Tribute framework, which mimics the game Tales of Tribute and provides access points for the development of AI agents. The framework does not allow to play the original game, nor does it connect to the game’s servers in any way.
The Elder Scrolls® Online developed by ZeniMax Online Studios LLC, a ZeniMax Media company. ZeniMax, The Elder Scrolls, ESO, Bethesda, Bethesda Softworks and related logos are registered trademarks or trademarks of ZeniMax Media Inc. in the US and/or other countries. All Rights Reserved.