Questions

Just a quick question regarding building time. According to the docs ENERGY buildings require 0 building time and ATTACK buildings take 1 turn. However, after running a demo “make run”, I see that the ENERGY buildings also take 1 turn to build (e -> E) and not just E as expected.

Is that intentional? Is the minimum building time 1?

I would expect no ‘e’ on the board at all with a building time of 0.

Hi sparky,

That is a mistake on the docs, good catch. We have corrected the game rules file and it should reflect correctly now on the website.

Guys any chance we can get a debug mode? Basically a flag on the main game engine that we can set so that if we play against our own bot or set the reference bot against them, we can debug our decision tree’s in the background live during a match. The current timer ( 2s ) is too short and while it can be extended, it would be rather frustrating to have to wait or force the time. Maybe simply a mode where we control the execution step? Like a next turn on a 4x game. From my understanding of the rules, the game receives instructions from both players ( human or ai ) and then executes simultaneously.

Also if I play a match as a human, every turn I get a null reference exception, yet the game works. This is from the main game engine not any code I’m running.

Greetings KosmikZA

Unfortunately the current capabilities of the bot engine does not allow live bot debugging. You can debug your bot by running it with the rounds’s ‘state.json’ file that you want to debug using command line execution.
For example the JavaScript bot is run by the game engine using the ‘node mybot.js’ command with the state.json file in the same directory (node being the Java JDK equivalent to JavaScript).

By running your bot, not the game engine, in an IDE in debug mode, your bot would read the specific round’s ‘state.json’ file (the state.json file for each round is stored in the matches > {timestamp} > Round {x} > Player 1/2 folder as ‘JsonMap.json’) and run through your code where you can debug your code regardless of the time limit. The engine is built to be idempotent and you should be able to run your bot again at any round during the game and output the same result each time, bar any randomness you built into your bot, finally stopping when writing the ‘command.txt’ file.

The specific details surrounding debugging your bot will certainly differ between languages but the fundamental idea remains the same. You copy the ‘JsonMap.json’ file from the round that you wish to debug, rename it to ‘state.json’ and debug your bot.

As for your second question, I believe it might be related to the amount of console players (this being set in the ‘config.json’) and the amount of bot configurations. Maybe try having only one bot configuration in the ‘config.json’ file, in the tag called ‘bot-meta’, and also set ‘console-players’ as 1 when you plan on playing against your own bot as a console player.

Debugging without the game engine was a real pain last year, because the game needed more reliance on storing state - and because I think the format of the replay files was different to those given to the bots during the game. The new way does seem more streamlined.

One thing I noticed, though, that will make debugging very difficult indeed: if a bot prints to stdout (or stderr), it prints to the console you’re running the game engine in. I know last year, the game engine captured the bot outputs for each round and put them into a Round xxx/Player n/log.txt file, which was very helpful. Please could we have this again? Or if the printing to console behaviour is what some people want, then an option in console.json to opt in to the behaviour I described? It would be a huge help.

Also, I notice that in the state file, “weaponCooldownTimeLeft” is always zero! I’m guessing this is supposed to count down from the cooldown period rather than being fixed at zero? The weapons still fire as expected, but the value is just not output.

Spot on, removing one of the bot-meta , eliminated the null reference when playing as human.

Regarding your second paragraph, that was what I was going to wind up doing but if I understand you correctly, then engine will read from my command if I set the round parameters in the from the respective output directory and always return to that game state regardless of how many iterations I do with the bot while debugging.

We talk about state which is produced by the game engine, is it a problem if we keep the prior rounds state for reference in our code or is the bot expected to only make decisions per round state? I’m hinting at a behavior pattern analysis here :wink:

In the read me. Under the building types section the energy building says Defence building. I was confused for a second when I scrolled up and read it again. Just thought I should point it out.

In regards to your last paragraph, I think it’s in the readme but I do remember a section saying we were allowed to store additional files in our bot folder for the kind of purpose you’re describing

Oh my, that is quite an oversight. Thanks for the heads up, it has been corrected!

Hi guys

@Malman

This might require some changes to the game-runner, and I am hesitant to just say yes, so I will find out ASAP from the engine team if it will be possible to implement this debug behaviour and get back to you.

Perhaps in the meantime it will be helpful to know that you are able to write to files other than 'command.txt’ and this should remain in the bot’s directory, maybe you can output some debug information per round inside a debug.txt file, appending to it each turn.

@KosmikZA,

I will find out from the game engine team for you, but if I’m not mistaken you are allowed, and as far as my tests have gone, able to keep track of previous states in your own capacity, not in memory however, but rather by writing to a “previous-state.json/txt” file, seeing as your bot will be run in a new context each round. I will just need to find out for you the specific limitations to which you are allowed to do so and get back to you.

1 Like

Thankyou, previous state file was exactly what I had in mind.

@KosmikZA, last year we were allowed to keep state between rounds (by storing whatever data we wanted in whatever files we wanted in our bots’ directories), but not between matches. So I’d guess it would be the same this year.

@GeelKanarie, thanks for looking into it. It will require changes to the game runner (though last year’s game runner could serve as inspiration!), but it is very useful. Writing to the local directory could work, but having each round’s output in the right round’s directory, and in the right match’s directory, is super helpful!

Also @GeelKanarie, did you spot this message about weaponCooldownTimeLeft?

Hi

if there are multiple own missiles in a cell, do they all destruct on the same building?

1 Like

@thinus

It would seem so…

private void calculateMissileMovement() {
    towerDefenseGameMap.getMissiles()
            .forEach(missile -> IntStream.rangeClosed(1, missile.getSpeed()) // higher speed bullets
                    .forEach(i -> {
                        try {
                            towerDefenseGameMap.moveMissileSingleSpace(missile);
                            towerDefenseGameMap.getBuildings().stream()
                                    .filter(b -> b.isConstructed() && positionMatch(missile, b))
                                    .findAny()
                                    .ifPresent(b -> {
                                        b.damageSelf(missile);
                                        towerDefenseGameMap.getPlayerByStream(missile.getPlayerType())
                                                .forEach(player -> player.addScore(b.getDestroyMultiplier() * missile.getDamage()));
                                    });
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    })
            );
}

I have a question about the Attack building and it’s firing rate:

The rules on the website state
"The attack building has a firing rate, meaning it will fire a missile every {Fire rate} turns after it has been successfully built. "

yet by running a match it seems like the attack tower fires a missile immediately after finishing construction. Is this intended? either way, something needs to change. either the wording on the website or the attack tower has to have a cool down before firing it’s first shot.

My opinion on this:
|I think that having no cooldown for the first shot might lean towards favouring aggressive play too much, as building an attack tower on the front line will give your opponent no time to react (especially if the ruling on the website which says buildings under construction gets destroyed in 1 hit is also true). I haven’t really had much time to test the tactics here, but just theorycrafting hre

@avanderw

Good catch, thanks for that one. It was definitely not intended to destroy all missiles hitting a “dead” building, or else a player could win by having their attackers fire in-phase

@MajorPAIN

We intentionally steered away from giving an advantage to defensive buildings, since a strategy of over-using them lead to stalemates. However, we really appreciate feedback about these things to dial in the balancing :smile:

@Malman

Sorry for the late reply, we have someone looking at that issue.
Some feedback I got so far was that defence buildings’ weaponCooldownTimeLeft will always remain zero because they can’t shoot.

Can you please check whether your attack buildings’ weaponCooldownTimeLeft is also stuck at 0?

Firing immediately after construction seems fine to me. That way one gets at least some value from that 30 energy spent. I think aggression is good, otherwise people will build too much defense and very little attack towers.

@GeelKanarie Thanks for looking into it. I’ve checked this out again. It is definitely the attacking buildings too.

It turns out that this problem only applies to Player 2 - both in the JSON file that is passed to the second bot, and in the replay files under the Player 2 directory. Player 1 has the weaponCooldownTimeLeft provided correctly in both places.

To demonstrate, here’s some code to add after line 32 of the Python sample bot (then play the Python bot against itself):

for row in self.full_map:
     for cell in row: 
         for building in cell["buildings"]: 
             if building["buildingType"] == "ATTACK": 
                 print("weaponCooldownTimeLeft: {}".format(building["weaponCooldownTimeLeft"]))
2 Likes

Great catch! :smiley: This is a problem with the way the map is generated for Player B.

It runs through all the entities, and returns a mirrored version of them, but during this it re-uses the same constructor it used to create the building in the first place (which starts with a zero cooldown).

To be clear, this only affects the Player B map, not the actual gameplay itself…but it would be nice to read weapon cooldowns from the opponent. This will be fixed to display the correct value

1 Like