[PREVIEW] QOL Fixes Update

edited 12:53AM in General Discussion

Testing is now open for a preview patch release – you can grab the installer here:

https://www.tribesnext.com/files/TribesNEXT_20250726_preview.exe

For your security, official binaries are digitally signed, and should be downloaded directly from this site. On Windows, you should see “TIMECAB Technology Co.” listed as the verified publisher when opening this installer.

If you have any feedback or encounter any issues running the patch, please post them in this thread, and include as much detail as possible, including crashlogs, demos, and steps to reproduce.

This is an RC2-compatible package of QOL fixes I pulled together to release for the most recent anniversary, but obviously that target slipped a little (every day there’s another nail that needs hammering). Some of you will be familiar with components from various other work over the years, but this package is a little more polished and stripped of some of the more experimental feature additions. The aim here is simply stability, performance, and restored compatibility for interoperability with modern systems where things have been breaking down.

For now, this preview build is only available for systems that meet the following increased requirements:

  • AVX instruction set support (generally CPUs produced past Q42011)
  • OpenGL 3.2+ support (GPUs from 2009 or later) and somewhat more vram for buffers
  • Windows Vista/Server 2008 or later Win32 API levels

I know some people are running on older hardware, so builds without the AVX requirement may be made available, but the latter two are hard cutoffs for some of the changes made to support modern systems.

Now, I don’t want to pump this up as being more than it is, but there’s going to be a bit to explain regarding some changes… and I might need to edit to add more details later. For an overview though:

Highlights

  • Enhanced windowing, borderless windowed fullscreen and nominally-exclusive fullscreen with refresh rate selection
  • Greatly improved frame pacing and timing precision
  • Up to 1000 FPS*, with many rendering and performance optimizations
  • Additional options, like multisample anti-aliasing, texture filtering modes, a FOV slider, render scale, (CPU) framerate limiting, etc
  • Support for ultrawide displays with “Hor+” style FOV projection
  • UI scaling and aspect ratio limiting for high DPI and wide displays, including a new scalable text rendering system
  • Revised, optimized low-level networking (within the limits of staying compatible with existing servers/demos), meaning on any patched server you’ll experience faster loading, (slightly) lower pings, lower input response times, and fairer and more regular delivery of the latest game state data each tick
  • Modern HTTPS support using the latest protocols and security, with optional scripting support for downloading binary files such as terrains and vl2s, which will be registered in the resource manager
  • Built-in support for automatically downloading** terrains/interiors/etc, as needed on mission load from the tribes2.net asset depot (there are currently ~11k individual assets available)
  • Revamped input management (raw mouse, binding all buttons, basic gamepad support, etc)
  • Higher resolution terrain textures and shadows, composed on the GPU, at higher color depths (sharper details and no compression or banding in darkened areas)
  • OpenAL alternative sound driver support
  • WINE support out of the box***
  • Loads of tweaks and fixes

* Technically the safe maximum, but it’s still running the old school fixed-function pipeline and doing a lot of blocking work on the main thread every frame; don't expect that to be your target framerate

** Disabled by default, you can enable it under your network options tab

*** Assuming it’s relatively fresh and has raw mouse input support included in the build


General

The game’s event loop and time management has been rewritten – this version of the game always uses high resolution timing (setPerfCounter is no longer an available setting), and, subject to hardware and the operating system’s scheduler, targets as reasonably close to stable intervals on modern systems as possible. If left uncapped, and given nothing to render, this means that in ideal conditions the game could process a game loop iteration (including all callbacks, scripts, and i/o) every millisecond, on the millisecond. The renderer is still coupled to this loop (and only minimally changed: it’s still the same old school OpenGL renderer), and obviously integer intervals aren’t going to match display output rates, so there’s going to be some variance to what you see if you’re trying track it in-game. Outside of some rare edge cases on barely supported hardware, it’s pretty well guaranteed that anything system able to run this patch will see significant performance improvements.

Servers will no longer encounter issues with losing timing performance/accuracy the longer they (or the host system) are online, although other factors could still cause issues to accumulate over time, and there is still a hard limit of around 49 days before the timer overflows and you’ll hit unexpected behaviour.

The memory manager has been replaced, resolving some minor stability and performance issues with the original.

Power consumption will be reduced in some cases, but possibly increased depending on the options you choose. Clients can set their (CPU) framerate limit lower in the “Video” options (though this isn’t technically a video option), though enabling vsync is likely still going to reduce it the most. I don’t advise setting the framerate limit at or below your refresh rate; while it’s reasonably accurate, it will never exactly match your display timing – it may be close enough if your display supports VRR, but otherwise you’ll want to either set it higher or use vsync. Server hosts looking to further reduce power consumption can try setting $Host::TimerPeriod = 16; which (on startup) will reduce the requested timer period on startup (but may have no effect if the system scheduler is already using a higher resolution timer), and raising $pref::Engine::ConsoleInterval = 64; which specifies the interval between polling for console window input (waking the thread and potentially running scheduled scripts or an iteration of the game logic if a tick has passed) and can be altered at runtime with setConsoleInterval(interval_ms);. The server otherwise already tries to idle when inactive, and will wake whenever it receives a packet.

MemPatch is disabled by default. This is in part because prior patches (including the many I have written) may conflict with changes in this patch or use space only available to the old modified exe, and partly because it’s dangerous to allow this code from unknown authors. If you’re aware of the risks and have memPatches you need to run, you can start the game with the -developer flag.

There are still a number of known issues and edge cases I intend to sort out, some of which are detailed below, but generally most areas touched should see decent improvements as-is.

 

Accounts

Tribes2.exe is no longer modified by the installer, Ruby is no longer included in the install, and all account-related code is now backed by a native implementation. If you were using the Ruby interpreter for your own code, you’ll have to make sure you keep the exe you have and continue to use that.

By default, anyone with this patch installed will send a much faster native authentication handshake to servers running this patch. Script-initiated auth handshakes are still supported, but if servers want to require clients be patched to this version (or later versions), they might set $Host::RequireAuth to reject unauthenticated users early or add a %client.getProtocolVersion() >= 52 check in relevant scripts. Script handshakes are still necessary connecting to any server that doesn’t support native handshakes, or for any client connecting to your server that can’t run this patch.


Audio

Miles 6.1c/tweaks

Miles has been updated to a slightly modified 6.1c build and includes minor fixes to the configuration and memory allocation, as well as fixing a handful of memory leaks. The WAV file load processing has been replaced to resolve an issue with ADPCM decoding (e.g. jet thrust glitches). 

OpenAL Integration

A new OpenAL option has been added as an alternative audio driver. This is largely going to give you the same sound, but may be preferable if you’re having any issues with the Miles mixer. You may be able to use extended functionality configured in something like OpenAL-soft, but the setup as-is is mainly aiming for parity with the Miles integration. The maximum number of simultaneously mixed audio sources is increased a fair bit.

Environmental reverb effects are supported, just as currently expected to be used by the game’s EAX/EAX2 room type implementation, i.e. not using a more advanced configuration than was available to previous common configurations.

By default, a limited doppler factor is being applied to give an interesting effect to sounds at relative velocities to the listener. Because the projectile audio is very much not designed to use this effect (e.g. whizzing by your head), they’re currently not being assigned a velocity. You can disable this effect entirely by setting $pref::Audio::dopplerFactor = 0; and restarting the game (or switching sound driver). This might be fully disabled by default later.

The mp3 music player in this integration can technically play some additional formats, such as .ogg and .flac

Known Issues

  • When switching sound drivers via the options menu, there can be an issue with menu bloops reverberating and getting louder. Switching the provider should fix this, restarting the game definitely will.
  • Loading of audio files (as with all other assets) is still a synchronous, blocking load, meaning that for systems with slow drives that take a long time to seek due to fragmentation or bad sectors the game can freeze up for the duration for dynamically loaded sounds. (This isn’t a new issue.)
  • Some lesser used parts of the api aren’t implemented, and may show warnings in the console if they’re hit. This shouldn’t commonly occur, though.


Input

SDL3 is being used for windowing and input capture. DirectInput is no longer directly used by the game - although admittedly this patch still contains code for an older DInput8 translation layer intended to resolve issues with DirectInput7.

  • The mouse will always use raw input. Because the game formerly used the system-provided pointer ballistics smoothing/acceleration, you’re likely to feel some differences here unless you used one of my older rawinput patches or exclusively played with DInput mouse in fullscreen. You might want to tweak your sensitivity settings.
  • Limited gamepad support is now available (rumble is temporarily disabled). If anyone is using a joystick and finds that it’s no longer working, please report it, this will likely be tweaked in future.
  • All available mouse buttons can now be bound in your controls
  • You should no longer see extra u/y characters added when opening chat


Interface

UI Scaling

Your eyesight isn’t what it used to be, so you can now make your hud big and readable by turning up a slider. On Windows, by default this should detect your current DPI setting and set it to the next step up (e.g. if you have 150% set in Windows, it should default to 200%) just because the UI does lean towards being a little small, and integer scales are less likely to see artifacts.

The game is now using a system cursor rather than rendering its own in software, and the cursor attempts to scale based on system settings. This may not always match up with the settings you choose in-game.

The way the scaling works isn’t perfect and won’t always be the most attractive, but given the limited sizes of the interface assets and certain tricks that needed to be done to allow arbitrary scaling of those assets without breaking out of the existing integer positioning or dealing with bleeding where the textures are sampled at the edges, it works well enough for now… just don’t go looking for the flaws, they’re only going to be distracting. Most of the obvious issues with it can be remedied, if someone wants to go through it, however: it just needs higher resolution textures for every UI element.

Because certain gui/hud textures use the pixels themselves to calculate element dimensions or atlas dividers, you’d find you can’t simply double the size of every image and hope for the best… so the texture manager will now attempt to find a *@2x.png larger variant of textures used by the GUI on registration, to switch to when at or above that scaling level. Currently this only searches for filename@2x, while @4x could be added if needed… but strictly speaking, this doesn’t actually need to be 2x the size − as long as you leave the original files at their original size, the @2x variant should be safe to set to whatever integer scale you like.

UI Aspect Limiter

An option has been added to the video menu to lock the GUI/HUD aspect ratio to a preset value, which should be useful for preventing everything going to the far reaches of your ultra ultra ultrawide screen.

Due to how this had to be implemented, you’ll currently need to change the UI scale or your resolution after changes to this setting for it to bubble down to inactive canvas screens. This is only a problem if you’re trying to change the aspect lock while playing, though; if you’re changing this setting once or twice from the main menu you may never notice.

Text Scaling

When UI scaling is in use, the game’s text is scaled to match, and does so by falling through preferred mechanisms:

  1. Multi-channel signed distance field rendering of glyphs. This method enables rendering sharp text at virtually any available scale. If a cached .sdft doesn’t exist in your fonts/ directory, the game will attempt to generate one at runtime if a compatible .ttf can be found.
  2. 2X bitmap fonts: a higher resolution font atlas using the standard cache/generation is tried if MSDF fonts aren’t available and couldn’t be generated. In many cases these will look perfect at 200% scale, but you’ll start to see flaws at any other scale. This method doesn’t attempt arbitrary scaling (3x, 4x) based on your UI scale largely because it’s not really expected to be hit; if it wasn't possible to generate an MSDF font, it's unlikely the OS will be able to generate these bitmap glyphs.
  3. Standard bitmap fonts: these are what's used at 100% scaling, and they're technically available to render at higher resolutions as a fallback. They could be made to look decent at integer scales with a bit of adjustment using nearest neighbour sampling, but for the moment they’re linear scaled and will be ugly if/when you see them at higher scales.

If a font in unable to be found by searching first for a .ttf file in your mod’s fonts/ directory, nor through system fonts, a substitute may be specified with a variable in the format $Font::Substitute["Sui Generis"] = "SuiGenerisRg-Regular";

For licensing reasons some fonts are shipped using alternatives, if you’re not a fan of the choices, you can provide your own or suggest changes

Known Issues

  • Some .TTF fonts do not provide TrueType glyphs able to be read by parser feeding the MSDF generator, or generate unexpected results. The system may be tweaked to add wider support in future, but for the moment you may need to choose a different substitute font if experiencing poor results.
  • Changes to the aspect ratio setting cannot propagate to inactive content (e.g. limiting your hud dimensions while in-game) without a change to the canvas size; you can change the UI scale at the same time to force this setting to apply.
  • Mouse selection/highlighting of scaled text is still a little off and may cause some re-positioning of the characters
  • Console text may initially be partially hidden if no longer strings have been printed while scaling is active


Rendering

For the sake of compatibility, the changes to rendering have been kept to a minimum; with the exception of what was necessary for features like UI/text scaling and certain optimization changes, everything is still using the classic fixed-function OpenGL pipeline. 

The renderer does run faster, but nowhere near as fast as it could in fully utilizing modern hardware acceleration or, arguably more importantly, decoupling the rendering overhead work from the main game thread. There are a number of areas where the engine will render the same geometry multiple times to accomplish a desired effect, and even where this has relatively few state changes per object, the preparation for each draw for each object eats a little more out of our cpu frame budget. 

  • The perspective projection has been rewritten and corrected for widescreen (and ultrawide) displays using a “HOR+” style FOV adjustment; keeping the perspective expected using a 90 degree FOV setting under a 4:3 aspect ratio as the baseline
  • A FOV slider has been added to the Video options menu
  • Multisample anti-aliasing is selectable in the options menu
  • Render scaling is available if needed for performance reasons (or if you want to see all the pixels), or if you want to anti-alias your anti-aliasing. There’s no fancy upscaling or sharpening being applied.
  • Textures are no longer limited to 512x512
  • Texture filtering options added: Trilinear/Bilinear/Nearest. Trilinear is maybe a bit of a misnomer, it’s essentially bilinear with linear interpolation between mip levels (no popping between high/low details). Bilinear is the standard filtering mode. Nearest will help you live your pixelated boomer shooter dreams. 
  • GPU mipmapping is used rather than the original software implementation. This frees up some CPU time on loads and you’ll notice the texture manager come back much faster after a flush.
  • Dynamic object shadow resolutions are doubled, and the surface projection has been rewritten to some performance improvement. The shadows themselves are still software rendered, so there is a small performance impact here, but it’s evened out by other optimizations. Shadows are also now oriented to match the direction of the last Sun added to the scene.
  • On supported hardware, the renderer utilizes a 32-bit floating point reverse-Z depth buffer with much higher precision over the visible range. This means you’ll see less flickering/z-fighting of thin and close together objects, and distant objects should effectively always remain coherent and correctly ordered.
  • The transition to/from the ambient terrain lightmap shadowing on dynamic objects is now interpolated over the applied height range – rather than being instantly darker when within 10m of the terrain, the object will derive full lightmap contribution when touching the terrain and gradually less as they gain elevation. This is still “faked” shadowing, but the transition is easier to believe. Interior lightmap ambient light sources (scanned from raycasts above/below the object) are not affected by this change. Mounted objects, rather than perform their own scan, now derive their ambient level from the parent object.
  • Detail level falloff has been adjusted to account for widescreen displays. Some detail bias sliders have also been given extended range to keep the higher detail meshes in use.
  • A very basic vertex buffer/array setup was hooked into the heaviest used shape rendering paths, for some frames cutting the total number of draw calls and data re-submitted to the GPU by 80 or 90%, but this really only starts to shave off a few milliseconds when there are hundreds of objects in frame. Many of the shape rendering effects are done in multiple passes, which do not currently use these vertex buffers, nor do interiors or terrain (which both use the original system of dynamically emitting a requisite set of vertices each frame), so each of those can still run up hundreds of associated calls per object - generally speaking, each draw call itself may only cost 3-5 microseconds to render on a high end modern gpu, but because they’re sequentially submitted to the driver by the main thread along with geometry and state, tens or hundreds of microseconds can easily be spent on the cpu preparing every object drawn
  • Software depth sorting of transparent/translucent objects (which can’t be done on the GPU without significant changes to the renderer) is now running in a background thread while solid objects are being submitted to the GPU. A few minor adjustments have additionally been made to the sort order of certain image types.
  • The sniper rifle’s base material is no longer read as being self-illuminating; it now uses correct lighting and environment map rendering (the latter is very subtle, but it’s there)
  • Precipitation now renders a little more efficiently, and the speed of droplets is now linked to the delta time, rather than being allowed to run wild with the render rate. 
  • While working on the precipitation, I wrote a quick proof of concept implementation on what I assume would’ve been the period-correct intent of the “Sand” type. It’s not ideal (this sort of thing can be done better with shaders than hundreds of floating dots), just left as a curiosity, but you can play with it if you want (unpatched players may crash with sand precip on a map).
  • The terrain texture blending has been rewritten both to run on the GPU and to effectively double the output resolution of tiles to match most inputs. You can also load in arbitrarily sized terrain textures, so keep in mind that what works here might not look right for unpatched clients. This isn’t the full hardware terrain I wrote about some years back, so the terrain rendering is still using fairly expensive software methods to produce the mesh, and blended tile textures are kept resident in CPU memory following generation.
  • Baked terrain shadows now use bicubic filtering (smoothing out those low res lightmaps a bit more to hide jaggy artifacts), and some self-shadowing AO is computed and baked in with the shadows at load/relight time. This is intentionally kept subtle, as it’s not meant to be something you notice or alter the art direction, but it helps in reading the contours of the terrain over distance. Try comparing a map like Sandstorm or Maroon Bells.
  • There's a "low latency" rendering option which essentially adjusts the timing to only start rendering approximately at the point where it'll be submitted to the GPU just in time for presentation of the next frame. When you have vsync enabled, this can reduce your perceived input latency, but it requires there to be some headroom to work with to be effective (i.e. it may not be ideal on a 15 year old iGPU). With vsync disabled, it may help reduce the number of unused frames drawn if you'd prefer not to use the cpu framerate limit setting.
  • There’s an optional DXGI interop output mode available on supported devices. The primary benefit of this is in stabilizing frame pacing and reducing power consumption in cases where the full functionality is supported by hardware. I have to stress, though, this isn’t going to improve framerate or change how the game is rendered; there is some overhead introduced, and the main thread of the game is blocking for the duration it takes your driver to make the shared buffers available at render time. In the case where the low latency option is selected, it uses a DXGI1.3 feature to wait until the swapchain is ready to accept a new frame before attempting to render, and if there’s enough cushion available, it will come back later to render just in time. There are some further tweaks that could be made in future, but on battery-powered Windows devices, you may find this feature uses less power while maintaining a smooth framerate.
  • Common issues with modern AMD GPU drivers were resolved.
  • Gamma correction is available again, and has an added reset button to disable it.
  • The range of the interior detail slider has been increased. This doesn't increase the detail more, it'll just keep the interior at the highest detail from further away.

Known issues

  • If you notice a difference in pacing while the cursor is active, you may want to set $pref::Video::enableMenuVSync = false;
  • Palletized (256 color) bm8 textures are no longer supported (intentionally)
  • The terrain texture detail slider is not tuned well, and should be left at max if possible. You can set $pref::Terrain::softwareBlender = true; in your prefs before startup to disable hardware blending if it’s preferable for your system.
  • Adjusting the height of terrain in the editor screws up some material info, which may cause the tile to render as black upon relight. This isn’t directly caused by the changes, but it’ll be investigated later. 
  • Dynamic interpolation between DTS LOD levels is currently disabled - it operates via manipulation of the stored vertices in software every frame, which ties up the CPU longer than necessary, and changing these in a remote GPU buffer creates a sync point which can delay rendering. The LOD levels themselves are still in use, the game just isn’t actively modifying the mesh to smooth between levels.
  • Rendering of mirrored portals is currently disabled (I don’t think anyone was using this unfinished feature)
  • The adjusted frame pacing of the “Low Latency” setting may go out of sync when enabled while both the VSYNC and DXGI settings are disabled. This is an experimental feature, and relies on precise timing that may not always be available, as such you may want to experiment with which settings work best for you. 
  • There's a short startup delay if your monitor has a lot of display modes
  • Demo recordings use the author's FOV setting, so old demos with raised FOV may look incorrect


Networking

There have been some fairly extensive rewrites to the engine’s underlying networking code, but to maintain compatibility with existing servers and demo recording, the game data protocol itself has not been changed (beyond authentication). For the most part the changes made shouldn’t be something you notice as a player, except that, as with most of the other optimizations, gameplay should feel smoother and more responsive.

DNS queries will no longer crash the game on failed lookups. Where queries return IPv6 addresses and IPv4 addresses for the same record, IPv4 will be given priority (for compatibility with certain TCPObject scripts connecting over HTTP expecting IPv4 addresses).

IPX support has been dropped (it’s unlikely anyone has tried to use it in many years). As part of the networking rewrite, transport over IPv6 has been added for future use, and game servers are able to listen for connections over IPv6. The master server doesn’t currently list IPv6 servers, but you could manually connect to an IPv6 server if you choose to.

As a host, if your mod makes use of TCP objects, you may occasionally see new warnings about connections closing/aborting you weren’t seeing previously, but these are harmless feedback and will likely be moved into script callbacks later.

Packet Timing Optimizations

  • Servers now always send a packet to every connected client as soon as possible following a tick if there is new data to send. While this means hosts can no longer configure their servers to send fewer than 32pps, it greatly improves responsiveness and equalizes fairness in delivery where previously some clients would only be sent the latest update after a delay.
  • Servers can opt to allow more than 32pps ($pref::Net::PacketRateToClient), however these will only be delivered if needed, i.e. when there is more data available to send. Generally speaking this will only be the case if a client needs new information about a handful of vehicles or a whole bunch of players are in scope at the same time. If you’re running a server with 64+ players, especially if you have vehicles enabled, it’s highly recommended to set your packet rate to 64 or higher to maintain relatively smooth gameplay without constant warping.
  • Servers can configure a “burst” rate for clients loading into the game, drastically reducing the time it takes to get in and play. By default, this will be set to double the packet rate, but you can configure it in your prefs via $pref::Net::PacketRateToLoadingClient
  • Servers can configure their maximum packet size ($pref::Net::PacketSize) up to 1000 bits per packet. If you choose a packet size of >= 1000, your maximum packet size sent to clients may dynamically adjust from 1000 to 1350 bits, depending on the type of data being sent. This, again, is recommended for high capacity servers with bandwidth to spare. Keep in mind your max bandwidth requirements (in BITS per second) for hosting a full server will be packet size * packet rate * max players. If you’re using either the burst rate option or a higher packet rate setting than 32, this will vary depending on activity, but it’s always going to fall into (or well below) the expected range.
  • Clients now prioritize sending moves and triggers as soon as possible on receiving user input, ensuring input response in the soonest possible server tick.

CURL Integration

HTTPObjects and all internal HTTP(S) connections are now backed by libcurl, meaning that any web connections needed (such as retrieving the server list) are now able to fully support the latest modern encryption and protocols. You can of course run as many requests at the same time as you have HTTPObjects, and your scripts will get the expected asynchronous callbacks when the transaction completes.

HTTPObject objects have the following fields and methods added:

  • obj.enableIPv6 = true; // set to false to only make ipv4 connections
  • obj.enableIPv4 = true; // set to false to only make ipv6 connections
  • obj.debug = false; // set to true to print detailed info to the console
  • obj.setHeader(key, <value>);
  • obj.getStatus();
  • obj.getFile(request-url, save-path, <mode>); // mode can be “w” (overwrite) or “a” (append), if left blank, existing save destination files will not be touched: the download will be aborted if the file already exists 
  • HTTPObject::onProgress(%obj, %dlNow, %dlTotal, %ulNow, %ulTotal); // script callback reporting binary download progress in bytes

If both enableIPv4 and enableIPv6 are left at default or set to false, both protocols are enabled.

If you want to allow binary downloads, you must set $pref::Net::allowDownloads = true;

If you want to allow binary downloads from insecure servers, you must set $pref::Net::allowInsecureDownloads = true;

By default, when launching the client in online mode, a connection is made to https://curl.se/ca/cacert.pem to see if an update to the certificate authority bundle is available.

If you don’t want to run this update check or it causes issues, you can set $pref::Net::updateCABundle = false;

If you don’t want to use this bundle at all, and would prefer to only use the certificates made available by the operating system, you can set $pref::Net::useCABundle = false;

Asset Depot

If assets don’t exist on disk at load, the resource manager can automatically download them from a curated secure central asset depot server and cache them locally. You can enable this by selecting the “DOWNLOAD MISSING ASSETS” toggle under the “NETWORK” tab of your in-game options. This system is currently limited to a subset of resource types (interiors, shapes, textures, and terrains), and primarily operates via a synchronous download run only when the file is needed; effectively, this is an “last second” source of files you need to join a server. In most cases this should be fast, but it is of course dependent on your connection − which is why it’s currently nominally only being used on initial load of a map, and why things like player skins and sounds aren’t in the depot: files that load during gameplay would require additional changes to the resource manager to ensure these types of assets do not block while loading.

Because lookups are running synchronously and expected to be as fast as possible, after login in online mode, the game requests an index of depot files and builds a table of files that are available to download. This avoids wasting time making connection requests and waiting for responses looking for files that aren’t there. The index also provides known sizes and hashes of all files for verification purposes.

The asset depot system cannot download arbitrary files, nor write anywhere other than the .cache directory. Server hosts cannot cause you to download malicious files through this system.

Missing textures trigger an onMissingTexture(%filename) script callback on failed load attempts. This could be used to trigger an asynchronous binary download with an HTTPObject script, however any textures conceivably saved by this method would not be used until the next time they’re needed. For player skins this might mean the next time a player with that skin comes in scope, but certain textures (e.g. terrain or interior textures) would not attempt to load again until either flushTextureCache(); is run or the map itself is loaded again. Third-party scripts designed in this way to download skins from other sources would, of course, be used at your own risk.

If you want your clientside map assets to be available through the asset depot service, you’ll need to share the vl2 file on this forum for server hosts to use, and let me know you want it to be added to the depot.

Comments

  • edited 12:59AM

    Miscellaneous

    Server Notes

    This patch applies fixes and extensions to the original ban system; if you have the earlier TN script variable based bans in your banlist.cs, you’re going to want to back them up or convert them to the BanList::addAbsolute format, or they’ll be emptied out. Bans stored in other ban managers should continue to work, assuming they’re using the game’s BanList API. 

    The asset depot doesn’t touch your server or bandwidth, it’s entirely clientside.

    You’re going to want to double check the packet rate variables explained above in prefs/ClientPref.cs – if you’re hosting a server with a lot of bots/players/vehicles, you’ll definitely want to raise them. If you have limited bandwidth and previously reduced the packet rate below 32 (no longer supported), you could instead reduce the packet size.

    Discord Integration

    This was an integration from years back, and thus doesn’t use their latest SDK, but should still be fully functional. It’s entirely optional, and you can delete discord_game_sdk.dll if you don’t want it to attempt to load, but if you aren’t running Discord, it won’t do anything anyways.

    Supported features are Discord rich presence activities (the thing showing what you’re doing in-game) and invites, although how the latter is shown in channels may have changed on Discord’s end recently. There’s some activity status support for showing an image correlating to the map you’re on, as well as the team you’re on, but this is limited to the loading image files I processed and scaled up a bit when setting up the integration. If you want to see more/better map images, you’ll need to submit them to me. I believe they prefer them to be 1024x1024, but 512 should work (the ones I uploaded back then did), and they should be named to match the .mis file name. 

    Physics/Math

    • A number of math functions run by the game every frame have been replaced with SIMD variants. The optimizations here are largely the reason for the AVX requirement, but the difference isn’t so extreme that it’s a necessity.
    • Some of the collision physics have been made more efficient or adjusted, but not in ways that break playback or gameplay.
      • Deadstops on terrain and (horizontal co-planar) interior surfaces have been eliminated.
      • Wheeled vehicles are somewhat more stable and compensate for yaw oscillations causing shimmying at high speeds. MPBs have had their center of mass rebalanced and the springs on the front axle adjusted to better carry the load and avoid ridiculous hull collisions, particularly under the higher classic gravity. There're some added penalty forces to counteract wheels that penetrate the surface when the springs bottom out.
      • Hover vehicles detect all static/deployed objects and adjust to the correct surface normal (use jumps, bridges, etc). 
    • You can set (linear) vehicle velocities via script.
    • A handful of simple utility script functions have been added or optimized, e.g.:
      • VectorMultiply(vec,vec);
      • VectorDivide(vec,vec);
      • VectorAngle(vec,vec);
      • VectorRotate(vec,axis[,angle]);
      • VectorProject(vec,vec);
      • VectorReflect(vec,vec[, refraction_ratio]);
      • VectorCouple(vec,vec);
      • VectorCompare(vec,vec[,epsilon]);
      • mRound(float);
      • mMin(float,float);
      • mMax(float,float);
      • InitContainerRayBoxSearch(startPos, endPos, radius, mask[, exempt object]);
        • Can be considered basically a “wide” raycast, but integrated into the InitContainerRadiusSearch existing set of functions: ContainerSearchNext/ContainerSearchCurrDist/ContainerSearchCurrRadDamageDist
      • InitContainerFrustumSearch(startPos, endPos, fov, mask[, exclude [, aspect=4/3]])
        • As above, but searching a perspective frustum

    Commands

    There are a bunch of functions relating to authentication and features already described that aren’t of much use in general scripts, but a few of other script commands and callbacks have been added or ported to native implementations, such as:

    • isxdigit(char);
    • ord(char);
    • chr(int);
    • BinToDec(binary_string);
    • DecToBin(int);
    • HexToDec(hex_string);
    • DecToHex(int);
    • Base64_Encode(string);
    • Base64_Decode(string);
    • rc4(data, key[, hexIn = 1[, hexOut = 1]]);
    • rsa_mod_exp(base, exponent, modulus);
    • rand_challenge([seed]);
    • sha1sum(string);
    • time(); | currentEpochTime();
    • getEpochOffset(seconds);
    • getEpochDelta(epoch1[, epoch2=”now”]);
    • dumpNetStringTable(); // debug mode only
    • setInteriorRenderMode(modeNum); // offline debug mode only
    • GuiPlayerView.setSequence(name);
    • queryServerInfo(address);
    • GuiServerBrowser.getServerPlayerCount();
    • GameConnection.getProtocolVersion();
    • GameConnection.onEarlyCommand(serverCmd);
      • Called when an unauthenticated client attempts to use a serverCmd prior to completing script-based authentication on an online-mode server
    • onMissingTexture(%textureName);
      • Called when the resource manager is unable to find a texture locally (or in the asset depot index when enabled)
    • onUpdateRenderTargets();
      • Called when render targets are created or change size, used to facilitate some necessary adjustments with maintaining UI scaling/aspect preferences
    • FreeMemoryDump(); // returns some memory states
    • AIConnection.getAddress(); // now returns “ai:local”
    • ShapeBase.getMass(); // returns the stored mass value of the object
    • setFramerateLimit(cpu_fps); // client only
    • setConsoleInterval(interval_ms); // allows reducing the polling rate for input on dedicated server console windows

    Fixes/Misc

    • A basic crash handler has been added that’ll attempt to dump some info to CRASHLOG.txt if the game hits an exception. Server hosts wanting to suppress the blocking message “OK” box can set $pref::Engine::ExitOnException = true;
    • Many crashes were fixed as they occurred or were reported. A few that were probably not mentioned elsewhere were:
      • Explosions occasionally attempting to explode after being deleted
      • Navigation graph generation/use crashes with invalid terrain nodes
      • Divisions by zero in scripts should now safely abort with the result set to 0
      • It’s possible to load some legacy shapes that would previously have crashed the game, however, their damage decals will not render, their normals are recalculated at load time, and the indices for LOD levels are not necessarily correct. This was more done out of curiosity in playing with some beta meshes, but could be finished and expanded to allow loading T1 meshes and others at some point.
      • It’s no longer possible for scripts to attempt to access tagged strings beyond the allocated range of the net string table
      • Material map lookups can’t return an out-of-bounds index
      • Adding interiors will no longer cause the game to crash if for some reason you’re using vertex lighting
    • Password saving uses the HKCU registry space instead of the (write protected) HKLM
    • Web links now open in your default browser
    • Certain interior/shape debug warnings are suppressed in online mode; if you’re creating new interiors or models, you may want to start the game in -nologin mode
    • The game no longer tries to unregister the lightmap manager’s TextureManager event callback on mission changes 
    • .png extensions are now searched before .jpg when loading textures
    • The hud is now only drawn a single time, rather than twice, improving performance but obviously somewhat reducing opacity
    • “Weird precipitation render bug”
    • Wildcard matching in strings is more performant and a little more flexible (should support multiple * variable-length wildcards and ? single character wildcards)
    • Options sliders can now snap when dragging the mouse
    • Your dude will play an animation when you test your voice
    • Unsupportable D3D & Voodoo renderer options were removed
    • You can set $pref::Video::Borderless = true; to remove borders from all windows (not just fullscreen), but there is no menu option for this and you might forget you set it
    • Zlib has been updated/replaced with a more performant version
    • You can set your first-person player/weapon model transparent using $pref::Player::renderFade (between 0.0 and 1.0), although it’s a little janky
    • Redbook CD audio is no longer supported (though I’m not sure anyone has tried in many years, and the game didn't ship with any tracks)
    • WON calls in general are no longer available and the no attempt to initialize the system is made
    • Handles for a few lobby icon textures (headset, listen, timedout) are now kept resident in memory so they are not re-registered every single frame they are shown
    • Demos can be played with correct pacing in slow motion
    • Hosts can override terrain materials by setting material[0], material[1] and so on in the TerrainBlock, which will be transmitted to patched players at load time. Material overrides will not be sent to unpatched players, and will not save to demo recordings (it’d be possible, but doing so without breaking compatibility is an extra step). This could be done fully dynamically in a later revision, but really requires full hardware terrain to be a useful mechanism.
    • All 8 standard terrain material slots are now available to paint in the editor (minor UI tweak) and the final two will be rendered as long as the hardware blender is enabled
    • If you want to experiment with higher terrain AO levels, you can set the following configuration values and run flushTextureCache(); after a change:
      • $pref::Terrain::AO_RADIUS1 = 1.5;
      • $pref::Terrain::AO_RADIUS2 = 6;
      • $pref::Terrain::NUM_AO_SAMPLES = 32;


Sign In or Register to comment.