PogamutUT2004


Multiple Servers in 3.2

I have some code that more-or-less worked in previous versions of Pogamut to launch multiple servers on the same machine for the purpose of evolution. Each server used its own ports, had its own bots, etc.

After upgrading to 3.2, when I run this code I encounter errors like the following:
java.lang.IllegalAccessException: Class cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.ItemDescriptor can not access a member of class cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.WeaponDescriptor with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.reflect.Field.doSecurityCheck(Field.java:960)
at java.lang.reflect.Field.getFieldAccessor(Field.java:896)
at java.lang.reflect.Field.set(Field.java:657)
at cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.ItemDescriptor.doReflexion(ItemDescriptor.java:87)
at cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.WeaponDescriptorFactory.getNewDescriptor(WeaponDescriptorFactory.java:22)
at cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.ItemTranslator.createDescriptor(ItemTranslator.java:108)
at cz.cuni.amis.pogamut.ut2004.communication.translator.server.state.ItemCategoryState.innerStateSymbol(ItemCategoryState.java:56)
at cz.cuni.amis.pogamut.ut2004.communication.translator.server.state.ItemCategoryState.innerStateSymbol(ItemCategoryState.java:22)
at cz.cuni.amis.pogamut.ut2004.communication.translator.server.support.AbstractServerFSMState.stateSymbol(AbstractServerFSMState.java:27)
at cz.cuni.amis.pogamut.ut2004.communication.translator.server.support.AbstractServerFSMState.stateSymbol(AbstractServerFSMState.java:17)
at cz.cuni.amis.fsm.FSM$StateWrapper.stateSymbol(FSM.java:181)
at cz.cuni.amis.fsm.FSM$StateWrapper.pushSymbol(FSM.java:187)
at cz.cuni.amis.fsm.FSM.push(FSM.java:361)
at cz.cuni.amis.pogamut.ut2004.communication.translator.server.ServerFSM.processMessage(ServerFSM.java:38)
at cz.cuni.amis.pogamut.base.communication.translator.impl.WorldMessageTranslator.processMessage(WorldMessageTranslator.java:102)
at cz.cuni.amis.pogamut.base.communication.translator.impl.WorldMessageTranslator.getEvent(WorldMessageTranslator.java:123)
at cz.cuni.amis.pogamut.base.communication.mediator.impl.Mediator$Worker.run(Mediator.java:299)

I'm pretty sure I might have had this problem in 3.1 as well, but I did a hack solution and basically edited your source so that the relevant fields were public instead of private. However, I would rather fix the problem properly this time. Is information inadvertently being shared between servers?

By the way, I also tried a small test using your new DeathMatch1vNative example code. I basically modified it to launch two instances of UT2004DeathMatch in separate Threads, and I received the same error.

Lastly, I'm interested to know if there is any more intelligent way to launch multiple servers on the same machine. If there is good clean code in the new version, I would prefer to use it. Even if the code is sloppy, just looking at it might give me some ideas on how to improve mine.
Hi!

This is very unfortunate - which Java are you using + are you launching JVM in server mode?
The trick is that we're doing
configField.setAccessible(true);
descField.setAccessible(true);
descField.set(this, configField.get(configMsg));
configField.setAccessible(false);
descField.setAccessible(false);


So even though the field is private it should be accessible for setting. Even more that bots are using the very same code as does UT2004 servers.

I'll try to put "sychronized(desc/configField)" blocks where, may be JVM is playing dirty tricks with us and multithreading is
smacking our face back as we're interleaving setAccessible true/false.

I'll try to push Pogamut 3.2.2 this night so you would be able to test that right away.

Regarding multi-server on one machine. I would suggest you to "multi-copy" your UT2004 folder and execute the UT2004 from different location.
Because last time we were using it 1 from 10 server has failed to execute leaving no trace behind what could possibly be the reason.

Also I'm not encouraging using more than one UT2004DeathMatch instance at a time. Won't be ok in long run.

Best,
Jimmy
I'm running jdk1.6.0_18, and I don't know what server mode is. How does that affect things?
I do all the port management manually in my code.

By the way, where does that sample code need to be placed? And do I need to do it just once, or once per server?

Regarding 3.2.2, what is the easiest way (using Maven) to pull down the latest code (as opposed to a SNAPSHOT) into an existing project?

> I have some code that more-or-less worked in previous versions of Pogamut to launch multiple servers on the same machine for the purpose of evolution. Each server used its own ports, had its own bots, etc.
>
> After upgrading to 3.2, when I run this code I encounter errors like the following:
> java.lang.IllegalAccessException: Class cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.ItemDescriptor can not access a member of class cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.WeaponDescriptor with modifiers "private"
> at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
> at java.lang.reflect.Field.doSecurityCheck(Field.java:960)
> at java.lang.reflect.Field.getFieldAccessor(Field.java:896)
> at java.lang.reflect.Field.set(Field.java:657)
> at cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.ItemDescriptor.doReflexion(ItemDescriptor.java:87)
> at cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.WeaponDescriptorFactory.getNewDescriptor(WeaponDescriptorFactory.java:22)
> at cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.ItemTranslator.createDescriptor(ItemTranslator.java:108)
> at cz.cuni.amis.pogamut.ut2004.communication.translator.server.state.ItemCategoryState.innerStateSymbol(ItemCategoryState.java:56)
> at cz.cuni.amis.pogamut.ut2004.communication.translator.server.state.ItemCategoryState.innerStateSymbol(ItemCategoryState.java:22)
> at cz.cuni.amis.pogamut.ut2004.communication.translator.server.support.AbstractServerFSMState.stateSymbol(AbstractServerFSMState.java:27)
> at cz.cuni.amis.pogamut.ut2004.communication.translator.server.support.AbstractServerFSMState.stateSymbol(AbstractServerFSMState.java:17)
> at cz.cuni.amis.fsm.FSM$StateWrapper.stateSymbol(FSM.java:181)
> at cz.cuni.amis.fsm.FSM$StateWrapper.pushSymbol(FSM.java:187)
> at cz.cuni.amis.fsm.FSM.push(FSM.java:361)
> at cz.cuni.amis.pogamut.ut2004.communication.translator.server.ServerFSM.processMessage(ServerFSM.java:38)
> at cz.cuni.amis.pogamut.base.communication.translator.impl.WorldMessageTranslator.processMessage(WorldMessageTranslator.java:102)
> at cz.cuni.amis.pogamut.base.communication.translator.impl.WorldMessageTranslator.getEvent(WorldMessageTranslator.java:123)
> at cz.cuni.amis.pogamut.base.communication.mediator.impl.Mediator$Worker.run(Mediator.java:299)
>
> I'm pretty sure I might have had this problem in 3.1 as well, but I did a hack solution and basically edited your source so that the relevant fields were public instead of private. However, I would rather fix the problem properly this time. Is information inadvertently being shared between servers?
>
> By the way, I also tried a small test using your new DeathMatch1vNative example code. I basically modified it to launch two instances of UT2004DeathMatch in separate Threads, and I received the same error.
>
> Lastly, I'm interested to know if there is any more intelligent way to launch multiple servers on the same machine. If there is good clean code in the new version, I would prefer to use it. Even if the code is sloppy, just looking at it might give me some ideas on how to improve mine.
>> I'm running jdk1.6.0_18, and I don't know what server mode is. How does that affect things?

Don't know I was just curious :-)

>> I do all the port management manually in my code.
>> By the way, where does that sample code need to be placed? And do I need to do it just once, or once per server?

What do you mean? The sample project can be anywhere on your disk, you may configure every instance of UT2004DeathMatch separately.
You may also launch many UT2004DeathMatch instances in parallel in one JVM as long as each one of them will use its own installation of UT2004
(which is effecrtivelly achieved by copying UT2004 folder elsewhere)

>> Regarding 3.2.2, what is the easiest way (using Maven) to pull down the latest code (as opposed to a SNAPSHOT) into an existing project?
You just delete -SNAPSHOT from the pom.xml file and Maven will download them on its own. Once they are downloaded in your local repository, you can extract .jar files manually for instance from the xxx.one-jar.jar of your project (pogamut-ut2004-bot-pom parent contains configuration for one-jar plugin that will create a runnable jar for you packing Pogamut libs together)

Best,
Jimmy
Thanks for the help with pom.xml. Maven is new to me, but I'm learning. Version 3.2.2 seems to have fixed the problem with accessing ItemDescriptor fields, so I guess making things synchronized was all that was needed. That makes sense too. I'm dealing with some other issues now, but I'll probably put those in another post, unless I figure them out.

Regarding the UT2004DeathMatch class: How do I configure the ports with this class? In my code, I was modifying the "ucc.exe" ProcessBuilder to add the port configurations as command line options, but in order to do that with UT2004DeathMatch I'd need to mess around with your source code, which I'd prefer not to do. I need to be able to configure the ports if I'm going to launch multiple servers on one machine, even if the game directory is copied. Or does UT2004DeathMatch automatically configure the ports?

Lastly, does UT2004DeathMatch modify my INI files somehow? Also regarding INI files, could you make it easier to specify the location of the INI file? Currently I get an error unless I move it to a very specific directory within the resources dir of the project.
>>Thanks for the help with pom.xml. Maven is new to me, but I'm learning. Version 3.2.2 seems to have fixed the problem with accessing ItemDescriptor fields, so I guess making things synchronized was
>> all that was needed. That makes sense too. I'm dealing with some other issues now, but I'll probably put those in another post, unless I figure them out.

You're welcome!

>> Regarding the UT2004DeathMatch class: How do I configure the ports with this class? In my code, I was modifying the "ucc.exe" ProcessBuilder to add the port configurations as command line options,
>> but in order to do that with UT2004DeathMatch I'd need to mess around with your source code, which I'd prefer not to do. I need to be able to configure the ports if I'm going to launch multiple servers on
>> one machine, even if the game directory is copied. Or does UT2004DeathMatch automatically configure the ports?

There is no need to. UT2004DeathMatch class will launch ucc.exe on its own utilizing UCCWrapper telling GB2004 to start on randomized ports automatically propagating these ports to bots. It will work as long as you won't interfere with the way how UT2004BotRunner is working, i.e., you must not provide your custom ports to bots inside your JAR. That is, we're using java.exe -D switch to propagate pogamut.ut2004.bot.port value right into UT2004BotRunner, of course UT2004DeathMatch class is written that you have to run java.exe with this class on the very same computer as ucc.exe.

If it's still confusing, I'll try to desribe it better, just ask :-)

>> Lastly, does UT2004DeathMatch modify my INI files somehow? Also regarding INI files, could you make it easier to specify the location of the INI file? Currently I get an error unless I move it to a very
>> specific directory within the resources dir of the project.

UT2004DeathMatch writes INI of its own - there is GameBots2004Ini class that takes as default a file from a crude location as you're saying. But basicly you may instantiate GameBots2004Ini class on your own, providing your own details and put it right into the UT2004DeathMatchConfig via its setGb2004Ini method, note that GameBots2004Ini class contains a contructor where you may pass your own GameBots2004.ini as defults and then it allows you to alter it to your liking.

....

Theoretically it should work, never tested though :-)

Best,
Jimmy
Last thing, yes UT2004DeathMatch class will overwrite your GameBots2004.ini file inside UT2004 installation (backing up original file, restoring it when it finishes).

Cheers!
Jimmy
Thanks again for all the help. Now, more questions/observations:

Although GameBots2004Ini has a constructor that takes a file as input, the UT2004MatchConfig class has the line:
protected GameBots2004Ini gb2004Ini = new GameBots2004Ini();
This is outside of the constructor, which means that even if I want to pass in my own INI, the one in the "resources" dir still has to exist, which is slightly annoying.

But I can deal with that. What I really want to ask is this:
Since I'm evolving, I need to be able to run the same bot over and over, but with a different controller each time (in my case, a neural network). My bot already supports command line options to load a controller from an xml file, but I haven't noticed a way yet to pass command line arguments to the bot being executed via its jar file.

Furthermore, even though having command line arguments to the bot jar file would be sufficient, the idea of needing to output a file for each controller/network before I even evaluate it is kind of annoying. I suppose it makes things run a lot smoother to have the bot completely encapsulated within its own jar (that way it doesn't interfere with anything Pogamut is doing), but it would be nice to simply launch the bot by calling some method from the source rather than having the bot loaded from the jar.

One last question: The DeathMatch1vNative example is currently set up to output a bunch of data to some directory. For evolution, instead of doing that, I would want to grab the data from within the code and use it to compute fitness values. I'm guessing things like AgentStats are not accessible, since that class is encapsulated within the bot, and within its jar. What's the best way to access the results of a UT2004DeathMatch?
Hi!

That GameBots2004.ini you're talking about is packed inside UT2004Tournament project jar, so there is no need for you to pack it manually as it should be loaded right from the tournament jar? **puzzled** Or it is not working this way for you?

Yeah, that's true, customization of every bot is not implemented yet. Would it suffice to add "pass specific -D params to this instance of bot" ? I.e., you will be able to specify PARAM_NAME=VALUE per bot instance?

AgentStats are now part of every bot ... check this.stats within your bot class (if it extends UT2004BotModuleController), if it does not, you can instantiate AgentStats for yourself.

Jimmy
>That GameBots2004.ini you're talking about is packed inside UT2004Tournament project jar, so there is no need for you to >pack it manually as it should be loaded right from the tournament jar? **puzzled** Or it is not working this way for you?

I was working exclusively from the 05-deathmatch-1vnative artifact, which didn't include the INI. I was able to figure out that it was necessary by looking at the source, and I just copied my own to the right location. By the way, UT2004DeathMatch doesn't seem to completely restore the original INI file when I use it. My port configuration is messed up every time after I run 05-deathmatch-1vnative.

>Yeah, that's true, customization of every bot is not implemented yet. Would it suffice to add "pass specific -D params to this >instance of bot" ? I.e., you will be able to specify PARAM_NAME=VALUE per bot instance?

This might work. If I go this route, I'll tell you how it works.

>AgentStats are now part of every bot ... check this.stats within your bot class (if it extends UT2004BotModuleController), if it >does not, you can instantiate AgentStats for yourself.

I know that AgentStats is in every bot, but can I access it if I use UT2004DeathMatch to launch the bot from a jar file? I would assume that in this case the JVM just treats the bot as a blackbox process.
Inside UT2004DeathMatch you can access observers which are attached to every bot. Search the code for "UT2004Analyzer".

In the end of the match, the object UT2004DeathMatchResult is created and filled up that also contains

private Map botObservers = new HashMap();


Which can be obtained via: getBotObservers()

Every such observer contains method: getStats() which returns AgentStats for particular agent.

Notice that NATIVE bots are not observed! This can't be supported by UT2004 unfortunately.


Regarding 05-deathmatch-1vnative it seems its not working as anticipated if it is failing. I will try to check it out and fix.

Best,
Jimmy
 

News

News RSS RSS feed for News link



Pogamut

Quarterly RSS RSS feed for quarterly reports

Acknowledgement

This work is supported by GA UK 1053/2007/A-INF/MFF (2007-8), GA UK 351/2006/A-INF/MFF (2006-8), the Ministry of Education of the Czech Republic (grant MSM0021620838) (2008-9), by the Program "Information Society" under project 1ET100300517 (2006-9), and the project Integration of IT Tools into Education of Humanities (2006-8) and by the project CZ.2.17/3.1.00/31162, which are financed by the European Social Fund, the state budget of the Czech Republic, and by the budget of Municipal House Prague.