Monday, March 9, 2020

Design work

It's been too long since my last post! I've been busy, but not as busy as I could have been. I'm still yet to set up any of my gameplay or game in Unity and have spent the last month doing spritework and designwork. I've also been working on polishing my gameplay and story as I can without actually laying it down in game, but I know that's just a stalling tactic. I really just need to fire up Unity and start...
But there's so many things to worry about. What if my systems aren't up to scratch and I end up having to re-write massive chunks of my content later one? What if my map design tile layout is catastrophically small and I have to start from scratch? Alas, these questions are great at stopping me from diving in. I know in my heart though that the only thing I can do is just do it. I will face big challenges no doubt, but they will in all probability be completely unknown until they happen and will not be the imaginary ones I've agonised over.

Enough with the excuses, let's get down to what I've actually done. First up, I started work on the industrial zone sprites. I left these a bit later because I had many ideas of ways I could do this area of the map. The industrial zone is between the wilderness and the Union, and is meant to allow the player to see firsthand what the Union has to do. From a gameplay perspective, the area is dangerous and hard to navigate, providing a challenge to traverse. 

So, my initial thoughts were to make it mostly brown and black like a wasteland. But I also had a strong inclination to make it white instead. This sounds odd at first, but in 2018 I saw a movie called "Vinterbrødre" from Denmark. The movie is set around an industrial estate where everything is coated in a gritty white powder. I thought it was a fascinating visual twist on the normal grimy brown/black industrial look and strongly considered using it in my game's industrial sprites.


A still from Vinterbrødre showing the white/blue industrial look
(retrieved from No Film School and attributed to KimStim)

In the end, I decided to not go this way. I decided it was too confusing with my pixelart to try this, considering it's very hard to tell the white powder apart from snow - and I didn't really want to have some guy lick it and go "it's silt!" to try to explain to the player what was going on. I also decided a brown toned industrial area suits my yellowish colour pallet best.
I did try using the same desaturated sky-blue colour from Vinterbrødre for my industrial building sprites, however. I'm not sure the colour matches the rest of my art style in the area though, and I might have to go back and recolour them later. Anyway, I should show what I have now:


Tada!
It's a start. The new cliff sprites took me an entire weekend, believe it or not. I ended up having a really hard time balancing the detail with the tiling and perspective. I'm pretty happy with the result - but I will have to redo the tiling on the front facing long cliff faces. That's some pretty rough tiling...

A big thing I learnt from the above sprites is that I'm going to have to make a lot of special junk pile and building/girder/scaffolding sprites. There's just not enough variation or density with the sprites I've come up with so far. We can help the effect a little though by adding some filters:


Wow, now that looks grim doesn't it? I have four filter layers applied here in this mockup, and I'd like them all to be in the game in the end. Firstly, there's a layer of fractal noise - clouds. The clouds I imagine would slowly move across the screen, perhaps even slowly changing shape as they move. The clouds help to break up repetitive tiling and add depth and contrast to the scene. After the clouds comes a layer of fine dust - white particles that drift around in the industrial zone to remind you the air is full of grit. After that comes a colour filter, a dark brown/orange colour that dampens everything and makes it all look gross.

The industrial zone will only be visible through filters like this. The filters help make it look very different to the clean areas of the map without requiring me to make another entire set of sprites for the terrain, trees, etc. I'm all for using programmatic and graphical solutions to ease my art workload.

The final filter above is one I intend to apply to the game at all times, a yellow tinge designed to make the game resemble film from the 1960s.

Above is without the filter, below is with

I've been designing my sprites from the start with this filter in mind and adjusting my pallet as need be. I'm a big fan of warm hues and I like the nostalgic look the filter gives. 



That's all I have for my spritework. I'm going to continue with the industrial zone sprites for a bit longer I think, and that'll leave only the unincorporated and Arcadian sprites left to start. I still have sprites I need to redo/add for the Union and natural areas, but those are lower priority now that I have those spritesets mostly figured out in terms of tone and layout. 


Here's some additional news; I may have a new name for the game. I've considered a few things many of which are too embarrassing to write down here but one of which was "Cockaigne & Arcadia". At the moment, the name I have is "Bentham's Lighthouse". This is mainly a reference to Utilitarianism, using the metaphor of a lighthouse being the guiding light of a person's morals. It is also an oblique reference to the panopticon, hinting at the sinister side to the political directions my factions take in the name of ethics. I drew some sketches for logo concepts using a vector editor. This is my first time working with vectors (outside of editing SVGs as text) and I think the results are promising. 

The above are my first batch of concepts. I was experimenting with representing a lighthouse and text placement. I think overall they ended up looking like fine logos for restaurants or companies maybe, but none of them really evoked anything relevant to my game. I did some mockups putting the logos on screenshots of my game, and they always looked out of place.


This is my second batch of logo concepts. I'm much happier with the feel of these logos, which contain my representation of Fresnel lenses. They pop a lot more and are very memorable. I tried using some more "retro" tech-y fonts to try to evoke the art style of my game, but I'm not entirely convinced I achieved that. Oh well. Onwards and upwards! 


Finally, here's some more music I've been listening to to help inspire me to get the feeling of the game right in the natural/industrial areas:

Wednesday, January 29, 2020

Eureka!


I've done it! I've finally bolted down my game's story and gameplay. I know what the player will be doing and why, and how this will present my world and themes. How did this happen? It was a combination of two things:
  1. I've had a lot of ideas and tried out many of them, narrowing down the things I liked and the things I didn't, forming a nebula of concepts and fragments
  2. I employed one of my best friends to sit down and "rubber duck" for me while we talked over my game, distilling down my ideas finally into a single liquid
We wound up in a tennis themed bar at the end of the night after spending most of the evening in the botanical gardens; I left grinning ear to ear with exuberance that I had finally solved the great challenge of my project. I am endlessly grateful for my friend acting as my sounding board, and thoroughly recommend the tactic to anyone else stuck like I was, with a cloud of concepts but no tangible solution.

I'm not going to lay out my entire story here in this blog (spoilers!), but I'll go over some of the ideas to lay down how the process unfolded. 

Our conversation started like this: my game looks like an RPG game. So, we talked about our favourite RPG games (mostly Fallout: New Vegas), what made them fun and interesting, any flaws we noticed or things we loved. We then talked about my original idea for my game's story (the 7000 word "timeskip" version involving massive branching faction decisions that affected the whole world), and my ideas I'd had since then, before talking about what I actually wanted to get across in the game. I talked about various "scenes" I wanted to have take place, how I wanted the player to feel and what I wanted them to be doing. We came up with a few problems that were at the core of my dilemma:
  1. The player needs to feel like they have something to do, a reason to take actions
  2. I want to have the player project themselves into the decisions they make in the game
  3. The purpose of the game is to make the player consider what they think humanity is "for"
We then decided to work out the start of the game. What's the player's motivation? My friend suggested that we reused my original concept from my first draft from the "timeskip" version; the player belongs to a neutral settlement caught between the Union and Arcadian lands. The settlement is slowly being destroyed by the Union's expansion, while the Arcadians are murdering the people of the settlement to stop them polluting "their" lands. My friend said perhaps the player is the leader of this town, and they have to broker a deal with one of the two factions to take their now homeless people in, this being a challenge because both the faction and the settlers would have to agree. I did really like this idea, but there was a fatal flaw in my eyes: by making the player responsible for the wellbeing of a town their decisions were no longer based entirely on their own wants and needs. They might make decisions they personally disagree with (without considering whether they agree or disagree with them at all) in the interests of the settlers. 

So, we tweaked this premise: the town is entirely wiped out. There will first be an introductory segment/cutscene/scripted scene where the player is introduced to the settlement, and the player character's life. They are shown the Union via tourists that ogle the settlers and wonder why anyone would live like this when anyone can join the Union and be looked after forever. Drones would also arrive and start disassembling parts of the town for parts to carry back to the Union. The Arcadians are met too, as murderers in the night who kill townsfolk and burn buildings. The player leaves town, or there's a fade to black timeskip, or a voice over or something, and the player finds themselves all alone in their destroyed settlement. There would be an Arcadian or a note from one letting the player know that by being the only survivor, they have proven themselves strong enough to survive and will be left in peace. The player is now thrust into a hard wilderness knowing about the two factions and being given hints that they can join either. 

At this point we talked about another concept a friend of mine had suggested earlier. And that was the survival concept. When I was in the early stages of my second story draft I talked to this friend about the themes and ideas. He suggested that a good way to make the player appreciate the factions and force the decision to join them would be to make them see what life is like surviving on your own. I liked this idea, but considered it to take too much away from my concept of a dialog and theme driven experience. I didn't want the player doing stat and inventory management busywork when they should be talking to people and thinking.

But with careful planning and a new direction, I think it is the way to go. So, after the player is thrust into the world with little to go on, survival becomes a problem. I haven't decided how this will work completely yet, but it will be fairly simple. The player will need to find shelter, food, etc. The goal of this section is to make it clear to the player that survival on their own isn't an option. The character will fail to light fires, or get food poisoning from berries and so on. There will have to be some reminder here to the player that the Union and Arcadians exist to prompt them, probably though roaming drones and Arcadian Journeymen. If all goes well, they will make their way to one of the factions.

At this point I'll bring up New Vegas again. One thing my friend and I loved about that game was the player's ability to hear most of the story of the various factions before committing to one side or the other. That is a requirement in my game, and what it needs is the player to see both the good and the bad of each faction, before being given a chance to leave (and come back if they want) or join. The Arcadians were fairly easy to do this with, their faction lending itself to having very simple markers for both their "good" and their "evil" aspects, and their complex initiation rituals making it easy for the player to see where the point of no return is. The Union were more of a challenge. My friend and I discussed various things about this, without any real result. We got side-tracked and talked about other things for a while, before I off-handily mentioned I was hoping to find a way to fit a Union "re-education centre" into the story somewhere as well. In a wonder eureka moment, my friend suggested that after talking to enough people in the Union on arrival the player would be flagged by the Central AI as a problematic citizen (asking weird things, making people uncomfortable) and they would be dumped into a re-education facility. This was a glorious victory! Not only does it let me show the player the ominous "evil" aspects of the Union, it also allows me to temper it with nuance. The "re-education" is sincere - perhaps unexpectantly unlike something like 1984 - with the AI asking the player things such as "are you aware that your actions caused discomfort in those around you?" with the goal of helping the player be a more empathetic and civil person. They can pass this test and are free to re-join the Union - but on the way out of the facility they meet some people who though genetics or accidents are mentally unable to pass the test, living their entire lives in forced isolation. This would serve as a potent reminder that nothing is perfect. 

The end goal of the game then is to join one of these two factions. Once that's done the game is over. This might happen very fast. Perhaps too fast. I'm not sure yet how much time I have to have my game take up. I'm happy for it to be fairly short. The goal isn't to speedrun it, but to take your time and reflect on your own. Perhaps the time can be padded by smaller "sidequests" or through making the survival aspects more challenging. I'll worry about the fine tuning later. The point for now is that I'm finally ready to lock this down. The game is go!


To wrap this blog post up I'll talk a little about what I was doing before I had this story breakthrough. Basically, I was spinning wheels again, just working on sprites. I ended up drawing more variations of my grass and natural sprites and tweaking my existing ones:



I also went and drew my initial ideas for the Union drones. These are the suckers the Union central AI sends out to do all the work required to keep the Union running. They'll mostly be seen by the player mining, digging, welding, and carrying things. 


It's difficult to get the amount of detail I want for my drones across with such a small canvas. The look of them is meant to be dirty and functional, sort of like flying lawnmowers. I ended up giving them jets in this version because of the limited space, but that doesn't make sense given the amount of fuel they'd need. Instead I'm going to try to redesign them again to use propellers. I think this will also give them a more "power tool" look. 

Things are looking up though, and I'm going to spending the next little while writing up my story while also tweaking some of the more specific sprites. I still haven't started tackling the industrial zone sprites, the Arcadian sprites, or the neutral zone sprites. 


Sunday, January 12, 2020

Some more sprites

So I was supposed to just work on my story and my gameplay until I actually knew what they were going to be. Oops. I instead went back and worked on my sprites...

New exterior building sprites for the Union, and some new groundcover varieties


I've made a few observations and discoveries since writing the last post. The first, seems to be that I'm stuck on a "scope see-saw". You hear a lot about scope creep - where as the project goes you keep thinking about new things you could squeeze in and before long your project is way over scope and impossible to complete - which is a real problem, but I've been having a new problem where I recognise myself scope creeping, counter by cutting down massively on scope, and start creeping all over again. Hence the see saw metaphor... I started this project with a very simple gameplay idea which slowly grew into something much more complicated, before I cut it all back to a much simpler idea. Only to start thinking of new things to add once again...

In the interests of preserving some of the ideas I've had that I will most likely abandon for scope creep here's a short list of some of the tangents I've taken the gameplay concepts:

  • A survival concept where the player character has to manage their various survival stats like hunger or sleep, and this provides the impetus to join one of the factions and gives the player something to do (this was suggested by a good friend)
  • A complex series of player choices all over a large free to roam world that interlock and affect each other. Such as blocking a drainpipe that might cause somewhere else to flood.
  • Playing with 3D/2D by having the 2D world "expand" into a 3D world at some point in the game. This could be a fun metaphor for something like Plato's Cave, with the game presentation suddenly and unexpectedly becoming much richer. Alas it would require a massive amount of work to redo most of the game's art in 3D.
Until I manage to finally lock down how my game is actually supposed to play, I don't think I'm going to be able to get off the scope see saw. It frustrates me not yet having that sorted out, and I feel almost like complaining about the story guy on the project for slowing down the art and programming, before I remember that I am the story guy ;_;



I'll talk a little more about my sprites now to take my mind off that again. I spent a lot more time than I expected during this sprite cycle redoing what I was working as I was doing it. I found I would draw something, place it on my demo scene, move on to something else, and then come back and tweak the lines and colours of the first things I drew for a while. Of all the new sprites I've drawn, I would have substantially redrawn about 70% of them. Here's a comparison shot of a small section of the above photo as I was working on it:

Note the small changes to e.g. the lightglobe or chimney

A lot of these changes were to increase or reduce the contrast of certain sprites relative to other ones. In the above one of the most obvious changes was the dimming of the ceramic tile texture from white to beige. I might end up undoing this change. It seemed to make the building easier on the eye and more harmonious, but when I showed this building to some new people that had never seen them before, they had no idea what the tiles were. They guessed they were small windows or bricks! The brighter white texture was clearer, I think. 

In terms of sprites I want to try drawing either some of the industrial textures for the Union wastelands, or instead jump back into unity and try to make some simple particles for things like butterflies or smoke from the chimneys. While I could do these with animated sprites (and indeed I will include some animated sprites for things such as ventilation fans or television screens), I would prefer to do them with particles where possible. Particles will allow me to add a lot of variation programmatically instead of through countless sprite variations, which will greatly ease my sprite workload. I enjoy drawing the sprites, but I can't spend all my time doing it!

So next on the agenda is more sprites, unless I get a brainwave and manage to clear up the gameplay/story mystery.

Saturday, December 7, 2019

Tracks: switched. Story work: engaged

As I predicted multiple times, I have finally switched tracks. Hooray! I've spent the last week working mostly on my game's story. This proved difficult and I haven't made as much progress as I would have liked. I'm stuck on a few main things, mostly to do with the big picture. It's strange that I've managed to fill in most of the smaller details but still lack my big overall concept, but we'll get into that in a moment. First up, I'll go over what I did that wasn't story related.

As I wound down my programming sprint, I thought more and more about my NPC conversation system I had developed. I worried and toiled over how I could possibly make it easier to use. How I could remove the dependence on mysterious global state enums, or the anonymous functions passed in to each conversation fragment to let it know when it's ready to be displayed. But I came to a conclusion. It wasn't so much anymore that my data structure was garbage (I'm not claiming it's perfect though) so much as it was that my tooling was lacking. There's no interface to add conversations, no way to visually see the relationships between fragments and responses except to trawl through C# source files. I really think that to make creating conversation trees and story flow logic easier, the next step will be to develop tooling that will generate my C# object code for me. I don't know if I actually will do this, but I believe if I were working on a team where multiple people were required to work on conversations it would be a necessity. It might end up being a necessity regardless, but for the moment I'm betting that because I'm the only one working on this I can store the links and relationships in my own brain well enough to get by without having to spend weeks on tooling. We'll see how it pans out.

In the art department, I did another concept drawing for some Union characters.


This was a fun task and I had a lot of feedback from some artists I asked about how to make these characters look better.

Now, on to the story!

What I decided to do was to define the NPCs that will exist in my game. There will be a set number of NPCs, and if I can define the number and interactability of all of them properly, I can come to terms with how difficult it will be to write/program my NPC conversation trees into the C# files directly. This simple task ended up causing more problems than it promised to solve. I started off with a basic list of something like 40 characters I was interested in. I progressively culled this down to the 22 I have at the time of writing this. Even this many is too many, so I will have to cull some more. Ideally I think I would want around 12-16 characters. The problems raised while defining these characters arose quickly, with one of the first being; what do I name them?

I started off naming my Union characters with generic names I might use when testing software input forms. Jim. Tim. Kim. I then went back and started creating worldwide names. I googled various terms and countries, and followed Wikipedia links to the pages for all sorts of people from around the world, coping fragments of names out to create an extremely varied set of worldwide NPC names. After doing this, I stopped and thought about my Union and their people. Two cores element of the Union concept are their inclusivity and their homogeneity. This can present a bit of a paradox. Would the Union stamp out individual nationalistic names in preference to a homogenised naming scheme, even though this goes against their inclusivity doctrine? I'm not sure yet. I thought they might, (taking a cue from Brave New World), and so I went back and renamed all my Union NPCs to have generic Anglo fore and surnames. Part of this is to allow a contrast to the Arcadian naming schemes.

My Arcadian NPCs have very strong ethnic naming schemes. I chose a few nations for my Arcadian NPC groups, Spanish, Finnish, British. By giving these NPCs very strong ethnic names it helps to highlight the Arcadian prerogative in contrast to the homogenised weakly-Anglo Union names.

But I can't help but think the more I homogenise my Union the more their tenant of inclusivity fades to worthlessness. There's no point in being inclusive if everyone is already the same. So that is a fine line I have to traverse. I am tempted to go back to an older concept I had for the Union, related to how certain groups of ex-pats behave in the real world. I might have Union characters have various ethnic names and even keep various symbolic trinkets from their supposed heritage in their rooms (flags, furniture), which they proudly talk about making them who they are. I can then contrast this hollow pride in a past they have no real link to with the ultra traditionalist Arcadians. Perhaps I can have an interaction with a Union NPC who has only just found out they have faint Irish heritage and has started wearing all green. Or, another NPC who has decided they don't want to celebrate their Arabic ancestory anymore and would rather identify and celebrate their Peruvian past.

I came across a separate problem while naming and inventing my Arcadian NPCs. Unlike the Union, the Arcadians live and breath their ancestry. This means that if I, for example, create a homestead of Czech Arcadians, they will certainly speak only Czech. This is true in the Universe, but makes it impossible for my player character to talk to them, unless they happen to also speak Czech. Because of this I am considering that I will have to have my Arcadian NPCs speak English (localisation of this game to other languages is not something I am considering yet). This makes a British Arcadian group obvious. I also created a Finnish and Spanish group. I created these groups to fill other constraints I had, but having them speak English might be too long a shot. I'm not sure how to resolve this yet. I might just not resolve it, and leave it a hanging plot hole. I'd prefer not to though.

Having multiple Arcadian homesteads that do not communicate in the same language all living nearby raises other problems. The Arcadians are even less of a cohesive force than I was originally planning. They will be unwilling and unable to cooperate as a larger force. Perhaps I can get around this and the previous language problems by having a local cooperative of Arcadian homesteads, all speaking a common language and serving a common purpose when needed. It seems flimsy but might be required. That would certainly solve a few issues...

One issue I haven't been able to solve yet and which has been growing in importance is; what is the player's actual goal? I've decided the gameplay will consist of ferrying messages between the two factions with the ability to distort either side's message to the other. But why are the two powers negotiating at all? The Arcadians want nothing but destruction for the Union, and the Union barely acknowledges the Arcadians at all. I can use my ultimate cop out card for the Union at least if I absolutely have to and say "the Union central AI has decided this is what they should do" using the inscrutable nature of the AI as a get out of jail free card. But I can't do the same for the Arcadians, even if I wanted to. One theoretical story hook I've been considering goes this way:

  1. A travelling Arcadian missionary tasks the player to deliver a letter to whoever is in charge of the local Union tower. The letter is requesting the right to preach to the Union citizens.
  2. The player brings the letter to the AI, who convenes a council of Union citizens to handle the request. 
  3. The council is more interested in debating the Missionary and write a letter talking about the scientific evidence for God to be delivered back by the player
  4. The Missionary is perturbed and appeals to the local Arcadian homesteads to write a response
  5. The player delivers the response, thus starting the debate...
This might work but seems like an awfully low-stakes story. I would prefer to have something escalate to the point where both sides are fighting for their very existence. I'm not sure yet how to do this, but I'm sure I can come up with something eventually.

I should leave this here, it's been a long talk. Hopefully next blog I'll have the major story close to being sorted out.

Sunday, November 17, 2019

... I am still programming

I meant to write this update last week, but I was this close to finishing my conversation system in a workable state that I just had to push it out before I wrote anymore. And so, now, I have done it. Yay! Now that this system is just about done there's only some vague UI and save/load problems left to tackle from the programming side (that I can see right now - sans refactoring).

Unexpectedly, I'm still on a programming run. I thought (as per last update) that I would switch over to either gameplay or art, but instead I've just been programming away. This has been good I guess, and I'm rounding out the logic to the point where serious game work might be able to begin at the end of the year. But of course, every step of the way and every breakthrough I make I get a firmer grip on how much there is to do and how far I have to go. And of course, it's a ways.

One thing that is becoming crystal clear is that there's no getting around the fact that at some point all my dialog is going to have to be written down in huge complicated files. I should backtrack a little first and quickly talk about what I've got at the moment for my conversation system's structure.

In a typical RPG game, your dialog choices with an NPC usually drive the rest of the conversation with that NPC. If the NPC asks, "how's your day?" And you reply "bad", they might respond with "oh no, what's wrong?". If you instead replied "good", they might say "that's nice", but the choice you made is forgotten by the game immediately afterwards; it only existed in the context of that specific conversation, or even just within that single response. There might be certain dialog choices in certain conversations that have a lasting impact in the world such as an NPC asking you "do you support faction A?" And later in the game faction B rejecting you for this. What I would like to do is have ALL conversation choices recorded. My game is going to be about the choices the character makes in every conversation. This demands a very comprehensive game state and a rigorous naming/namespace scheme.

Unfortunately, I'm not happy yet with what I've made. I pushed through and finished it into a working state however, because it's better to have something working than it is to just fret continuously over what could go wrong. Here's a diagram of what I have:


I realise it doesn't exactly make things crystal clear. Truth be, I think this system is a bit of a mess. But it works, for now, and so I'm going to push on. Each NPC has a "Conversation Manager" assigned to them. This manager contains a number of "Conversation Fragments" which in turn contain a list of responses. Each response has a condition to be available, and a post-selection outcome. Both of these are anonymous functions provided at instantiation of the class. Conversation Fragments can also contain conditions and can be set to be repeatable or one off conversations.

In this way, I can build up conversation "trees" full of conditions and responses. The responses to conversations are at the moment being stored in named Enums inside the global state. E.g. "responseJimAreYouOk.Yes". This again isn't ideal but is quick and dirty. You might also notice that the current method has all my conversations being created inside the script (C#) files. This doesn't bode well really, but again works for now. Ideally, I'd want the pure content strings of the conversations to be in external files, but I'm not sure how I can link them to my anonymous delegate functions for conditions and outcomes that must be in the codebase. I might end up creating some generic (named) conditions and outcomes as members of some conditions and outcomes classes, and then I could reference them via strings in external files. But for now, again, my rough system is ready.

The advantage of this system right now is that I can access any response to any conversation from the global state. A bit awkward for sure, when you might rightly expect the conversation states for an NPC's interactions to belong to that NPC only, but having random NPC's access other random NPC's to poll their interactions is just as icky if not more so than doing to to the static global state. That's my belief at this point, anyway.

The biggest risk with this system going forward is that I dump hours and hours into writing content inside of it only to find that it's got some huge flaw or to get some brainwave down the line for a much much cleaner system only to find it will take weeks of time to refactor into that system. So, I will proceed with caution with my testing, and create a moderately complicated set of test NPCs and mock gameplay to see how well the system performs under pressure.

I shouldn't leave you without a picture to show what my system looks like!

On a side note before I wrap this up, the Unity UI builder has been a little tricky to deal with, but overall not terrible. I've worked with some truly awful UI builders in the past and I understand it's a tricky problem to tackle. I've appreciated not having to work too hard to deal with UI this time around. The player controls settings are a bit more difficult to work with, however. I'm sure I'll get the hang of it.

Sunday, September 29, 2019

Back to the programming

It's finally time for a new blog post! So far this has been one blog a month... hopefully I can pick up the pace in the future.

Basically, I took a three week "break" from this project immediately after the last post. Not a good idea. I'm not completely new to the danger of "taking a break" from a project only to never return. Many of projects have gone that way, but this blog has really been a great motivator. So last week I decided it was time to get back into it, and to get something done. I spent two nights stressing over what the next step I should take and realised it would have to be the dialog system. So come Monday, I opened the Unity project and...

Began procrastinating.

But, I had made a start. I fiddled with some settings and scripts in-between watching Simpsons videos on Youtube. In about 3 hours of time I probably got 20 minutes of work done on the game, but it was STILL PROGRESS! I finally set up a local git repo for the main files in my project - which brought some much needed peace of mind and confidence when I started refactoring massive sections of my janky but functional scripts - and collected some more references. I did some other assorted house cleaning tasks as well, updating my version of visual studio and organising my reference images.

And then, the rest of the week, I just plowed through my scriptwork. I committed code every day of the week and made some solid and serious progress. I don't have much in the way of images to show for it, because it was script work after all. But the main thing I did was a basic dialog system and restructure of my NPC classes:


I now have a functional UI system too. You can walk up to an NPC and they'll say something to you on the screen. After a time the message will fade away. From a gameplay point of view I'm not sure about this system yet. It's not obvious where the text is actually coming from or who it's relating to from it's position. I might instead have to place the text about the NPC that is speaking. This will also allow me to have multiple NPCs "talking" at the same time, without player interaction.
When the player enters "conversation" with an NPC (where they will need to decide on a response and the game pauses) I will use a UI perhaps closer to this experimental one, where it takes up more of the screen and is obviously the main mode of interaction.

Either way, I had some interesting challenges and decisions to make during this development "sprint". For one, I wanted the text to fade out after some time, and as part of this to set a global "in_conversation" state to be false once the text was gone. It turns out Unity has a function for this: CrossFadeAlpha. You give the function a time and some alpha variables and hey presto it fades your graphic away! However; there is no callback or return for this function. It doesn't return a task, it doesn't even set a flag. It just "goes". I'm not sure at all why this function was written in this way, but it makes it completely impossible to work out when the fade is actually finished.

More revealing, while trying to solve this I found many online forum threads with other programmers trying to solve this problem. The solution I kept seeing come up was to check the "alpha" state of the graphic being faded every frame in the object's update function and react once it reached 0. This is just a terrible idea. Checking a random attribute every frame is a shocking anti pattern. To see it repeated so much online has me very worried about any of the advice or examples I'm seeing online.

In the end, I wrote my own IEnumerator function that fades a given graphic out given a time to do it in. This allowed me to have actual control over when the fade was done. However as part of writing this I had to rely pretty heavily on online examples and tutorials. IEnumerators and the yield keyword are very new and confusing to me. I ended up writing the dialog function like so

private IEnumerator RenderDialog (string message, int duration) {
    dialogText.text = message;
    yield return new WaitForSeconds(duration);
    yield return StartCoroutine(FadeOut(dialogText, 2));
    dialogText.text = "";
    dialogDisplayed = false;
}

Which freaked me out due to the two return statements. I'm still not yet used to yields, IEnumerators, and Coroutines, but it's fascinating learning such different programming styles (coming from Javascript's Async promises).


Finally I once again restructured my NPC class structure. Again, coming back into a highly structured language has been interesting. I'm re-learning all my old Java concepts in a new context and it's been a lot of fun.
This array is an array of "Interactables". An Interactable is any class that implements my "Interactble" interface, which at this point just means it has a "onInteract" function for the controller to run if the object has been activated. I have a class now GenericNPC that impliments this interface for NPCs to use. After some experimentation I ended up making this class Abstract, as a sort of midway between an interface and an class. It is a generic class for instances of "real" NPCs to extend, which contains basic NPC logic - such as the implementation of the "onInteract" function that fulfills the Interactable interface. Whew. This whole structure looks like this right now:

At the moment I have a huge global static state singleton that holds the gamestate. I've done this in the hopes it'll make saving/loading incredibly simple, and to ease global controller scope. As part of this, there is a global 2D array that is the size of the map, which contains every interactable object on the world at the slot in the array that corresponds to the slot in the map where it exists. So if I have a door at 8,12 on the map, the door object will be in the global interactables array at 8,12. This makes checking where things are pretty easy.




In this image you can see what really drove this structure right now: the need for a singular place where I define what an NPC should do (print dialog when interacted with), and the need to have instances of NPCS that actually contain the unique properties of each NPC (unique dialog). 

Obviously this system isn't done yet. For one, I'm probably going to need to make further layers of abstraction and inheritance in order to have multiple types of generic NPCs. For example the different factions will have their own generic NPC scripts that behave differently, and there may be different types of NPCs in general. 



That's probably enough on all that for now. I have some final thoughts though before I close, about the work I've done this week. I expected going into this project that I would enjoy switching between the art, music, story, and gamedesign rapidly and repeatedly, changing hat and working in all the areas maybe at the same time. Not so. I've found so far I've much preferred working only on the art for a week or so, and then only working on the programming another week. It seems to be much easier for me to just focus on a singular area for a reasonably extended time. I didn't find myself at all interested in working on the sprites or anything else this week while programming. 
This has me wondering if maybe I should try a sprint-style development method where I deliberately only work on a single aspect in cycles, perhaps only programming for a time and then switching to only doing art for a week, and so on. It might be a very productive and motivating work style. 

Finally, I did some more thinking about music (again). I'm starting to swing back around to making my own music again, but very minimalist and sparse. I'm considering producing music consisting completely of sampled sounds of the 60s/70s. I've found it very hard previously to edit audio to make it sound like it was from that era. It seems that the best way to get that authentic period sound would be to use actual recordings from then. Creating my own warped and disjointed sounds from original samples would be a very neat way to capture the era while also creating something new and tailored to this project. I'll keep thinking about it.

Thursday, August 22, 2019

The spritetrain chugs on

It's been a long time since my last post. The blog has been working though, I've kept thinking about it ever since the first post, and the guilt at not having anything to say here kept motivating me to keep working on my project. So, I have some progress to post!

Last blog I said I was going to work on the gameplay and story sides of the project, but I haven't made as much progress there as I'd hoped. I've done some heavy thinking on where that's going but haven't managed to write much down. The main thing I have been up to is spritework! I've been grinding out sprites to get to the state where I can start feeling what the end might look like. Here are some screens:




I've also mucked around with some of the game logic and programming (as you can see in the last picture above). I adjusted some render and image compression settings to get a crisper, true pixel 2D look using some instructions from the Unity blog, and a downloaded 2D camera preset. I want to avoid using presets and plugins where it makes sense, so I can learn as much as possible myself, but for now the camera is extremely lightweight and useful. It handles adjusting the game pixel mapping to the screen resolution, which involves a lot of finicky maths that I'm happy to outsource - especially as testing the results across multiple resolutions is already painful enough without having the debug my own code as well.

I had a lot of fun with the sprites, and got to flex my creativity a little in some of them, however seeing the results from my work is a little underwhelming. I haven't magically improved over time without practice, so I will need to focus and try hard with the sprite work. I anticipate I will require many animations later on as well, some very complex. The natural sprites in particular will need some movement from wind if I want to use a complex soundscape with wind audio while outside. Leaves rustling, grass blowing in waves. I'm not sure if I can pull that off yet, but I'd like to try it.

I did a little more programming on my game too. If you thought I was insecure about my spritework well... the programming is much worse. Every decision I make, at every point, I second guess whether I'm laying down a landmine for myself that will cause massive issues later! I'm finding it really really hard to even write anything at all, which is a huge problem that's causing me to work slowly. I need to remind myself constantly that writing buggy difficult code is better than writing nothing at all, but I don't know if I even believe it myself. The code I have been writing was around transitioning from room to room, and some changes to my collision system.

Going forward now, I will continue on the trajectory I'm on, producing sprites and building test rooms to try out basic logic and layouts. I firmly believe now that I shouldn't begin on the actual game until I've ironed out my systems and artwork in test rooms. This has come about after observing the number of times I've had to totally rebuild vast sections of my Unity project layouts, my sprite/tilemaps, and my programming structures. If I was attempting to build my actual game at the same time I was doing these re-writes I would be throwing about hours and hours of work and shattering my motivation. 

So for now, sprites and logic programming in test rooms. I think it will take another few months at this rate before I start to work on the actual game proper.



I've been listening to some 80s synthpop music recently while working on this project, but I don't think the tone totally suits the setting. Which is a shame, because the music is extremely evocative and I would love to use it if I could.






I also listened closely to the Far Cry 5 soundtrack. One of the tracks from the game stood out to me. It plays in a few loading screens, and sometimes as distant ambient music. It sets an incredible mood and tone, and I feel my Arcadians would match the tone very well. I know a few people who play guitar and I might be able to pull a similar sound off myself with clever mixing. It's an avenue I want to explore. I like the idea of any music in the game being natural to the world. Union music would come from speakers and be pop focused - expertly mixed crackling vinyl, while Arcadian music would be performed live with guitars and voices, wafting gently though the misty forests.