mxgmn / WaveFunctionCollapse

Bitmap & tilemap generation from a single example with the help of ideas from quantum mechanics
Other
23.06k stars 1.23k forks source link

How to run / develop this project #3

Closed squarism closed 6 years ago

squarism commented 7 years ago

For anyone curious (on a mac):

Run:

$ brew install mono (if you don't have it)
WaveFunctionCollapse $ mcs -pkg:dotnet /reference:System.Drawing.dll *.cs
WaveFunctionCollapse $ mono Main.exe

(it starts working your CPU)

🌻

mxgmn commented 7 years ago

@NNNenov Of course! There are symmetry parameters for individual tiles in the corresponding data.xml files.

NNNenov commented 7 years ago

ah yes of course! I was just looking at one example (knots) which didn't use it..

mxgmn commented 7 years ago

@NNNenov Knots also use it: there are only 5 tiles, without symmetries there would be 13.

nanodeath commented 7 years ago

@mxgmn @NNNenov Maybe. File an issue if you would use it (i.e. you're using the JVM).

I do have some regrets not implementing kollapse on a multi-target language...would be a little silly to have N implementations of WFC for N different platforms.

marvinside commented 7 years ago

So i'm trying around with the Circuit Version and i tried to do a resistor. But i am unable to make the resistor connect to itself.

<tile name="resistor" symmetry="T" weight="1.0"/>

and

<neighbor left="resistor" right="resistor"/>
<neighbor left="resistor 1" right="transition 1"/>
<neighbor left="resistor 2" right="substrate"/>

Also: is there any Documentation which side (number) is for used on which symmetry?

mxgmn commented 7 years ago

@marvinside Could you show the picture of your resistor? Impossible to answer without that.

marvinside commented 7 years ago

resistor

@mxgmn Here it is. Why is it important?

mxgmn commented 7 years ago

@marvinside Your 4 lines above are correct. But you need to add other lines to describe other ways how resistor can connect with itself and other tiles. For example:

<neighbor left="resistor" right="resistor"/>
<neighbor left="resistor 3" right="resistor 1"/>
<neighbor left="resistor" right="resistor 2"/>
<neighbor left="corner" right="resistor"/>
<neighbor left="corner" right="resistor 2"/>
<neighbor left="resistor" right="skew"/>
<neighbor left="resistor 2" right="skew"/>
<neighbor left="resistor" right="substrate"/>
<neighbor left="resistor" right="t 1"/>
<neighbor left="resistor" right="track"/>
<neighbor left="resistor" right="wire 1"/>
<neighbor left="transition 3" right="resistor 3"/>
<neighbor left="bridge" right="resistor 3"/>
<neighbor left="wire" right="resistor 3"/>

Here is what output looks like:

Don't forget to add resistor in the subset.

marvinside commented 7 years ago

@mxgmn Do you have some Information what the Numbers mean? So at Symetry T what is 0, 1 and 2?

mxgmn commented 7 years ago

@marvinside They are rotations 90 degrees counterclockwise: 1 - 90 degree rotation, 2 - 180, 3 - 270 = -90.

gromilQaaaa commented 7 years ago

Well, my task is to make an infinite tiled 2d maze with chunks 100x100. The maze should contain treasures, buildings and enemies. I thought this asset would give me everything I need, but no... Absolutely no comments (even for input fields like symmetry, N, periodic)... Anyway I managed to launch it with this input image (red is building, blue is treasure): labirinth And it gave me: 1 labirinth 0 1 labirinth 1

Not so really bad, but lots of blocked zones (white walkable place without entrance). What can I do to fix that? And the second question is tiling... Can it simply tile my image without any input data? For example: I give it an image and it makes a right-side tiled image for the given one,

mxgmn commented 7 years ago

@gromilQaaaa One method to make output connected is to run a "fill" (like in graphics editors) process in a separate layer. By default WFC doesn't guarantee connectedness. I don't really follow your second question, WFC needs input data in any case.

selfsame commented 7 years ago

@gromilQaaaa @mxgmn I think the second question was if WFC can output a tiling texture. I believe you could achieve that by using a N thick border constraint on the output array, where top/bottom left/right is repeated, and cropping that from the final output?

mxgmn commented 7 years ago

@selfsame @gromilQaaaa Then sure, periodic="True" option generates a periodic texture. Most of the examples on the readme page are periodic.

nanodeath commented 7 years ago

@mxgmn So periodic means the images should tile seemlessly, then? Didn't realize that.

mxgmn commented 7 years ago

@nanodeath Yes. I scroll right/left up/down in videos and gifs to demonstrate that generated images are periodic.

nanodeath commented 7 years ago

@mxgmn Ah...I had no idea what the panning was supposed to signify. I just assumed you were generating a larger image than what was initially being shown, and then panning for effect. Anywho, glad to learn more about the codebase.

mxgmn commented 7 years ago

@nanodeath I also stacked 2 tiled "Rooms" outputs in the readme to demonstrate that they stack seamlessly.

mxgmn commented 7 years ago

@NNNenov @nanodeath Pardon, nvm, this actually can be done fast, I'll do it right now...

selfsame commented 7 years ago

@NNNenov you can take a look at this version of the tiled model, I use strings instead of bitmaps that include a rotation number and parse that for the 3d display ("0foo", "3foo") https://github.com/selfsame/WaveFunctionCollapse/blob/master/SimpleTiledModel.cs

NNNenov commented 7 years ago

Hey! I've just been trying to understand whats happening in the data.xml file for the tilesets. Here's my understanding so far:

image these are all the types of symmetry you can define for a tile.

Symmetry types define which way the tiles' neighbor rule can be mirrored to accommodate for more connection types and cut down on the amount of neighbour definitions needed?

So because of symmetry types, all neighbour entries are defined with single neighbor values, which are then calculated for the rest of its sides based on its symmetry type

So with left = X, right would equal something that can connect to the tile on any of its sides at the given rotation, because of this, X tiles never need to have a rotation defined. left = I, right would equal something that can connect to only the left or right side of the tile, left = T, right would equal something that can connect to only the left or right side of the tile, but left = T 1 (or 3), right would equal something that can only connect to that side, but not the other?

If I am correct with the above assumptions, I have some questions about the following: if left = L, technically not a symmetrical tile, does it still mean that if left = L, right can equal something which can connect to the right and top side? If that's the case I guess it is symmetrical because top and right are equal and bottom and left are equal? See image: image

however, in the castles data.xml file, there's a section(line 57,58) roadturn, which is L type, and is listed twice for a Tower to the right, which would suggest L symmetry has to be treated as unique on all sides?

    <neighbor left="roadturn 2" right="tower"/>

I still have some more questions, but they are likely to change after I learn more from these queries

mxgmn commented 7 years ago

In this castle example top row is <neighbor left="roadturn 1" right="tower"/> and bottom is <neighbor left="roadturn 2" right="tower"/>. What does that mean?

First, note in the Castle example tower tile has symmetry type L despite its picture having symmetry type X. I've redrawn it a little so L-symmetry would be apparent.

Imagine that we don't have any symmetry system at all. Than we also need to add lines like <neighbor left="tower 2" right="roadturn 3"/>, <neighbor up="roadturn 1" down="tower 3"/> and many more. But with the symmetry system we need only to enumerate neighbors up to a symmetry, and there are exactly 2 ways to do it for roadturn and tower - with continuations looking in the same direction or in different directions.

pointyointment commented 7 years ago

@CoenraadS

Step 2 fails, saying:

WARNING: Install failed. Rolling back... Package 'Microsoft.Net.Compilers.2.0.0' is not found on source 'https://api.nuget.org/v3/index.json'.

I have tried various things without success.

mxgmn commented 7 years ago

@pointyointment I don't know why it fails, but you can also try building through Visual Studio:

  1. Download Visual Studio 2015 Community (free).
  2. Create a console C# application (file -> new project).
  3. Delete Program.cs.
  4. Add all WFC .cs files.
  5. Add System.Drawing reference through solution explorer on the right.
  6. Move all WFC data files to bin/Release.
  7. Switch to release build option. Build, run.
CoenraadS commented 7 years ago

@pointyointment

nuget install Microsoft.Net.Compilers -Version 1.3.2

Not sure what changed since I posted, but it seems a version is required now.

kronpano commented 7 years ago

Not sure if this is still active but could somebody expand a bit on a 3D extension of the SW?? I was thinking of extending the XML with an "up" tag and then I would somehow need to "fix" those tiles in that level and build the rest around it?? Does that sound reasonable??

mxgmn commented 7 years ago

@kronpano What is SW? I uploaded a simple 3D implementation of WFC here, the algorithm is the same in 3D.

kronpano commented 7 years ago

SW = software and Thanks - hadn't seen that - will give it a try. Cheers

fxgenstudio commented 6 years ago

I want to generate a city for my voxel game, do you have a simple example, other than knots, to start understand ? thanks.

mxgmn commented 6 years ago

@procfxgen You mean a 3d example? 3d version is not released yet, so only Knots so far. Check out 6 2d example tilesets here, the algorithm is the same in all dimensions.

fxgenstudio commented 6 years ago

I play with knots 3d example, how to add ground ?

mxgmn commented 6 years ago

@procfxgen Add ground.vox and ground.png, then in data.xml add the ground tile and vertical and horizontal adjacencies with existing tiles.

fxgenstudio commented 6 years ago

Thanks, I have my ground titles now ! wfc_01 How to make "line" tile above "ground" titles ? my "data.xml"

 <set` pixelsize="8" voxelsize="3">
   <tiles>
     <tile name="down" symmetry="T"/>
     <tile name="empty" symmetry="X"/>
     <tile name="line" symmetry="I"/>
     <tile name="turn" symmetry="L"/>
     <tile name="up" symmetry="T"/>
     <tile name="vertical" symmetry="X"/>
     <tile name="ground" symmetry="X"/>
   </tiles>
   <neighbors>
     <horizontal left="empty" right="empty"/>
     <horizontal left="empty" right="ground"/>
     <horizontal left="ground" right="up"/>
     <vertical left="empty" right="empty"/>
     <vertical left="empty" right="ground"/>
     <vertical left="ground" right="up"/>
   </neighbors>
   <subsets>
     <subset name="dense knots">
       <tile name="down" symmetry="T"/>
       <tile name="line" symmetry="I"/>
       <tile name="turn" symmetry="L"/>
       <tile name="up" symmetry="T"/>
       <tile name="vertical" symmetry="X"/>
       <tile name="ground" symmetry="X"/>
     </subset>
     <subset name="only turns">
       <tile name="turn" symmetry="L"/>
     </subset>
   </subsets>
 </set>
mxgmn commented 6 years ago

@procfxgen Try this

<vertical left="empty" right="empty"/>
<vertical left="line" right="ground"/>
<vertical left="line" right="line"/>
<horizontal left="empty" right="empty"/>
<horizontal left="empty" right="line"/>
<horizontal left="empty" right="ground"/>

It should generate vertical columns.

fxgenstudio commented 6 years ago

sorry volume is empty ....

"vertical" correspond to blue axis (Z) and "horizontal" (X,Y) to red axis in magicavoxel ?

<set pixelsize="8" voxelsize="3">
  <tiles>
    <tile name="down" symmetry="T"/>
    <tile name="empty" symmetry="X"/>
    <tile name="line" symmetry="I"/>
    <tile name="turn" symmetry="L"/>
    <tile name="up" symmetry="T"/>
    <tile name="vertical" symmetry="X"/>
    <tile name="ground" symmetry="X"/>
  </tiles>
  <neighbors>
    <vertical left="empty" right="empty"/>
    <vertical left="line" right="ground"/>
    <vertical left="line" right="line"/>
    <horizontal left="empty" right="empty"/>
    <horizontal left="empty" right="line"/>
    <horizontal left="empty" right="ground"/>
  </neighbors>
  <subsets>
    <subset name="dense knots">
      <tile name="down" symmetry="T"/>
      <tile name="line" symmetry="I"/>
      <tile name="turn" symmetry="L"/>
      <tile name="up" symmetry="T"/>
      <tile name="vertical" symmetry="X"/>
      <tile name="ground" symmetry="X"/>
    </subset>
  </subsets>
</set>
mxgmn commented 6 years ago

@procfxgen This data.xml

<set pixelsize="8" voxelsize="3">
    <tiles>
        <tile name="empty" symmetry="X"/>
        <tile name="vertical" symmetry="X"/>
        <tile name="g1" symmetry="X"/>
    </tiles>
    <neighbors>
        <vertical left="empty" right="empty"/>
        <horizontal left="empty" right="empty"/>
        <vertical left="vertical" right="g1"/>
        <vertical left="vertical" right="vertical"/>
        <horizontal left="empty" right="vertical"/>
        <horizontal left="empty" right="g1"/>
        <horizontal left="vertical" right="vertical"/>
        <horizontal left="g1" right="g1"/>
    </neighbors>
</set>

and this samples.xml

<samples>
    <sample name="Knots" X="10" Y="10" Z="10" periodic="False" screenshots="2"/>
</samples>

should generate vertical columns.

If you want 3d, I think it's better to wait for a proper 3d release in September-October, it'll be much easier to experiment with, or try VoxModSynth.

mxgmn commented 6 years ago

@procfxgen Yes, vertical corresponds to blue in MV, left=top, right=bottom. Horizontal - to red, and then it mixes red and green with symmetries.

nanodeath commented 6 years ago

@mxgmn, is there a way you can close and lock this issue? Right now it seems to get reused every time anyone has a question (and emailing 23 people in the process), when really those questions should be new issues. Thanks!

mxgmn commented 6 years ago

@nanodeath Oh, didn't know about that, closing.