Introducing: the topology police

What do you want to see in Armagetron soon? Any new feature ideas? Let's ponder these ground breaking ideas...
User avatar
Z-Man
God & Project Admin
Posts: 11710
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Introducing: the topology police

Post by Z-Man »

Topology is the science that tells you that, when moving in a plane, you cannot get out of a square without crossing the boundary. I am sure you see how this relates to AA :)
The basic engine of AA is topologically correct: the grid consists of eFaces ( triangles ) that are connected; every cycle is in exactly one of those eFaces at a time and when it passes to another eFace, it has to go over the edge. If that edge has a wall on it, BOOM.
However, there is a flaw in the design: It only works while the grid is not changing. If the grid changes, some eFaces get destroyed and others are created. If your cycle is on a eFace that is destroyed, you will be assigned a new one. If you are lucky, that eFace lies on the other side of a wall and you cheated. I hope to get to fix this root of some problems soon.
As some of you have seen, the cycle's walls don't get inserted into the grid right away, but with a delay. That is to avoid the above eFace-deletion problem. Maybe this workaround can be removed when that problem is solved.
But in the meantime, I coded in some sort of police that checks if something unusual is going on: whenever two walls run exactly parallel, the functions eWall::RunsParallel*() get called ( one active, one passive, since there are two walls involved ). Likewise, if two walls turn out to cross, the functions eWall::SplitBy*() get called. The simple reaction of a player wall to the active versions of these funktions is to kill its cycle. Since the walls are put into the grid with a delay, this execution by the topology police appears after the cause and feels like a lag death. Not perfect, but at least you die. This should prevent players from enjoying to get through their own walls or the rim wall. They still get through, but ( provided they don't find new tricks ) die shortly afterwards.
Then I found a real bug in eGrid::DrawLine() when exactly parallel and overlapping lines are drawn: the old wall got destroyed... I guess this was the rip bug since when it happened to the rim wall, a hole would be cut through it and the floor as well. It should be fixed now.
Sorry for
a) not fixing it earlier, but back in the days I used to debug on a P266 MMX without 3d card and the bugs are found better at higher FPS
b) for writing such unreadable code as in eGrid.cpp ( Hey, I ran out of letters for variables... :oops: )
c) for taking away the pleasure of fixing it on your own.
User avatar
Tank Program
Forum & Project Admin, PhD
Posts: 6712
Joined: Thu Dec 18, 2003 7:03 pm

Post by Tank Program »

Well done z-man :). I think it shall be well worth the lag if it solves the afore-mentioned bugs.
Image
User avatar
klax
Project Developer
Posts: 481
Joined: Tue Jun 08, 2004 3:51 pm
Location: Barcelona, Spain
Contact:

Post by klax »

Nice if it works. I lol with this: 'provided they don't find new tricks' lol

I remember those afternoons trying to understand something of the ascii maps with all that variables ;)
User avatar
Tank Program
Forum & Project Admin, PhD
Posts: 6712
Joined: Thu Dec 18, 2003 7:03 pm

Post by Tank Program »

Hmmmz.... Windows is not happy to compile...

Code: Select all

eGrid.cpp
C:\armacvs\armagetronad-rcon\src\engine\eGrid.cpp(1803) : error C2374: 'j' : redefinition; multiple initialization
        C:\armacvs\armagetronad-rcon\src\engine\eGrid.cpp(1794) : see declaration of 'j'
I'm guessing those single letter variable names are rizing from the dead like zombies now and cluttering up the place...
Image
User avatar
Tank Program
Forum & Project Admin, PhD
Posts: 6712
Joined: Thu Dec 18, 2003 7:03 pm

Post by Tank Program »

Line 1803:

Code: Select all

for(int j=0;j<=2;j++){
to
for(j=0;j<=2;j++){
compiles, but I don't know what it'll do to linux...
Image
User avatar
klax
Project Developer
Posts: 481
Joined: Tue Jun 08, 2004 3:51 pm
Location: Barcelona, Spain
Contact:

Post by klax »

In linux works with both ways, but the correct way of doing it is how z-man did it.
Don't know why windows compiler is not happy because when you initialize a variable inside a block (like a for) must be forgotten outside the block ¿?
User avatar
Tank Program
Forum & Project Admin, PhD
Posts: 6712
Joined: Thu Dec 18, 2003 7:03 pm

Post by Tank Program »

Not that I saw :?.
Image
User avatar
philippeqc
Long Poster - Project Developer - Sage
Posts: 1526
Joined: Mon Jul 12, 2004 8:55 am
Location: Stockholm
Contact:

Post by philippeqc »

Good, that will fix some things

In my changes I was contempling the following concept:
The rim is based on the edge of efaces, so the number of segments change through the game, and the position can change through complex situations and floating point error. So instead, I wanted to bump that operation to the eField. The eField would hold a list of the initial coordinates, instead of relying on the eFaces coordinates.

Also, the edge of a grid is not necessary a rim wall, but can be connected to another grid. The evolution of the eFaces on both eGrid will differ, so there are no correspondance between the eEdges of the eGrids. Only the eField can cope with that.

-ph
Canis meus id comedit.
User avatar
Z-Man
God & Project Admin
Posts: 11710
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

klax wrote: I remember those afternoons trying to understand something of the ascii maps with all that variables ;)
Especially the one that completely got messed up by some reformatting ( not by astyle, it's already destroyed in the original source ). As Murphy goes, that was exactly the one I would have needed to understand the parallel walls bug...

The issue Tank is reporting is a known nonstandard behavior ( again you can't blame Microsoft since VC6.0 is pre-standard ). Altough there is no visible scope, the scope of the for loop should include the loop statements themselves. The loop variable should be invisible to the outside. There are two ways to code multiple loops with equally named variables portably:

Code: Select all

{
    for( int i = .... )
    {
        ....
    }
}
{
    for( int i = .... )
    {
        ....
    }
}
or

Code: Select all

int i;
for( i = .... )
{
    ....
}
for( i = .... )
{
    ....
}
I had totally forgotten about this issue, it is not the first time I stumble over it. BTW, there is a switch in VC7.0 that reenables this behavior since
a lot of old code relies on it...
I commited a fixed version.

And philippeqc has a good plan for the future. At least those functions of the rim walls that act nonlocally ( the stuff that breaks down when the rim is nonconvex ) should be done with a fixed structure outside the grid.
User avatar
Tank Program
Forum & Project Admin, PhD
Posts: 6712
Joined: Thu Dec 18, 2003 7:03 pm

Post by Tank Program »

cool
Image
User avatar
philippeqc
Long Poster - Project Developer - Sage
Posts: 1526
Joined: Mon Jul 12, 2004 8:55 am
Location: Stockholm
Contact:

Post by philippeqc »

z-man wrote: Especially the one that completely got messed up by some reformatting ( not by astyle, it's already destroyed in the original source ). As Murphy goes, that was exactly the one I would have needed to understand the parallel walls bug...
Last summer I made images to explain all the different scenarios met in eGrid::DrawLine. They are in the branch world-0-1. I'll try to extract them tomorrow and put it in the trunc.
z-man wrote: And philippeqc has a good plan for the future. At least those functions of the rim walls that act nonlocally ( the stuff that breaks down when the rim is nonconvex ) should be done with a fixed structure outside the grid.
The fields will still be limited to convex shapes. The assemblage of field will provide a way to create any shape. A convex test will still be required for safety measure, but could be pushed to the parser.

-ph
Canis meus id comedit.
User avatar
Z-Man
God & Project Admin
Posts: 11710
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

philippeqc wrote: Last summer I made images to explain all the different scenarios met in eGrid::DrawLine. They are in the branch world-0-1. I'll try to extract them tomorrow and put it in the trunc.
That would be sweet.
User avatar
philippeqc
Long Poster - Project Developer - Sage
Posts: 1526
Joined: Mon Jul 12, 2004 8:55 am
Location: Stockholm
Contact:

Post by philippeqc »

commited
Canis meus id comedit.
User avatar
Z-Man
God & Project Admin
Posts: 11710
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

Thanks, philippeqc! Very well done.

The complete makeover of everything that could allow a cycle to slip through a wall is complete. The changes are threefold:

1) the cycle rubber code was changed a bit to not let you get arbitrarily close to the wall in front of you. You still get so close that you can see through the wall in the internal camera, but you don't get so close that you are almost on the other side.

2) the basic problem of eFaces being replaced by new ones is solved; when an eFace is removed from the grid, a list of the new eFaces that replaced it is stored. A gameobject that notices the eFace it was formerly on has been removed checks this replacement list first. On that transition, it cannot tunnel through old walls.

3) the topology police: it gets activated whenever a new wall gets drawn over an old wall either in parallel or crossing it. It checks for the legality of this ( holes and the times the walls were laid out ) and kills violators. This should catch all loopholes of point 2. Finding at least one loophole ( I know one, but it is unfixable and should be caught by 1. most of the time ) is left as an exercise :)

And of course, there were bugfixes. I already told you about the one to the parallel wall placement code. The dreaded "left grid" error message has been replaced by recovery logic: the grid just gets expanded, if that does not work, the topology police is called. Grid growth is limited to a maximum size to prevent escalation exploits.

I guess this qualifies as a coding frenzy 8) Be on the lookout for new bugs that may have popped up, random kills could be a likely symptom.
User avatar
philippeqc
Long Poster - Project Developer - Sage
Posts: 1526
Joined: Mon Jul 12, 2004 8:55 am
Location: Stockholm
Contact:

Post by philippeqc »

z-man wrote: And of course, there were bugfixes. I already told you about the one to the parallel wall placement code. The dreaded "left grid" error message has been replaced by recovery logic: the grid just gets expanded, if that does not work, the topology police is called. Grid growth is limited to a maximum size to prevent escalation exploits.
It is my understanding that the "left grid" didnt happen when someone when out far far, but rather when there was hole in the frabic. (Probably not, but could be described as:) A bug in insertion of eFace didnt link all of its sides to neighbor eFace. Crossing that unlinked side cause the "left the grid error".

-ph
Canis meus id comedit.
Post Reply