Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

MapMagic 2 - infinite procedural land generator

Discussion in 'Assets and Asset Store' started by Wright, Apr 24, 2020.

  1. RafaelMartin

    RafaelMartin

    Joined:
    Dec 1, 2016
    Posts:
    3
    Hi Wright,

    Thanks for the documentation for custom generators!

    Could you point me to what is the best way to convert an float['] heightmap to Den.Tools.Matrices.Matrix?

    I have a modified heightmap saved in disk as Matrix but when I try to load it in a custom node to combine it with the current runtime Matrix I'm getting unexpected behavior (a lot of ups and down peaks).

    In a nutshell: I need a way to load a previous saved heightmap in a node and combine it ( matrix1.Mix(matrix2)? ) with the input of the node, and then return the modified Matrix.

    Thanks a lot for your help!
    PS: Sorry for my english.
     
  2. michaelcmartino

    michaelcmartino

    Joined:
    Jul 2, 2019
    Posts:
    6
    Thank you and no worries! Will give it a try asap and let you know if it works!
     
  3. mick129

    mick129

    Joined:
    Jun 19, 2013
    Posts:
    228
    This will look like a strange question, but is there a way I could spawn mountain created via MM2, with MM2 Object?

    Edit: Could a tool like Microsplat's Terrain to mesh make the terrain compatible to be spawned via MM2 Object?

    upload_2020-11-4_19-50-54.png
     
    Last edited: Nov 5, 2020
  4. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    Are you trying to spawn another MapMagic object instance as prefab in objects output? Sounds a bit overkill to me, you can spawn a mountain with the Stamp node. The pipeline will be the same - just connect your mountain graph not to the height output, but to stamp.

    Other than that, theoretically it's possible. You can spawn any prefab here, just keep Use Objects Pool toggle turned off. However haven't tried this myself.

    Doubt so.

    Glad to help! But keep in mind it's still under development. I'll repeat a link for everyone who missed it: Custom Generators.

    The reason of peaks could be in changing the matrix size while maintaining all of it's data in array the same. This way pixels become 'shifted'.

    The use case you describe could be done with the Import node that serializes matrix and Blend that can add or mix two matrices together. If you want to do it from code then try using Den.Tools.MatrixAsset asset instead of matrix itself - it was designed to serialize matrices, and import them from RAW, textures, and yep, float[,] with
    MatrixAsset.ImportArray (ref Matrix matrix, float[,] heights)
     
    ThatGuyFromTheWeb and mick129 like this.
  5. Jshh

    Jshh

    Joined:
    Sep 14, 2019
    Posts:
    38
    Hey Denis, just bought the Objects asset, and I'm loving it.

    Quick question- I'm wondering if it's possible to create a scatter of parent object prefabs, and then within each parent, create a separate scatter of child prefabs. Or alternatively just one parent with a scatter of child prefabs.

    For context, I'm scattering landing points for generated flocks of birds, but each landing point needs to be within a parent component.

    Any pointers much appreciated
     
  6. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    It's too specific to be done out of the box. However you can use custom script iterate in all tile children with a specific component, tag or name and group them the way you like. You can use TerrainTile.OnTileApplied event (
    Action<TerrainTile, TileData, StopToken> OnTileApplied
    ) - it's called when terrain tile is generated and the results are applied.

    Just in case - write a function like GroupBirsSpawns (TerrainTile tile, TileData data, StopToken stop), subscribe to it in OnEnable with TerrainTile+=GroupBirsSpawns, unsubscribe in OnDisable errainTile-=GroupBirsSpawns. Using MapMagic.Terrains namespace.
     
    Jshh likes this.
  7. michaelcmartino

    michaelcmartino

    Joined:
    Jul 2, 2019
    Posts:
    6
    Hey there! I just attempted to fix the problem of no infinite terrain on final WebGL build by disabling C++ Native Code with no luck. I'm also still having to remove the NativePlugins.dll for the build to be successful. Not sure if they are related? I can link the game or send via dm to show you what happens if necessary, but either way thank you for your replies and support thus far!
     
  8. SSL7

    SSL7

    Joined:
    Mar 23, 2016
    Posts:
    336
    Is anyone having issues creating occlusion culling with mapmagic? I open the whole world and bake it but I have artifacts in the terrain in places nothing is in front of it. Doing it on smaller area terrains everything works fine
     
  9. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    So does removing NativePlugins.dll fixes the WebGL build? If so thanks for finding that out - at least I know where to look for a solution.

    MM creates terrains dynamically, so most of the baking won't work for it unless it's performed in realtime. Default Unity occlusion culling can't do that.

    And I'm not sure that occlusion culling can improve the performance on vast and relatively "flat" maps like terrains. It makes sense if you have mountainous landscapes. In some cases it may even make things worse.
     
  10. SSL7

    SSL7

    Joined:
    Mar 23, 2016
    Posts:
    336
    I have mountanous landscapes, what I did is bake the occlusion culling after pinning all terrains, sjhouldnt that work?
     
  11. michaelcmartino

    michaelcmartino

    Joined:
    Jul 2, 2019
    Posts:
    6
    Hey, to clarify, it allows me to build the game in WebGL, but it does not have the infinite terrain working!
     
  12. Daniel-Talis

    Daniel-Talis

    Joined:
    Dec 10, 2011
    Posts:
    425
    Make sure you are compiling x86_64 in the build settings.
     
    michaelcmartino likes this.
  13. michaelcmartino

    michaelcmartino

    Joined:
    Jul 2, 2019
    Posts:
    6
    I tried changing it and still got the same results. Thank you for the advice though, I'm looking further into the different build settings options to see if anything is going on there.
     
  14. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    That should work as long as MM doesn't generate the new tiles. If it is turned on it will generate terrains around the camera. And it uses already created terrains with their object pools for performance reasons. So it takes the generated tiles you have and moves them to the camera. Try turning off MM component before starting the scene - it should leave the tiles as they are.

    Oddly enough development build gives no error. I just can't see the terrain - even the pinned one. Is standard Unity terrain working in WebGL at all? Maybe it requires some specific shader?
     
  15. michaelcmartino

    michaelcmartino

    Joined:
    Jul 2, 2019
    Posts:
    6
    I'm not sure how to test for that. (I'm using Unity terrain type instead of Perlin Noise in the Noise node if that helps?) I can dig deeper to try to figure something out though!
     
  16. Innom

    Innom

    Joined:
    Dec 6, 2014
    Posts:
    6
    I just realized I managed to post my message in the old thread, despite following links from the Version 2 page. Not sure how. Please see this link in the other thread, where I'm wondering if there's a trick to get directional filters on slopes so the slopes from one direction can be mapped differently to replicate sand dunes that have ripples on one side:
    https://forum.unity.com/threads/map...ite-game-map-tool.390920/page-98#post-6531020
     
  17. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    It's easy to do it with the custom generator, however I can't think of a way to do it via nodes. But I like the idea, and I've added 'Normal' generator to my to-do list for 2.1.0.
     
  18. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    Picked up the bundle, love what is here. My current desire is to use this to generate the base for my static levels. Then detail in the levels. Once I've gotten a nice terrain, is there a way to bake or export it to another scene so there is zero chance of accidentally changing it?

    I found the locks, to lock an area, but it seems like there might be a better way. Thanks for the great asset.

    Edit: (Do you want feedback here, or in the issues thing?)

    Some initial thoughts as a noob. It would be nice to be able to zoom in further. Seems like an arbitrary zoom limitation.

    It would be nice to be able to resize the nodes/generators to make them wider so I can read the labels better.

    Edit 2: Looks like the Veg Studio groups output might be in reverse order. (Edit 3: I see the issue reported here: http://mm2.idea.informer.com/proj/?ia=134562 )

    New issue, it appears to be changing the scene.unity asset to binary from text. Even when using force text serialization.
     
    Last edited: Nov 22, 2020
  19. longiy_

    longiy_

    Joined:
    Nov 22, 2020
    Posts:
    3
    @Wright Hi, greatly enjoying your plugin. But for some reason can't get "Other Trees" input to work. The trees are still growing into each other position. Not sure what I am doing wrong. Any solution for this? Thanks
     

    Attached Files:

  20. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    Why don't you change some of the seed values from 12345 to something else so they do not match. Should achieve what you're looking for.
     
  21. longiy_

    longiy_

    Joined:
    Nov 22, 2020
    Posts:
    3
    Thank you, that did help a bit, although some trees grow really unnaturally close to each other.
    Makes me wonder why "other trees" input is not affecting anything then.
     

    Attached Files:

  22. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    Need Wright to give feedback on the other trees feature. But, from a personal note, I'll mention that tree branches often intersect and overlap with other tree branches in nature.
     
  23. Quique-Martinez

    Quique-Martinez

    Joined:
    Oct 1, 2013
    Posts:
    141
    Hi, is it possible to generate the textures of an existing terrain?
    Thanks
     
  24. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    Personally I use this simple script I've made to save all kinds of assets: terrain datas, meshes, materials, textures - all those assets that were made procedurally and are not saved in any file yet. Select the terrain (not MM or it's tile, but the terrain itself), and press Edit - Save Asset - Terrain. Can save multiple selected terrains too.
    Plan to integrate it in MM in 2.1.0, to make saving terrain to tiles similar to pinning them.

    Just a note: when terrain saved as an asset, it's still changed by MM. Technically there's no difference whether terrain is saved in scene or in file. To create a snapshot duplicate the saved asset - this will store copied terrain at it's current state.

    Feel free to write ideas/issue here, but I would be grateful if you could use idea.informer (or just duplicate them here). So far it is the most convenient way to keep things organized.

    I plan to expose node width value in graph settings, but hmm... making them changeable, the way it's done with the group... I'll think this over. Thanks for idea!

    Are you using the Import node and the Imported Map asset?

    The thing is Forest generator is not operating with the real distances between trees. It uses a map based on density settings, where each tree is a pixel. It was not designed to clean up closely located objects, however, there's a special node aimed to do that - Rarefy.

    Unfortunately no, not yet. At least this month - then I plan to announce a new module that can change existing terrain. It should make MM a hand tool for level-designer. Will share more details when I'll settle down what exactly it should do and how, and probably record some video.
     
    mick129 likes this.
  25. Quique-Martinez

    Quique-Martinez

    Joined:
    Oct 1, 2013
    Posts:
    141
    That sounds great!!!
     
    zrocweb likes this.
  26. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    So I'm an edge case, and I have solved this for my use, so nothing you need to do. I tried your script, and it is cool. However, it does not copy the CTS splatmap to the terrain.

    Your CTS Output node is writing directly to the CompleteTerrainShader.Splat1/2/3/4 textures. (CTSOutput.cs ApplyData())

    I solved this by writing the Splat1 to the alphamap of the terrain. I posted my code over on this thread.

    So, now my process is simple.
    1) Tweak graph until I'm happy.
    2) Run DoExport()
    3) Delete MapMagic and children.
    4) Drag terrain data into the terrain.
    5) Add CTS and VS Pro to terrain.
    6) Static map with all desired data.

    I'm very happy with this workflow, and it gives me some peace of mind so that I don't accidentally regenerate the terrain and lose all of my customizations.

    Done, great tracker. Thanks.

    I would say if you expose a variable that I can use to adjust the width easily, that would be sufficient. No need to spend a ton of time making them resizable.

    Edit: Based on what you said, I realized I could adjust it. I went in and changed nodeWidth from 130 to 200 and now I can read all of the labels. Hah, sometimes I forget that everything in the editor can be changed.

    No.

    Example to reproduce:
    1) Create empty scene. Open empty scene. (With camera and directional light.)
    2) Create -> MapMagic -> Template Graph
    3) Drag resultant template graph into the scene.
    4) Save.
    5) Open and inspect the Scene.unity file.

    Observe it is saved as binary.

    I have found that once you export the TerrainData to a saved asset, the Scene.unity file reverts to saving as text again.

    Thus, this is no longer an issue for me since my process above ends up with standalone terrains and text scene files. Which is what I want to track in GIT.


    Again, thank you for the amazing asset. I picked up the MM2 bundle, and I'm very happy with it. The splines are awesome.
     
    Quique-Martinez likes this.
  27. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    Oh man, I can't recommend this enough.




    Adjusting the node size to 230, now I don't need to be able to zoom in anymore. The larger nodes automatically make the previews larger, and this is beautiful!
     
    protopop and zrocweb like this.
  28. zrocweb

    zrocweb

    Joined:
    Dec 19, 2016
    Posts:
    43
    Hi Dennis. I have confirmed there are def issues with MM2 when using IL2CPP on build, in both native and non-native modes as well as in standard 3D Rendering and especially in URP Rendering.

    Note: Below findings are for builds only.

    In Standard 3d Rendering (x86 and x86_64 architecture):
    IL2cpp w/out Native C++
    If you don't pin tiles, no tiles get generated on builds
    If you pin tiles, only those tiles generate along with tress and objects on those tiles. All neighboring tiles only generate the draft tile and are not stitched properly to connecting tiles.​
    IL2cpp w/Native C++
    No tiles/terrain is generated with or without pinning tiles.​
    In URP Rendering (x86 and x86_64 architecture):
    IL2cpp w/Native C++
    If you don't pin tiles, tiles generate but neighboring tiles do not stitch or generate from draft
    Thread(s) seems to lock up the main thread after a min or so and build will just hang if it does not crash​
    IL2cpp w/out Native C+++
    Same result as above.
    I truly hope you can get MM2 to coincide with IL2CPP as IL2CPP is so much faster and cleaner, especially for final builds. Additionally, I know Unity will be phasing Mono out as a backend scripting method and pushing IL2CPP as it sole replacement, for performance issues, etc.. So any insight you have here would be greatfull!
     
    Last edited: Nov 25, 2020
  29. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    91
    Is there a way to save the TerrainData generated by MapMagic into an asset file?

    Thanks
    David
     
  30. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    @cybie Read what I wrote 3 posts above yours. I linked to a script I'm using that includes CTS splatmap. Or if you just need the terrainData use the link from Wright, 5 posts above yours.
     
    cybie likes this.
  31. longiy_

    longiy_

    Joined:
    Nov 22, 2020
    Posts:
    3
    Neat, can I ask, where do I change the node size value?
     
  32. zrocweb

    zrocweb

    Joined:
    Dec 19, 2016
    Posts:
    43
    Add a noise generator with generally low values to the other trees pre-nodes(top right nodes in your pic). Blend the noise into that and plug your lower middle nodes into the blend of these trees that are currently routed to your other trees node. should spread them out a bit and not make them grow into each other so naturally.
     
  33. sarynth

    sarynth

    Joined:
    May 16, 2017
    Posts:
    98
    Assets/MapMagic/Nodes/Editor/GeneratorDraw.cs

    public const int nodeWidth = 230;
     
    Chusuk likes this.
  34. jimmygladfelter

    jimmygladfelter

    Joined:
    May 3, 2020
    Posts:
    83
    Ive included my map magic integration for those who were asking about my island. Hopefully you guys can see what I was doing with these graphs/functions/etc...the main one is mainscene. @arjobmasher @zrocweb

    fyi..the water level is 418
    The trees are all speedtrees and the rocks are from naturemanufacturer
     

    Attached Files:

    Kaen_SG, sarynth, camta005 and 2 others like this.
  35. zrocweb

    zrocweb

    Joined:
    Dec 19, 2016
    Posts:
    43
    Thanks. @jimmygladfelter check your inbox.
     
  36. cacotigon

    cacotigon

    Joined:
    Jun 12, 2015
    Posts:
    9
    I'm having the same issue, infinite terrain does not seem to work with WebGL builds in Unity 2020. It only shows the initial tile's worth of terrain, but if I move around nothing happens.

    Works in Windows builds and inside Unity though.

    @Wright is this something that is going to be addressed in the near future? I just want to get an idea timetable wise as I may need to look into other options.
     
  37. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    Thanks for the findings! I will definitely try to fix it for the next version 2.1.0 - going to release it in two weeks (still a plan, not promise). At least I'm going to make it work without native code - theoretically it should be converted to C++ on build, so the performance should be about the same.

    Thanks for sharing your work! Guess other users will find these biomes and functions useful too. Would be great if you could insert a link or screenshot just to give an idea about contents.

    Hope it is related with IL2CPP issue - symptoms are pretty much the same. But if not - will be finding out for the next release after 2.1.0.
     
  38. zrocweb

    zrocweb

    Joined:
    Dec 19, 2016
    Posts:
    43
    Hi Dennis. Thanks for looking into. Much appreciated. Hopefully you will find the conflict(s).

    Having another issue though in standard 3d Rendering. Have no tiles pinned and for some reason, all of a sudden, everything renders except for the actual terrain itself. Trees, grass and other objects appear but the terrain is not there. For the heck of it, I tried adding the "nature/Terrain/Standard" to the included shaders for the build, but for some reason it's still not rendering. Don't know what could have happened. Have tried everything at this point. Only thing that works is pinning a tile which I'm not apposed to but prefer not to. Just wondering if the Infinite Terrain (Playmode) settings for the "Generate Terrain Markers:" is doing something weird. I have both options checked with a "player" as the tag.

    If anyone else has come across this happening to them, please share your resolve. Driving me crazy.
     
  39. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    zrocweb, what shader to include depends on current rendering pipeline. Nature/Terrain/Standard fits only for standard one, if you are using URP or HDRP shaders should be different. You can find them by creating empty terrain and looking into it's material.

    And other thing: in Shader Stripping below Instancing Variants should be set to Keep All. Otherwise Unity will throw out not used variants.
     
  40. zrocweb

    zrocweb

    Joined:
    Dec 19, 2016
    Posts:
    43
    Hi Dennis. Yes understood. I was using URP but have reverted back to Standard Pipeline with a new project. Seems it may be an issue with non-pinned tiles. I believe I have always pinned at least 1 tile in prior scenes and perhaps that is why I have all of a sudden been getting no terrain when no tiles are pinned, regardless of Pipeline. If I pin one tile all tiles render properly. But will continue to look things over, could be something I have set or changed along the line somewhere.

    I will take a look and see if I somehow reversed this setting. Perhaps that is the reason for non-pinned tiles not rendering the base layer(terrain).

    Thanks Dennis! Appreciate the quick response!
     
  41. camta005

    camta005

    Joined:
    Dec 16, 2016
    Posts:
    320
    I looked into this issue a while back, check this post:
    https://forum.unity.com/threads/rel...al-land-generator.875470/page-10#post-6394982
     
  42. David_AuthorDigital

    David_AuthorDigital

    Joined:
    Apr 16, 2020
    Posts:
    3
    I have a couple of different issues that I wanted to find out if there are solutions for:

    1. When using Microsplat with MapMagic 2, I cannot paint terrain textures when I lock an area of a pinned terrain tile. I can paint trees, detail vegetation, and heights. Should this work? If not, is there any way to get it to work?

    2. Using MapMagic 2 in an HDRP project, I cannot see some of the scene window area indicators. In particular, if I lock an area, I don't see the two circles outlining the locked area. Similarly, if I select the "Pin a new tile" button on the mapmagic object, I don't see the light blue square outlines showing where tiles could be pinned in the scene.

    Versions: Unity-2019.4.9f1, MapMagic 2-v2.0.8, MicroSplat-3.51

    Thanks for any help!
     
  43. aganm

    aganm

    Joined:
    Sep 25, 2019
    Posts:
    114
    Hi!

    Is infinite terrain supposed to be used in real time or is it meant for generating background scenery on game start? I ask this because if I walk outside of the original terrain, the infinite terrain generation makes my game freeze for a moment.

    Using only map magic, it takes about 5 seconds for the new terrain to get generated when I walk outside the original terrain. But if I use vegetation studio pro on top, then it takes 30 seconds to generate all the new terrain.
     
  44. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    MicroSplat requires the standard splat maps applied to terrain to perform paint. You can try using MicroSplat output together with the standard Textures Output. Not sure if it is convenient or will work at all, so I'm planning to properly combine these two outputs together in 2.1.0

    Could you please check if you have gizmos enabled in a scene view (Gizmos button at the top right corner of the scene view window)? Tile frames and lock circles are the gizmos and work similarly to Unity's camera frustum or light cone gizmos. They are not displayed and edited when gizmos toggle is disabled.

    By the default MM copies the vegetation system on newly created chunks - this takes some time. However you can speed it up by disabling "Copy VS" in VSPro output's advanced settings. This way it will use single vegetation system per all tiles.

    Do I understand it correctly that you've got the game freezing for 5 seconds in one frame when applying new tile? If so then there's definitely something went wrong - usually the apply frame time does not exceed 100ms in worst case. Might there be something with the number of objects, or resolution?
     
    mick129 likes this.
  45. mick129

    mick129

    Joined:
    Jun 19, 2013
    Posts:
    228
    You made my day, thank you 1000x!

    I had to do this workaround for another project and it is very hard especially if you have multiple biomes and "what you see is not what you get". So if you need to check the ground for X texture (like for footsteps noise) you may need to put the grass's noise on the sand even if the connection is clearly grass to grass with the same texture.
    In any case, thanks again this will unlock some possibilities :).
     
  46. aganm

    aganm

    Joined:
    Sep 25, 2019
    Posts:
    114
    Yes, the game is freezing for 5 seconds in one frame when a new tile is generated (in the main range).
    I have "Copy VS" turned off.
    I think the problem is that the VSP objects are regenerated for the entire map every time a new tile is created.

    The process appears to go that way:
    - Map Magic creates the center tile
    - VSP regerates objects for the center tile (takes 3 seconds)
    - Map Magic generates a new tile
    - VSP regerates entire map (takes 4 seconds)
    - Map Magic generates a new tile
    - VSP regerates entire map (takes 5 seconds)
    - Map Magic generates a new tile
    - VSP regerates entire map (takes 6 seconds)
    (and repeat until all tiles are created)

    If I have "Copy VS" turned on, then VS only generates the objects for each tile instead of regenerating the whole terrain every time. But when I use this option, my VS objects on my center tile disappear as if Map Magic forgot to copy VS for the center tile.
     
  47. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    2,226
    Is it disappearing in editor, in playmode or in build? Is there a reliable way to reproduce this issue? And what about performance with Copy VS?
     
  48. zrocweb

    zrocweb

    Joined:
    Dec 19, 2016
    Posts:
    43
    Hey Thanks for your input and response. Yes I have tried those and have to do one of the three do get it to build properly. no worries. Prefer not to but is ok. not a game changer. MM2 is more important to the project and will just pin something in the distance or something else..
     
    camta005 likes this.
  49. zrocweb

    zrocweb

    Joined:
    Dec 19, 2016
    Posts:
    43
    In regards to MM2 and IL2CPP I think it's a major Unity Bug with 2019.4.14f(lts) +
    I havne't lookinto the actual bug yet but it's listed multiple times on your bug trackers for the LTS version and could be casing the issue relative to MM2 / IL2CPP builds.
     
  50. mick129

    mick129

    Joined:
    Jun 19, 2013
    Posts:
    228
    I'm trying on two different projects and the result is the same. Infinite terrain seems to work on "play mode" but once the game is built, it doesn't load any terrain.

    The main terrain distance and draft terrain are both set to 1
    They are set to follow the Main Camera but I have also tester with following the player with the tag "Player" and it is still not working.
    I also have no error when I build any of those projects.

    Edit: I'm still testing to see if I can fix it or what is causing it

    upload_2020-12-4_17-43-37.png
     
    Last edited: Dec 4, 2020