Comments (5)
That's indeed a worth thing to document. We can start by collecting some of specific questions users have, so let's keep them in tis issue for now.
I will try to answer questions here and will collect them into a dedicated document later.
How add ground tiles?
When there is a single type of "ground" tiles (let's call it A
), it's enough to have pattern like this in positive sample in order to define that the tile can repeated along both axes and fill any area:
AA
A
to add a second tile type B
(and any other next) interchangable with A
the following pattern will be enough:
A
ABA
A
The algorithm will be able to infer that combinations like
B BB
B
are also valid - but only if complete_matrices
flag in WFCRules2D
is enabled (which is default). Otherwise you'll have to specify all possible combinations:
AA
ABB
BA
When there are more interchangable cell types and complete_matrices
is disabled, the pattern above should be repeated for every pair of interchangable tiles.
create different kind of biomes
I'm not sure, what does it mean, what you're trying to achieve in this case.
from godot-constraint-solving.
Thanks, I learned a lot with this answer 👍
By multiple kind of biomes, I mean more something like, being able to make it learn every possible transition but also the ones that cannot exist, alongside with making the solver learn that for instance, a grass patch must be at least X tiles by X tiles for consistency.
I've also been trying to create global rules (like no more than X times a given tile for instance) and I feel like having more explanations on how to implement a proper problem would be nice.
Extending WFC2DProblem
is a good start I think and I started with this, but understanding which method will make you able to do what can be a bit hard and would be amazing with some docs on the topic.
from godot-constraint-solving.
learn every possible transition but also the ones that cannot exist
I don't quite get what this means, but seems like this may be related to how learns possible tile combinations.
The algorithm may learn some combinations that are not represented in the sample. For example, when there are cells A
, B
, X
, Y
, and the following combinations (let's consider only one dimension here): AX
, BX
, AX
, the algorithm will alse decide that BY
is an acceptable combination as well. It will decide so because both A
and B
can be placed left from X
, so perhaps, they have the same pattern/connector on right side. It may be useful to think of tiles as jigsaw puzzle pieces - in this case A
and B
have the same shape on their right edge. And thus, since shape of A
is compatible with both X
and Y
, shape of B
should also be compatible with both of them if it is compatible with at least one of them.
However, sometimes, the algorithm may lern some combinations that aren't really valid or just don't look right aesthetically. In such cases, there are two possible ways to resolve this:
- completely disable this behavior by disabling
complete_matrices
flag in rules. This way the algorithm will only learn combinations present in the sample, so it will require more manual work to build the sample. - disable some combinations using a negative sample. All combinations present in negative sample will be considered invalid, so be careful to not add some useful combinations there accidenally.
learn that for instance, a grass patch must be at least X tiles by X tiles for consistency
I'm afraid, that won't be possible with standard rules. When deciding, what tile can be placed in given cell, the solver looks only at limited number of other cells - by default it's neighbours along X and Y axes, but it can be changed using axes
property of WFCRules2D
.
Extending WFC2DProblem is a good start I think and I started with this, but understanding which method will make you able to do what can be a bit hard and would be amazing with some docs on the topic.
That's a complicated topic, and WFCProblem
is currently missing some methods that coult make implementation of global constraints easier. I did leave some description of what's available now in #1.
Also I did leave a description of an alternative approach that may replace global constraints there - you can limit what tiles are placed in some cells before WFC starts. In fact, there is a more flexible version of that approach available in another branch, see WFC2DPrecondition. It allows user to define custom initial constraints in a more flexible way than strictly setting what tile should be placed at given coordinates. There is currently a dungeon generator that has customizable settings of what tiles are considered walls and roads. Generating different biomes may be another use case for preconditions - user may create few subsets of tiles for different biomes and precondition will use value of a noise texture to choose which biome each cell belongs to.
from godot-constraint-solving.
I feel like all this boils down to two issues (no offence, I'm trying to find good ways to help with the lib because I love it ^^):
- DX is a bit lacking, this is mostly because the lib is a generic solver and not just a WFC solver, making it hard to follow for someone who's trying to just use it as a WFC solver and add their own constraints.
- More examples would be amazing, for instance with a more complex tileset that's closer to what a real game would use (I was thinking something like https://freddypixelart.itch.io/top-down-adventure-pack and I'd be fine paying for a copy to use as example in the project).
- Examples of what NOT to do would also be amazing (like this time in #4 where I had a tile that prevented multithreading for a reason that I'm not sure I understood, but that happened again on some tests I've made locally).
from godot-constraint-solving.
DX is a bit lacking, this is mostly because the lib is a generic solver and not just a WFC solver, making it hard to follow for someone who's trying to just use it as a WFC solver and add their own constraints
I'd say that the issue is rather lack of proper API/extension points for some kinds of modifications. The fact that the code is decomposed the way that solver does not depend on specific kind of problem shouldn't be an issue itself.
more complex tileset that's closer to what a real game would use (I was thinking something like https://freddypixelart.itch.io/top-down-adventure-pack and I'd be fine paying for a copy to use as example in the project)
Licence of that specific tile set does not allow redistribution. So if we use it in examples (examples are distributed along with the addon), everyone who wants to check them out will have to pay for their own copy of a tileset. This doesn't sound like a good idea to me 😆.
But that may be just a misinterpretation of the license. Anyway, I'd prefer to not mess with any proprietary assets. However, it totally makes sense to use a larger tileset - both to test and show how the addon works at larger scale and to test and show future feature with biome preconditions.
Examples of what NOT to do would also be amazing
Perhaps, a textual documentation will be enough for that. Since we're collecting Q&A here:
Why some rules stop the generator from using multiple threads or make it produce invalid results?
When deciding to use multithreading or not, the solver uses parameter of rule set named influence range. Influence range is the minimal distance from a cell at which change of it's domain (i.e. set of tiles that can be placed in a cell) never changes domains of other cells.
Example of influence range computation in 1-d case
Let's consider the following single-dimensional example:
- the tile set contains tiles
A
,B
andC
- the following combinations are allowed:
AA
,AB
,AC
,BA
,BB
,BC
,CA
To compute influence range, the algorithm will consider every tile:
A
can be followed by any other tile - bothAA
,AB
andAC
are allowed. It's partial influence range is 1.- same goes for
B
-BA
,BB
,BC
are allowed. - in case of
C
it can be followed byA
only. ButA
then can be followed by any other tile:CAA
,CAB
,CAC
. So partial influence range forC
is 2.
Then the same is done for right-to-left direction 'cause result for some rule sets may be different in different directions. But in this example it's still 2. The final influence range for this rule set is also 2.
The generator uses approximated influence range value to decide how to split work among multiple threads: the lower the influence range is - the smaller chunks and the more threads will be efficiently used.
- Influence range is infinite. Algorithm could detect it and disabled multithreading.
- Algorithm couldn't correctly calculate influence range. Currently it uses an approximation of actual influence range that may be incorrect in some cases.
- You could create a complicated set of rules for which the influence range logic is not applicable. This is even more likely to happen in case of modifications to
WFC2DProblem
. Unless you can simplify the rules, your best choice in this case is to just disable multithreading (by setting maximum threads number to 1).
Infinite influence range
A minimal example of a rule set with infinite influence range would be one with two tile types A
and B
and the following combinations allowed: AA
, AB
, BB
. Tile B
placed in any cell will influence all cells to the right 'cause rules don't allow to place anything except another B
tile to the right from B
tile.
Another example is set of rules that allows combinations AB
and BA
. With these rules, by putting, for example, tile A
in an even cell, we decide that all even cells will contain A
and all odd will contain B
. Cases like this can be fixed by either allowing repeating tiles (AA
or BB
) or by adding third tile C
and allowing it ti be placed between A
and B
(allowing AC
and CB
combinations).
A more trivial example is set of rules with combinations AB
, BB
allowed. Nothing can be placed to the left from A
tile, so it always makes all cells to the left invalid. That is considered as infinite influence range as well. The same may happen with 2D rules defined by sample like
AB
BB
nothing can be placed on top or to the left from tile A
. It may be fixed, for example, like this:
B
BAB
BB
When using WFC2DGenerator
, such situation can be detected by enabling "Print rules" flag and running a generation. A message like
Influence range: (5, 6)
At: res://addons/wfc/nodes/generator_2d.gd:126:start()
will be printed, along with full rule matrices. In cases when algorithm could detect infinite influence range, at least one of numbers will be 2147483647.
Undetectable infinite influence range
Current implementation can not detect influence of a tile if it is not propagated directly along one axis. For example let's consider a set of rules with floor tiles X
, two road (or wall?) tiles ┐
and └
and the following sample map:
XX
┐X
X└┐
XX
With these rules, when ┐
or └
tile is placed at coordinates (x, y)
there always will be the same tile in any cell with coordinates (x + a, y + a)
.
Best solution in situations like this would be to have dead-end tiles (e.g. ╶
and ╵
). Allowing road to turn in different directions (┘
, ┌
) and move straight (─
, │
) may also help to some extent.
from godot-constraint-solving.
Related Issues (11)
- How to use your addon to generate dungeons. HOT 3
- [Docs] Add metadata to GridMap HOT 2
- [Docs] Samples and Negative Samples HOT 3
- Does this respect the various properties of the tile? HOT 10
- Rerun on different Rect. HOT 1
- Air tiles HOT 3
- [Suggestion] Multi-Layered TileMap Support HOT 5
- Cannot seem to find WFC2DGenerator node HOT 2
- [Discussion] Tile probability HOT 6
- [Discussion] Why gdscript and not something else? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from godot-constraint-solving.