Giter VIP home page Giter VIP logo

aoe2-ai-module's Introduction

AoE2 AI Module

Branch Build Build Documentation
main Build Build Documentation
dev Build Build Documentation

Introduction

This project is aimed at extending the possibilities of AI scripting in Age of Empires 2 beyond the built-in rule-based system. This is mainly accomplished by exposing the fact and action functions that the game uses internally to an outside scripting environment chosen by the user.

The AI module consists of a DLL file that has to be loaded into the Age of Empires process, after which it starts a gRPC server on port 37412 by default. Available gRPC definitions can be seen in the protos folder and in the project's wiki. These can be used from virtually any scripting environment the gRPC framework is available on. A Python example has been provided in the client_python folder.

At the moment the 32-bit version of the module supports AoC with Userpatch 1.5 and the 64-bit one supports builds 43210 and higher.

Note that this library is still under development and is not an easy to use solution just yet. There may be bugs, unsupported functionality and the release binaries might not always be up to date.

Compiling

  • Clone this repository.
  • Install Microsoft Visual Studio 2019 with support for "Desktop development with C++" component.
  • Install Microsoft vcpkg package manager (https://github.com/microsoft/vcpkg#quick-start-windows). By default the build scripts assume that it is installed in aoe2-ai-module/vcpkg, where aoe2-ai-module is the top level directory of this repository.
  • Install necessary C++ libraries with the command .\vcpkg\vcpkg install --recurse @.\aimodule\vcpkg_dependencies.txt --clean-after-build.
  • Run .\protos\make-protos.bat to convert .proto files in the protos directory to useful C++ and Python includes into folders aimodule/protos and client_python/protos respectively. Edit paths in .\protos\make-protos.bat if using a different directory structure.
  • Open aimodule/aimodule.sln with Visual Studio.
  • Build an x86 (for AoC) or x64 (for DE) Release build for the aimodule project.
  • DLLs will be available in aimodule/Release/aimodule.dll and aimodule/x64/Release/aimodule.dll respectively.

There are also automated builds by GitHub Actions available under the Releases section.

Dependencies

  • gRPC C++ framework
  • Google Protocol Buffers
  • Microsoft Detours
  • Zydis

Known issues

  • DE: The module can trip the anti-tampering mechanism and/or crash the game sometimes.

Disclaimer

  • This library interfaces with Age of Empires 2: Definitive Edition in ways that are not officially supported by the developers of the game. While the authors of this library try to minimize its impact on the normal operation of the game, it cannot be guaranteed due to the nature of the design. It is therefore recommendeed to use this software only in offline mode in local single player matches. The authors of this library do not provide any kind of warranty nor take liability for the consequences of (mis)using this software. See the license document for further details.

aoe2-ai-module's People

Contributors

flwl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aoe2-ai-module's Issues

Error in auth_context.h when trying to build

Hi!
Tried to build the code, although I get an error in this line (line 38):
class AuthPropertyIterator
: public std::iterator<std::input_iterator_tag, const AuthProperty> {

the full error is this:
Error C4996 'std::iterator<std::input_iterator_tag,const grpc::AuthProperty,ptrdiff_t,const grpc::AuthProperty *,const grpc::AuthProperty &>': warning STL4015: The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. (The header is NOT deprecated.) The C++ Standard has never required user-defined iterators to derive from std::iterator. To fix this warning, stop deriving from std::iterator and start providing publicly accessible typedefs named iterator_category, value_type, difference_type, pointer, and reference. Note that value_type is required to be non-const, even for constant iterators. You can define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.

Basically I need to define _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS in one of the file before I include anything else to make VS ignore the error, however I don't know in which file I should do this, as I tried to define it in multiple files, to no avail.
PS: I use Visual Studio 2019

Missing documentation for facts and actions

Currently most facts, actions and their parameters are undocumented in the proto files. Adding documentation there would automatically carry over to the project's Wiki, creating a helpful reference, especially for more obscure functions.

Remove/change the current anti-cheating protection

The current anti-cheating protection, where the server keeps track of which application tries to access commands for which player, is ineffective at its goal and leads to issues. It is ineffective because it doesn't stop players from controlling other players' units or getting their information, the underlying scripting system already allows for such exploits (we just recently had such a case in the scripters tournament). The protection mechanism is however giving issues in the following use-cases:

  • When the user plays a game with one AI and then wants to play a game with another AI then the second AI doesn't work because it gets locked out by the server which is still looking for the first AI. I ran into this when trying to test both a debug and a release build of my AI.

  • A casting bot doesn't work. Specifically I was thinking of a bot which reads the game state of all players and controls the camera for casting. So it doesn't actually play the game, it doesn't make any changes to the game state, it just reads the game state for all players for camera control. This would also fail against the server's anti-cheating protection.

  • It makes the user interface for AI's clunky and error-prone. Specifically the user has to manually start and stop the AI's in their own user interface each game and make sure to do this correctly. A better way to do this would be to just have the AI listen to all 8 players (getting their goal/sn values), for the AI to set a particular goal/sn to a specific identifier value inside its .per file, and then take & release control of a player depending on whether the identifier is set or not.

I think it would be best to just remove the current anti-cheating protection since it's ineffective anyway. If an anti-cheating system is created it must be implemented at the command level (for example up-add-object-by-id should fail to add a non-player unit to the local - ie controlled - unit list, there are plenty more examples of this).

GetGoals() and GetStrategicNumbers() for other players

It would be useful to have GetGoals(int player) and GetStrategicNumbers(int player) commands which return the goal/sn arrays for allied players. The underlying facts would be up-allied-goal and up-allied-sn. In the current situation with 3 allies it takes about 3000 commands (512 goals + 512 sn's per ally) per tick, or about 3ms per tick, which can be brought down to 6 commands and negligible time per tick through the proposed additions. If the given player is not an ally then return an array of 512 -1's (the up facts should also return -1 in that case).

Return time spent in CommandResultList

Add a ´ms´ property to CommandResultList which contains the number of milliseconds spent on the command list. Basically the same as the output in the debug window. This would be useful for finding performance bottlenecks.

AoC support

This issue is to track AoC support as a possible feature. Due to the way the module is built, it should be fairly straightforward to implement, at least for the Expert subsystem.

Document obscure AI commands

A few AI commands are more uncommon and obscure, which is why there is no information on them. They also might be missing one or more parameter names.

Actions:
up-testharness-test
up-testharness-report
fe-break-point
skybox-clear-signal
skybox-set-name-mode
up-chat-data-to-all-using-id
up-chat-data-to-player-using-id
up-get-treaty-data

Facts:
fe-can-build-at-point
players-achievements
trace-fact

Add a way to resolve constants

It would be helpful to be able to resolve constants such as "villager" or "siege-workshop" to their numeric IDs from the client application. There is currently a function stub for that in Expert API subsystem but it is unimplemented.

Functions

Hi, tried to figure out how to get the fact.CcPlayersBuildingCount(playerNumber=1) command working (built houses around the enemy tc), but I got a value of 0 as a result. In the unpack_result(result_list.results[NUMBER], fact.GoalResult).result command, I only havee to change the NUMBER value to get different results, or do I have to change other thing as well, depending on what I'm checking for (vills, military, etc.)?

Another thing that puzzles me is how to change the parameters of the action.UpGetFact function to check what the AI has. I tried to look at the code and figure out which parameters does what, and what attributes do the return values have, but it left me as confused as I was when I started.

grpc not connecting?

Hi, I'm new to this grpc, proto stuff, so I don't know how difficult or easy my problem is, but here it is. I tried to test the client_python file to see if I can get data out of the game (or from a recorded game), when I encountered this bug, not sure what causes it / how to solve it:
image

My steam was in offline state, and I had a singleplayer skirmish playing in DE with 2 bots + me. I think it happens before the 5 second timeout.

Positional arguments?

Hi! I'm trying to figure out how to get villagers to gather resources and I treid using a couple of commands that resulted in the same error:
TypeError: init() takes 1 positional argument but 3 were given

The commands I tried to use were:
action.UpRetaskGatherers()
action.UpFilterStatus()
action.UpFindResource()

Are these commands not implemented yet, or did I make a mistake somewhere?

I checked the airef website for commanding villagers to gather resources, but didn't find one that seemed promising. Is it complicated to control villagers or did I just overlooked a command?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.