libtcod / libtcod

A collection of tools and algorithms for developing traditional roguelikes. Such as field-of-view, pathfinding, and a tile-based terminal emulator.
BSD 3-Clause "New" or "Revised" License
984 stars 63 forks source link

Refactoring TCOD's field-of-view algorithms. #71

Open HexDecimal opened 4 years ago

HexDecimal commented 4 years ago

I'm mostly making this issue to track the resources I've been collecting:

http://www.roguebasin.com/index.php?title=Comparative_study_of_field_of_view_algorithms_for_2D_grid_based_worlds Older benchmarks of TCOD, there should be code added to the repository to reproduce these benchmarks. Some notes on FOV quirks but these are minor compared to the other links.

http://www.adammil.net/blog/v125_Roguelike_Vision_Algorithms.html Some benchmarks of common algorithms and a lot of good information on the quirks and artifacts of existing FOV implementations. The custom algorithm here looks decent.

https://ir.lib.uwo.ca/cgi/viewcontent.cgi?article=8883&context=etd A thesis about field-of-view using examples from TCOD, should be useful for refactoring the existing algorithms and fixing obscure issues. I don't have as much interest in ultra-high resolution 2D FOV algorithms at the moment.

https://www.albertford.com/shadowcasting/ TCOD probably doesn't need a new shadow caster, but this should help with refactoring or making similar algorithms.

There are my long term goals for FOV refactoring:

I'm not in a hurry to do these. I'm just making sure these resources are saved somewhere.

Andres6936 commented 4 years ago

I have succeeded in implementing the Diamond Wall and the Permissive inside my Fork of Libtcod.

Here the links to my implementation.

Diamond Wall Doryen Permissive Doryen

Andres6936 commented 4 years ago

For Ray Casting's case, the implementation although successful did not work as expected, so I had to go back to the implementation inherited from Libtcod.

I think the problem must have been in these lines of code:

int xDiff = x2 - origin.X, yDiff = y2 - origin.Y, xLen = Math.Abs(xDiff), yLen = Math.Abs(yDiff);
int xInc = Math.Sign(xDiff), yInc = Math.Sign(yDiff)<<16, index = (origin.Y<<16) + origin.X;

If you do the implementation of this algorithm, try to be careful with this code, which although short, is very misleading.

HexDecimal commented 4 years ago

Unfortunately I've stopped adding C++ implementations into libtcod. It's been too much of a hassle to port C++ implementations to a C API compared to the other way around. The were also runtime dependency issues and issues related to ports to other languages. It's too bad since C++ lambdas were really useful when writing flexible FOV and pathfinder implementations.

Shadow-casting, diamond, and permissive are already implemented, but it doesn't hurt to have another reference implementation.