Jump to content


  • Posts

  • Joined

  • Last visited

Posts posted by Happenstance

  1. Definitely some valid points being discussed here but I feel like this thread pops up about once a year. Some conversation happens, some proposals are put forward, and ultimately nothing changes. Wasn't it about this time last year we had the 'Why doesn't anything get done?' thread where we discussed how fragmented & unfocused development was, the huge backlog of PRs waiting to be committed, etc.? That spawned a few additional threads where we started reviewing PRs (many of which have still not been committed) and more proposals about how to better involve the community.

    I do think there's a need for more organization so development efforts can be focused toward realistic goals & timelines but I'm not sure how to get there at this point. The steering committee model looks good on paper but only works if you have members that are active, capable, and willing to work toward whatever 'goal' the community sets. Past steering committees have lacked at least one of those ingredients and I doubt we have a large enough community to even use that model again. Godot's method of one main developer working on things the community votes on makes more sense but that's also a paid, full time job whereas Jeff and the one or two others still working on Torque are doing so as a hobby so having the community dictate what they do in their free time feels like a big ask.

    Just for the sake of conversation, here are some facts that have been relevant for the past several years:

    1). The last official release, 3.10.1, happened over two years ago. It is woefully out of date at this point due to the tremendous amount of fixes made to the development branch in the interim. The process of backporting these fixes is tedious, time consuming, and more than we should expect from a new user but even if they do make the effort, they'll be left with a weird Frankenstein version of Torque that's stuck between the 3.10 way of doing things (ShapeBase everything) and 4.0's shiny newness (half-implemented modules/assets/components and incomplete BaseGame template).

    2). There's never been a -worse- time to start a new project with Torque. If you build off of 3.10 now you're willingly setting yourself up for pain later but 4.0 is still incomplete and unstable enough to be a no-go for any serious effort.

    3). The last commit to the official repo was over a month ago, the one before that happened 5 months ago which indicates either development has completely stopped or (more likely) is still happening in personal/private repos and never making it back into the GG repo. Anyone that's not actively monitoring discord is going to be confused on what the true state of the engine is and will be hopelessly lost if they actually want to contribute.

    4). There are still over 70 PRs waiting to be committed & over 300 issues needing to be addressed. Many of these are years old at this point and have been addressed but never closed.

  2. Certainly impressive! I haven't watched the full presentation yet but did they offer any details on how they intend to keep file sizes in check? I'm hearing about thousands of models with millions of triangles and 8k+ textures everywhere and it seems to me that a full AAA game could take up hundreds of gigs worth of HD space. Downloading games that size, even at fiber speeds, would be annoying and 1TB HDs seem small by comparison.

  3. Not sure about Unity, but Godot does it by including precompiled binaries for each supported platform as part of an "export template" package. When you 'compile' your game Godot just pulls out the corresponding binary from the export template and renames it for you. We could do something similar in Torque but it'd only be useful for people that work exclusively in TorqueScript. As soon as you modify the engine you have to recompile for (and on) every platform you want to support.

  4. Tinker with those warp settings as well - try setting them to 64 or even 128 and see how that changes things.

    My suspicion is that the AIPlayer's yaw handling is breaking in situations where the client & server desync. The server says the AIPlayer's rotation is one thing and it should turn to this angle but the client thinks it's a slightly different angle. Once an update packet is received by the client the rotation is synced back to the server's version and the change in rotation is interpolated over several ticks. The difference in angles could potentially be enough to result in a wildly different return value in that bit of code that calculates the shortest turning distance (see comment in aiPlayer about "shortest way around a circle"). You'd see the AIPlayer spin from one extreme to the other as it corrects the rotation if the difference was large enough.

    That's my shot in the dark theory, anyway.

  5. My guess is that this is going to be an issue deeper in the engine, you were probably on the right track looking at the yaw code. The fact that it happens during the initial spawn makes me think it's an issue with the way yaw data is initially networked & interpolated.

    Is there any change if you disable warping?


    // Set these to 1 in aiPlayer.cpp
    static S32 sMaxWarpTicks = 1;          // Max warp duration in ticks
    static S32 sMaxPredictionTicks = 1;   // Number of ticks to predict
  6. In your examples '.type' & '.color' are known as 'dynamic fields' in the world of Torque.

    Internally each object has a SimFieldDictionary (basically a hashmap) that stores a key:value pair for each 'dynamic field' the object has. When you add a new dynamic field (e.g. %obj.myNewVar = 15) the object itself isn't reallocated, a new entry is simply added to its field dictionary.

    Adding new dynamic fields can happen in onAdd() or any other time. If you define a dynamic field as part of a datablock definition I believe you'll be adding it to the actual datablock, not the object itself so to access it you'd need to do something like: %obj.getDataBlock().myNewVar = ... This method also has some networking implications. Datablocks are downloaded to clients once so dynamic fields in datablocks is a bit of an odd choice.

  7. setSkin/setSkinName are indeed networked but the actual retexturing work is done clientside by the reSkin() method. The only reason calling setSkin/setSkinName applies the change to all clients is because those functions set a netmask (SkinMask) which sends the mSkinNameHandle string across the wire. Clients then see that 'SkinMask' is set, read in the new mSkinNameHandle, and then call reSkin() on the object in question.

    I would make a new function based on reSkin() (let's call it reSkinLocal()) that just accepts a string as the name of the skin instead of using the networked mSkinNameHandle variable. Expose the reSkinLocal() method to the scripting system so you could then call commandToClient() to tell specific clients to call reSkinLocal() on their (ghosted) mesh. It'd work something like this:


    // serverside door.cs script
    function Door::unlock(%this, %clientToNotify)
        commandToClient(%clientToNotify, 'UnlockDoor', "green_skin", %this.getId());
    // clientside commands.cs script
    function clientCmdUnlockDoor(%skin, %doorServerID)
        // need to convert the serverside ID to the ghost ID on this client
        %obj = ServerConnection.getGhostID(%doorServerID);
        // retexture the object
  8. The code is correct Az (at least on Windows, poor Linux...) but if the registry key is missing for some reason it'll fail which sounds like what's happening in Hodo's case. There are some other registry keys we can check as well (the thread I linked lists those). Another potential alternative would be to call ShellExecute, something like:


     ShellExecute(NULL, "open", "website_URL_here", NULL, NULL, SW_SHOWNORMAL);
  9. Center

    • Centers the object in it's container. Only the position is changed, not the extent (width/height) of the GUI control.



    • Object will change position (not extent) when its container object is resized. This allows you to keep a control positioned at a specific position/offset relative to its container. One counter-intuitive bit about this: the setting works off of the opposite edge, so choosing 'Right' will reposition based off of the left edge of a control, choosing 'Top' offsets based on the bottom edge, etc.



    • Object will adjust its extent (width/height) whenever its container object is resized. Only the extent is adjusted, the position will remain the same.



    • Object will adjust both extent (width/height) and position whenever its container object is resized.



    • I believe this was intended specifically for GuiWindowCtrls so that they could maintain position relative to their parent container when collapsed. I haven't looked at the code but I would assume it works like the 'Relative' setting but also takes into account collapsed size.



    • These were newer options added in T3D at the end of the GG/TorquePowered fiasco I believe so there's not much info on them and I'm not sure any UIs currently use them. Looking at the code, it looks like they do the same as the non-aspect versions with regards to repositioning/resizing a control when its container object is resized. The main difference is these settings use the change in aspect ratio of the container object when calculating a new size/position.

  10. I might be the only one that finds this useful but I'm constantly forgetting to close Torque before recompiling which of course results in VS complaining that it can't access the exe. This bit can be added as a Pre-Build Event and will automatically terminate the exe before building.

    taskkill /f /fi "imagename eq $(TargetFileName)"

  11. Going to dig into this today (likely an issue on my end based on the feedback so far) but all of the builds fail to run on my system. They show the Torque3D splash screen and then immediately close. Console log seems normal, last line is 'sfxStartup...' but that's not particularly helpful.

    This is on a Win10 machine with a 1060 3GB card.

  12. People like @jamesu, @Hutch, and @MangoFusion made improvements along these lines and most of those changes were rolled in at some point. T3D's version of TorqueScript is noticeably faster at certain things than previous versions as a result. The largest improvement was probably a result of simply disabling the antiquated memory manager TGE/T2D uses (this is off by default in T3D).

    One of the issues with that resource is that the seven benchmark tests the author uses aren't particularly realistic. It's rare to call a function a million times in a single loop, and if for some reason you do need to do that doing it in script would be bad design anyway. It'd be more realistic to test function calls over a few thousand iterations but that would likely take less than 1ms to complete and make it difficult to measure the performance differences (if any).

  13. It might be worth tracing the code from here to see what's happening with the mouse events:


    A workaround in script might be to also bind the right mouse button to a toggleCursor() function so that you're responding to the mouse event from both the GUI side (PlayGui::onRightMouseDown()) and the ActionMap side. You can find an example of how to do this in default.bind.cs but it'll look something like:


    // button1 = Right Mouse Button
    // binding to moveMap so that this only works in a level
    moveMap.bind(mouse, button1, toggleCursor);
    function toggleCursor(%val)
  14. Ah, I see what you're attempting to do. The issue is when the cursor is hidden mouse events are sent to ActionMap for processing, when it's shown they are sent through the GUI system. In your case PlayGui::onRightMouseDown() is never being called because those events are being handled (and ignored) by ActionMap.

    In the old TGE days this would require a C++ change but it looks like T3D handles this case. Set Canvas.alwaysHandleMouseButtons to true and see if things work from there.

  • Create New...