Jump to content


WFG Programming Team
  • Content Count

  • Joined

  • Last visited

  • Days Won


elexis last won the day on November 18 2018

elexis had the most liked content!

Community Reputation

1,970 Excellent

About elexis

  • Rank
    Primus Pilus

Profile Information

  • Gender

Recent Profile Visitors

4,104 profile views
  1. Yes! Just make sure to keep it smart,simple and accurate.
  2. elexis

    F.P.S. Overlay bug when in bulgarian language

    I would assume it's an issue with the Engine.GetTextWidth function not taking into account line-wrapping or whitespace correctly. The network dialog also displays "Bad connection to:" and then the name on the next line but that line being cut off by the height setting.
  3. Networking code has to be threaded, because any slow code that suddenly consumes 10 seconds or more will trigger a timeout disconnect. The NetServer NetClient code are equally affected, but only the NetServer had been threaded to fix that (ages ago). In a23(a) we had such a 10 second lag on gamestart which literally broke every single 4v4 we started and left at least one player unable to start the game, which was one of the reasons we needed a re-release. We had addressed this 10 second lag and added timeout tolerance to 60 seconds, but the problem must be fixed with threading. (Other than the disconnect issue, there is also no reason other than subideal code why slow code should trigger network lag.) The according ticket is at #3700 and the according patch resting somewhere on a dusty git branch. But don't expect that this NetClient threading will make the game more performant (FPS-wise).
  4. It might just have been one of the JSInterface_Simulation / Selection / StatusBars c++ bugfixes / cleanups. The rangemanager having to filter mirages. IIRC was reproducible, just had to change perspective and use observermode and hover over non-displayed mirages. It was probably only irreproducible if the mirage entities hadnt been created yet. (Guess one could do the bughunting thing, test 3min, if that doesnt work try to find the bugreport (then probably notice the replay is for an outdated release), and then read the code and derive the bug from the reading the code).
  5. Reported somewhere a year ago or two or so (it's also what I was refering to in https://code.wildfiregames.com/D1460#69897). I only recall it's the status bars of the entity and it's mirage both shown in observermode.
  6. Thanks for having adopted the multiplayer fixes that allowed this game to be played during the last two seasons!
  7. elexis

    Testing pathfinder update

    Network latency should not be an issue, the turn lengths are 500ms in multiplayer and you can test by simulating lag that if the meanRTT <= turnLength, there is no network lag perceivable. On "Simulation interpolation lag": However there is a different aspect that can make the simulation consume 550-600ms, even when there is no performance bottleneck: it's the approximation / interpolation of the turn events to the intended turn length. The computation may be done in 50ms, but the events should unfold in 500ms on screen. I think the approximation depends on the performance of the recent frames, is inaccurate and can thus overshoot often. At least that's the only theory that I can come up with that explains when one measures and displays the time between the "TurnStart" and "TurnEnd" network packets (#5323). If I recall correctly, even on a new_rms_test map with about 20 entities on the entire map and only the localclient, < 10ms ping and no units moving there are often 550ms between the two packets. Other things to thread: There are some edge cases that need async calls or threading: The NetClient threading doesn't really remove performance bottlenecks, but it is absolutely necessary to split it so as not to get disconnected when some C++ or JS code blocks the main thread for some seconds, like we saw in every single a23 4v4 if one didn't simulate lag to increase the timeout tolerance artifically. (ticket and patch somewhere) Map generation is threaded already (one couldn't see the loading screen progress). But not all parts of the loading screen are threaded. Running the renderer and simulation in different threads might or might not have potential (for both loading screen and ingame). Rejoining clients that finished the loading screen simulate the missed turns - that can freeze the application for many seconds. This is the most important issue to be fixed. It would be probably better if the rejoining client simulates 3 turns, the other players one turn, rather than the others simulating 0 turns while the rejoining client simulates all missing turns. XMPP connection startup freezes the GUI until the server responds or timeout (ticket somewhere) STUN connection buildup freezes the GUI for some hardcoded seconds replay menu loading thousands of new replays will freeze for that period userreporter libCURL interaction was threaded, but if the server times out, then the main thread exists while the userreporter thread still waits (ticket somewhere)
  8. On object-orientated programming vs procedural programming: Conclusion: Procedural style isn't a big issue with most of our current interfaces, but in some distinct cases it's a strong case to use object-orientation. The object-oriented approach is sometimes inevitable and hence already in use in some cases. For example: let label = Engine.GetGUIObjectByName("label"); label.caption = "foo"; label.tooltip = "bar"; To write this as procedural style, it would have to be: Engine.SetGuiObjectProperty("label", "caption", "foo"); Engine.SetGuiObjectProperty("label", "tooltip", "bar"); But the main problem with procedural style is that it becomes messy when handling object instances and separation of private and public data. Also notice the requirement to use strings, numbers (or hardcoded C++ globals like g_NetServer) to identify C++ objects, if one doesn't want to allocate JS objects that refer to C++ instances. The Networking code for example would be much cleaner if it would use object-orentation style (#5321): Procedural: Engine.CreateNetServer(...); Engine.SetNetworkGameAttributes(); Engine.SendChat(...); Engine.KickPlayer(...); Engine.DisconnectFromNetServer(); Engine.StopNetServer(); Object-oriented: var g_NetServer1 = Engine.CreateNetServer(...); var g_NetServer2 = Engine.CreateNetServer(...); g_NetServer1.KickPlayer(...) var g_NetClient = Engine.ConnectToServer(...); g_NetClient.SendChat(...); g_NetClient = undefined; g_NetServer = undefined; Equally it was arguable to instantiate other components such as XmppClient or even the simulation (there is no additional cost to gain these freedoms if one would use OOP since the beginning). A third example would be one parent GUI Pages wanting to close or update one of it's child GUI pages (#5369): Object-oriented: g_ChildPage = Engine.PushGuiPage(...); g_ChildPage.updatePage(newData); Procedural: g_ChildPageName = Engine.PushGuiPage(...); Engine.CallFunction(g_ChildPageName, "updatePage", newData); For the other JSInterfaces (see also #4772), there is no strong case for OOP with the current code (as the JS GUI is still overall messy due to excessive procedural spaghetti): ##./source/gui/scripting/JSInterface_GUITypes.cpp ##./source/gui/scripting/JSInterface_IGUIObject.cpp ##./source/lobby/scripting/JSInterface_Lobby.cpp ##./source/network/scripting/JSInterface_Network.cpp ./source/graphics/scripting/JSInterface_GameView.cpp ./source/gui/scripting/JSInterface_GUIManager.cpp ./source/i18n/scripting/JSInterface_L10n.cpp ./source/ps/scripting/JSInterface_ConfigDB.cpp ./source/ps/scripting/JSInterface_Console.cpp ./source/ps/scripting/JSInterface_Debug.cpp ./source/ps/scripting/JSInterface_Game.cpp ./source/ps/scripting/JSInterface_Main.cpp ./source/ps/scripting/JSInterface_Mod.cpp ./source/ps/scripting/JSInterface_ModIo.cpp ./source/ps/scripting/JSInterface_SavedGame.cpp ./source/ps/scripting/JSInterface_UserReport.cpp ./source/ps/scripting/JSInterface_VFS.cpp ./source/ps/scripting/JSInterface_VisualReplay.cpp ./source/renderer/scripting/JSInterface_Renderer.cpp ./source/simulation2/scripting/JSInterface_Simulation.cpp ./source/soundmanager/scripting/JSInterface_Sound.cpp One difficulty with C++ JS objects is that they can't be copied to other contexts currently (but that should be practically solveable, because these JS objects may only store one void* and that can be cloned). Perhaps you refer to the GUI<->simulation interface in JSInterface_Simulation.cpp, that uses global procedures. But the JS simulation <-> C++ simulation script interaction is an example of object-oriented implementation, not procedural! This argument seems to the contrary - if X and Y are object-oriented, it's typically easier to have them interact directly rather than adding an object-procedural and a procedural-object translation layer (indirection). (At last depends on implementation details which is easier to implement.) While it is true that it is clear that `Engine.Foo` is an engine function and that it allows finding many but not all JS GUI <->C++ GUI interaction. But it should not be unexpected to any programmer that the properties of `Engine.GetGuiObjectByName` objects or likewise interact with C++. On the flipside, with a global object-oriented style it were easier to find all objects that are created in C++ and it becomes easier to see which Engine functions relate to which C++ object instance. For example it's not clear which Engine.NetworkFoo functions relate to the NetClient and which to the NetServer. In procedural style it would have to be solved adding the type to the name: Engine.NetServerDoFoo and Engine.NetClientDoFoo, but that's then already mimicing OOP.
  9. I'm not sure if the performance requirements for such an endeavor are met. Machine learning simulates the game with semi-random inputs, so I assume you will have to run at the very least a couple of hundreds of matches, right? Try running one match - depending on the number of units on the map and the number of Petra AI instances, you will get a lot of "lag", i.e. the engine simulating slower than it should. Say a 30 minute 1v1 game on a small map taking 5-10 minutes to simulate, a 60min 4v4 on a normal map with 150 pop 60+ min. Which means you can simulate somewhere between 20 and 50 games per day with a casual desktop computer and your CPU/cooler won't be happy. One can start new matches and replay previous matches without graphics from commandline, check the readme. If performance isn't a dealbreaker, and one would require http communication, one would have to use libCURL to do http posts to the webserver. If doing so, sending JSON would be the data format that is easiest do digest by spidermonkey. Assuming a python agent can be used with pyrogenesis/0ad, how should the simulation data be parsed? If it's a very simple learning algorithm, it might alternatively be considerable to implement that in JS than to implement the interface to a different program and teach that program how to parse/send simulation data.
  10. Is loading more data when the scrollbar reached the bottom the nicest solution? Paging would be an alternative. Or displaying everything is made fast enough, which ought to be the case if the cache is always prefilled. Having complete search results also means that one can sort the results.
  11. FeldFeld and ValihrAnt reported that "Windows Defender SmartScreen" complained about the "Editor" not being known. I'm not sure how their "reputation system" works.
  12. That's the revision number of the last .exe file, as it should.
  13. elexis

    MacOS / OSX RC Bundles.

    Just for the record, it a23b multiplayer, savegames and replays are fully compatible with a23. The new lobby room was created to push players into installing the update, not because we feared bugs. There are 5 to 10 Windows and linux multiplayers that use svn since months, because the release was too broken to be usable. So at least multiplayers have a first hand account of the compatibility of a23 to a23b.)
  14. elexis

    Grumpy Gurken's recenst ramblings

    The entity ID is either already seen in the erorr message, or one can add a warn(entityID) to the bugging piece of code, then start the replay, press Alt+D to enable the developer overlay, make sure no unit is selected, press F9, type g_Selection.addList([entityID]) and it should show the template name of the entity, for example.
  15. elexis

    Grumpy Gurken's recenst ramblings

    Was the relevant relevant entity actually an actor?