Giter Site home page Giter Site logo

Comments (5)

AlexeyBond avatar AlexeyBond commented on May 15, 2024

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.

Supamiu avatar Supamiu commented on May 15, 2024

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.

AlexeyBond avatar AlexeyBond commented on May 15, 2024

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.

Supamiu avatar Supamiu commented on May 15, 2024

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.

AlexeyBond avatar AlexeyBond commented on May 15, 2024

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 and C
  • 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 - both AA, AB and AC 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 by A only. But A then can be followed by any other tile: CAA, CAB, CAC. So partial influence range for C 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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.