EssexUniversityMCTS/gvgai

Concurrent and sequential execution should not be mixed

Closed this issue · 2 comments

movable wall > stepBack
movable wall > killSprite

With the above combination, the killSprite effect does not get triggered when the Pacman runs into a wall, but if it is something like:

paint ground > killSprite
ground paint > killSprite

If the both paint and ground collide then they will both take each other out. There are various surprises like these sprinkled through the library.

As some game depend on the precise execution of the InteractionSet, it might be worth taking a step back, defining the semantics of the library more precisely and following those rules without mixing concurrent and sequential execution like in the above. Game programming is hacky by nature, but it does not have to be.

In the example above, having the InteractionSet be evaluated sequentially would mean that only one of the killSprites would get triggered, but that could get replaced by a hypothetical killBothSprites for example.

Problems such as boulders sinking into one another in BoulderDash could be fixed by applying StepBack multiple times. In my own library, I made a serious mistake of having separate collision stages for that issue that caused some of the later games to become unimplementable.

Now, having the InteractionSet evaluated sequentially by rule would mean that for every interaction, all the objects would have to be iterated over which means that in essence each tick would be executed N times with N being the number of items in the InteractionSet.

A middle of the road solution between a (prioritized, loosely serial) concurrent execution of the InteractionSet and totally sequential one would then be to have multiple InteractionSets and guarantee their sequential execution, while the particular items inside them are loosely prioritized - that is a sequence of effects applied to the same sprite is ordered by sequence in which they appear in the InteractionSet.

At any rate, the absence of having a strictly defined hierarchy of execution and in fact the lack of hierarchy itself, makes for the situation where InteractionSet effects are evaluated in loosely defined order thereby making the language less flexible and preventing further optimizations.

Thank your for your work in the other issues.

Let me elaborate on the above a bit on how the above could be implemented.

Here is how it is now:

movable wall > stepBack
movable wall > killSprite

Here is one way how it could be the (concurrent execution, both effects in a block get applied):

>>
  movable wall > stepBack
  movable wall > killSprite

Here is how a serial version with two blocks delimited by >> would look:

>>
  movable wall > stepBack
>>
  movable wall > killSprite

In the above the first block would get executed - the sprite would StepBack - and at the start of the second block the collision detection would get done again and KillSprite would not get triggered.

The above feature would allow the programmer to clearly define the order of execution. The way VGDL is designed now, it is pretending to be a declarative language, but in the later games it relies heavily on the precise order of execution. I think modifying the semantics of the language to reflect this in the game description would be an absolutely essential step. As it is now, it is in essence relying on undefined features of the engine to make the games run correctly.

The two examples in my first post are in fact examples of data races.

Hi,

Thanks for the suggestion and explanation! It's certainly an interesting idea! It could make the games more readable too.

Making this change is an important piece of work, though (engine + 80 games); and it's not going to be less work in the future (we'll have 60 more games at the end of this year, if all goes as planned), unfortunately.

The issue now is that we cannot make this change at the moment without jeopardizing the competitions we are running for 2016, but it's definitely something to have in mind for the next iteration of the framework.