ondras / rot.js

ROguelike Toolkit in JavaScript. Cool dungeon-related stuff, interactive manual, documentation, tests!
https://ondras.github.io/rot.js/hp/
BSD 3-Clause "New" or "Revised" License
2.33k stars 255 forks source link

Differences in FOV calculation depending on position #218

Open scalemaildev opened 5 months ago

scalemaildev commented 5 months ago

I've noticed that the FoV calculation puts out different results based on the source position. For example, in these two images: standing on the bones in the lower left allows the player to see the hex next to the bones in the upper right. However, standing in that same spot in the second image doesn't allow the player to see their original position.

cornercase1 cornercase2

Is this normal behavior? I'm using pointy-topped hexes with double wide coordinates, and the topology is set to 6.

Code snippet for how I'm implementing fov:

updateVis(scene: any, entity: Entity): void {
        const vis = new Set<number>();
        const viewPosC = intToCoord(entity.c.e.pos);
        const px = viewPosC[0];
        const py = viewPosC[1];

        const fov = new FOV.PreciseShadowcasting((x: number, y: number): boolean => {
            const pos = coordToInt([ x, y ]);
            return scene.currentLevel.tiles[pos] && !scene.currentLevel.tiles[pos].c.e.blocksSight;
        }, { topology: 6 });

        fov.compute(px, py, entity.c.mem.visRadius, (xi: number, yi: number) => {
            const pos = coordToInt([ xi, yi ]);
            vis.add(pos);
        });

        entity.c.mem.vis = vis;
    }
ondras commented 5 months ago

Yeah, I am afraid this is just the way it is. The algorithm is not symmetric, i.e. "you see B from A" does not imply "you see A from B".

I understand that this might not be ideal for some games, but I am not aware of any straightforward way (algorithm modification) to enforce the rule.

Visibility in general is complex and hard. See https://www.reddit.com/r/Damnthatsinteresting/comments/1agtkaj/optimal_distance_to_peek_in_shooter_games/ for an interesting example.