Jump to content

wraitii

WFG Programming Team
  • Posts

    3.399
  • Joined

  • Last visited

  • Days Won

    76

Everything posted by wraitii

  1. I think you would have a bit of trouble writing an AI that pretends to be a player, though with some good C++ modding it's probably doable. Indeed however currently there's no way for the AI to get visibility information, it assumes everything is visible all the time, so you will run into trouble with unitAI not agreeing to your orders (as there are some visibility checks in unitAI that would succeed for you all-seeing AI and fail for your AI-as-a-player) At the moment, implement LOS for AI is quite complicated.
  2. Hey gameboy, that's related to me merging D359 yesterday. You can fix it by de-activating fancy effects as it turns out I can reproduce this (didn't notice yesterday, unluckily). Edit - I'm interested in other people reporting SQL/GL error, by the way, as testing these shaders things is annoying at best.
  3. I think we should consider OpenGL deprecated going forward, too. Mac OS has done so, so the only useful thing is OGL 2 for legacy systems support. Vulkan / Vulkan+MoltenVK are probably the systems of the future for us.
  4. The renderer isn't bad, it's actually fairly well designed (except for the GUI). It's just quite coupled with OGL2, which isn't the best coupling for 2019 . Also agreed pithing pinging Vlad' on this, he's probably more knowledgeable than I am about the renderer.
  5. With things like arrows, I think triangles are a lesser concern than draw calls. 60 polygons is nothing in 2019, but 60 draw calls is something. Reducing the # of polygons would help, possibly after instancing of some kind, but it won't fundamentally speed things up right now imo.
  6. Those are definitely the pros and con... "Bit more work" is I feel a bit of an understatement though. Modern graphics are complex affairs, and we already don't have much workforce. I don't think we can make an AAA level RTS graphics engine - and that's kinda what we're talking about here. The dependency problem is a big issue because most "probably won't fail" projects have grown a bit too big. Things like godot or Ogre are complete and modern, but we can't really easily adapt our current code to them. Smaller projects have a more uncertain future, or don't support all of our three platforms, and such. Regardless, the renderer abstraction is probably something we'll need to do anyways, so it's a good first step.
  7. Unit Motion is rather subtle to be honest because it ties the actual pathfinders, the unitMotion component and UnitAI together to work. Mostly if we want to keep supporting old versions and new versions we first need to clean up the code to support different renderers, and that's not too easy, and then actually code the new one, which isn't easy either. We don't have a lot of graphics programmer, and it's getting increasingly hard to do graphics correctly. I've been somewhat convinced, for a few years now, that we need to change our strategy of doing most things in-house and just use a rendering engine, but I haven't really found a very satisfactory one so far.
  8. @Stan` I think some of your info is a bit outdated. This isn't that accurate to be honest (sadly, how good would that world be) At a high level, the renderer is draw--call bound (heavily so) because we aren't using any instancing - because we support OGL that doesn't support it. They "why" on this will lead to a flamewar. The GUI rendering is particularly unoptimised, since we don't even render similar items together. At a high level, the simulation is pathing + JS bound. The AI itself is a slowdown, but it doesn't increase over time that much. I have ideas on how to improve it, but surprisingly perhaps my idea is actually to unthread the AI. The reason for this is that the AI is slow mostly because it needs a copy of the simulation state every turn, which is slow to create, which it wouldn't need if it lived in the same JS container as the simulation itself. The pathfinding is slow. There are 3 pathfinders. The hierarchical one is high level and fairly fast. The long-range pathfinder is JPS and fairly fast on its own, though it searches very large grids and can still take some times if enough calls are made on a given turn. Then there is the vertex pathfinder, which isn't fast. I think it's also kinda broken (see D1908). These 3 pathfinders are used from CCmpUnitMotion.cpp, which I am currently in the process of rewriting. The pathfinding calls should be threaded (D14 - which as far as I know does not leak memory, it might have done in the past but the current revision should work), which will help. We should also implement unit Pushing (D1490) to reduce the usage of the vertex pathfinder. After that, it's just optimising stuff and we'll get into 'difficult' territory. The rest of the simulation isn't extremely fast either. JS code is slow, and from profiling I would say about as slow as the pathing itself. There's just not much that we can do here except move some of the slow stuff to C++ and hope for the best. Spidermonkey, our engine, needs to be upgraded and hopefully things will get a bit better in the future. Finally, our Entity-Component-System is also rather unoptimal, using maps in a lot of places and not really being optimised for cache misses. ---- Your extended corner thing is an interesting idea, though one needs to consider that: - adding more vertices slows the vertex pathfinder further - there is a bug that we always try to go for the nearest point on goal with the vertex pathfinder, even if that is unreachable, which can lead to stuck-ness. Maybe it's better/faster to fix that instead.
  9. I think special attacks should rather be handled by allowing multiple attacks. Abilities I'll get back to someday I guess. I've had new ideas.
  10. Well yeah obviously, so we'll have to change the interface a bit. But I think overall it would allow us more liberty in doing things while keeping a competitive game. Also no I think we should still allow player to pick "Random Tier 1" or "Random All Tiers" so that one player can play a Tier 4 and another a tier 1 civ in the same game - would also be a neat way to introduce handicap. Edit: also it would help with historical accuracy - a siege that didn't really have siege might be Tier 4 but we wouldn't have to shoe-horn ways to have siege in, for example.
  11. Sorry, I guess I wasn't clear. I'm suggesting that we put civs in "tiers" and then we differentiate and balance them compared to civs amongst the same tier. So we can keep what we have now, but we only need to make sure Persians are balanced with Macedonians and Mauryans, it's not a big deal if they crush Kushites every time because they have superior technology.
  12. This is an idea I've had for a while now (couple of years maybe?)... Original text in spoiler: Proposal below: Our civilisations are currently supposed to be balanced. Picking a random civilisation should, on average, give you a fair chance to win assuming equal skill. Since we now have 13 civilisations, that means we need to balance 78 matchups. This is a considerable amount, particularly since we actually have limited manpower, particularly for gameplay purposes. In my opinion, we only have 2 ways to balance so many matchups: Effectively reduce the # of civs (e.g Celt, Greek, Roman, Kushites), by making the different "sub-civs" very similar. This precludes adding too many different groups, or we have to add "trash" civs. Effectively make all civs very similar. We can't get AoE2 level of variety because our tech tree/unit tree is much too small. So we're reduced to making them all basically equivalent. I like neither of these options. My proposal is to split our civilisations into groups, and only balance inside a given group. What I mean is that any matchup inside a group should give you a fair chance of winning - but matchups across groups (say, below, Roman vs Kushites) could be terribly unbalanced - or could not be. Romans might have one unit or one strategy that Kushites can't counter for example. Below is a Group List (proposal with some quick reasoning). My criteria are, to some extent, chronological and geographical. I am also picking what I think would be interesting matchups. Superpower Group - the 3 largest empires in the relevant timeframe Macedonians - Under Alexander the Great, circa 330 BC, they conquered most of what I will call the then "civilised" world. Obvious pick. Aechemenid Persians - While Cyrus II is technically out of our date range, he's in the game files, and it makes fine gameplay to have Macedonians and Persians in the same group since they did fight. Mauryas - Under Chandragupta, became one of the largest empires — period — back then. These 3 together also form a continuum of Greek-Indian empires and are historically somewhat tied. I think they make up an interesting group. Mediterranean Civs - More naval oriented Romans - Since we are pre-marian, this is the Rome of the punic wars. Stronger in terms of naval power than we might think, not yet mingling with the gauls up North too much. Carthaginians - Foil to the Romans at the time, we need them in the same group for historical play reasons. The question is "who next?". I think we might put Athens, a strong naval city state, but they did not really wage war on each other too much. Alternatively, Iberians were conquered by Rome by 100BC, so they could be put here. I'm having a hard time putting Athens somewhere more relevant, because as a strongly Naval civilisation they would be easily unbalanced against "land-based" greek civs, and they're historically not really relevant against anyone but these same greek states. Athens/Iberians Aegean Civs - more land-based civilisations perhaps. Spartans - land-based, which makes them good to fight the two other successor states. Seleucids - Successor state in the region, that mingled with Ptolemy Ptolemaic Egyptians - likewise. Celtic Civs I'm grouping these here because they were relatively similar, and thus would be relatively easier to balance. To be honest, we could perhaps move them all alongside the "Rome" group, particularly if we put Iberians there. The trouble is that they didn't really fight many of the other civilisations from our time-range. We could also dispatch one celtic civ in each other group, for variety, but that throws historical realism somewhat out the window and might complicate balancing. Gauls Ibers Britons Unbalanced Civs - those that aren't in a group (yet/ever?) Kushites ---- The advantages of this are: We need to balance fewer matchups. With easier balance, we can make civs more diverse, possibly more historically accurate. Currently, and particularly in A24, we've made civs very similar as balancing is hard. It makes it possible to highlight some different matchups. It also makes it possible to add more civilisations - we don't need to consider the overall balance. As such, a Mesoamerican group can easily be added, like wise for Asian civs. The drawbacks, obviously, are that MP users would have a reduced # of picks, and that it needs some development to support.
  13. Not to discourage you but the chances that we commit something that changes gameplay in such a way is low at the moment. In my opinion, these need a physics manager that handles collisions in c++, something that we will also need for unit pushing.
  14. It appears to me some people enjoy the game, so I would not say this is an absolute fact. One can also create an almost perfect AoE 2 clone, which is a good game, purely by editing templates. Now, regardless of what the team will decide on balancing, I would like to say that borg has worked hard on his mod to make something that (it seems) people like, and that is a valuable achievement, which we should all recognise and applaud.
  15. Hey guys, I have a change (D1871) that could significantly reduce the number of units stuck (and improve pathfinding behaviour overall) because of the use of 2 different pathfinders in 0 A.D. The change feels good to me and Itms agrees, but it needs to be tested (a lot). I'm asking for help on this: if people could try this differential and report how things felt. I'm wondering most if there are cases where units get 'stuck' walking (which generally doesn't happen in svn). In general, this will make unit movement more permissive (they can get closer to trees and other structures). Thanks for the help
  16. It just means I enjoy coding for coding's sake. I've mostly worked on 'engine' things lately (pathfinding optimisations, code cleanups, things like that) because that's fun to me. Whether I was optimising an RTS or another type of game is not very relevant. I do have my own opinions on where I believe 0 A.D. should go as a game, some strong, other less so, but for me personally there are higher priorities right now and so I am not debating gameplay or playing much.
  17. That's not related to the state or quality of the game (and thus not a proper argument). I enjoy working on 0 A.D. regardless of whether I play it. It could have become a fishing game at this point for all I care.
  18. Just had this idea, and I think it's good, so I wanted to share this... Current situation As you may know, the AI is currently designed to ultimately be run in an asynchronous manner, in the background, over possibly n turns. A reference is this interview of @quantumstate for example, but it's also quite obvious from the architecture. The Idea was that thus the AI wouldn't be blocking for the simulation even if it was slow. Based on the fact it currently runs once per 8 in-game turn (about 1.5 seconds in SP, about 4 seconds in MP), we can assume that this is a reasonable time-frame for such a threaded AI. To support this, the AI receives a copy of the simulation state, through AI Proxy components on most entities and AI Interface. Consequences This is nice in theory - I've never questioned it and I don't think anyone questioned it in the past few years. However it has several significant drawbacks: The AI wouldn't be able to be run more than once every n turns (n=8 right now). That makes it basically impossible-by-design to micro efficiently, for example. Note that our synchronous AI can, but that's not how it should work (and it doesn't leverage that). Copying the simulation state is slow. AIProxy listens to most messages, all entities have one. It can easily take up several ms per turn (in fact I had a diff for that which I didn't keep as it was kinda broken.). Copying the simulation state is error prone. We have to do it manually. Techs in particular were a real pain to handle. Mitigations for multiple AIs (the common-API) are a mess. Copying the simulation state is greedy and custom. If the AI wants new information, we have to add it to its state. If it doesn't care about some information that we've added, we've payed the price anyways. The above flaws are all fundamental to the design. The second and first can be mitigated, but at great cost, and only up to a point. Proposed Change The biggest change is simple conceptually: we run the AI synchronously. It fixes all the fundamental design flaws above: we can run it every turn if we want to. This fixes point 1. we no longer need a copy of the whole simulation state. This fixes points 2/3/4. The AI can call into the Engine directly (using QueryInterface or something similar) - in a read-only manner. This can be by setting a flag or by copying only that relevant bit of data it's asking for. If the AI remains in its own context, we can use structured clones. The problem of this design is that if the AI wants to do something slow (and it does sometimes), it will lag. There is a solution. We let the AI run specific computations asynchronously, over a specific number of turns, using an interface similar to worker threads. Then if the computation isn't done, we block, otherwise we return the result and process it synchronously and deterministically. For these computations only, we copy whatever state is necessary. What I hope this achieves A speed-up of several ms per turn on both SP and MP. A much simpler AI interface (basically no interface). Still the ability to run longer computations asynchronously.
  19. Fixed by https://code.wildfiregames.com/D1856
  20. This appears to be a rounding issue, we're off-by-one. The walking speed is computed correctly everywhere, but unitMotion moves by one 'comma' more than should be possible. That doesn't always happen though, and I don't think the run multiplier code is related... But it's the one related change we did recently . Odd.
  21. This exposes us to dangling pointers, as the component pointed-to may very well be deleted at some point (particularly for components referring to other entities). Now 0 A.D. doesn't actually change an entity's templates (i.e. its components) at runtime right now, so we could take some liberties with components of the same entity, but that's probably not something we want to do from a design point of view. Then again, changing components at runtime might be too difficult to ever implement. What we could maybe do is a component cache on the JS side to avoid going back to c++ everytime, but that's also scary for mostly the same reason. At the moment, we have bigger performance concerns imo.
  22. It would make the code much easier to understand though :p
  23. Hey, What you've noticed is accurate, and somewhat known (mostly by me I guess): The rendering is draw-call bound and slow, the pathfinder can be slow, and the Javascript main loop is very slow (we use it for most gameplay stuff, which is why it's slow). Unfortunately, profiling spider monkey accurately is very difficult. There are few tools, and almost none that can be integrated with an existing profiler. What you'd see in OSX's instruments and I assume VTune are memory addresses, which are actually JIT-ed code and/or spider monkey code (mostly the former). With a lot of hard work, using JIT debug output and the trace logger, one might create debug symbol-like structures to document these, but it seems not super useful. What we did in the past (and probably will in the future) for profiling JS was using our internal profiling, which does have an overhead but can give you an idea of what's going on. _Overall_, though, we've already optimised most obvious bottlenecks. The remaining bottlenecks are not trivial to fix, and JS is somewhat of a lost cause.
×
×
  • Create New...