1. Super Video Golf
  2. News

Super Video Golf News

Progress Update 1.22 Part 1

[p]Hello all! Welcome once again to a progress update, to players both old and new, veterans and newcomers alike![/p][p][/p][p]First of all thank you to everyone who has made the DLC launch a success - and to those who left comments and feedback. You seem to be really enjoying it, so Thank You![/p][p][/p][p]Since the last release I’ve been hard at work on the next update to Super Video Golf. However, while most updates concentrate on adding new features, right now I’ve been doing my best to optimise the game, particularly at a GPU level. While adding new features is great, every new feature brings with it a little more overhead and, unfortunately, some players with lower spec hardware are beginning to get left behind. I decided it was time to take a look and see just what I could do to improve performance and, as it turns out, it was rather a lot 🤔[/p][p][/p][p]This post, then, is going to take a relatively deep dive into what I’ve changed and may also get a little technical. If this isn’t your thing then you might want to skip this one - however if you’re interested in how the sausage is made, read on…[/p][p][/p][p][/p][hr][/hr][p][/p][p]Where to begin?[/p][p]Super Video Golf has always been a game which is very much ‘GPU Bound’ - that is the hardest working part of the game has been on the graphics card. In the early days of the game it was so relatively simple on a technical level that it didn’t matter too much - almost any GPU could chew through the vertices that were being fed to it. As the game has grown more complex over the years, however, optimising the data to be processed on the GPU has become more important as the need for more quickly processing that data has increased.
[/p][p]To avoid just throwing up a bunch of numbers on the screen I’m going to try using a warehouse analogy - so bear with me. Apologies up front if it just ends up sounding daft 😅[/p][p][/p][p]We’ll start with the GPU’s memory, aka VRAM. Consider this as a large warehouse - although the warehouse can vary in size based on any particular graphics card. It has a loading door around the back where a delivery truck can pull up and drop off a bunch of packages in various sizes. This truck represents the game when it’s loading - and the packages are the images, shaders and 3D meshes used to display the game, being brought by the truck from wherever they were stored on your hard drive.[/p][p][/p][p]These packages get placed on a variety of shelves and stands throughout the warehouse, waiting to be taken to the front counter - or in other words displayed on screen - by our GPU who, in this analogy, takes the form of a friendly custodian, whose job it is to walk the aisles and fetch packages from storage (the things we want to draw) and bring them to the counter (display them on screen).[/p][p]
[/p][p][/p][p]Size and Locality[/p][p]Before I started optimising the game many of the packages were far larger than they needed to be. While our custodian could fetch the data with a bit of effort, it was heavy work. Packages were also strewn all over the place as if they were just dumped in the first place that would fit. Worse still, smaller warehouses (GPUs with less VRAM) would fill up so much that it was difficult for the custodian to move around. Some packages might even get left out in the back alley!
[/p][p]This meant I had two things to tackle off the bat:[/p][p]
[/p][p]Size:[/p][p]Drawables such as 3D and 2D meshes are made up of vertex data - vertices are the points which make up the mesh and are joined together to form triangles. A single vertex can have a variety of properties, depending on its use, and each property can be stored in a particular way, or data format.[/p][p][/p][p]As an example a typical mesh might have a vertex layout with the following properties:[/p]
  • [p]Position - the 2D or 3D position at which this vertex should be drawn[/p]
  • [p]Colour - the colour of the vertex which may also affect the colour of the associated texture when it’s drawn[/p]
  • [p]UV Coordinate - this tells our vertex which part of the associated texture should be drawn[/p]
[p][/p][p]When I started out (some 4 years ago now!) I created all vertices equal. They were all represented by a series of floating point numbers: 3 for the X,Y and Z coordinates for the position, 4 for the Red, Green, Blue and Alpha parts of the colour and 2 for the U and V coordinates.[/p][p][/p][p]Each floating point number takes up 4 bytes in memory, so each vertex has a memory requirement of[/p][p](3 + 4 + 2) * 4 bytes - 36 bytes in total.[/p][p][/p][p]While this seems like a relatively small number at first, a 3D mesh may have thousands of vertices. It may also have many more vertex properties, such as a mesh with skeletal animation (bone weights, bone indices, normal vectors etc…). When we consider all this as part of a package in our warehouse it starts to become quite hefty, and hard work for our custodian to move around.[/p][p][/p][p]Fortunately there are other data types in which we can store our properties, and effectively compress the vertex data by reducing its size. For instance the UVs can be stored as 16bit (2 byte) values instead of 32bit (4 bytes) which immediately halves the amount of memory needed for the UV properties. Even better than that it turns out that colour values can easily be represented in a single byte for each Red, Green, Blue and Alpha channel. A decent reduction in size of 4:1 😁[/p][p][/p][p]Reducing the size of position data is a bit more complicated  - so let’s just assume we’ve done our best for this example. If we look at our new vertex size we have the 12 bytes for position as before, but now colour is a mere 4 bytes as is the UV property. This brings our total size down from 32 to 20 bytes per vertex - about 63% its original size. Our custodian (the GPU) can now move these lighter packages around more easily - and even pick up two or three at a time, so it’s a good start! [/p][p][/p][p]Using this technique I went through all of the various mesh formats throughout the game with a fine toothed comb, and reduced all of the vertex data in size as much as I reasonably could.[/p][p]
(It should be noted that, depending on use case, vertex layouts vary wildly and the amount of reduction which can be done varies as much. There are also different techniques available depending on which property you’re working on. If you’re interested in more details check out the OpenGL wiki page on the topic.)[/p][p][/p][p][/p][p]Locality[/p][p]The second consideration is locality. What do I mean by that? Although our packages in our warehouse have been made more compact and easier to move around, they’re somewhat scattered around the warehouse itself. It stands to reason that many of these packages are related to each other - for instance all the images which make up a particular menu, or all the meshes which make up the 3D background in the game. Even if the packages are easier to carry now, our custodian is going to have a hard time if they have to keep climbing over or walking around all the other packages which are in the way. It makes more sense that, when we unload the packages from the truck, we store related packages close together - on the same shelf if you like - so that they can be easily accessed in as few trips as possible. In other words, related packages should be local to each other.
[/p][p]To do this we can take advantage of OpenGL’s buffer storage mechanism - think of a buffer as a shelf in the warehouse. Before optimisation every mesh was just given a small buffer - whichever the graphics driver had to hand, and the mesh was placed in it. Now, when the game loads, it specifically requests a series of large buffers - each a whole wall of shelving - and then as the packages come in from the truck they are examined and placed in the relevant storage location to group them together by relevance. As a result when we switch from, say, the main menu to the driving range in the game, both the menu and the driving range have their own area in the warehouse. Our custodian can concentrate on just a small area relevant to the active part of the game, bringing as many packages as possible to the counter swiftly (and with style 🎩) - with much less of a chance of tripping over a stray shader or a box of textures 😅[/p][p]
[/p][p]
[/p][p][/p][hr][/hr][p]
[/p][p]Making the mesh data, particularly, compact and well sorted immediately showed a performance improvement - but is that all I could do to optimise performance? Of course not 😁[/p][p][/p][p]
Image Compression[/p][p]Textures are large blocks of contiguous memory. They often contain image data (but not always, we’ll touch on that below) used to colour the meshes which are drawn on screen, either as 2D menu items or 3D objects. When we use images on our computers or phones they are usually stored in some sort of compressed format such as png or jpg to take up less storage space. However, in order to display them on screen, they have to be decompressed fully into GPU memory. This means that even though a small 2kb png file might not take up much storage space on your hard drive it’ll take up more shelf space in our warehouse once it’s moved to VRAM. This is because graphics cards like to work on many small blocks of an image in parallel (see this Mythbusters video for a great explanation) but compression formats like png and jpg need to be processed sequentially, making it unreasonable to decompress them in good time on a GPU.[/p][p][/p][p]It doesn’t matter how compressed a 512x512 8bit RGBA image is on disk it will always uncompress to:[/p][p]512x512x4(bytes per pixel, RGBA) = 1,048,576 bytes (approx 1mb).[/p][p][/p][p]Switch to a 1024x1024 image and it jumps in size to 4mb! You can see how having many images in a game can suddenly take up a lot of space in memory. Fortunately there is a special type of compression suited to processing images in blocks, handily titled BC or Block Compression. Block compression is a complex topic and there are many variants (check out this article if you’re interested in the technical details) however it’s relatively easy to implement in a game engine with open source programming libraries out there available for the job.[/p][p][/p][p]In the case of Super Video Golf I used the libktx library to add support for loading compressed textures, and nvidia’s Texture Tools to update the game’s existing assets. This means that, for the same reasons above (size and locality), image textures are now compressed into smaller, manageable blocks to sit on the warehouse shelves and, by the very nature of image data, all sat in a continuous, data-local, row.[/p][p][/p][p]Win number 2![/p][p][/p][p][/p][hr][/hr][p]
[/p][p]As I hinted above, not all textures are necessarily images. Super Video Golf uses a series of ‘multi-render targets’ or MRTs to store rendering information in textures, which are written by the GPU. In particular effects such as the lighting when playing golf at night are processed via a series of render targets:[/p][p]
[/p][p]and then combined into the final image you see on screen. [/p][p]
[/p][p]I’ll avoid going into details as to exactly why this is - however you can read about the technique (also known as deferred shading) at Learn OpenGL.[/p][p][/p][p]The crux of the matter is that, as these textures are writable, they are unavailable for Block Compression and each of these layers, before optimisation, were all set to 4 channels, with 32bits(4 bytes) per channel. For a full screen effect at 1920x1080 with layers for position, colour, normals, lighting this adds up to:
[/p][p]1920x1080[/p][p]x4 (channels)[/p][p]x4 (bytes per channel)[/p][p]x4 (layers)[/p][p]= 132,710,400 bytes - using a whopping 133mb of GPU memory![/p][p][/p][p]Throw in the fact that there are MRTs for not only the main scene but also the ‘ball flight’ window and minimap view (a somewhat ridiculous 4480x2560 image - yes the real optimisation here is to take a different approach to zooming 🤦‍♂️) it’s suddenly very obvious where much of the GPU memory was being used 😅[/p][p][/p][p]With a bit of head scratching it’s actually possible to apply some of the vertex data reduction techniques on the texture. For instance the colour data (such as the illumination values or lighting) doesn’t need 4 bytes per channel, just one byte, so there’s a gain to be had there simply by changing the format of the colour layer and even reducing the channel count from 4 to 3. The layer containing the normals can also be reduced in precision as a normal only represents a direction (and has a unit length of one) - and so will also fit nicely in an 8-bit channel without perceptible loss of accuracy.[/p][p][/p][p]As it happens it’s also possible to recreate the position data from only the z-depth using a shader on the GPU, so the position layer can be reduced from 4 channels to just one, and even converted to 16 bit from 32bit - reducing the position layer to one eighth its previous size as we’re now only storing the z position. Nice![/p][p][/p][p]There are some other potential optimising techniques available to use - such as combining mask images with colour ones into Array Textures which would reduce the number of state changes, or using a z-prepass which I may still experiment with. However, for the effort required, it feels like I’m approaching the point of diminishing returns.[/p][p]
[/p][hr][/hr][p]
[/p][p]In conclusion[/p][p]So… does this give a perceptible boost to the game’s performance? I think so, but it’s hard to tell 😅 I actually have a limited amount of hardware to test the current version on, and compare it to the 1.21 version of Super Video Golf.[/p][p][/p][p]On an older PC with a GTX1070 GPU and an intel processor from 2013 I can now play the game at a crisp 1440p without much of a hitch. On the Steam Deck I can increase the tree quality to high and get a solid 60fps which I couldn’t before, and playing a round in night mode no longer makes the fans work as hard as they were. I haven’t measured it but the lower power consumption ought to make the battery last a little longer too. I don’t have a dock, or even a TV to test the Steam Deck at 1080p or higher though, so I don’t know if there was any improvement there. Hopefully it’ll perform well even if you do have to switch the tree quality to low.[/p][p][/p][p]So perhaps, dear reader, assuming you've made it this far (congratulations if you did!), you could tell me what your experience of the optimised version is compared to the current 1.21.2 version? It’s currently available on the beta branch on Steam - found in the game’s properties, under the beta tab and select the beta branch from the drop down menu. I’d be very interested to hear! Drop any comments you have over on the Discussions, Group Chat, or Discord. Thanks![/p][p]

[/p][p]However…[/p][p]With all that being said there’s still more planned for the 1.22 update - including some new features! Unfortunately I've already waffled on for far too long so I'll have to save the details for what else I have planned for a future post.[/p][p][/p][p]Until then though, as always,[/p][p]Happy golfing! ⛳🏌️[/p][p]
[/p][p][/p][p]"Janitor" (https://skfb.ly/6Z9GD) by Víctu is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).[/p][p]"PSX Storage Shelves & Cardboard Boxs" (https://skfb.ly/oWpno) by Drillimpact is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).[/p][p]"Kei Truck" (https://skfb.ly/otNAF) by grs is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/).[/p]

Monthly Challenge For November Has Begun!

[p]Every calendar month a new challenge runs, starting and ending at midnight UTC. Now that you've completed last month's challenge (you did complete it, didn't you? 😉) it's time to hit the back 9! Score at least 1 Eagle on the back 9 of each of the (non-DLC) courses. You can play solo, online and against CPU. Rounds can be played at any time throughout the month, and completing the challenge awards 1000XP! Track your progress from the menu in the Clubhouse on the 19th hole, and look out for the notification in the top right corner of the screen. And, don't forget, new monthly leaderboards and Global League are now live too! 😁 Happy golfing! ⛳ [/p]

Double XP Weekend

Greetings Golfers!

It's the third weekend of the month which means all day throughout the 18th and 19th October 2025 you'll be earning double XP when you play Super Video Golf!

Weekend times are, unlike the monthly challenge, in your local timezone running from midnight to midnight - so you won't have to get up at 4am to scoop up those extra helpings of XP 😁

So, if you're looking to buff your stats and climb the ladder, now is the perfect opportunity!

Happy Golfing! 🏌️‍♂️⛳

The Adventurer DLC is now available! 🚀

[p]Hello all![/p][p]I'm happy to say that the first DLC for Super Video Golf is now available to buy on Steam! With new cosmetics, avatars, balls, sound and a full size new course, the DLC can be yours at 10% off for the first week,[/p][p][/p][p][dynamiclink][/dynamiclink][/p][p][/p][p]Head on over to the Store Page now to start your adventure! 🚀🌛[/p][p][/p][p]Happy Golfing! 🏌️‍♀️⛳[/p]

Patch 1.21.2

[p]Greetings golfers! [/p][p][/p][p]It’s been a busy few weeks here at the clubhouse, what with the impending DLC on the horizon, but I’ve still managed to squeeze a few bug fixes and some QoL improvements into another patch.[/p][p][/p][p]While smaller than most updates, the 1.21.2 patch does bring some interesting new features based on player feedback. Firstly the much asked for auto-rotate for the player camera has been added. Now, when aiming, the camera will automatically follow the player. This behaviour is optional, however, as I know many players have gotten used to the existing camera and muscle memory can be hard to change 😅 - to turn this behaviour off just hop on over to the Settings page of the Options menu.[/p][p]
[/p][p][/p][p]
[/p][p]This update also adds the ability to measure distances when putting, useful for either those dog legged putting courses, or when putting without the Putt Assist enabled. When you’re on the green simply press Up on the D-Pad (or 1 on the top row of the keyboard) and a small widget will appear on screen. You can move the widget around with the aim keys or left thumb-stick and the distance from the current lie of the ball will appear in your chosen units above the widget.[/p][p]
[/p][p]
While these are the most noticeable changes there are many smaller fixes, such as a bug in the Workshop tools which was applying the incorrect animations to imported avatars 😅[/p][p]
[/p][p]Here’s the full change list:[/p]
  • [p]Fixed - Elevation display is properly hidden for remote clients in network games[/p]
  • [p]Fixed - Game no longer plays menu music in-game when the soundtrack is installed from Steam[/p]
  • [p]Fixed - Workshop tools were loading the wrong player animations when importing an avatar.[/p]
  • [p]Fixed - Crash when loading the game and no audio hardware was available[/p]
  • [p]Updated - CPU players are less likely to go into ‘meltdown’ when failing to make a shot[/p]
  • [p]Updated - Tutorial and How To Play now cover the Putt Measuring Tool[/p]
  • [p]Added - Option to automatically rotate camera when aiming (on by default, disable in the Options menu) [/p]
  • [p]Added - ability to measure distances when putting with Up on the D-Pad or 1 on the keyboard [/p]
  • [p]Added - Support for the Adventurer DLC
    [/p]
[p]Thanks to everyone who highlighted bugs or offered feedback - make sure to let me know of anything else you might find! You can drop a note over on the Discussions, join the Group Chat or come say Hello on Discord.[/p][p]
That’s it for this update - up next we have the release of the DLC (soon!) and once that’s available I’ll detail what I have planned for the 1.22 update.[/p][p]
[/p][p]Until then though, as always,[/p][p]Happy Golfing! ⛳🏌️‍♂️[/p][p]
[/p]