Code of Kutulu - Bugs

Later it says:

They keep the last target until it goes out of sight. When it goes out of sight, the slasher picks the nearest target in LoS. If none exist, it remembers the last position of the target.

I agree that it might be better to move that sentence higher to the section you quoted. The action itself (attack another player if the old target is hidden) is exactly the intended behavior.

I uploaded it here.

Thanks a lot!

I’m having frequent problems with games in the last battles. I’ll click on view a game and get “An error occurred (#-1): “internal error”. Please contact codersHS@codingame.com”. Perhaps related: I’ve had several tabs locking up when submitting. Game result not found.
It looked like, I submit, opens the last battles tab and tries to display a game it can’t because of whatever is going on with this internal error, the tab just locks up, takes 100% CPU and has to be killed.

Edit: Also had a failed IDE game and got a “reference error” message.

Edit: I’ve also had games in the last battles where I cannot change the time backwards or forwards. The game plays at normal speed but kind of glitches backwards and forwards a bit.

2 Likes

In the “Turn Workflow” documentation, it does not say when the minions decide who to target (and whether to change their target) - it only says when they actually move.
My experimentation suggests that they decide it at the same time they move, after all players already completed their moves for the turn, using the new updated position information (that’s not available to me as the player when I’m trying to guess where they’ll move). This is problematic since it makes the game much less deterministic, and much harder to debug and make plans around the minions’ behavior. Some sample problems I’ve encountered:
(each of these happens all on the same turn so there is no good way to compensate for this)
A) slashers

  1. There is a slasher already in RUSH mode, targeting another player. Both that player and me are in LoS of the slasher, but in different locations.
    2a. I decide that I don’t need to “duck” out of LoS, and there are higher priorities for me to be worried about, because the slasher is supposedly rushing at someone else THIS TURN. So I move somewhere that’s still in LoS.
    2b. At the same time, the other player does leave the LoS.
  2. The slasher makes a decision based on the updated information that the players did not have, and targets and instantly spooks me.

B) wanderers

  1. There is a wanderer, I am 2 spaces away from the wanderer, and another player is 1 space away from the wanderer.
    2a. I decide that because the other player is closer, the wanderer will be / is targeting that player. Based on other threats, I decide to move toward the wanderer because I assume it will be moving away from me.
    2b. The other player moves away from the wanderer
  2. Based on the new positions, the wanderer recalculates its target, and decides to target me instead. Again, its decision is made using newer information than the players had on the same turn

I think ALL decisions about where to move and who to target within one turn - both the players’ and the minions’ - should be made based on the same board configuration. Otherwise, it’s not really one turn, is it.

I’m guessing that some of the other confusion people reported above, about how minions make decisions, is also due to this order of operations issue.

(or at least explicitly state this somewhere in the rules. Somewhere prominent.)

1 Like

Really odd behavior that at the moment I can’t determine if it’s a bug in my bot, or… somewhere else.

I’m using java.

Here is run from my last submit where I apparently timed out, and so died very early on.

I sent that match to my IDE so I could try and figure out what was causing the issue and it didn’t happen. In fact, I won:

I’m not quite sure what to make of this. Anyone else seen similar behavior?

Do you use streams by any chance?
They have a slow init and tend to timeout. So make sure to use them in the first turn already (when you have 1s) and you are fine.

Yes, I also saw such thing a couple of times and it is not easy to predict, but I think that it was done intentionally otherwise if there are two cells - one of them fro your and another for minion you will change them on each step and minion will not be able to hit you.

yanamal it’s exactly for the reason stated by dbf that minions plays with the state of the game after players move.
So the game is not 1 turn based, but some sort of alternance explorer/minion.

Is there a bug in the slasher state diagram? ( and problem statement)

The state diagram shows Slashers might go from spawning to Wandering.
But the code:


Indicates he goes directly into rush, and if noone around at the next round => Stunned 6 turns…

State diagram:

This is not necessarily a game-breaking bug, and probably doesn’t need to be fixed right away, but the 3rd place players have the label 3nd at the end of a round.

1 Like

IMO that’s not a good way of addressing that problem. Instead of addressing the root cause, it just alleviates the symptom at a cost to the game.

The problem arises from the discrepancy of using a turn-based model of a conceptually continuous behavior - you want the wanderers to act as if they’re sweeping out a continuous path, and anyone caught by them at any moment is spooked; whereas the game model is more that everyone essentially teleports one (or more) steps each turn. But rather than modeling the concept of “anybody touched by a wanderer at any moment at all triggers the spooking” more precisely, you’re fixing it by making some kind of weird hybrid between a plain-turn-based and simultaneous-turn-based game.

Some are games that are “plain turn-based” (e.g. vanilla DnD combat), in that each actor makes a decision given a game state, and then the decision is resolved immediately using the known game state, and the next actor makes a decision based on this new state. These work because when you are making a decision, you know exactly what state it will apply to, so you can reason about what the effect of your action will be.
Some games are “simultaneous turn-based”, in that all actors make a decision using the same game state as each other, and then all decisions are resolved together. These work because when you are making a decision, you know exactly what state the other actors see when they make a decision, so you can reason about what they might do (or in the case of “deterministic” actors, what they will do).

What you have doesn’t have either of those two benefits, so it’s kind of the worst of both worlds.

Two better fixes, off the top of my head, would have been:

a) when resolving whom (if anybody) the wanderer will spook, and at which cell, consider all cells that the wanderer has gone through this turn (which is at most 2 cells), in order that he went through them. Stop when he’s actually spooked someone and disappeared. This would make it more like actual collision detection, which is really sort of what you’re going for.
(this would of course only apply to wanderers, not slashers spooking, since their effect is conceptually point-based rather than continuous sweep)

b) check for spooking multiple times throughout the turn - easiest would be after each game state update - for all minions who might currently be in a position to spook (e.g. not rushing slasher pre-actual-jump).

IMO either of these would have produced behavior that’s much easier to interpret and debug.

As it stands, this loses a huge part of the game’s appeal to me, since I was basing many of my algorithms on the assumption that minion actions are predictable, and the fun was in figuring out which parts I could model deterministically (with the information given to me).

Thought of a third fix, which is a bit of a hack in that it still doesn’t directly address the root “continuity” issue, but would at least alleviate the particular quirks I’m seeing:

C) Make the decision on who to target using the same game state as the players are using when they make a decision; then make the actual move in a second pass as is happening now, but using a target you didn’t acquire by “looking into the future” with respect to the players making decisions.

While I’m here, other smaller issues I’ve found:

  1. Light effect wraps around corners. You seem to be using some kind of dijkstra/flood fill to decide where the light effect reaches, but normally light only goes in a straight line, so you probably should have used some kind of “manhattan line of sight” logic. Don’t actually fix it though, because I’m also just re-using my generic dijkstra function to model it, and it’d be a pain to have to write a whole separate algorithm.

  2. when a Slasher is in the RUSHING state, param0, which is supposed to be “time before changing state” (according to the documentation), is 33. whereas it should be 0 (since RUSHING always changes to STUNNED on next turn).
    You really do not want to see the comment I’ve written next to the special-case I’ve had to put into my logic in order to work around this inconsistency, after an hour of debugging and printing the most random things.

  3. The documentation also says that for minions, the parameter for the target being “-1 if no target” “occurs only on spawn”. This is not true, and again, was a pain to special-case once I realized the documentation is wrong. (luckily, this problem at least caused an explicit error when I tried to look up explorers with id -1)
    For example, a Slasher that loses LoS with its target seems to reset its target to -1, rather than keeping the target id of the explorer it was planning on rushing toward (in cases when it would rush toward last-seen location)

  4. Not 100% sure, but I think there’s something non-deterministic happening. Twice in a row, I saw a weird behavior (of my bot) in a battle, did “send game parameters to IDE”, tried to debug, but the outcome was different! The code in the IDE was still the same as the submitted code. I even tried removing my IDE bot and adding the Arena bot in its place, and still a third different thing happened. At least once, I saw two different outcomes after hitting “replay in same conditions”
    All of this was at 4 AM, so it’s marginally possible I was slightly delirious. But other people seem to be reporting similar glitches in chat and here. Will report back if I can get together some replays that demonstrate this.

Hi, I thing there is a possible bug in the replay below, at turn 200, Slasher id=10 is RUSHING explorer id=0 instead of the targeted explorer id=3:

This is not a bug, at that frame, player id 3 goes out of sight of wanderer while id 0 goes in, so the Slasher changes target since he lost the previous one just before rushing.

I’ve found a scavanging slasher !


At frame 154. slasher14 is in PREPA_RUSH. His target was Explorer2. But, Explorer2 just died during frame 150.
At frame 154, the Slasher14 has the 3 other Explorers in LOS.
But, at RUSH time, slasher14 goes to Explorer2 tomb! in order to savagely eat the Explorer’s corpse!
The slasher14, should have tried to target the group of 3 Explorers. And with that many choices be confused, and loose target.
Then, He should have been stunned in place, without going to Explorer2’s tomb.

My guess is: in MinionSlasher.java:acquireTarget(), there’s no check the Explorer has died. So, the slasher can continue on a dead target.
Please, tell us if you correct or not this behaviour. I would have to patch my simu.

The real explanation is that the player dies the previous turn but no player is LoS (we can see blue explorarer moving up) so he doesn’t change the target and rushes to the last position of the previous target.

For me, all other Explorers doesn’t move, as they’ve all just YELLed. So, they are in LOS.

Not exactly a bug, but probably not as intended:
You missed (15, 1) for rotational symmetry.
seed=85981458

1 Like