Can AI Players without Capitals Purchase/Place Units?



  • I am trying to build a scenario on the random start delegate, which assigns territories to players randomly. Naturally, I do not want to have capitals in this scenario, so I set optional="true" for each player. However, they were then unable to purchase or place units. I then found that I could set "retainCapitalProduceNumber" to zero to allow unit purchasing/placing without a capital. This allows a human player to purchase/place units, but whenever an AI player attempts to, the game crashes. I get the following error in the console:

    TripleA engine version 1.9.0.0.9687
    Loading map: the_grand_war, from: C:\Users\Justin\Documents\triplea\downloadedMaps\the_grand_war\map
    Loading resources from the following paths: [C:\Users\Justin\Documents\triplea\downloadedMaps\the_grand_war\map, C:\Users\Justin\Documents\TripleA\assets]
    Loading map: the_grand_war, from: C:\Users\Justin\Documents\triplea\downloadedMaps\the_grand_war\map
    Loading resources from the following paths: [C:\Users\Justin\Documents\triplea\downloadedMaps\the_grand_war\map, C:\Users\Justin\Documents\TripleA\assets]
    Error: java.lang.NullPointerException
    java.lang.NullPointerException
    	at games.strategy.triplea.delegate.AbstractPlaceDelegate.getAllProducers(AbstractPlaceDelegate.java:697)
    	at games.strategy.triplea.delegate.AbstractPlaceDelegate.canProduce(AbstractPlaceDelegate.java:559)
    	at games.strategy.triplea.delegate.AbstractPlaceDelegate.getPlaceableUnits(AbstractPlaceDelegate.java:179)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at games.strategy.engine.delegate.DelegateExecutionManager$1.invoke(DelegateExecutionManager.java:129)
    	at com.sun.proxy.$Proxy9.getPlaceableUnits(Unknown Source)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at games.strategy.engine.message.unifiedmessenger.EndPoint.invokeSingle(EndPoint.java:157)
    	at games.strategy.engine.message.unifiedmessenger.EndPoint.invokeMultiple(EndPoint.java:140)
    	at games.strategy.engine.message.unifiedmessenger.EndPoint.invokeLocal(EndPoint.java:126)
    	at games.strategy.engine.message.unifiedmessenger.UnifiedMessenger.invokeAndWait(UnifiedMessenger.java:105)
    	at games.strategy.engine.message.UnifiedInvocationHandler.invoke(UnifiedInvocationHandler.java:52)
    	at com.sun.proxy.$Proxy9.getPlaceableUnits(Unknown Source)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at games.strategy.engine.gamePlayer.DefaultPlayerBridge$GameOverInvocationHandler.invoke(DefaultPlayerBridge.java:151)
    	at com.sun.proxy.$Proxy9.getPlaceableUnits(Unknown Source)
    	at games.strategy.triplea.ai.weak.WeakAi.placeAllWeCanOn(WeakAi.java:1004)
    	at games.strategy.triplea.ai.weak.WeakAi.place(WeakAi.java:989)
    	at games.strategy.triplea.ai.AbstractAi.start(AbstractAi.java:480)
    	at games.strategy.engine.framework.ServerGame.waitForPlayerToFinishStep(ServerGame.java:515)
    	at games.strategy.engine.framework.ServerGame.runStep(ServerGame.java:404)
    	at games.strategy.engine.framework.ServerGame.startGame(ServerGame.java:263)
    	at games.strategy.engine.framework.startup.launcher.LocalLauncher.launchInNewThread(LocalLauncher.java:58)
    	at games.strategy.engine.framework.startup.launcher.AbstractLauncher.lambda$launch$0(AbstractLauncher.java:51)
    	at java.lang.Thread.run(Unknown Source)
    	at games.strategy.engine.message.UnifiedInvocationHandler.invoke(UnifiedInvocationHandler.java:64)
    	at com.sun.proxy.$Proxy9.getPlaceableUnits(Unknown Source)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at games.strategy.engine.gamePlayer.DefaultPlayerBridge$GameOverInvocationHandler.invoke(DefaultPlayerBridge.java:151)
    	at com.sun.proxy.$Proxy9.getPlaceableUnits(Unknown Source)
    	at games.strategy.triplea.ai.weak.WeakAi.placeAllWeCanOn(WeakAi.java:1004)
    	at games.strategy.triplea.ai.weak.WeakAi.place(WeakAi.java:989)
    	at games.strategy.triplea.ai.AbstractAi.start(AbstractAi.java:480)
    	at games.strategy.engine.framework.ServerGame.waitForPlayerToFinishStep(ServerGame.java:515)
    	at games.strategy.engine.framework.ServerGame.runStep(ServerGame.java:404)
    	at games.strategy.engine.framework.ServerGame.startGame(ServerGame.java:263)
    	at games.strategy.engine.framework.startup.launcher.LocalLauncher.launchInNewThread(LocalLauncher.java:58)
    	at games.strategy.engine.framework.startup.launcher.AbstractLauncher.lambda$launch$0(AbstractLauncher.java:51)
    	at java.lang.Thread.run(Unknown Source)
    


  • @elreigh
    Without more information it hard to figure out what might be causing this error, but I will try to help you. In your 'playerAttachment' you have set 'retainCapitalProduceNumber', have you also tried setting 'retainCapitalNumber' to zero?

    Also there are some 'rulesAttachment' settings that might help 'productionPerXTerritories', 'placementAnyTerritory', 'placementAnySeaZone', 'placementCapturedTerritory', 'placementPerTerritory', 'maxPlacePerTerritory' and 'unlimitedProduction'.

    And then there are some '<property>' settings:

    <property name="Production Per X Territories Restricted" value="true" editable="false">
       <boolean/>
    </property>
    
    <property name="Production Per Valued Territory Restricted" value="false" editable="false">
       <boolean/>
    </property>
    
    <property name="Unit Placement Per Territory Restricted" value="true" editable="false">
       <boolean/>
    </property>
    
    <property name="Place in Any Territory" value="true" editable="false">
       <boolean/>
    </property>
    
    <property name="Give Units By Territory" value ="false" editable="false">
       <boolean/>
    </property>
    
    <property name="More Constructions with Factory" value="false" editable="false">
       <boolean/>
    </property>
    	
    <property name="More Constructions without Factory" value="false" editable="false">
       <boolean/>
    </property>
    
    <property name="Unlimited Constructions" value="false" editable="false">
       <boolean/>
    </property>
    

    Sorry I can't be of more help, but I hope this gives you some hint on where to look.

    Cheers...



  • @wc_sumpton Yes I have now also set retainCapitalNumber to zero as well, It didn't help. The game still crashes whenever it's the AI's turn.

    I found an alternative solution, wherein I set the impassible territories to be the player capitals, thus accomplishing a "player without a capital" situation, but this feels like a sloppy workaround to fix a feature that is, according to POS2, already in the game.



  • @elreigh said in Can AI Players without Capitals Purchase/Place Units?:

    I found an alternative solution, wherein I set the impassible territories to be the player capitals, thus accomplishing a "player without a capital" situation, but this feels like a sloppy workaround to fix a feature that is, according to POS2, already in the game.

    I just tried this; everyone can place units and the game no longer crashes, hooray! But the AI still doesn't place units. It is able to, it just chooses not to. Even in the Bid phase, it doesn't buy units. The AI just stockpiles its resources indefinitely.

    EDIT: I let the game run for a few more rounds, eventually the AI (easy) started building units, but on different rounds. It's round 6 and one AI still hasn't bought anything, sitting at 300+ PUs.

    EDIT2: Have just tried a game with "Fast" AI, which seems to work fine. Ideally I would like a true no-capitals situation, but I think I can live with what I've got as it is.



  • Alright, after some playtesting I've found that the AI can, and consistently will, place units in impassable territories during the "bid place" and "random start" phases. Even if I put unitPlacementRestrictions on all units to keep them from being placed in the impassable territories, the AI can still put them there. I guess the bid and random start phases don't check for placement restrictions.

    I'm thinking that I'll have the impassable capitals under neutral control at game start, and then give ownership to the players after all of the bid placements have occurred, thus preventing the AI from placing units in their impassable capitals. But that opens a whole other can of worms and I'm pretty sure that if they don't have capitals in the first place then they won't be able to place units at all.



  • @elreigh
    I'm almost certain that 'bidPlace' does not follow 'unitPlacementRestrictions' and I am not sure how 'randomStartDelegate' does thing. And a territory with a 'territoryAttachment' '<option name="isImpassable" value="true"/>' should stop both types of placement. If it does not then maybe you'll need to create a bug report.
    But its hard to say what is happening without some idea of whats in the xml.

    Sorry I can't be of more help.

    Cheers...


  • Admin

    @elreigh

    Take a look at ww2v3 1941. The china there has no capital but still places units based on territories it owns. This can be altered to collect income and purchase for factories too.

    Also some AI's don't function well. Hard AI usually is ok when it comes to this.


  • Moderators

    @general_zod In "World War II v3 1941" "Chinese" has 1 capital (Mongolia).


  • Admin

    As @General_Zod says, there are small differences in how the AI handles maps.

    The Easy AI is kind of outdated. I don't think that anyone is updating the Easy AI code anymore. It can't handle players without capitals as far as I know, not even small players not meant to be played. I had this problem when making Dragon War with all the small AI nations, like pirates, trolls, barbarians etc. I also did the trick with fake capitals in impassable territories, but I eventually removed them again.

    The Hard and Fast can handle no capitals. In most of the maps I have writen in the notes that the map is not compatible with Easy AI, but needs Fast or Hard AI.


  • Moderators

    @frostion Years ago Veqryn said that Fodder used to work with no capitals (but I don't recall it did), and this bug should be fixed. This is the ticket I made almost 3 years ago:
    https://sourceforge.net/p/triplea/bugs/1125/


  • Admin

    @Cernel Yes it is an old problem, and I don't know if it is fixed with the Easy AI. It may have been. Here is the discussion about it from 3 years ago (you also join the discussion on page 45):
    http://tripleadev.1671093.n2.nabble.com/AI-Development-Discussion-td7585227i860.html#a7589083


  • Admin

    @elreigh Easy AI is essentially deprecated at this point and I eventually plan to remove it. Please use Fast AI, Hard AI, or Does Nothing AI when testing maps.


  • Moderators

    @redrum I guess with "Fodder" you mean "Does Nothing"? I believe "Fodder" is just the old way weak AI was called, before being renamed "Easy".


  • Admin

    @cernel Yeah, fixed it.



  • @redrum Ah, that's a shame. Fast AI and Hard AI run far too slowly on my computer, although I have tested using them it usually takes around five minutes per player. Easy AI runs much more quickly so that's been my go-to for testing.


  • Moderators

    @elreigh This has been already discussed, and some may remember I agree with this point. The other item may be that some maps, like Feudal Japan FFA for the Minor Clans, require a randomish AI, but I don't think that was ever supported; just a few mapmakers using it such (also TWW used to mention to use Fodder for the AI players).


  • Admin

    @elreigh You'll want to make sure you have enough memory set and Fast AI should be considerably faster than Hard AI. I'd have to test your map to see what is slowing it down.