Jan 21, 2022

User Interfaces in Virtual Reality

Making a UI in VR adds a layer of additional concern that pancake UIs don't have to deal with. Someone in Discord asked for feedback of their VR UI. My response turned lengthy, and potentially useful to others.

Make menus accessible. In VR, this has an added step of considering how difficult it is for a user to reach out with their controller to reach the menu. Is it within their play space? Can they alter the location of the menu? Some games use the wrist watch method. Intuitive to open and put away. Intuitive to move around. Another common type is to open with a button press near the user based on their facing angle. This lets the user close the menu and reopen it in a more convenient spot should the menu appear out of the play space.

How are buttons pressed? Does the user need to have their digital hand come into contact with the menu, or can they point from a distance and click? If the latter, a line from the hand should help indicate that this is going to happen. Do you allow both options at the same time? If so, is there a distance that the laser click option disappears? I recall one game that when the digital hand neared a button, open hand would turn into a pointing finger. This is falling out of favor with controllers that can detect what the user's hand is doing, and mimicing that instead.

Are the buttons large enough that they can be uniquely pressed? If it is easy to fat finger (fat fist?) the wrong button, something needs to change.

Don't attach a menu to the user's head facing. It should be either static in the world, or attached to the user's controller. If it is attached to the controller, it should be intuitive to "put the menu away." It's annoying to try and drop something that is stuck to your hand.

Most regular UI design principles apply:

Use understandable labels. Don't use made up words, internal jargon, or memes. Stick with established terminology.

Consistency. Menus throughout the game should appear thematically similar. How a given menu works should be the same throughout the menu tree.

Readability. Menu text should be legible. The menu's colors should have contrast between text, buttons, and the background. Don't use fancy fonts. Don't use fancy effects on those fonts. Careful with over designing for the wow factor of theme. If it isn't easy to use and understand, it's failing it's main job. Remember Me's main menu is an example of going way over the top into the point of being borderline unusable.

The top level menu should limit how many options appear in it to no more than eight. If you need more than that, consider categorizing them into a smaller number.

Bonus: The user should understand where they are within the menu system.

On images.google.com, look up "Video game menu" to see what pancake games have done. It's harder to convey this in VR, but there are many good examples out there. SteamVR overlay. RecRoom's watch. (edited)

Nov 14, 2021

C# error with FoxPro

While running a query via System.Data.OleDb.OleDbDataAdapter on a FoxPro dbf, I sometimes get an error "Column 'Q37P2' is not found.", where the column name appears to be incrementing each time the error occurs. This is happening on adapterObject.Fill(datatableObject); call. It took me a while to figure out this was caused by not providing the adapter with enough parameters as the SQL statement has ? question mark placeholders for parameters.

As the error message isn't useful for knowing the cause of this bug, I added validation to our GetDataTable calling method:
C# //Via: LukeH on StackOverflow.
if (System.Diagnostics.Debugger.IsAttached)
{
    if (parameters.Length != sSQL.Length - sSQL.Replace("?", "").Length)
    {
        StringBuilder sbError = new StringBuilder();
        sbError.Append("Parameters count is different then the number of parameter placeholders (? marks).");
        sbError.Append(Environment.NewLine);
        sbError.Append("? count: ");
        sbError.Append((sSQL.Length - sSQL.Replace("?", "").Length).ToString());
        sbError.Append(Environment.NewLine);
        sbError.Append("Params: ");
        sbError.Append(parameters.Length);
        sbError.Append(Environment.NewLine);
        sbError.Append("SQL: ");
        sbError.Append(sSQL);

        System.Diagnostics.Debugger.Break();
        throw new ArgumentException(sbError.ToString());
    }
}

Jan 30, 2021

VR Room Motion Curator: VR Fitness Gym (Cycling, Marathon, Football, etc)

Main room has a floor 20 feet below the player. Though this isn't room motion, to suddenly find yourself high above the ground is disorienting. To navigate menus, I had to hold the joystick away from neutral to get a selection indicator to function.

   Snake game is rotated ground vertigo with perspective attached to character which is controlled by your facing direction. Third person camera is already weird enough, but to then be looking outward some 40 feet away from you to see the ground, then look around to see that the world is rotated such that gravity is into the horizon is not comfortable. Add to that clumsy head oriented controls, ignoring controller input. I think the selection indicator is stuck on "always selecting" instead of using the trigger to make a selection in this game.

  The archery game is rather standard, using teleport movement. The bow without an arrow is held as though the length of the bow is attached to your arm, instead of your hand holding the handle. After playing the archery game, it rotated gravity on me, such that one side of the world was steeply down hill. This game wasn't translated into English, so I just randomly selected window options.

  The running game knows you have controllers, but chooses to make the interface all about head facing direction for selections (WHY?). Within a game, it has you swing your arms around to move in the course's forward direction, and uses your facing direction to move sideways, but not in an analog way that your head works. No. Instead it's a set speed once you've rotated your head at a bit further then 30 degrees off center. It doesn't care which way your are swinging your arms. You can't look around to enjoy the scenery, because that would change your moving path. You also have to collect gold coins along the path, so you need to accurately use this poor controller style to navigate.

  The cycling game has multiple locations. In the city, it has so many bombs falling from the sky and particle effects, that it runs at a noticeably slower frame rate as any other part of the game. In the Jungle, if you don't "bike" fast enough, you will be dropped from the elevated bridge down to the jungle floor below. If uncontrolled falling wasn't bad enough, once you land, you get thrown into a random orientation as the room is rotated around you as though your head was chopped off and thrown around. Super great /s.

  I can't recommend this product in it's current state for any value.

Nov 14, 2020

Sea of Thieves, Windowed Resolution

For me on Windows 10 using a NVIDIA GeForce RTX 2080 SUPER, Sea of Thieves resolution settings are ignored. When I set to full screen, it works as expected. When I set to windowed mode, it uses the screen's max height, and displays as a borderless window locked size mode. Changing the resolution doesn't change anything. After messing with it for a while, I got the resolution to listen to me.

First, in Steam, Right Click on the game in Library -> Properties... -> Set Luanch Options -> Enter: -WINDOWED
If you aren't on Steam, you should be albe to set launch options in your launch application of choice, or the shortcut of your game (via right click of the desktop icon -> Properties -> Target "[LaunchLocation]" -WINDOWED
Within the game, go to windowed mode in the game's Video Settings
Shift+Right click the program in task bar -> Maximize
This will get the game to display the title bar with Min/Max/Close buttons.
Now, when you change the resolution... it still won't do anything, but then messing with Display mode will get it to apply the given resolution! Having the launch setting set to -WINDOWED locks the game to windowed, which is nessisary for the game to apply this resolution. I think the dev has the resolution being set as you leave windowed mode instead of entering it, causing this bug.

Nov 8, 2020

Data from MDF to SQL Script

I needed to export my data out of a MDF SQLServer file so that I could import it into a PostgreSQL database. In case we figure out time travel, or in a few years I need to remember how to get data out of a mdf, a series of images.

In server explorer, right clicking a connected mdf and selecting Browse in SQL Server Object Explorer provides a way to export a table's schema.
In the SQL Server Object Explorer, Right click on the MDF's table->view data, followed by the second script icon "Script to File" gives the SQL server format insert statements. I still had to convert from that into PostgreSQL, but that wasn't too hard once the data was in my hands.

Aug 19, 2020

Fun with Virtual Monitors

tl;dr: This is a rambly post about trying to get a Virtual Monitor setup to work with a multi monitor display.

Fought with monitors tonight. Couldn't get a second monitor to work (Display Port). I've been using a UHD hdmi monitor for the last two weeks. Even after unplugging the HDMI and only running the DP, nothing would show up. Since the UHD is a smart tv, every time I unplug/replug the monitor, it decides to screw with it and go into detect the device mode.  Mind you, when it does this, the screen comes up normal like it always has for about 3 seconds, then that gets hidden by the detection software of the smart tv, which eventually decides it is a 4096x2160 that I don't want fit to screen so it should display the center 3840x2160 pixels. Now I know how to get to the setting that doesn't fit to screen... but then... if the 4096x2160 is fit to screen, that means it doesn't actually display that size... then why is it reporting to Windows that it can if it is faking that size? Looking at it, I can't tell if anything is stretched or not.

So three restarts later I've got 2 Display Port monitors and an UHD HDMI monitor. Index still throws a 108 with "Last USB device malfunctioned) error, so that doesn't appear to be solved by getting the DPs working. But now, DisplayFussion's taskbars are fighting with Window's taskbars for which should be displayed and how. I've got DF's settings set to use the UHD as a 2 by 2 virtual monitors which does good for maximizing to quadrants of the UHD, and has split up taskbars for these 4 Virtual Monitors (VMs), but now every 10 seconds or so, the taskbars flash back and forth as windows things "Wait... isn't the main bar suppose to be across the entire bottom? and isn't the second monitor's bar supposed to be on top?" and DF replies "No Windows, the main taskbar is supposed to be the bottom left VM, and that's it. Stay on your half of the bottom of the UHD."

Found a post from 5 years ago asking NVidia to handle virtual monitors at the hardware level, telling windows "Yea... I've got 4 screens here, each 1920x1080 in a 2x2 square" and then let windows dictate what happens on these multiple monitors, allowing full screen, toolbars and windows to appear as separate screens, and NVidia pushing those displays out as the one UHD.  This is the way to use UHDs.  A seamless multi monitor. (I don't have a link to that post, as that was a week ago that I read it).

One of the things that DisplayFussion doesn't do right is the windows key + arrow keys. On a monitor, this means "move to this half of the screen", but in Virtual Monitors, it pushes it to the VM on that side, instead of that half of the VM.

Virtual Display Manager V3 is another Virtual Monitor tool. It doesn't do toolbars, but does one up DF in the full screen of a youtube video department. DF's VM full screen takes up the full UHD. VDMv3 correctly full screens to the given VM.
The bottom of my screen is still flickering, even after returning to 3840x2160 without fit to screen. I don't _think_ it's been there all this time.

Jun 26, 2020

Dealing With Cached CSS Files

If a stylesheet is updated and sent to prod, the customer's computer usually won't get the updated version for a while since their computer has a cached version of that file on their machine. This can often make the website look bad. There is a super simple solution to this. Adding a query string to the css request request makes the browser think it is a different file, even if the server still gives the same file regardless of the query string.

<link rel="stylesheet" href="/assets/css/main.css?version=20200626" />

Learnt this from Gordan of WPReset, who was a bit more verbose about this problem and solution.