Coder Social home page Coder Social logo

microrts's Introduction

Build Status

microRTS is a small implementation of an RTS game, designed to perform AI research. The advantage of using microRTS with respect to using a full-fledged game like Wargus or StarCraft (using BWAPI) is that microRTS is much simpler, and can be used to quickly test theoretical ideas, before moving on to full-fledged RTS games.

By default, microRTS is deterministic and real-time (i.e. players can issue actions simultaneously, and actions are durative). However, it is possible to experiment both with fully-observable and partially-observable games, as well as with deterministic and non-deterministic settings via configuration flags. As part of the implementation, I include a collection of hard-coded, and game-tree search techniques (such as variants of minimax, Monte Carlo search, and Monte Carlo Tree Search).

microRTS was developed by Santiago Ontañón.

MicroRTS-Py will eventually be updated, maintained, and made compliant with the standards of the Farama Foundation (https://farama.org/project_standards). However, this is currently a lower priority than other projects we're working to maintain. If you'd like to contribute to development, you can join our discord server here- https://discord.gg/jfERDCSw.

For a video of how microRTS looks like when a human plays, see a YouTube video

If you are interested in testing your algorithms against other people's, there is an annual microRTS competition. For more information on the competition see the competition website. The previous competitions have been organized at IEEE-CIG2017 and IEEE-CIG2018, and this year it's organized at IEEE-COG2019 (notice the change of name of the conference).

To cite microRTS, please cite this paper:

Santiago Ontañón (2013) The Combinatorial Multi-Armed Bandit Problem and its Application to Real-Time Strategy Games, In AIIDE 2013. pp. 58 - 64.

Setting up microRTS in an IDE

Watch this YouTube video to learn how to acquire microRTS and setup a project using Netbeans.

Reinforcement Learning in microRTS

If you'd like to use reinforcement learning in microRTS please check this project: https://github.com/Farama-Foundation/MicroRTS-Py

Executing microRTS through the terminal

If you want to build and run microRTS from source using the command line, clone or download this repository and run the following commands in the root folder of the project to compile the source code:

Linux or Mac OS:

javac -cp "lib/*:src" -d bin src/rts/MicroRTS.java # to build

Windows:

javac -cp "lib/*;src" -d bin src/rts/MicroRTS.java # to build

Generating a JAR file

You can join all compiled source files and dependencies into a single JAR file, which can be executed on its own. In order to create a JAR file for microRTS:

javac -cp "lib/*:src" -d bin $(find . -name "*.java") # compile source files
cd bin
find ../lib -name "*.jar" | xargs -n 1 jar xvf # extract the contents of the JAR dependencies
jar cvf microrts.jar $(find . -name '*.class' -type f) # create a single JAR file with sources and dependencies

Executing microRTS

To execute microRTS from compiled class files:

java -cp "lib/*:bin" rts.MicroRTS # on Linux/Mac
java -cp "lib/*;bin" rts.MicroRTS # on Windows

To execute microRTS from the JAR file:

java -cp microrts.jar rts.MicroRTS

Which class to execute

microRTS has multiple entry points, and for experimentation purposes you might eventually want to create your own class if none of the base ones suit your needs (see the "tests" folder for examples), but a default one is the gui.frontend.FrontEnd class, which opens the default GUI. To execute microRTS in this way, use the following command:

java -cp microrts.jar gui.frontend.FrontEnd

Another, more expansive entry point is the rts.MicroRTS class. It is capable of starting microRTS in multiple modes, such as in client mode (attempts to connect to a server which will provide commands to a bot), server mode (tries to connect to a client in order to control a bot), run a standalone game and exit or open the default GUI.

The rts.MicroRTS class accepts multiple initialization parameters, either from the command line or from a properties file. A list of all the acceptable command-line arguments can be accessed through the following command:

java -cp microrts.jar rts.MicroRTS -h

An example of a properties file is provided in the resources directory. microRTS can be started using a properties file with the following command:

java -cp microrts.jar rts.MicroRTS -f my_file.properties

Instructions

instructions image

microrts's People

Contributors

acemad avatar andertavares avatar axgdev avatar bastinat0r avatar dennissoemers avatar douglasrizzo avatar fbricon avatar jkterry1 avatar luci-dot-exe avatar marcelo-lemos avatar nbarriga avatar nitzanfarhi avatar pseudo-rnd-thoughts avatar richard-kelly avatar richoux avatar rubensolv avatar santiontanon avatar scheffield avatar vwxyzjn avatar

Stargazers

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

Watchers

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

microrts's Issues

Introduce features from new Java versions into the code base

Java 5 introduced the "foreach" loops, which can replace 28 traditional for loops in microRTS.

Java 7 introduced the diamond operator, which simplifies how objects that take Generics as arguments are instantiated. For example

ArrayList<Integer> l = new ArrayList<Integer>();

can now be created like this:

ArrayList<Integer> l = new ArrayList<>();

There are 274 places where this change can be made in microRTS.

Lastly, Java 8 introduced lambda expressions, which can replace anonymous types 77 times in the code base. An example of that is

Collections.sort(featureIndexes, new Comparator<Integer>() {
    public int compare(Integer o1, Integer o2) {
        return Double.compare(featureGR.get(o2), featureGR.get(o1));
    }            
});

which can be simplified to

Collections.sort(featureIndexes, (o1, o2) -> Double.compare(featureGR.get(o2), featureGR.get(o1)));

The automated tests of microRTS made me realize that the repository already is compatible only with Java 8/9 upwards, so these changes would not break compatibility. Would changes like these be interesting in the master repo of microRTS?

Jaxen library needed for loading bot jar file

When trying to load a jar in the tournament bar, the classloader error is:
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/jaxen/SimpleNamespaceContext

Stuff already tried

  1. Using JDK 8, 9, 12, 11, 19
  2. removing all the code from my bot.

However, if I add jaxen as a dependency for the microrts then it loads my bot without error.
I even tried it with the bare minimum needed to make a random bot:
My bot code

package abid;

import ai.core.AI;
import ai.core.AIWithComputationBudget;
import ai.core.ParameterSpecification;
import java.util.ArrayList;
import java.util.List;
import rts.PlayerActionGenerator;
import rts.PlayerAction;
import rts.GameState;
import rts.units.UnitTypeTable;

public class MyBot extends AIWithComputationBudget {

    UnitTypeTable m_utt;

    public MyBot(UnitTypeTable utt) {
        super(-1, -1);
        m_utt = utt;
    }
    
    @Override
    public void reset() {
    }

    @Override
    public AI clone() {
        return new MyBot(m_utt);
    }
   
    @Override
    public PlayerAction getAction(int player, GameState gs) {
        try {
            if (!gs.canExecuteAnyAction(player)) return new PlayerAction();
            PlayerActionGenerator pag = new PlayerActionGenerator(gs, player);
            return pag.getRandom();
        }catch(Exception e) {
            return new PlayerAction();
        }
    }
    
    @Override
    public List<ParameterSpecification> getParameters()
    {
        return new ArrayList<>();
    }
}

The complete error is as follows:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/jaxen/SimpleNamespaceContext
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:575)
        at java.base/java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:864)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at tournaments.LoadTournamentAIs.loadTournamentAIsFromJAR(LoadTournamentAIs.java:54)
        at gui.frontend.FETournamentPane$2.actionPerformed(FETournamentPane.java:139)
        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
        at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
        at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6632)
        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
        at java.desktop/java.awt.Component.processEvent(Component.java:6397)
        at java.desktop/java.awt.Container.processEvent(Container.java:2263)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5008)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
        at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
        at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
        at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2762)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.lang.ClassNotFoundException: org.jaxen.SimpleNamespaceContext
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 48 more

Compress terrain String representation for socket message

Hi there @santiontanon. Thanks for being so receptive of my contributions. I am trying to apply what I have learned from previous projects into microRTS in hopes to make it better for me and future users and I am really glad you are open to contributions to the project.

Anyway, when I was looking at the JSON representation of a state, I realized that the terrain information is a binary string (composed only of 0s and 1s) which is passed as a large String of size width * height. So, not only are its contents very simple, but it grows quadratically with the size of the map.

I decided to test a simple method to compress a String with those properties. I count the number of consecutive occurrences of a character and append this counter to a String, along with the character itself. Since 0 and 1 may appear inside the counter, 0 is replaced by A and 1 is replaced by B. For example, the string 00000011110000000000 is transformed into A6B4A10.

I think this is especially beneficial, since many maps only have terrains and no walls, so they are fully composed of 0s.

I created functions to make this compression and decompression inside the PhysicalGameState class. I made sure they are reversible (t == uncompressTerrain(compressTerrain(t))).

I also implemented the decompression function in Python and made a successful client-server communication test.

Lastly, I compared two text files with 720 states (saved as JSON) and saw a decrease of 15% in the size of the file that used compressed terrain representations.

{"time":0,"pgs":{"width":16,"height":16,"terrain":"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","players":[{"ID":0, "resources":5},{"ID":1, "resources":5}],"units":[{"type":"Resource", "ID":16, "player":-1, "x":0, "y":0, "resources":25, "hitpoints":1},{"type":"Resource", "ID":17, "player":-1, "x":0, "y":1, "resources":25, "hitpoints":1},{"type":"Resource", "ID":18, "player":-1, "x":15, "y":14, "resources":25, "hitpoints":1},{"type":"Resource", "ID":19, "player":-1, "x":15, "y":15, "resources":25, "hitpoints":1},{"type":"Base", "ID":20, "player":0, "x":2, "y":2, "resources":0, "hitpoints":10},{"type":"Base", "ID":21, "player":1, "x":13, "y":13, "resources":0, "hitpoints":10},{"type":"Worker", "ID":22, "player":0, "x":1, "y":1, "resources":0, "hitpoints":1},{"type":"Worker", "ID":23, "player":1, "x":14, "y":14, "resources":0, "hitpoints":1}]},"actions":[]}
{"time":0,"pgs":{"width":16,"height":16,"terrain":"A256","players":[{"ID":0, "resources":5},{"ID":1, "resources":5}],"units":[{"type":"Resource", "ID":16, "player":-1, "x":0, "y":0, "resources":25, "hitpoints":1},{"type":"Resource", "ID":17, "player":-1, "x":0, "y":1, "resources":25, "hitpoints":1},{"type":"Resource", "ID":18, "player":-1, "x":15, "y":14, "resources":25, "hitpoints":1},{"type":"Resource", "ID":19, "player":-1, "x":15, "y":15, "resources":25, "hitpoints":1},{"type":"Base", "ID":20, "player":0, "x":2, "y":2, "resources":0, "hitpoints":10},{"type":"Base", "ID":21, "player":1, "x":13, "y":13, "resources":0, "hitpoints":10},{"type":"Worker", "ID":22, "player":0, "x":1, "y":1, "resources":0, "hitpoints":1},{"type":"Worker", "ID":23, "player":1, "x":14, "y":14, "resources":0, "hitpoints":1}]},"actions":[]}

I also changed the methods that read XML and JSON to automatically detect if the terrain data is compressed and decompress it as needed.

If you find this interesting, I could create a pull request with this contribution.
I was thinking about adding a property to the config.properties so users can choose whether they want their client/server communication to employ this compression method or not.

Proposal for restructuring the project.

Hey all,

I was wondering if we could move the current project structure to a gradle structure.

  • .idea/
  • src/
    • main/
      • java/
      • resources/
        • maps/
        • config.properties
    • test/
      • java/
      • resources/
  • build.gradle
  • settings.gradle

At the moment to setup the project in Intellij (or another IDE), you need to manually define the project structure (libs, src folder, java version, resource folder).

The above proposal allows the structure to come predefined. Other benefits include

  • Gradle's dependency manager, which will allow us to remove jdom / minimial as an embedded dependency.
  • Unit Testing structure.
  • Resources folder, if you build the current MicroRTS as a Jar, you need to specify the maps folder as a
    resource folder, in which all elements of maps are added to the root of the jar (not in a seperate
    folder). Adding the above resources folder will prevent this.
  • Provides a universal structure for all developers.

The above changes are not backwards compatible as such the major version would need to be incremented.

As well as the above, i also propose the implementation of a main class which is configurable. Configuration could be as below.


### NETWORKING ###
server_address=127.0.0.1
server_port=9898
# If true the environment will be running as a server, false as a client.
server=False
# XML = 1
# JSON = 2
serialization_type=2

# MAP
map_location=16x16/basesWorkers16x16.xml

#### GAME SETTINGS ###

# The max number of cycles the game will perform.
max_cycles=5000

# If false, the players have full vision of the map.
partially_observable=true

# Versions (DEFAULT = 1)
# 1 =  Version one
# 2 = Version two (a fine tune of the original)
# 3 = A non-deterministic version (damages are random)
rules_version=1


# Conflict policies (DEFAULT = 1)
# 1 = A conflict resolution policy where move conflicts cancel both moves
# 2 = A conflict resolution policy where move conflicts are solved randomly
# 3 = A conflict resolution policy where move conflicts are solved by alternating the units trying to move
conflict_policy=1

I have experimented with both proposals and have them working quite well. I'm more then happy to submit two seperate pull request for each proposals so they can be examined.

Note: The above isn't for bots to participate in a tournament, but to provide better infastructure for remote agents running the game locally.

Regards,
Scott.

PhysicalGameStateTest.java depends on junit, which is not included in lib

I noticed that tests.rts.PhysicalGameStateTest depends on junit, which is not included in microRTS. For some reason, when I try to build the project on Intellij, I get an error because of that. I used this JAR to fix the problem.

I don't know if junit should be added to lib or if PhysicalGameStateTest.java should be made to not depend on junit. Since this is the only test class that uses junit, I believe the dependency was never intended to exist.

Implement socket communication via protocol buffers

Hello @santiontanon . You have mentioned to me in another medium that, when communicating to and from MicroRTS using sockets, building and passing XML and JSON messages creates a bottleneck in simulation time.

I have seen a tendency in the community to opt for protocol buffers (protobuf) when communication time is a priority over human-readability.

Basically, you create a .proto text file which dictates the message format, compile it using a tool that generates classes in multiple languages, and use these classes to create interchangeable objects, which can be serialized in byte arrays, for example.

I have found this comparison between JSON and Protobuf which indicates that the later is up to 5x times faster.

I was working through the tutorials and ended up creating a .proto file for a MicroRTS game state and was thinking about testing it sometime soon.

If successful, would there be interest to include something like this into MicroRTS?

syntax = "proto3";

option java_package = "ai.socket.protobuf";
option java_outer_classname = "GameStateProtobuf";

message unit {
  string type = 1;
  int32 ID = 2;
  int32 player = 3;
  int32 x = 4;
  int32 y = 5;
  int32 resources = 6;
  int32 hitpoints = 7;
}

message player {
  int32 ID = 1;
  int32 resources = 2;
}

message PGS {
  int32 width = 1;
  int32 height = 2;
  string terrain = 3;
  repeated player players = 4;
  repeated unit units = 5;
}

message action {
  int32 type = 1;
  int32 parameter = 2;
}

message actions {
  int32 ID = 1;
  int32 time = 2;
  action action = 3;
}

message state {
  int32 time = 1;
  PGS pgs = 2;
  repeated actions actions = 3;
}

Apply some kind of code formatting in the master branch

In PR #54 we talked about formatting the code base according to some kind of standard. Back then, these remarks came up:

reformatted codebase using Google Style Guide (with 4 spaces, not 2) <-- this is ok, but working at Google myself there is one think I dislike about the style we use at Google, which is the 80 character limit in code lines. As long as that constrainted was not enforced, this is fine! (hard to see in the diff online :)

added EditorConfig file to enforce code standard <-- same with this one. Code standards are very personal things. I need some time to see if I can live with this standard

I understand this would be a welcome change in the repo, but I would like to discuss a few things before working on this.

Instead of depending on a specific IDE to format code, I propose using an IDE-independent tool, such as uncrustify. We configure a formatting style in a .cfg file, let people work in the IDE they like the most and, right before pushing to the repo (or to the master branch), use uncrustify to format all files. I've employed similar editor-independent tools, like YAPF or black, in my Python projects with great success.

I think this would be a nice addition to the repo since, regardless of code standard, I've been finding files with multiple blank lines, no spaces around operators or too many spaces and other issues which could be automatically fixed by a tool. If we do this right, we can even create a CONTRIBUTING.md file in the repo, teaching people how to comply to the standard before making a pull request.

I can come up with a style that would be welcome in the repo (large character limit for lines, indentation with 4 spaces), add the .cfg file to the repo and, after that, we can periodically format the code base using uncrustify, keeping everything according to a standard.

People can still use whatever code standard they want while working on their computers, as long as they uncrustify all Java files just before contributing to the repository.

As for viewing the files online, on GitHub. There is a way to configure the online viewer by adding a .editorconfig file in the repo. It only has 6 or 7 options, but not only does it configure some major options for the online viewer, it also helps to configure most code editors (natively or via plugins) so that gross mistakes are not made in the code (enforce LF instead of CRLF at the end of line, use spaces and not tabs as indentation, use UTF-8 encoding on files etc.).

Duplicated ID in map

Hi,

I discovered this by mistake. Suppose you have this simple map:

<rts.PhysicalGameState width="2" height="2">
  <terrain>0000</terrain>
  <players>
    <rts.Player ID="0" resources="0">
    </rts.Player>
    <rts.Player ID="1" resources="0">
    </rts.Player>
  </players>
  <units>
    <rts.units.Unit type="Base" ID="5" player="0" x="1" y="1" resources="0" hitpoints="10" >
    </rts.units.Unit>
    <rts.units.Unit type="Worker" ID="5" player="1" x="0" y="1" resources="0" hitpoints="1" >
    </rts.units.Unit>
  </units>
</rts.PhysicalGameState>

I defined by mistake the BaseID and the WorkerID to be the same and the game loaded it without problem. Then I tried to retrieve a unit by ID and I would get the unit I did not want.

I think the ID of the units should be unique, right? Maybe it would be good to check that a unit is never assigned the ID of another unit. Perhaps it is only the case when the map is loading.

Make GameState extendable

I would like to be able to inherit from GameState to construct a partial view of it for use internally in my bot. Something similar to what the PartiallyObservableGameState class does.

However, some of the internals, are package-private, rather than protected.

This means I would have to put my new class in the same package, which doesn't work if I want to keep my bot in a separate JAR. Would it be possible for you to change some attributes to protected and add a new constructor?

protected PhysicalGameState pgs = null;
protected HashMap<Unit,UnitActionAssignment> unitActions = new LinkedHashMap<Unit,UnitActionAssignment>();



    protected GameState(GameState gs){
    	pgs=gs.getPhysicalGameState().cloneKeepingUnits();
    	utt=gs.getUnitTypeTable();
    	time=gs.getTime();
    	unitCancelationCounter=gs.unitCancelationCounter;
    	unitActions.putAll(gs.unitActions);
    }

Problem with SocketAI

Greetings,

we are using microrts in a small machine learning project that is being programmed in python. We use python-microRTS as socket interface.

When the source code is downloaded and compiled everything works as expected in STANDALONE mode. WorkerRush beats hands down RandomBiasedAI. If we modify the source code a little bit and print the return of function getAction in WorkerRush.java we can see the bot is performing actions like

{ (Base(20)(0, (2,2), 10, 0),produce(up,Worker)) }

which create new workers.

Problems appear in CLIENT mode. We execute the example program random_actions.py. Indeed, the initial worker moves randomly but the base does not produce any additional workers in spite of having enough resources. Inspection of the python program shows that the JSON string.

[{"unitID": 20, "unitAction": {"type": 4, "unitType": "Worker", "parameter": 2}}]

is sent every 50 time steps, which means that the base at least is being busy when ordered to produce a worker. Again printing the return of function getAction on SocketAI.java shows actions like

{ (Base(20)(0, (2,2), 10, 0),produce(up,Worker)) }

which is exactly the same as with WorkerRush but for some reason it is not producing workers.

While it could seem it is a problem with python-microRTS, the python part seems like it is doing its job all right and even getAction in SocketIA.java seems to understand and send the action. So the question is, why these instructions keep the base busy but do not yield workers as expected?

Any help with this issue would be greatly appreciated. Thank you very much in advance for your help.

The equivalents method in PhysicalGameState does not compare terrains

The equivalents(pgs) method in the PhysiscalGameState class is supposed to compare two physical game states and return true if both of them are identical. This method successfully compares :

  • The pgs's width and height
  • Players (count, IDs and resources)
  • Units (count, type, hit points and x,y coordinates)

But what if the terrain is different ? equivalents will return true if all parameters are equal but terrains are different.

  1. Is this a desired behavior ?
  2. If it is not, I suggest adding a terrain comparison to equivalents by comparing a String representation of both terrains, or using Arrays.deepEquals

About the Bayesian method

Hello

Thank you very much for your contribution to our research on real-time strategy games. How can I use the Bayesian method in the package? Is there a related introduction document?

From a graduating postgraduate student for help.

Instructions on creating JAR file

Hi there @santiontanon, happy new year.

Recently, I found myself in need of creating a single microRTS JAR file, so that I could autonomously start microRTS from another script without the need of configuring classpaths. I learned how to do it via the command-line and added it to the README in my fork.

Maybe if I polish the instructions a little more, would that be an acceptable contribution for the upstream repo?

I also thought about gathering these compilation and execution instructions into a wiki page instead of keeping them in the README. What do you think?

support Python

Hi ,
Do you have any plan for supporting python? I think that will be much easy for AI research with machine learning approach, especially deep learning.
Thanks.

Equals method for Unit

Hi!

First of all thanks for the hard work put into this game! It has been very useful for my research

I have faced the problem that if I were to look for example a Unit in a map, there is a lack of an equals method that helps me to find this unit. There are workarounds like using the UnitID, or by using a wrapper class over the Unit that has an equals method, but I think the most ideal solution is to have an equals method directly in the code.

Do you think this makes sense?

Corrupted Traces in Tournament Mode

Trying to view traces generated by tournaments (Both tournaments I've run myself as well as traces from the 2017 competition), in the Traces pane of the FrontEnd GUI causes an error, generally around t=50 when the first workers are finished and issued commands. Viewing the xml file, it appears actions are being saved with invalid unit IDs. For example, see Line 954 of 7-vs-6-7-3.xml of the 2017 competition. There is an action for a downward movement for unit 152027043. This ID does not occur anywhere else in the file.

Running a match with the same settings in tournament mode and the state pane (i.e. 1 iteration, same two (built-in) AI, etc) results in a corrupted trace from the tournament, but a working trace from the state pane.

The RoundRobinTournament constructs traces by cloning the player actions, while FEStatePane just passes pa1 and pa2 rather than cloning. Removing the clone() process from RoundRobinTournament produces uncorrupted traces.

Although, looking at the cloning code for PlayerAction, it's not obvious to me what the root issue is.

Lastly, corruption happens regardless of whether the GC is run before each AI call.

Few issues in getPlayerActionsSingleUnit

The getPlayerActionsSingleUnit method in the GameState class, from what I understood, returns a List<PlayerAction> list containing UnitActions for the provided Unit, that are consistent with the UnitActions in unitActions map. The PlayerActions returned only contain a single UnitAction, but also include the full ResourceUsage of unitActions.

I have identified two slightly confusing issues that can be misleading :

  1. The method expects two arguments, a pID and a unit. But, the pID is not needed anymore, but it's still present. There are only two usages of this method in the codebase, specifically in UCTUnitActionsNode, where it is used for maxplayer and minplayer, whereas, this differentiation doesn't hold much meaning and can be trivially fixed by eliminating the superfluous argument.
  2. A superfluous for loop (2nd one) that loops through a list with a single element that never changes prior to the start of this loop.
    for(PlayerAction pa:l) { // l has only one element, all the time
        l2.addAll(pa.cartesianProduct(unit.getUnitActions(this), unit, this));
    }

Before fixing those issues, I would like to confirm the correctness of such reasoning.

Importing Multiple UTTs

I am doing some research on optimizing AI engagements using units with asymmetric advantages. For example, Zerg are weaker, less expensive, but faster compared against Protoss who are more expensive but more powerful. How difficult would it be to allow the import of two different UTTs, for each player, with different attribute distributions (through the terminal interface and/or GUI)?

SocketAI (JSON) not sending "getAction" request.

Greetings,

An action request is not being sent, I believe this is due to the action socket not being flushed.
The issue seems to be in SocketAI.java, line 158 where the out_pipe.flush() is commented out.

This should be uncommented.

Regards,
Scott.

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.