-
Posts
1.426 -
Joined
-
Last visited
-
Days Won
28
Everything posted by FeXoR
-
Some combat enhancement ideas (& suggestions)
FeXoR replied to Unarmed's topic in General Discussion
Moral boost in home territory seams OK to me as well. -
Flamadeck: For me that is no argument. It's like preferring "Hey, we could then have worms that glow in the dark! (OK, they stumble around like random walking protozoa... but:) They are shiny!" instead of preferring "Wow, our worms can now talk and sotialy interact with each other!". In fact not even very basic functionality like line-of-sight are in the game. Using up all available computational resources for graphics seams a very bad idea to me. I admit that the support for old graphics cards could be dropped if computers, that can have those cards, are not capable of running 0 A.D. due to the lack of other resources anyway. However, ruling out computers because they have a weak graphics card but would otherwise be able to run 0 A.D. (just for the sake of graphics) is unacceptable to me. I would accept Arguments like maintenance effort though. That doesn't include implementing features, that only the newer of the supported graphics cards will be able to display, and then (because maintaining compatibility to older graphics cards get more complicated due to this) drop the support for older ones.
-
Some combat enhancement ideas (& suggestions)
FeXoR replied to Unarmed's topic in General Discussion
I don't like capping anything. It's quite unnatural that a civilization can build some fortresses, siege rams or whatever and then gets incapable of building another one. Instead I'd prefer to balance things. Unit capping might be needed though to ensure a fluent multiplayer experience (and balancing will not help here). I don't like arbitrary group bonuses as well. Some advantages might still arise from groups but they should arise naturally (like units shielding each other, fresh troops are cycled to the groups "border", ranged units are covered by melee units or such things). I'd like the tech tree in general (including phase upgrades) to be more detailed and dispersed. That might include other phases but dependencies of technologies, buildings and units would do as well (indeed no phases would be needed then). So in general I'm not opposed to more phases but think other dependencies in the tech tree would do better. -
The gate should react only on mobile units, not on buildings. I'm not sure if the area of code where the gates auto-open/close functions life have access to such data. If so the fix should be easy.
-
Using a percentage for armour (discussion)
FeXoR replied to quantumstate's topic in Game Development & Technical Discussion
alpha123: Thanks for this patch! Any drawback in performance to speak of? Now that exponential armor is in I'd recommend to do the same for damage upgrades. Damage would be then calculated like: BaseDamage * 1.2 ^ numberOfDamageUpgrades (Again 1.2 is just an example and could be any number greater than 1. It should just be slightly greater though) This is a lot less needed then the armor upgrade change but has the following advantages: - Balancing will be a lot easier because everything scales independent on the number of upgrades - An upgrade effects all units (this upgrade applies to) the same. (This only is true if floats would be used for damage and health but using floats only for the calculation of health loss while base damage and health stay integers would be fine as well) What to keep in mind: - It still might be good to scale up base damage and health by a factor of 10. That way we'd get at least another decimal point precision (while keeping base damage and health as integers). That is not really needed though as you can see below. - I chose 1.2 as a basis because a damage upgrade is than stronger than an armor upgrade (To be equally strong it would have to be 1/0.9 = 1.11...). That way battles become more rapid with the game time (after 5 damage and armor upgrades combat will become about 1,5 times as fast/deadly). As is now (absolute damage upgrades and exponential armor upgrades) battles will take longer later in game. - Although base damage could stay integer it might be good to show the damage in the GUI with 2 decimal point numbers. In the bottom center of the screen (with one unit type selected) just 1 value could be shown e.g. if a unit type got 7 base damage and 1 armor upgrade effects this unit type it could say "8.4 Damage". In the mouse-over a simplified calculation (with base damage + damage gained by upgrades) could be shown like "7 + 1.4 Damage" while in the manual the exact formula could be mentioned with an example for a unit type (or for all units a detailed description with a table or the calculation for all possible upgrades and the resulting damage e.g. "1 Damage Upgrade: 7 * 1.2^1 = 7 + 1.4 = 8.4, 2 Damage Upgrades: 7 * 1.2 ^ 2 = 7 + 1.4 + 1.68 = 10.08 and so on). For me a main reason why I'd like to have this is because I like consistency -
Whoo, this looks interesting: http://codeflow.org/...-erosion/#video And this, hui: http://proland.inrialpes.fr/ And all open source...
-
I would like to know if and how in detail it is planned to add and/or support collision detection and line of sight. I read (http://www.wildfireg...showtopic=17334) that it's not planned. IMO line of sight and collision detection (for projectiles mainly. Units could be handled by the pathfinder) is a quite basic feature of an engine to be realistic. That doesn't necessarily mean everything should be checked for collision/sight blocking (as said in the post). Line of sight calculation for rough terrain and buildings would do I guess. About the same for projectile collision. AFAIK collision detection with the terrain is already implemented (arrows that miss stick in the ground). I'd appreciate a small information about what is planned and what is already in concerning this.
-
@historic_bruno: Your scepticism is justified. However, after having sane base terrain generation I intend to write some functions to make the flat parts more flat and the rough parts more rough. That way cliffs will form that are unpassable and a greater part of the map will be more suited to place buildings. Additionally woods and rock formations can be set to change passability. How well all that will turn out in the end is to be seen. IMO the reason for most modern RTS games not having random maps is that they likely don't have eyecandy areas. Note that most 3D RTS games don't allow to zoom out far (with few exceptions) so that those areas have to be small to be noticed. However, I don't think that should be our concern here why or if other RTS games do something or not. If something in another RTS game worked well we should think of adding it. If something went very wrong we should try to avoid it. But just because it does or does not appear often is not a criterion of quality at all.
-
Here's a screenshot of some random terrain that came out while trying to get a working hightmap manipulation library. (2 sec.generation time, no erosion applied)
-
Here's a version with a much cleaner and easier to read function. It also does not need any additional function so in principle could be copied and pasted anywhere and be used (for the map the rmgen library is still needed though). It still only produces riverbeds if the strength is set so high that interference appear. However, to clean up the interference only one decay erosion (so only a range of one tile) is needed (and not the evil hack like in the last version. Definitely a progress: erosion2013-5-14b.zip To play with: The function in question: getWaterErodedHeightmapStandalone line 783 Parameters to play with: - Number of erosion processes: Line 969 (currently 200) - The attributes the function takes: Line 1015 (description of the attributes in the line before) - Smooth the noise: Document in line 1021 (Applies a simple decay erosion once. Rivers will be harder to see but are still there) - Where the magic happens: Line 869 (Here the question is: What's the correct function? E.g. just multiplying the current version with 1/2 destroys all "river digging") Not much "qualitatively" changed though. EDIT: Some more thoughts: Information we have: - Slope := Dh = (dh/dx, dh/dy) with h = height of ground, D = Del operator, d/dx, d/dy the partial derivation in space (local) in the given direction. (This all is meant for the borders between tiles) - Volumetric flow rate: Q = W*H*v = dV/dt (We assume dV/dt depends linear on Dh and V is distributed dependent on the arithmetic mean. That might be wrong) (We could use the harmonic mean or the root mean square easily while the geometric mean might be harder to use) with W = tile width, H = water depth, v = water velocity in the x/y plane, V = water volume, d/dt the partial derivation in time (This all is meant for the borders between tiles. Assume W = 1) Information we might additionally need: - Decouple water velocity and depth (should be easily and should be the next step) -> Would additionally grand: water gravimetric potential energy, water kinetic energy, gravimetric force (and maybe water pressure) (That would mean we had all parts of the incompressible Navier–Stokes equation - if that helps in any way (which is questionable) because we have to assume the water velocity reaches it's critical speed on every single tile to be constant in time) - Water pressure (may additionally need the grounds bending) - Stress at (near) the ground and the critical stress needed to pick up material. I'd prefer to do without it because that would mean more constants to assume/tweak. What's to be done next (imo): - Decouple water velocity and depth @wraitii: As you suggested we could then use the water depth as water derivation map for the next run - Implement harmonic, root square, and geometric water distribution (I think this might really matter) Any ideas welcome.
-
I'll try to get stuff done until then (including cleaning up the many fail tries and debug code). I'll try to explain a bit how to play around with the parameters to test the functionality/outcome in different situations so flaws can emerge and what kinds of parameters are useful/have an effect (in the long run it would be nice if erosion functionality could be used as a global filter and a local painter for atlas and ofc. for random maps). That would work. But (without any disrespect to your idea - indeed I like different game modes) my focus would be to make the entire game (including structures) work on realistic terrain (while the terrain has to be scaled to the structures ofc.), not to make a game mode working on realistic terrain. For me this is part of "historical accuracy" because indeed civilizations had to deal with advantages/disadvantages in resources/space to build etc. given by terrain, ground type, flora and fauna inside there territory. Still there should be very balanced maps to ensure a non-frustrating (luck independent) multi-player experience: http://www.wildfireg...160#entry268242 And now I'll jump upon the code getting it by it's throat
-
Yep, I noticed. Though I'm still not sure why. It does something e.g. smoothen everything (though not much different from erosion simulating material just falling downhill). What it does not do is "unlinking" tiles with even and uneven values of x+y - and as sad as it is I have to admit this seam to be the cause of the river like structures. I still hope though because it somehow looks to good to be just numerical artifacts. Yes, I've done this right away (to get rid of the even/uneven noise). The result is just smoothing out the random noise of the initial ramp (mainly). There might still be some small "rivers" but no material seam at all to be carried further then one tile which is odd after 200 cycles. The effect is so sensitive that the diagonal calculations of the water drain and the carried material has to be scaled with 1/(2)**0.5 to take into account the higher distance of the center of that tiles - otherwise diagonal crinkles appear. And just to make that clear: I'm quite sure it is sane. For each tile I calculate the material carried over the border to it's positive x and y direction - not from the field away or towards it but above that border. So the calculation is not really done for the current field but for two borders of the grid. Calculating those for all tiles however exactly calculates each border once. Each tile might have it's material changed up to 3 times: 2 times when the calculation reaches the field (get or loose material over its top or right border), when the calculation reaches the field with the x coordinate 1 lower and the same y coordinate then the field in question (material transport over it's left border) and the field with the same x coordinate and a 1 lower y coordinate (over the fields bottom border). So adding the x-1 and y-1 field to compare does nothing but double the effect (because all borders are calculated twice). From the quality point of view it's exactly the same. I hoped the diagonal fields to fix the issue but that only eliminates the visual "rivers" entirely. Yes, that's true. And I don't see another sane way to get rid if the "singularities" in local minima. However, that means I have to calculate it several loops (I think). I agree that ignoring water hight might be one real flaw though. Sounds like a good idea. Just to explain why I chose the "static" version with the water not added to the fields height: This calculation is somehow the lim(t -> inf; integral(0 to t; WaterVolume/time)) for a static heightmap on each tile (which seamed nice). But indeed this describes only the unnatural case that no water is "lost". THX much for your reply. I thought I was totally stupid not to find the cause. But you hit mainly the same points as I did so I seam to do at least some things sane. Rewriting the water drain and adding a field that contains all information "unshifted" (so for example each field contains 4 slope values - for each border of the field - rather than just 2 for the borders towards positive coordinate directions just to make sure therein lies no problem). EDIT: Though somehow "cheated" (and still a bit noisy) we definetly got some rivers going here: Some seeds might be not so good so try 5 or so out: The screenshot is from seed 7752. erosion2013-5-14.zip The "hack" is from line 1073 to 1094. It splits the map in two maps, one only containing tiles with even, the other with uneven values for x+y, then applies a non-linear function to the height values (x³) and finally fuses them back additive to one map. That strengthens the structure otherwise barely to see and this is something looking quite like riverbeds. Note that this only seams to work for a "strength" parameter of exactly 1/4. @wraitii: The "multi way" calculation of material movement is in there but documented out. Not much more done yet.
-
Oh, maybe I posted an old version, so again: erosion2013-5-12b.zip Tiles with even values for x+y are somehow independent of tiles with uneven values for x+y I had something like this before and it turned out that the implementation indeed handled x and y comparisons totally independent on each other. In principle there is nothing wrong with that. But in some cases they are not only independent in a single call of the function but stay independent over multiple applies. That can cause "resonance" in space (not as normally in space and time). First some strange screenshots (all of the same seed 710 of the version above): First again the hightmap the manipulation started from: for (var x = 0; x < mapSize + 1; x++) for (var y = 0; y < mapSize + 1; y++) myReliefmap[x][y] = x + randFloat(- mapSize / 10, mapSize / 10); ...so just a ramp increasing towards x direction with a noise of an amplitude of 1/10 of the total height difference: Then we apply the changes of the functions mentioned in my previous post and get (with seed 710): Added code as final heightmap manipulation: for (var x = 0; x < myReliefmap.length; x++) for (var y = 0; y < myReliefmap[x].length; y++) if ((x+y)%2 == 0) myReliefmap[x][y] = myReliefmap[(x+1)%myReliefmap.length][y]; This sets all fields with even values for x+y to the height of the "next" field with uneven value for x+y: for (var x = 0; x < myReliefmap.length; x++) for (var y = 0; y < myReliefmap[x].length; y++) if ((x+y)%2 == 1) myReliefmap[x][y] = myReliefmap[(x+1)%myReliefmap.length][y]; This sets all fields with uneven values for x+y to the height of the "next" field with even value for x+y: for (var x = 0; x < myReliefmap.length; x++) for (var y = 0; y < myReliefmap[x].length; y++) myReliefmap[x][y] += myReliefmap[(x+1)%myReliefmap.length][y]; This now adds the height of the "next" field (so even if the actual field got an uneven value for x+y and the other way arround) to the actual fields height: ...so there is nothing but some noise at the places I thought to see rivers ...otherwise it's just a smoothed version of the original ramp. And just for comparison: for (var x = 0; x < myReliefmap.length; x++) for (var y = 0; y < myReliefmap[x].length; y++) if ((x+y)%2 == 1) myReliefmap[x][y] += myReliefmap[(x+myReliefmap.length-1)%myReliefmap.length][y]; And than I didn't believe what I saw: for (var x = 0; x < myReliefmap.length; x++) for (var y = 0; y < myReliefmap[x].length; y++) myReliefmap[x][y] += myReliefmap[x][((y+myReliefmap[x].length)-1)%myReliefmap[x].length]; ...so this is mainly the same as before just adding the height of the field with 1 lover y value instead of this with a x value 1 higher, but: I might miss something here because it looks exactly like: myReliefmap[x][y] = x * y; But I don't get what's happening here! No signs of flaws left, btw. Well, at least I got some nice shapes x) Trying to link them by adding diagonal calculations... (Who can explain the last picture is my hero for the day!) (Who can fix the functions is the hero for the week! )
-
This is the hack WORKING!!! ...somehow... Now we have to get rid of the resonance... (Seed 710) erosion2013-5-12.zip (I made a mistake before: I assumed getWaterDrainMap() returns the amount of water that drains through a tile. But it return the amount of water that drains through a tile per time! So the waters speed is already in it!) wraitii: The ramp was a good idea. I'd never have chosen values needed to get rivers if I had used a more natural heightmap because I had never seen there actually is something (because of the resonance). The used functions are only: getWaterErodedHeightmap() line 684 that uses getWaterDrainMap() line 603 ...so that should be quite easy to debug... *hope* NOTE: The many lines commented out in getWaterErodedHeightmap() are the version assuming getWaterDrainMap() returning the amount of water only, not the amount per time (which was wrong, see above). EDIT: Additionally not all tiles are taken into consideration (the last raw and line) in getWaterErodedHeightmap(). I fixed that but it does have no effect on the resonance. After the fix I'm quite sure getWaterErodedHeightmap() is correct so the problem has to be in getWaterDrainMap().
-
Yes, I thought about that too. Result (pretty equal with all functions including your proposal of applying getWaterDrainMap result as the initial water distribution for another run): ...so still no riverbeds. What I actually do: myReliefmap = getDifferenceOfFields2D(myReliefmap, getDiv2d(getProductOfFields2D(getRescaledField2D(getWaterDrainMap(myReliefmap, 0), 1), getGrad2d(myReliefmap, false)))); With: - myReliefmap: The heightmap the erosion should be applied to (a scalar field). - getGrad2d(myReliefmap, false): The slope vector field (the 2D projection of the normal vectors). I assume the water speed between tiles depend on the vectors length (which might be wrong since it might be the square of it or something). The second argument just means that the field is generated assuming myReliefmap is not "wrapped" (top +1 = bottom, right +1 = left). - getWaterDrainMap(myReliefmap, 0): The amount of water draining through each tile (calculated downhill, a scalar field). I scale this to have a maximum value of 1 (with getRescaledField2D) and than scale the slope with that (with getProductOfFields2D() assuming the amount of material carried by water equals the waters impuls = amount * speed [assuming its density is 1]). The second argument is the "seepage" (how much water sinks into the ground and so is lost to run further downhill each tile it passes). - getDiv2d: Calculated the amount of material carried from one tile to the other downhill. Second argument is "wrapped" like in getGrad2d(). - getDifferenceOfFields2D: Actually applying the change to the heightmap. NOTE: The only real difference between this and "decay erosion" (where just some material "falls"/"rolls" downhill) is that the slope field is scaled with the amount of water gathering in "channels". This is (in opposite to everything else) a global effect and so takes much longer to calculate. What we might miss is that we need to calculate the "pressure" of the water towards the ground. That would be proportional (maybe not, maybe square or something) to the "bending" of the ground (where the water is driven upwards - in holes with positive bending - it carries away more while leaving material where it's "falling" - on hills/ledges with negative bending). Not sure right now how to calculate it though it should be similar to how to get the slope by grad(heightmap). So the bending would be the differentiated slope field (this cannot be grad because the slope field is a vectorfield though). So small "hills" are lengthened downhill (the direction the material is transported) while shortened uphill (since there will be a "hole"). Mainly the same thing with holes (dug out downhill while filled uphill). That's what may "dig" riverbeds. (For physicists: The second-order term might be needed to generate riverbeds). EDIT: Indeed the pressure is (at constant density) the square of the speed. I can't find any formular for this (material carried away by water "raining" down equally distributed on a given heightmap). Instead I find tons of formula to calculate the waters pressure, speed, density (though it's nearly incompressible, tztz) dependent on each other or the width of riverbeds dependent on the amount of water etc.. Further thoughts: So still no real clue and any input welcome.
-
Hm. I got it working (as far as I can tell as I planned). Some screenshots and the evolution of the map after a different number of water drain erosion steps: [steps: 0 (just a random heightmap), 1, 2, 5, 10, 20, 50, 100, 100 (zoomed out)] ...so it somehow works. There are still no signs of "riverbeds" though x) I tried to apply it to a more smooth heightmap (like the one in my last post) but still no riverbeds. Maybe I have to take into account material of different hardiness? At least it gives a quite different shape (more spiky hills and more flat low areas) than the other erosion functions (though it's quite slow ofc.). I don't understand the effect of the "seepage". It only seams to strengthen (lower values) the effect so higher seepage but more loops give about the same result as before. (If I rescale the water drain speed field to a fixed value before applying it changing the seepage does seam to have no impact at all). Maybe I'm doing something wrong again x) However, I am not entirely sure that the library functions work properly or can be defined better/faster etc. so if someone would be willing to look through at least the 2D part at the end that would help me greatly. fexor_hightmap.zip Any help/suggestions/ideas very welcome!
-
Help! I got stuck with erosion functionality somehow... There are generally some different (abstract) erosion types: - Decay erosion: Caused by sun, gravity and slight vibrations of the earth. Implementation: Easy and fast. - Directed erosion: Caused by wind or sun mainly coming from one side. Implementation: Fast but not that easy to adjust by parameters. - Water drain erosion: Caused by rain draining downhill forming rivers and gathering in pits. Implementation: Slow and not really working at all. Maybe I didn't find a good approach at all for water drain driven erosion. I mainly implemented some general functions to handle calculations for scalarfields and vectorfields. I use a discrete version of vector analysis which may in the end be a bad way to do this. Maybe an algebraic approach would be better and faster. Here's what I got:so far: discreteVectorAnalysis.zip Some basic functions for discrete vector analysis. The first part works for any dimension but is emmensly slow. So I added some 2D functions that are much faster later in the file. fexor_hightmap.zip A random map to test things (very unorganized, sorry). In it many ways to simulate and apply the different types of erosion and visualize the multiple fields. The only function that seams to work for water drain erosion is getWaterDrainMap(). Uncomment line 858 to paint it (for color code see drawFieldAbsOnTiles() line 165). However, I can't seam to find a way to scale it right to do something sane. BTW: It ignores the height of the water so in pits it's somehow singularly. (For a little orientation: Functions ending with DVA are extremely slow so avoid them. Functions without DVA and 2D are (more or less) stand alone functions not needing discreteVectorAnalysis.js ) I tried to avoid "multi step" water drain simulations (like suggested by myconid) because they are so slow. Maybe it sinply can't be done without multiple simulation loops for each erosion step. If anyone has any idea or information about how the transported ground material depends on the amount of water and it's speed draining through this field - that would greatly help! As well I'm not exactly sure how water speed depends on steepness (and/or how water distributes depending on it). Screenshots: Just a hightmap formed by decay erosion: Water drain field on the same heightmap (water removed to see the bottom of pits): Color code: Amount of water draining through the field: yellow (not much), neon green, green, light blue, blue, purple, red (very much)
-
True. But I don't think it's a good idea to have 3 ways to initialize a map. A rough concept (nothing more than the order of things) I have in mind would be: 1.) Generating abstract map data structure: This would include the terrain and placements of entities (if any). If it's a random map just an empty map is generatet fitting the settings in the RMS .json file. If it's a scenario it will be (more or less) entirely loaded after this stage. For skirmish maps just some entities has to be replaced later. 2.) Map manipulation: If it's a random map script some manipulations are made to generate the map. For a skirmish map the "placeholder" entities of the start positions are replaced with the appropriate entities. (When we have triggers implemented they could be add here for custom scenarios etc.). 3.) Loading the map: Now that all map data are present actually load the needed entity templates and the terrain art etc. and initialize the game. That way we only have one way to load maps. Additionally all the RMGEN stuff could (not need) to be done with triggers (as far as all needed functions work with the abstract representation of the map and don't need the art etc. loaded. Entity templates might be needed earlier on though e.g. for obstruction/terrain analysis for AI and stuff, not sure here). If all map types are initialized the same way it would need to be linked in a similar way so it also might get easier/more urgent to make shared libraries like mentioned here: http://www.wildfireg...showtopic=17052
-
This also happens to be related to a recent post of mine: http://www.wildfiregames.com/forum/index.php?showtopic=16887&st=80#entry268738 ...because random maps and scenarios happen to be initiated differently. So I think it would be good to grab this issue by it's roots.
-
...and for that we need some quite fundamental design decision - the earlier the better, the later the more over all work. My last related post concerning this (with links to older ones): http://www.wildfireg...showtopic=16887
-
I'm not sure but don't you think something like this is "discussed" better in a (so-called) "social" network or another place where it's more about opinions/believes than about developing a game? I saw some more helping posts of you. I'd appreciate if you try to focus on that even if that might be hard for you.
-
Triggers (split from A couple of suggestions)
FeXoR replied to Kimball's topic in Game Development & Technical Discussion
I don't think triggers should be made to fit the campaigns needs. The map designer, random map generator API, triggers and player-AI-API should be as powerful as possible and general purpose tools (and not designed to work for specific needs and only work well when used as "meant to be used"). ATM only Atlas seams to head the right way (AFAIK). So we need to figure out a new "structure" for scripting or something IMO so that all parts can access any information they want (or at least as many as possible) without causing to much headache to debug (and not only those thought to be needed). In the end this will cause much less pain adding new features and less work to make all parts work well together. We have to keep in mind here that player-AIs are meant to be threaded. I personally am horrified by the current situation where every part has it's own libs and cannot (easily) access those of another part. I explained why at various parts in the forum and in track (which was maybe a bit stupid because now I can't find most of it). Zoot noticed that and opened a topic for that some time ago: http://www.wildfireg...showtopic=17052 THX again, Zoot! A related ticket would be: http://trac.wildfire...com/ticket/1589 Another related topic: http://www.wildfireg...showtopic=16096 We had some discussions about triggers before and it was agreed on (to my disappointment) to wait until part 2. However, if we implement triggers they should be general purpose triggers. Otherwise I agree it's better to wait until part 2 but to implement some basic triggers - because they will be used and it will be more work (including convincing PPL that this is needed) to implement/change to more general/powerful/useful triggers. -
In this case I didn't say a thing