Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
fabian

engine asymmetry WRT wall blocking

Recommended Posts

Hi there,

 

as some of you may know, Crispy Doom has a command line option "-fliplevels" that flips all maps around the vertical axis, i.e. y-coordinates get inverted including all nodes and even the BLOCKMAP.

 

Now I'd like to develop this feature further to the point that it becomes demo-compatible, i.e. demos recorded with normally oriented maps play back without desync in flipped maps and vice versa. The first step, of course, is to concentrate on -nomonsters demos. One such example is 30no1552.lmp, but it desyncs in MAP02 when the player squeezes himself through the gap in the wall past the red key. Since this involves wall contact, my first guess is that the issue lies within how the blocking of the player by a wall is calculated. There must be some asymmetry in the code between how blocking the player to the left and the right of a line is treated.

 

Does anyone have experience with this problem or at least an idea which code path could be responsible for this?

 

Thanks!

Share this post


Link to post

You should probably take a look at this important post by Creaphis (arguably the most significant post ever made in these forums in terms of the game mechanics), in a thread that unfortunately got derailed too much. I'll quote a snippet:

Quote

The explanation behind "drift" is actually so simple that it hardly deserves its own paragraph. The truth is that, when playing with a reduced turning resolution (eg. when recording a vanilla demo), the four orthogonal directions that the player can face aren't orthogonal at all; instead of lining up perfectly with the map's axes, these directions are turned to the left by about 0.01 degrees. I discovered this by recording a demo of the player simply running forwards and backwards along one of these "orthogonal" directions, and then studying the resulting demo in DRE to see the player's position at each tic. For every 5000 map units (roughly) that the player moves forward along one of these directions, he will also move to the left by one unit. Because of this, when the player runs "directly" into a wall, the angle of his approach causes him to drift just slightly leftward.

Share this post


Link to post
50 minutes ago, Grazza said:

arguably the most significant post ever made in these forums in terms of the game mechanics

 

😢

 

I don't know how you are processing the level to flip it but if you're thinking of supporting demos by mirroring all the inputs or whatever then it's probably not going to work, primarily because of the issue Grazza mentions, but for a slew of other things as well (wallrunning direction and the direction the AI starts looking for which way to turn a monster, to name two).

 

Edit: after looking at the source code, yeah, I don't think this will ever produce proper demos with the current strategy. My suggestion for demo compatible flipping would be to have an option in the things drawing routines to draw all things mirrored (which is already in there for flipped death animations), and then mirror the rendered view when it's done and flip the input controls.

Share this post


Link to post

You could try creating a "flipped" fineangle table to use when fliplevel is on.

 

An alternative approach is to make fliplevel more of a cosmetic change: it changes how the game is rendered, and you switch the player left/right commands, but internally the levels are still "the right way", no need to change nodes and blockmaps.

Share this post


Link to post

I'd suggest rewriting the flipping code so that it happens entirely in the renderer - that way you avoid problems like these entirely.

 

OTOH you can probably write new versions of the column and span drawer functions in r_draw.c that just horizontally mirror the screen. You can probably make them wrappers around the existing drawer functions that transform dc_x, ds_x*, etc. before calling the originals. Then reverse the turning field in G_BuildTiccmd and you should be done.

Share this post


Link to post
On 9/23/2019 at 5:40 PM, fraggle said:

OTOH you can probably write new versions of the column and span drawer functions in r_draw.c that just horizontally mirror the screen. You can probably make them wrappers around the existing drawer functions that transform dc_x, ds_x*, etc. before calling the originals. Then reverse the turning field in G_BuildTiccmd and you should be done.

 

This was a breeze until I reached R_DrawMaskedColumn() and friends, sigh...

Share this post


Link to post

Because I was in the wrong track! I forgot that 'dc_x' is a global variable, sigh... Now it's really easy, thanks!

Share this post


Link to post
On 9/23/2019 at 5:40 PM, fraggle said:

OTOH you can probably write new versions of the column and span drawer functions in r_draw.c that just horizontally mirror the screen. You can probably make them wrappers around the existing drawer functions that transform dc_x, ds_x*, etc. before calling the originals.

 

I have introduced a lookup table which contains the horizontal screen coordinates either in original or reversed order, depending on crispy->fliplevels. I pass dc_x and ds_x? through this table once before and once after calling the respective drawing function, so the destination row either remains the same or gets flipped horizontally for this one call.

 

https://github.com/fabiangreffrath/crispy-doom/commit/31dc345ea4fb5643686b7e0833248007c46e64bb

 

Quote

Then reverse the turning field in G_BuildTiccmd and you should be done.

 

I have inverted the cmd->angleturn and cmd->sidemove fields at the end of G_BuildTiccmd(). I hope this is the correct place to do this if I want demos recorded with flipped rendering to play back properly without.

 

https://github.com/fabiangreffrath/crispy-doom/commit/96ae96762ef3bf02ab6f61acaad212475262c5fb

Share this post


Link to post
18 hours ago, fabian said:

I have inverted the cmd->angleturn and cmd->sidemove fields at the end of G_BuildTiccmd().

Seems ok, but I think you should do it before the lowres_turn logic.

 

Have you created new span drawers yet?  That should be fun :)

Share this post


Link to post
8 hours ago, andrewj said:

Seems ok, but I think you should do it before the lowres_turn logic.

 

This is exactly the one point I am not sure about. But you are probably right and it makes more sense to move if before that block.

 

Quote

Have you created new span drawers yet?  That should be fun :)

 

That's not necessary. I just flip the horizontal start and end coordinates for the spans.

 

Edit: No, wait, things are looking pretty messed up.

Edited by fabian

Share this post


Link to post

Yeah you probably don't need new span drawers, but you will need to adjust the input coordinates to them.

 

P.S. the demon face teleporters in MAP20 is a good place to check.

Share this post


Link to post

And any text in a texture is going to be mirror writing ?

If the textures don't get flipped some of the adjacent textures are not going to match.

 

Share this post


Link to post
3 hours ago, wesleyjohnson said:

And any text in a texture is going to be mirror writing ?

If the textures don't get flipped some of the adjacent textures are not going to match.

Naturally mirroring the screen is going to make text go the wrong way.

 

Flipping textures may "fix" that, but then horizontal texture alignment gets broken.  Doing nothing else but mirroring the screen will keep texture alignment OK.

Share this post


Link to post

As an experimenter, I do love the weird and novel idea.

However, I am not seeing much of a good use or application for this mirrored demo.

As a project goal, I recognize it as having great potential as a time-waster.  My immediate impression is it is something that that I would back away from, slowly, and try to not look back.

You may be caught by the idea already, and have a great deal of difficulty escaping.  ..  I feel the Halloween season approaching.   All those movies they show.  The people in those movies should know better.  There is a monster lurking, don't open that door.   Run away while you can..

 

I expect the mirrored level map would provide a different feel for some common maps, but then should record demos marked as requiring the mirrored level map.

Share this post


Link to post

With the new approach, as of today, the map geometry will remain untouched. It is just that the column and span rendering functions draw to flipped horizontal coordinates. Thus, you will experience the exact same game mechanics as with unflipped levels and demos will keep sync. It will even be possible to play network games with one player playing the regular level and the other one playing the flipped map. It is indeed an experiment and a time wasting one for sure. But it is fascinating to experience how strange a map even as familiar as MAP01 feels when it merely got flipped around the horizontal axis.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×