I asked Astra what it thought about it's chances
@Rroff ...
I’d start with the radar because it tests the central constraint with fewer moving parts. The mouse UI adds harder questions about extracting mouse movement from view-angle input, holding the camera still, and keeping the interface responsive despite network and HUD update limits.
My approach would be to inspect the actual source, trace what the unchanged client can receive and display, then build and test small experiments. Those are plausible engineering tasks for me; I wouldn’t need you to supply each workaround. However, an apparently convincing patch that compiles would not establish that I’d solved them.
Rroff’s caution about engine limitations is justified. His stronger claim—that a model cannot discover the necessary workarounds from a high-level request—is something we can test. Equally, “just give it the source” understates the importance of running the result and observing its behaviour.
The fair test would be a working demonstration on an unchanged Quake II RTX client, with all changes confined to the agreed server/game-module code. I’d be willing to take that test; I wouldn’t promise the outcome in advance.
Opus had this to say:
Probably yes, especially the radar. The mouse UI is harder, but I can see a route through it. One caveat up front: everything below comes from memory of the Quake 2 and Q2PRO code (Q2RTX’s client is based on Q2PRO). I haven’t opened the Q2RTX source in this session or built anything. Rroff’s real point is that you hit the walls when you build it, so the only honest test is to try.
Here’s how I’d approach it. You can judge whether I’ve understood the constraints.
The radar, using only game DLL code
- How the game DLL can draw at all. Game code can’t draw anything itself. It can send a layout string (svc_layout via gi.WriteByte/gi.WriteString/gi.unicast). The client’s layout interpreter runs that string while bit 1 of STAT_LAYOUTS is set. It’s the same path the scoreboard and help computer use. The radar becomes a string of xr/yt positioning commands followed by string/string2 draws, one per blip.
- Drawing each frame. For each client, find the live SVF_MONSTER entities. Take each one’s offset from the player, rotate it by the player’s yaw, scale it, and clip to the radar radius. Use a different character, or string2, to show whether a monster is above or below you.
- Problems you hit:
- Send it unreliably (gi.unicast(ent, false)). A dropped packet then just leaves the radar one frame old, instead of piling up in the reliable stream until it overflows.
- The layout buffer is small (around 1KB in vanilla). You have to cap the blip count, drawing the nearest monsters first.
- The scoreboard, inventory and help all share the one layout, and they clear STAT_LAYOUTS. The radar has to merge with them or step aside.
- The statusbar configstring looks like a way to send the layout once. It doesn’t help much, because xv/yv only take fixed numbers and there are only 32 stats, so blips can’t move without a big grid of if cells.
The mouse UI
- Locking the view. The client only uses its own predicted angles while pm_type < PM_DEAD. Set PM_FREEZE and it renders the server’s ps.viewangles instead. The 3D view stops following the mouse, but the mouse still changes the angles in every usercmd.
- The cursor. In ClientThink, take the difference between this command’s ucmd->angles and the last one’s. Subtracting as shorts handles wraparound. Scale that to virtual screen coordinates, clamp it, and treat a fresh BUTTON_ATTACK press as a click. Firing has to be suppressed while the UI is open.
- Running out of vertical mouse. The client clamps pitch to about ±89° relative to delta_angles, so moving the mouse vertically eventually stops doing anything. The fix is for the server to keep rewriting ps.pmove.delta_angles[PITCH] to re-centre it. That change takes a round trip to reach the client, so the server has to allow for the delay.
- Update rate. The vanilla game runs at 10Hz, so a layout cursor moves at 10Hz plus network latency. One alternative is to draw the cursor as an entity in the world just in front of the locked camera. The client smooths entity movement between frames, so it looks smoother, but adds about a frame of delay. I’d want to try both and see which feels better.
Where I’d actually struggle
The exact mapping from mouse movement to screen pixels under Q2PRO’s HUD scaling, whatever Q2RTX changed in its client, and how the cursor feels in use. Reasoning won’t settle those; building and running it will. I partly agree with Rroff that a one-shot answer to a high-level prompt would likely ship with bugs. Given the source, a compiler and the running game, though, the process is the same iterate-and-test loop a human would use.
I could do it for real: clone NVIDIA/Q2RTX, change only src/baseq2, build the game DLL, run it with the shareware data that ships with Q2RTX, and screenshot the result. To do that I’d need to know:
- whether this machine has a ray-tracing-capable GPU and Visual Studio/CMake installed;
- whether you want the radar, the mouse UI, or both