Blog 15th year anniversary

Wow. Can't believe it's been 15 years already for this blog. This year additionally just happens to be a 10 year anniversary for my very own domain, too! I'm kinda forced to celebrate a little. Maybe even get a bit sentimental?

Anyway :3 How this blog started out does feel a bit cringey. I was quite young then. Also, I feel like blogging was kinda only becoming a thing then, and there were no social media in the larger sense. As such there weren't really any expectations on what a blog should or could be. At least I didn't. I mean, this blog was something that wasn't really even meant to become a thing. It was actually just kind of a fad I tried; something to perhaps practice voicing my thoughts on. How to somehow feel connected on something, just by writing things.

And I guess I really like writing things (not too often of course, as evident by the post history :p). But seeing how this blog has stood for 15 years - it's so long that I can't really even comprehend it all at once. So much has happened, yet remained unchanged, even. But I guess I feel pride, at least.

And that - barely - bridges us to the sentimental part. Or whatever this is. So what are all those things that have happened, then?

* * *

As mentioned in the intro, at the beginning the blog was an experiment. And there had to be something to experiment, platform wise. What's the point otherwise? :p So I started out by trialing a couple of self-hosted PHP-based blogging solutions, but was quickly turned away from those due to them feeling bloated, or just not the right fit for me personally. So instead I did what I always do: rolled my own. A great learning experience, but ultimately something that I grew bored of maintaining. But I still liked blogging, so to my own surprise I jumped for quite the opposite end of the spectrum, and moved my blog to Blogger. The final act of this transition was implementing an Atom feed for my old blog so that I could use Blogger to import the content. While reather unremarkable on itself, that may have been the first time that I really interfaced with another software solution to make it ingest something I made - instead of me just processing what some other piece of produced.

Blogger was about convenience. I had already learned what little there was to learn about the technical side of blogs, and it was now about just the content itself. And when I learned that I could post to Blogger using Windows Live Writer, blogging became effortless. A new blog post was literally just the matter of opening the application and clicking publish. A surprisingly welcome change when compared to my own solution, which required manual file uploads, or editing files directly on a remote server. Or perhaps I had an ugly web-based editor? But the quality of life was so much better with the new system. While I did have some grief about how much larger the page loads were on Blogger, all the other things won. With a proper theme it didn't look that much more heavier, and the dialup era had already ended.

And I guess that's all I have to tell about my history with blogging. Let's talk about the (evolution of) content next.

* * *

And boy, have I talked about a lot of things. And the initial years is something that I'd rather not really even talk about, anymore. It's like cringey Twitter. But how the blog has evolved since then, that we can talk about. Statistics-wise the first post was made a little over 15 years ago, and since then 79 other posts have followed, including this one. For a nice round total of 80 posts.

But I guess for completeness's sake I do have to address all the content. Like I mentioned above, the blog started out as something to allow me to have my own voice. At the time I wasn't (and still isn't) very social, so writing was an exciting opportunity to comment on things I had interest on: my beginner programmer stuff and other experiments with computers. Especially programming stuff, since I had very limited opportunities to talk about it otherwise. And I guess I can't deny the fact that having a blog was cool, as not too many people had one! I was hipster before you even knew it was a thing!

It also didn't take long for me to switch the language from Finnish to English. Because if I bothered to write about things, why not write about things in a language that maximized the potential audience with minimal cost?

After a time I also began experimenting with voicing some of my other experiences; how I was doing in the physical world, and after quite a bit of hesitation even about taste-testing meads. But talking about myself always felt strange, still. It was a lot easier to just talk about concrete stuff, and preferably in a way which could perhaps benefit the random reader. Value! Not that many of the posts really were that way, but that was the idea.

And value is actually maybe the most important talking point here. The blog was (and still is) my very own corner of the world, and with the only rules being the ones I make (or break :o) myself. Now, writing this I realized that the blog is a lot more me representable of me than I knew.

The most controlling aspect is the stride for just not half-assing things, but doing them well. The early tweet-like posts are especially hilighted here, because they were low in effort, and with little thought put into them: just stating a thing. Contrast this to later posts where I not only state things, but also the thoughts behind them. And better yet, explaining the things in such a way that the reader is able to hopefully learn something tangible. For example the times I talked about procedural asteroid generation or WebRTC. Or even the post venting about the instability of InfluxDB has a real tangible command to rebuild the index in a non-standard, yet common enough case.

Or to put that in other words, to create value. Why would anyone want to read this blog if it was just me talking about myself, on a surface level? When I could feel like an VIP and be talking about things that could benefit people. I've never even tried to chase readership numbers, but it does feel awfully nice to see that some posts have had up to 500 views. For some strange reason.

But like in real life, there are the extremely rare cases where I realize that the only one stopping me is myself. Times when I get to post about tasting those meads, or how a video game hit me really hard. Though even all those posts are still subject to my strict requirements of avoiding the "air-headed" beginnings and having some real thought behind them. Especially those posts, it seems. And this one, to a point.

* * *

Did I mean to talk about summarizing past post? I'll keep it short, then. It's high time for this post to start giving out some value :d

  • 2006: Short posts about developing a primitive blogging system with PHP. First comments around Linux experimentation. First post about my game project, USG.
  • 2007: Mostly a continuation of the previous year. A one-off comment about tech news.
  • 2008: More short commentaries about dev stuff. Not many posts.
  • 2009: Like the previous year. A small side step about game consoles.
  • 2010: More dev stuff, first non-tech post. At this point the posts start to get more thought put into them.
  • 2011: Conscription makes me ponder my life's choices. And perhaps ending it. A rather special year, with most posts about non-tech stuff.
  • 2012: A rather busy year; the level of thought reaching a "steady-state" :d Guild Wars 2 is released.
  • 2013: USG, refreshed.
  • 2014: Value.
  • 2015: A lot more value. Life is Strange happens.
  • 2016: The special interest of web development returns,
  • 2017: A rather busy year again, it seems; focus split to the first season of the vlog. Only a single post, but summing up the whole year.
  • 2018: A rather busy year, once again. Again a single almost panicked post before the year is over.
  • 2019: Hey look, we're back to producing value! With an asterisk. The new normal. Also, I finally graduated.
  • 2020: The new normal continues.
  • 2021: And continues; focus is split to vlog's second season. Return to gamadev.
  • 2022: The year some scary life-changing stuff is likely to start happening. There's a good chance I'll blog about it, you know.

Talk about value! There's surpsisingly lot of it. And lots of other stuff too, indeed. See you again in 10 years I guess, for the 25th aniversary. A time that seem more distant than ever before.


VLOG season 2

OMG. I did it! …again?

I’m not sure if I’ve mentioned it here before, but I have a VLOG in finnish. A few years ago, I shot and edited eight episodes of me talking about what I’ve been doing, or what I’ve been cooking. I also made one special episode about some low-level serverless technology alternatives with C# and dynamic code compilation and execution, including syntax tree editing. I didn’t dare to publish any of these, but they exist.

Now I’ve began the second season, with more focus on technology. Perhaps gamedev. And this time it might just be good enough for public release! The format itself is still subject to evolution, but the two episodes I’ve so far completed serve as an introduction to the series and the reasons behind its existence.

Though, truth be told the first episode isn’t that good, and made me hesitate on the whole thing. Ultimately, I decided that I’d shoot an episode or two more, and if they are good enough, they could perhaps redeem the farce that is the first episode. I think it would be quite bad if the only episode available was the first one, and it was unbearable to watch. But if there’d also be some better episodes immediately available, the viewer could perhaps skip the first one and, and decide to like the series based on those later episodes :3

I’m now at the point where I have one better episode ready. Although even that starts a bit weary. But it gets better! Content-wise I’m still debating. So far, the series has been only about me, and isn’t really useful for anyone ­– unless they just want to get to know me better. That would be perfectly fine if I had a fanbase, but the case is completely the opposite, so I’m not sure why I’m bothering with this. But, as said, at least the episodes still have the purpose of laying the foundations for the episodes to follow, should someone want to invest (more of) their time in all this right now, or at a later date.

I’m also still not sure of the best way to present the auxiliary information about each episode. Not that anyone would really care. First of all, I have a short description of each video in YouTube’s video description field. That is fine. But I also have some ‘technical’ notes about the video there just in case; perhaps to deter some obvious commenters. Much of these notes are also duplicated on my own website, but not all. And vice-versa the site contains some notes not on the video description. I’d like to unify these somehow. I’d like to have as much information on my own site as possible, yet I feel like there should also be some on the video description for those obvious cases. But maintaining these two in sync is a pain, and they have each have their own purposes :( So what do?

But, anyway. Here’s the page for the new season. It goes a bit more in depth into the production of individual episodes. There's also the near-complete script available for each video if you just want a quick overview of the stuff. Then there's also those video links. Videos themselves are still unlisted, but the links are there D:

About pride and accomplishment in optional multiplayer games

(This is effectively a rant about how I am incompatible with MMORPGs)

As Destiny 2 has been feeling very stale for a long time, I’ve shifted my gaze to other games. There was a rather long burst of Borderlands 3, and then a bit of Roboquest, and a longer phase on Gunfire Reborn. And all the time I’ve had a tiny longing towards Guild Wars 2. A longing that has been growing in such a way that now I can’t wait to play it. I’m also very happy that they just announced a lot of details about an upcoming expansion, including the release date. What a coincidence. Although the release is about six months away still; plenty of time to get bored, and I kinda already am. Allow me to explain:

Destiny 2, Guild Wars 2 and Borderlands 3 all have a mountain on content in them. And they are great games, with great gameplay. Sounds great, right? That a lot of content I’ve been really enjoying, taken time to get good at, and/or maxed out on. I’m on the very peak of (almost) everything. But it is not as simple as this. Things are (almost) too easy, and there is little challenge left or rewards to earn which I can do on my own. Which brings us to the following:

My time is limited.

Outside of expansions(!), a lot of content in D2 and in GW2 is just replaying old content. In D2 it is the age-old formula of bounties and the season pass, and in GW2 the latest one is the quest for a legendary amulet. These offer nothing new to the game, and just direct playing the old content again and again for some reward. I’m all for replayability, but these literally offer nothing new, or change the experience in any way.

And actually, D2 makes things even worse. It’s a loot-shooter. But the bounties require to use your less good loot. And that’s basically the content. Or well, some bounties just tell you to do X three times. And then repeat that YYY times. And if you don’t complete those other bounties while at it, you are basically throwing away almost all “progress” and ability to better “enjoy” further content.

And in GW2’s case, the new questline requires to replay both the story-content and some open-world aspects of the past several years. While this is a good opportunity for the player to spot if there’s any foreshadowing in the story, that’s about all the value there is. No skips for lengthy dialogues, and nothing to change the experience. Just a mountain of playing it all again. And the fact that I’ve already played it once doesn’t net me anything.

Then why play? Like I already mentioned with D2, if that work would be completed, it would (even greatly) enhance the ability to enjoy the new expansions, and the other repeating content. But in D2’s case the bounties are so ingrained in the game nowadays that even the expansions are filled with bounties that punish using the weapons and subclasses you enjoy.

And with GW2 (especially after the very recent legendary armory feature), a legendary piece of equipment is the literal best-in-slot that replaces everything that would ever go in that slot. It has the same stats as the otherwise best stats containing Ascended-rarity items, but it allows for free and unlimited stat swapping. After that you don't need anything else on that slot ever again. In a game like Build Wars 2, that’s the hot shit, and highly desireable. You'd be mad not to pursue that.

It’s all about the economy and playtime — and psychology

In a boring game, wouldn’t it be nice to be able to switch playstyle at will, and for free? Or in case of looter-shooters, wouldn’t it be nice to be able to sometimes enjoy our hard-earned loot, and get new loot?

I’d enjoy those things, but things just aren’t meant to be. In D2 that means being broke and longing for new fun and interesting ways to play, just brand-new content out of reach. And as it just happens, in GW2 that also means being broke and longing for new fun and interesting ways to play, with brand-new content just out of reach. Even when the games and the reward structures are completely different. The essence of all this seems to revolve around accessibility, skill, balance, long-term investment and perceived value, and efficiency. It’s quite complicated, but I’ll try to render out my own experience in relation to this:

In “short”, a lot of the content in these two games is balanced for good equipment and depending on content, almost no skill. Some content on the other hand might require near-literal godlike skill and/or a lot of time — or just a larger amount of less able players.

In D2 the open-world sandbox enemies are frail, and they die from about anything. But it’s also fun to mow down large amounts of red bars, even though there could be even more of them. But to get new ways of destruction, or any kind of real challenge, the content to play changes. There’s the adjustable-difficulty 3-player nightfall strikes or 6-player raids, and also the 3-player dungeons to explore. Strikes are the only piece of content that has matchmaking, and even that stops right as the actually challenging difficulties start. All non-matchmaking content is balanced in such a way that a lone solo player has little chance to really even begin playing them, let alone finish them (dungeons and lost sectors being the exception).

And the game makes this exceptionally hard for so-called hardcore-casuals (which I like to call myself). Every few months a new season begins, and rises an arbitrary “power cap” on equipment. It also raises the power level required on all content to match. Effectively undoing any investment towards difficult content. Soloing content like dungeons or master-tier lost sectors is something the game’s creators reserve for the sweatiest players – those with time to grind the game and increase that arbitrary power level to a sufficient value in order to match the level of the enemies. But I don’t have that kind of time. So even if I was as skilled as them, I just can’t play the same content as them, as I haven’t done the ever-elusive the numbers game beforehand.

With GW2 this changes slightly. Lot of the solo content open-world content does have challenge, but sooner or later it starts to essentially feel like the infinite variety of oatmeal. Different, but the same. The game tries perhaps combat this by being a theme-park MMO. Every playable area is vastly different than others, and as such the world feels disconnected. But then there’s some things that can’t be soloed. And everything gets very easy with more players.

In all these cases, the rewards stay the same. More players, more easy, a lot more rewards in the same time span. But at least with these rewards it would be possible to change the way the game is played in order to keep the experience fresh. Is there really no good way in the middle?

In D2 I could play with the equipment I already own and like, but would eventually grow tired. Or I could try the challenging content, and not really get anywhere. With the most fun weapons gated in that content. In GW2 I can either keep soloing challenging content and miss out on a lot of rewards. I could still purchase a limited number of new ascended-tier gear with new stats, but would eventually go broke. Or I could purchase less-able and a lot cheaper exotic-tier equipment, but I’d only be making the game intentionally a lot harder, while also missing out on even more rewards, further limiting my ability to change things up and stay in a nice position in the game.

In GW2 the most long-term cost-conscious choice would be to craft a full set of legendary weapons, armor and trinkets. Then I could just enjoy playing with what I want. But the amount of work is legendary. Just to get the gated materials for one armor weight class (out of 3), it would take an estimated 500-1000 hours of constant gameplay via WvW over 24 weeks. More if there are gaps on some weeks. Alternatively, via PvP the gated materials for the in about 280-330 hours over 6-24 months (but still a good number of hours every two months, or else things take a lot longer). Then there’s also the weapons and trinkets, and the normal materials for all these. And that is not cheap. But then again, legendaries are the be-all end-all of equipment. Equipment-wise there's nothing left after acquiring them.

WvW is just grind when solo, but PvP can be really engaging. But then it, too, eventually turns to rewards and tryharding, and starts to feel like a chore. Just like everything else. And if only I had better, more predictable teammates.

Then there’s the (5 out of 6, already have one) legendary trinket and their quests. I have no estimate on how long they take; PvE ring and accessory have similarly lengthy quests as the amulet I spoke of earlier. Second ring and accessory are PvP and WvW only, and take time comparable to multiple armor pieces. And then the weapons, which are thankfully mostly just about money, but still have a lot of gated stuff. But the weapons are perhaps the most irrelevant of these, and I already have few of them.

Let’s finally talk about multiplayer

Nearly all these problems are solvable. There’s so much more content gated in and behind raids (in either game), or fractals, or dungeons, or even WvW. Simply play them with a group for the intended experience. A lot of perfectly balanced challenge, and great rewards. Just like all things should be.

But that is the problem. It all requires a group. Not only is my time limited, but my social energy is exceptionally limited. Luckily things are easier with people I know; and I really used to enjoy doing guild content in Guild Wars 2. Unluckily the schedules and expectations eventually just took a toll on me. I just couldn’t find the social, mental or even physical energy (due to sleep problems) to always be there for the group, and fell out. People missed me, for a while. Then life went on, and getting back became hard. Then even later many people stopped playing, or found new groups, and there was nothing left.

Now I’d have to find a whole new group, and find the constant energy for it. Or alternatively I could look and fight really hard outside of the game, and eventually land in less-organized pick-up groups for a single instance of some content. But to make that happen, I’d already be expected to be master of that very content. And be expected to talk, fluently. If I can’t do that, I can’t ever even begin enjoy any of that gated story content, challenge or rewards. I really like the games, but would like them even more if I could play them they way I want, and all the content. This is not just the fear of missing out. This is missing out.

In the end I’m like Sisyphus. Forever doomed to meagre repeating work with pride and accomplishment in sight, but always just out of reach.

Top things to pursue

My long-time readers might know or guess that I struggle with anxiety about wanting to do too many things, and that I always try stay productive even when I should relax. I was recently prompted to make a ranked list of 20 things I’d like to pursue, and forget everything except the top 3. I shall now combine these concepts: I’ll make the list, but won’t forget a thing. And as everything doesn’t always have to be perfect, it is not ranked. At least to the absolute final degree. Kek. Also, true to myself the list is a mixed combination of ‘work’ and ‘leisure’. Because leisure is still a serious business, and can’t be taken lightly.

So anyway, in a surprisingly small amount of time I came up with this list, which I’ll just leave here. I feel that something important might still be missing, but this is what I came up with. And as nothing is ever truly complete, I might augment this one later. I'll try to leave a note.

  • Game development
  • Articulation and verbal skills via/and VLOGs
  • Gaming
  • Expanding social life
  • Embedded programming
  • Home automation
  • Television and movies
  • ‘Home’-server, high-availability computing, serverless and modern web infra
    • a) in the cloud
    • b) self-hosted
  • Getting really good at cooking
  • Transition in fashion
  • DAW-centric music
  • Skill-based sports
  • Travel
  • Long- and short-range radio communication, both data and voice
  • Photography and videography
  • Demoscene music and synchronized visuals, also on a stage; performance coding
  • Writing
  • Playing tabletop RPGs
  • Designing my dream home together with professionals

Rambling about C# 9.0, games and networking

Back at it once again! Rambling about stuff, and not really even trying to make a point. I'm warning you. What else are you supposed to do when your train is late by several hours?

* * *

I recently got an urge to test out the new C# 9.0 language features and see if they could make it easier to write state-centric games (like USG:R I blogged about earlier). TypeScript is nice, but nothing really beats C#, so this is quite exciting. With the addition of data classes (now called just records), the promise was that it would be easier to use immutability, which is one of the core principles with React and Redux.

And things did work. And they worked just like with Redux. But that's the problem. The Redux way is that each reducer produces the new state by creating a new instance of the state with the changed part replaced: return {...oldState, counter: oldState.counter + 1}. Very simple, and the reducers stay pure by not mutating the input values. And each state object can be safely stored in case there's need to do some kind of time travel debugging or state replaying, or anything like that. But the very huge downside of this is that it gets very messy if the state hierarchy is any deeper.

The alternative is something like ImmerJS, where the reducers are allowed to mutate the state directly: state.very.deep.someArray.push(value). The library takes care of efficiently making a copy of the state object as needed, meaning that if something isn't modified, it also doesn't need to be copied either. So that 10 000 element array isn't copied each time the counter is incremented. And it works great. The code is A LOT simpler, and the performance penalty isn't actually that huge thanks to the on-demand functionality.

Imagine my dissapointment when I realized this. I'd been waiting for records for maybe few years already, before even hearing about ImmerJS. And then when I finally get them, the problem I wanted them to solve had changed... But that isn't to say they aren't a good addition, and can't be used elsewhere. But state stuff was what I was really waiting them for. For carrying simpler things - espicially events - they are great.

* * *

But back to the state games. The dream is to be able to write them in C# and surpass the productivity of React and Redux. So, what do? Why not just mutate the global state like all the other normal games. The state can be explicitly copied if need be. Well. That is a good point. Can't really counter it. (There's also some very React-like bindings for Blazor and MAUI, solving the other part of the equation).

Except if the domain is network games! If the game can be constructed in such a way that there isn't too many state changes (and preferably the state itself is small), it would be trivial to transmit those changed states over the network, and render the state in the client. And the big thing: what if we took a page out of the ImmerJS playbook, and replaced the state object on the server with one that keeps track of the concrete changes made to it? Then just the changes themselves could them be transmitted over the network. No need for expensive copying, and no need to transmit the whole state. Also no need to "manually" compute the deltas, as the data structure itself does it. It sounds so cool!

Although realisticly I'm not sure if this has ever been a problem. The states in most games should be relatively small anyway, and especially with the hardware today the deltas can be computed with just brute force by even relatively simple algorithms. Just like games like Quake 3 have been doing for ages. I highly doubt it will at any point really be that prohibitely expensive. But one can always dream of doing things better. Especially when it comes to cloud-scale and IoT, where every cycle counts.

Speaking of which. Related to the above, I've been building a general purpose framework for state based applications. I'm not sure if I'll ever really get to using it, but it's been nice coding something of my own once in a while. And using Redis always evokes warm fussy feelings :) If executed well, a framework like that might have some money-making potential. Or just be a nice tool to easily create some multiplayer games. Or just research, as always. That's the most important point.

This framework I'm making consists of an ASP.NET Core SignalR WobSocket gateway that handles user registrations and authentication (with EdDSA JWTs! Although with an unsafe curve, because libraries...) and then connects them to sessions that are persisted on a sharded Redis pool. The clients receive state updates and can send inputs to a session's input queue. They can also optionally see the other clients participating in the session. The session itself is managed by server applications (for the lack of a better name). They connect the the session's Redis server and take ownership over sessions assigned to them (or otherwise delegated upon them). Then they simply take inputs from the input queue and mutate the state based on the input and the current state (just like Redux), and finally publish the new state to the clients (in the future hopefully with a delta). They can also inject their own events (such as time passing) to the event queue. If a client needs to reconnect, it can simply read the current state from Redis. And if the server crashes or needs to restart, the state and the inputs are persisted in Redis, resulting in no data loss. Well, of course as long as Redis stays alive.

The key point is that this kind of architecture enables laughably easy way to upgrade the server code, as there isn't really any downside to killing the server application and then having it restart with changed code. When it starts it just reads the current state and starts processing inputs like before. Of course this could just be achieved by co-operatively shutting down the old server instance and saving the state before it closes. But that isn't any fun. And it would be extra effort to support taking over individual sessions. With that system it comes for free. Not that it would really be of that much use, but how cool is that in theory! (Each session has a host serial, and only the application server holding the most recent serial can make changes to the state. When taking over a session the serial is just incremented, invalidating the old server.)

Anyway. What I also like about this is how scalable it is. There isn't any application-specific code on the gateway and as all the clients communicate only via sessions, and one client is connected to only one session at a time. This means that it is easy to spin up as many instances of the gateway as is needed, and other than the Redis session backplane there really isn't any cross-communication between the gateways. Except of course the user registration and login. Also, the sessions themselves don't need to talk to other sessions and are completely self-contained except for the orchestration (what server instance starts serving a new session). This means that the Redis side of things can also be easily scaled by sharding the sessions by their id. And further, the server application nodes themselves can also be infinitely scaled. So should something happen and the games running on that framework became hugely popular, it is no problem architecture-wise to just spin up some more instances.

The only problem is how reliant this is about Redis. The initial prototype I've been building makes excessive use of Redis lua scripting and combines dozen operations in things like adding an input to the queue. It should be extremely unlikely, but should something go sideways during the execution on such a script, the recovery won't necessarily be easy. Although most of those operations are about checking consistency and updating expiries anyway, so it really isn't a problem. But what I am really interested about is the performance. I'm really curious to see what kind of performance charasteristics this kind of system has. Also, scalability is nice and all, but as I've talked about before, single-node performance is what is really the name of the game. Less nodes, less cost. This isn't really going to end up in that category ':D But hey, we have to remember that all's of course not that straightforward, as development time is also a factor. For once...

And this thing here is actually really simple and easy. I hope to prove it. At least to myself :d After that I'd like to test some other topologies. Dwell on all the missed performance and the system's dependency on Redis. A loose coupling between the gateway and the servers, but an even tighter coupling decoupling them.

But at least it'll be fun.

Dreaming about Ampere

Hello again,

quite a while since the last update. Again. But at this point you should know me well enough to expect it. Or maybe you just happened to read the previous post. Go figure.

Anyway.. One lesser thing I've been pondering is how me upgrading to an ultrawide display might have played a part in me not finding as much joy from gaming as I used to. Sure, this a minor thing considering all the other factors, but a factor nonetheless. Ar at least the lack of the best possible GPU is a good excuse to not play games. Irregardless of that, I've been in the process of upgrading my GPU for a while now, and I was extremely happy with how good of a product Nvidia managed to launch with Ampere!

"A great generational leap in performance", good pricing, and even the Founder's Edition models seem very good. Typically FEs themselves have been a bit lacking, but now it seems that they might actually be the better product! I'll still of course have to wait for the reviews, but I don't remember being this exicted about hardware in quite a while. It's also one of the very few things I've really been excited about the whole year.

As that's not all. I recently got myself the Valve Index VR kit. The waiting list for it was so long that I'd almost forgotten about it. Now, I've mostly been using it so get some exercise in form of Beat Saber, but I also did play through Arizona Sunshine. AS has some flaws, but the gunplay itself was rather nice. I also started Half-Life Alyx a while ago elsewhere, but haven't really gotten to play it more. This is unfortunate. Instead, I've been busy playing Minecraft, and just simply keeping busy.. This is hopefully maybe changing, but we'll see. Anyway. What saddens me a bit is how increasing the render resolution scale in AS made the game a lot more clearer, but completely killed the FPS. Maybe the new GPU will chance that! And most certainly I'll get that sweet 144 Hz on Destiny 2 again, too!

Hmh. It seems that "whiles" are the staple of my timeframes :p And while this post feels a bit lackluster, it feels good to produce some content once in a while. Maybe I'll even get motivated to write some development-themed post at some point, too. We can all hope, at least :) We'll see, we'll see...

And I know what you are thinking. About everything. We'll see.

Presenting USG:Rerolled


Despite the hardships, I’ve been able to at least occasionally dedicate some time for the continued development of this year’s Finnish Game Jam / Global Game Jam game. Worked alone this time, and still made a nice game. With TypeScript :o
Now, with the continued effort, it’s starting to look pretty good! The game itself is a mix of Dicey Dungeons, Slay the Spire and maybe even FTL - Faster than Light. It’s about dice-rolling and loot in a turn-based combat, from encounter to encounter. Originally it was to have gameplay that would have emulated Cultist Simulator in at least some questionable way, and hence got the name SDC: Slay Dicey Cultists. But then it occurred to me that this could be an excellent chance of carrying on the torch from the project that is my unicorn, The Peli – or as more recently known, USG. So let’s give it up for USG:Rerolled!
The main focus of the game is the equipment, and the many effects the pieces can have. This made me to choose to implement the effects with straight up code, instead of trying to codify all the effects in some kind of standardized structural form. It's been a good choice for productivity. But I dread the day I need to make some kind of breaking chance. I also did some snooping, and found that this is how other games have chosen to approach this problem, too. As the game will have (and already has) quite an assortment of equipment, it only made sense to also create and editor for the items. And the editor. Well… I guess I’ve spent as much time on it as the game, or something `:D
The editor has some standard fields for the most basic attributes of the equipment. It also has an integrated code editor with syntax highlighting and auto-completion. This is achieved by embedding the very same text editor component (add diff viewer) that powers Visual Studio Code, the Monaco Editor. The changes made via the editor are versioned separately from the rest of the game, and the editor has an ASP.NET Core backend for implementing the filesystem and code generation functionalities. Upon saving the data, the game itself is automatically reloaded with the new equipment data. I’m rather pleased of the setup. I’m planning on extending the editor for also creating random encounters for the game to balance out all the combat. Then there’s always some quality-of-life improvements to be done… But overall, it’s already in a surprisingly good shape! The editor even has a graph of the saved versions and their relations...
The latest addition to the game was an encounter map, which brings some structure to the game. Compared to the work already put to the game, this was a relatively small addition, but it did take a few days to get the SVG-based drawing and random generation to work in a satisfactory way. Evening out the randomness would be the next step. Speaking of next steps, I’m kinda testing out if I could bring ships with limited hardpoints to the mix, without everything getting too confusing. Then I’d be quite close to the dream that is USG. See you next time!




Plans


Everything I planned for. Crumbling before my very eyes. And I’m not even talking about the pandemic.

I kinda thought that now that I got my studies finished, I’d get a chance to focus on what is important and make time to do things. But that didn’t quite plan out, as there surfaced some things that’ll be requiring my attention. And not just for a little while, but for several years :( And some things that directly contradict everything.

Though it (mostly, not completely) depends on whether I think about those things or not (: It would be wise to give some thought to one of them, but thinking about it doesn’t really help it at the moment… Was this vague enough? :s

But, as they say: it is important to try to keep sense of normality in a time of crisis. Remains to be seen how well that'll pan out.

Nuget package creation addentum

A short and informational blog text for once!

In preparation to some big plans™ I changed the way I generate my Nuget packages. The old way where all the metadata was specified in the .nuspec file was otherwise good, but it didn't specify version metadata for the actual DLL.

I've now changed the process so that version is specified in the .csproj file, via the VersionPrefix element. I've also defined a VersionSuffix element with a value of dev. This way when the project is built "locally" the assembly version ProductInfo field reads for example 0.1.0-dev. Whereas when the Nuget package is built I pass the option -Properties VersionSuffix=, resulting in 0.1.0. And as a side effect of moving the version element away from nuspec, I also had to also specify -Version $version, where $version is a PowerShell variable parsed from the csproj file and include a placeholder version in the nuspec file.

While slighly complex, this now allows me to fetch the version programmatically and know whether the library is an "official" release version via Nuget, or a locally compiled version with unversioned changes. I've also considered to just inject the version together with the prefix as a build step, but for now I'll try my luck with this thing that needs the assembly to reside on disk:

PS: there's a ton of unresolved issues with the Nuget CLI program, many of them several years old. When investigating the above, I also noticed that my Nuget packages don't include external libraries as dependencies even when using the option -IncludeReferencedProjects. It is a reported bug, but hasn't been fixed. One alternative might be to use dotnet pack instead of nuget pack, but I'm not sure what other changes that would entail.

InfluxDB broke, again

It is not a long time ago that I blogged about how I experienced my first fault with InfluxDB. And now it has happened again. This time a bit different, though. And much worse.

It all started with the familiar NATS alert, so I tried rebuilding the indexes again with buildtsi and thought that would be it. I was wrong.

This time there was an invalid CRC on one data block, which caused segfaults(lol) within the InfluxDB executable. Speaking of error checking... the verify command in influx_inspect has a bug. It erroneusly reports a block as healthy, because the right counter is never incremented. But anyway... The block is faulty. What now? Where is the option to fix it, or remove the block? Removing the offending file manually doesn't help.

So in the end this made me abandon the data, and start from scratch :'( And for some reason docker-compose kept doing some weird caching with the data (even when it was a filesystem mount), even after downing and removing the old container, and emptying the old data directory, and it was an effort to get everything working again...

I should probably consider upgrading the hardware. If that is the real problem. For the lulz I also asked for a quote of InfluxDB enterprise. If I cluster it, then one node can fail and it recovers, right? Right?? But I don't expect the quote to be realistic. And even if it was, it's probably still too much. One alternative might be Apache Druid. But it, too, seems a bit too young a product.