News:

Simutrans Chat Room
Where cool people of Simutrans can meet up.

Make world limits not forced to water level

Started by Markohs, November 16, 2012, 01:39:10 PM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

Markohs

it's actually a good idea, the problem is the random component on the pattern, I'll see what can I implement, have something almost finished.

IgorEliezer

^ You know I was kidding, don't ya? Some of us play Minecraft and these mash-ups are kind of inevitable. :D

If you are going to implement some kind of pattern, it doesn't need to look exactly like that nor does it need to have those random generated caves shown in my montage. These caves have a purpose in Minecraft, in Simutrans they would look somewhat out of place. Players would wonder "what those thingies are doing there?". The simpler, the best.

For me, a flat dark grey with brownish borders and being able to see the depth of water masses would be enough and better fitting.

Markohs

Yes, I know you are kidding. ;)

But the thing it's that adding some variety to the slope is one thing I was thinking of, because I'd like to add soemthing sightly better than the image your showed. In fact, now sea can be deeper so we can have even deep water, so more slopes are needed there. Soon I'll have some SS to post here so you can all give your opinion. :)

Markohs

Btw, wich is the program you screenshoted, Igor, Minecraft? Where can I get it? I'd like to drag some info about it.

IgorEliezer

#74
The screenshot I took is not from the actual game, it's a map render obtained through a 3rd party tool. Wait, let me explain each part. ^^'

Minecraft is a 3D, 1st person, sandbox construction game where players mine resources (mainly ores) and build anything such as farms, machinery, rail tracks, towns or whatever, and explore procedurally generated environments made entirely of blocks, pretty much like playing Lego, but inside it a là Lost series (after 10 minutes playing the game you'll understand the "Lost series" part).

Purchase: https://www.minecraft.net/
Wiki: http://www.minecraftwiki.net/
A sample of "1st day" in Minecraft: https://www.youtube.com/watch?v=v41aZQhOcfI

The map render is made with a tool, Cartograph G. Once you have created a world in Minecraft and explored it a bit, you can render top-view and isometric maps of your worlds.

Download: http://www.minecraftforum.net/topic/153066-cartograph-g-map-your-world-minecraft-14/

It's possible to get the source-code of the game and give a look in (programed in Java). The company that develops the game doesn't mind about it much -- as long as you don't build and publish "parallel" versions of Minecraft -- they're pretty open-minded, since it helps fan-coders to make modifications and tools for the game and spread the game even more.

almaf

#75
Quote from: IgorEliezer on March 11, 2013, 01:44:33 AM
These caves have a purpose in Minecraft, in Simutrans they would look somewhat out of place. Players would wonder "what those thingies are doing there?". The simpler, the best.

I remember some discussion here about coal mines, iron ore mines, linked to the map (real mines from beneath the earth). Perhaps, this Minecraft style, is the way to add some "real" coal mines to Simutrans.

Isaac Eiland-Hall

In Minecraft, there are small seams of coal and iron - very small and frequent. It's not actually a good model to copy, although some inspiration might work.

There is the concept of biomes - different types of terrain. These are mathematically computated such that given a particular seed, consistent maps are generated (like maps in simutrans). The main problem right now is that there are a number of different biomes - from jungle to desert to forest to taiga (winter snow forest), and these all generate in patches. Well, that's not the problem; the problem is that they are all randomly mixed. So jungle can border taiga, for example... and desert next to forest.

So, that being said - if there was a way to automatically generate a more logical dispersion... we could have that in Simutrans - snow at some latitudes; and biomes scattered around; some mountainous, some plains; some with more rivers; some with more trees; and below them, some with coal seams and iron ore seams....

...but it would be a complete rewrite of how maps work, and so many gotchas - how to handle expanding maps, for one example.

But it also might be awesome. heh

IgorEliezer

#77
Quote from: almaf on March 11, 2013, 01:52:20 PM
I remember some discussion here about coal mines, iron ore mines, linked to the map (real mines from beneath the earth). Perhaps, this Minecraft style, is the way to add some "real" coal mines to Simutrans.
The discussion that I can recall was about the position of the mines on the map. For example, coal mines would be generated according to the climate, proximity to rivers, topography etc... I think it's pretty sensible for Simutrans. In Minecraft, ores are generated according to the depth (the rarest, the deepest) and biome. Coal can be found anywhere and at any depth; iron can be found anywhere under sea level; emerald anywhere in the deepest layers and at any depth within mountainous biomes, and so on.

The thing about "real" coal mines is that, the focus of the game is transportation, I don't think the someone would also want to manage a mine or any factory of the game too. The factories pretty much put their goods in their yards and expect you (the transport company) to transport them.

Quote from: Isaac.Eiland-Hall on March 12, 2013, 04:16:09 AMThere is the concept of biomes - different types of terrain. These are mathematically computated such that given a particular seed, consistent maps are generated (like maps in simutrans).
(About biomes in MC: http://www.minecraftwiki.net/wiki/Biomes)

If someone who doesn't own Minecraft yet but wants to mess around with how Minecraft maps are generated, there's a little tool that can "preview" maps, AMIDST.



( :warning: SPOILER :warning: If you're a Minecraft player, don't use it on your world if you don't want to spoil it. :warning: SPOILER :warning: )

It's just a little EXE that doesn't require the game installed. Once you've downloaded this tool, double click the EXE, go to File > New > From Seed. Type anything; then any world type, a map will be generated out of the seed you typed. The map can extend up to 60,000,000 meters large... if you're deadly bored.

Markohs

 Since we got a release today finished, I commited the patch to SVN, next nightly will have it already.

Visuals for world slopes are not implemented in the commited version, just black background. It also causes a savegame version step since saved games will not display properly in previous versions.

Visuals for the world slopes will come next, testing is welcome.


Once kierongreen has time to review his double height patch to make int compatible with this, I'll make the necessary changes for it, ofc. ATM this patch is incompatible with double heights.

Dwachs

Looks good so far! I took the freedom to wipe out some dead code.
Parsley, sage, rosemary, and maggikraut.

Markohs


prissi

Wouldn't it make sense to terminate the for conditions now earlier in simview. It would save looking up nonexisting tiles, since there will be nothing drawn anyway.

Markohs

I don't know if I understand you fully on "looking up nonexisting tiles", on my secound update I changed it back to grundwasser level.

Anyway if you see anything worng, just change it as you feel, I'll just focus displaying world slopes now (I'll make it optional) and fixing any bugs that might arise and you rest of developers don't catch.

What needs to be solved is welt->get_minimumheight() and get_maximimheight(). We can maybe allow the player/pak creator to set that values. I'm unsure of how to implement it, if you want to change it, do it.

Go ahead, change it if you want. :)

prissi

Sorry, I will not be able to dig through such a patch so quickly. I mean in simview, you iterate over tiles in lines. However, as soon you reach the right border, no further tiles will appear and you can go to the next row.

Furthermore, if the skip condition never occurs, no need for drawing the black area around at all. Both should not be very difficult to implement and could improve drawing performance.

Dwachs

The redraw-black part could be implemented as follows:
-- The ground tiles at the north and west edge draw the region above them on screen black.
-- The ground tiles at south and east edge do the same for the region below them
-- The ground tiles at the north-east and south-west corner draw the screen right and left of them black, respectively.

This could be done in simview / display_region.

For underground mode, there is no such simple receipt to black out parts of the screen.
Parsley, sage, rosemary, and maggikraut.

kierongreen

Setting the entire screen to be black is quicker than painting individual black tiles if the area is more than a handful of tiles .

Markohs

#86
 The algorithm is not trivial because it needs to fill a diagonal zone on screen and I doubt its performance whould be good. Anyway it would be better than this full screen darkening since most of the time the player is not on the edges of the map, I guess, and this new algorithm should not impact performance.

I wish there was some way to clear screen in an instant like glClear does, OpenGL and Direct3D clear screen before each frame and draws afterwards. Maybe there is some way to do this in the Windows and Linux backends, that would solve our problems. I just need to clear the buffer in constant time, I'll investigate if this is possible.


Edit: maybe we can use memset ? Maybe that's fast enough.

Ters

Diagonal zones? Maybe you misunderstood Dwachs, like I first did. (Unless I removed the problem by misunderstanding the second time.)

But I might have an improvement on Dwachs' idea, if the screen position of the northwestern and southeastern corner of the map can be found. Filling vertical regions is not as fast as horizontal region, but if Simutrans could clear the entire regions, from left screen edge to right screen edge down to the tip of the uppermost tile (northwestern corner), and similarly below the tip of the lowermost tile (southeastern corner), one could then use Dwachs' third rule to clear the rest, all using horizontal lines. One would however need to consider all tiles on the edge of the map, unless one it is possible to find and use the uppermost and lowermost visible tile.

Markohs

did not read dwachs post carefully enough. it makes sense, I'll try it that way.

Markohs

I've begin to implement it and to speed up the test to check if the grund_t item is in a border position I've think caching this information in a member variable, and updating it on map redimensioning, if not I'd have need to do a test each time a tile is drawn:


   is_border = pos.x == 0 || pos.x == welt->get_size().x || pos.y == 0 || pos.y == welt->get_size().y;


What do you think?

I've also thinik of making this a direction mask to indicate in wich of the dimensions this tile is a border, because it can be of two dimensions, NW,NE,SW and SE.

From this is easy, just write black to the corresponding direction as Dwachs/Ters pointed out (depends of the hang, but it's doable easy), and the normal algorithm whould just do an extra test for every displayed tile, I guess this will imply no performance diference. And it's only 8 bits extra for each grund_t in map.

Ters

It might be not just 8 bit due to alignment.

Dwachs

Imho it is not necessary to store this information. If you like, one bit is enough: tile is on boundary or not. Then one can determine the precise boundary by looking at the position.
Parsley, sage, rosemary, and maggikraut.

Ters

My impression from the latest performance problem reports is that Simutrans isn't exhausting the CPU with instructions, but possibly with data.

Markohs

well, a boolean will prolly have a size of 8 bits too at minimum I guess. It's not so important through, I can change it. What's not working so good with the algorithm is:



I'll have to detect this situation too, this is not so easy as it looks.

Oh, I wish clearing the screen to a solid color was faster... :(

Ters

Isn't that zone point 1, second clause of Dwachs' suggestion? It is also the weak spot of my improvement, though I offer two suggestions.

Markohs

 Dwachs suggestion talks about painting vertically, I implemented it horizontally, that's the problem, I misunderstood what he said, again.

As you say, I fear vertical painting is worse performance-wise, that's what I was thinking horizontally, but that exposes the problem I screenshoted above.

I still don't understand you fully on your improvement suggestion. If I understand it correctly it will only increase performance if the NW or SW corner is on screen, rest of the cases it won't improve nothing, with overhead calculations.

Yes, you can determine easly the on-screen position of the corner tiles and know if they are inside the display or not.

What you don't know, is if those tiles will be processed, it depends if the viewport contains them or not.

Anyway I think it can cause be some problems on the edges of the screen, but this is just only a gut feel. I'll see.

Sorry, will get back to this now. :)

Ters

Above a tile, you don't need to draw vertical lines, but columns of <tile width> horizontal lines down until you reach the top of the tile. That same tile's horizontal lines will then take the rest. Similarly for the bottom. The down side is that areas will be clear twice, both by the horizontal rows and the vertical columns. I don't know if you can get into the viewport a region that is neither above/below or to the left/right of any tile. I think it might happen on very small maps and/or when zoomed far out.

That my version only offers an improvement when the NW or SE corner is in view is in a sense both right and wrong. It is true that it won't do anything if these are not in view, but in all cases, it should avoid the need to do clearing in vertical columns above/below edge tiles. However, one needs to clear to the left/right of edge tiles, even if that tile is outside the viewport horizontally. If the tile is above or below the viewport, it can be ignored. Alternatively, one must clear all lines above the uppermost visible edge tile, and below the lowermost visible edge tile. I haven't looked at the code in a while, so I don't know which, if any, solution works.

Fabio

Quote from: Markohs on March 20, 2013, 05:59:16 PM


Just my 2 cents: the scroll could be limited so that at maximum scroll a map corner lies on the window border. This would reduce cases where half or more of the window view is black. Could this speed things up somehow?

Markohs

Naj, no need to do that, the algorithm Dwachs proposed should solve all those problems.

Markohs

#99



The same problem arises with Dwachs implementation. Imagine the viewport is in the RED square. Only the tiles under the arrows will , from right to left be processed. Areas on the yellow part doen't have a grund_t item associated so they are skipped, but are lookuped on the algorithm.

The yellow-gray area is painted in vertical stripes by the border tiles, but... who will paint the green part?

Maybe the best option will be on camera movement checking if there will be any area of the screen off-map and activate the full screen black only when necessary. That will keep performance unaffected in the player is not looking near the world limit. If he's near the map limit he'll be affected by this 30% performance hit prissi talked about. Maybe even we can activate screen darkening just 1 frame after camera darkening, and not doing it again until the camera moves.

Dwachs

This part has to be drawn in the routines of simview.cc directly. It should be possible to  figure out the position of the green stripe on the screen.  ???
Parsley, sage, rosemary, and maggikraut.

Markohs

 What do you think of my idea of just clear the screen black on a camera movement? I that should solve all problems and has even better performance.

Only problematic when movable objects higher than a tile (planes maybe) or high buildings (we could maybe draw just one tile black on top of border tiles. On a gui element movement we should force screen black also.

Markohs

#102
Okay, decided to implement it like this:

1) a welt->set_dirty() will trigger a whole screen clear in black, *JUST ON NEXT FRAME*, this happens on camera movement and zoom change, so it will only impact on the performance of one frame. This can be optimising checking further if the four corners of the screen are inside of the map or not, but the performance gain already is huge (will only trigger unnecessary redraws when following vehicles..
2) West and north tiles display a vertical column of wide/2 of black, for the rare case of high buildings or planes being just on the edge of the map can be over the background.
3) Right now I tag all border tiles even the N  and W ones are necessary. This is intended, S and E ones will have world slopes that I'm implementing on a separate patch.
4) Back background now I'd like to give the chance to the user/pak creator to change the desired color. I'd also like to allow him to use a image to be repeated, this will be implemented also if you don't mind.
5) I added some extra variables (a member bvariable in the view for example) that are not necessary, I'll clean up the code when I have this working.
6) the threaded version of simutrans triggers an artifact in the merge of the threads drawing area, I'm not sure of how to eliminate it atm, any idea? in the image I posted you can see it in yellow, not far from the middle of the screen.

Note: The alrogithm Dwachs and Ters posposed whould have been able to do the same, but at the end I decided to implement it like this because:

1) It's simplier.
2) Saves memory I/O bandwith.
3) Doesn't require much modifications in the display code, so should be easier to deal with.

To debug this easier borders draw in Yellow and red now, this will ofc be fixed.

Do you want me to discuss this in programmer's corner or we are ok here?

The patch and a image:


Dwachs

#103
I do not like that you add a member variable to grund_t. It will make this structure at least 4 bytes larger (due to memory alignment). The check for border can very well be done in any of the display-methods on the fly.

About set-dirty: What happens if there are gui windows moving in the black area?

Threaded artifacts: no idea.

Edit: The hang_t::corner_* enums are misleading: It should be north-east, north-west, se, sw instead of directions n/s/e/w.

Edit2: The dirty flag of the ground tile has to be set after drawing the border regions. Then the artefacts will go away.
Parsley, sage, rosemary, and maggikraut.

Markohs

Quote from: Dwachs on March 22, 2013, 06:24:15 PM
I do not like that you add a member variable to grund_t. It will make this structure at least 4 bytes larger (due to memory alignment). The check for border can very well be done in any of the display-methods on the fly.

I understand your reasons, but do you think expanding grund_t::flags from 8-bit to a 16-bit value can maybe be an acceptable compromise? I just need one bit, to indicate it's border, that's 1 operation per visible tile compared to 4 checks per tile, don't you think the trade off can be worth?

Anyway I can do it on the fly, of course. Maybe the difference it's not so big.

Quote from: Dwachs on March 22, 2013, 06:24:15 PM
About set-dirty: What happens if there are gui windows moving in the black area?

Oh right, fixing it, won't affect performance so much.

Quote from: Dwachs on March 22, 2013, 06:24:15 PM
Threaded artifacts: no idea.

Edit: The hang_t::corner_* enums are misleading: It should be north-east, north-west, se, sw instead of directions n/s/e/w.

Ok, changing them.

Quote from: Dwachs on March 22, 2013, 06:24:15 PM
Edit2: The dirty flag of the ground tile has to be set after drawing the border regions. Then the artefacts will go away.

Ok, changing this too. Thank you!