I’m developing a game with MonoGame. While in the past I’ve been unsuccesful in finishing a project, my point of view in development has always been to cater to the user. In that sense it’s necessary to support both HD resolutions like 1280x720, 1920x1080, 2560x1440, 3840x2160 as well as various other resolutions and aspect ratios like 1366x768, 1280x1024, 1680x1050, … Which brings me to fonts.
Fonts in the monogame content pipeline are delightfully easy. You add the truetype font to your VS project, make a spritefont, add it to the pipeline, build, and ready presto. Unfortunately it’s not a very flexible system as far as many sizes or run-time font importing goes.
With the current system I see two solutions to scaling for variable screen resolutions. I add a legion of font sizes, calculate the desired font size, pick the font size either “closest to” or “just below” that and draw. Works well with screen resolutions that are multiples, may lead to odd behavior where not (e.g. not fitting onscreen or in the message box). Does require some one-time work up-front adding all the different spritefonts (per font I intend to use).
// for example; basing font size on backbuffer height int[] fontSizes = { 12, 15, 18, 21, 24, 30, 36, 42, 48, 56, 64, 72 }; // 72 at 4k becomes 36 at 1080p and 24 at 720p. Nice! // 25.6 -> 24 at 1366x768 // 34.1...-> 30 (or 36) at 1280x1024 // 35 -> 30 (or 36) at 1680x1050
Another solution is to pick one font and simply scale it using the scale factor in SpriteBatch->DrawString(). I’m no expert but my brief testing - using Baskerville font size 72 as a base - seems to show it works well enough down to .5f (upon inspection characters 5 and 7 are getting blurry), including odd scaling like 0.948… (1024/1080). It’s clearly not as crisp when scaling up, or below .5 - I could see people scaling down to .33f but .25f is clearly distorted.
Perhaps the ‘best’ solution with the current system is a combination of the two. Round up the desired font size (e.g. 34.1 uses spriteFont for 36) then scale down using drawString (1024/1080*36 = 34.133…).
My ideal solution would be to have a default size based on the resolution height then give the user a slider for font size (and - wild thought - perhaps even a dropdown menu for type), which then gets dynamically generated. One piece of code would be valid for all current, future, esoteric resolutions, and adaptable to user preferences. I might enjoy Baskerville 72, but someone else might prefer Baskerville 108 or even monospace 56. Currently looking into KonajuGames’ TrueTypeSharp which - with a few days work building my own drawString function and such - sounds perfect.
So I’m asking for your thoughts. After 8 months of gaming on a 4k resolution, quite a few games are straining my eyes or are just plain unreadable (tiny red text is the worst!). I on the other hand probably go too far on user customization. I love MonoGame. The pipeline is delightfully simple and makes content very fast to access. My perception (which may be wrong) is that it’s very rigid though. There’s little focus on helping me out with pseudo-random meshes, pseudo-random textures, scalable (pre-texture) fonts (runtime generated fonts), SVG -> appropriately scaled texture, …
Food for thought: Steam Hardware Survey
Primary Display Resolution: Height % _720 1.55 _768 30.45 _800 1.76 _864 4.01 _900 11.02 _960 0.21 1024 4.31 1050 3.78 1080 37.65 1200 1.49 1440 1.72 unk/othr 2.05 sum 100.00