Posted on 07/31/2015 - 16:31
This morning I chatted with Steve about some possible tablet UI concerns for NEO Scavenger. Seeing it on his phone's screen caused him some concern about usability and button size. So I tried running it on my 7" mini tablet and a 5" phone.
There were definitely some fiddly controls at those screen sizes. Small buttons, like the message window expand button and the attack mode switchers would be tricky. And the main menu's options button was even a bit small. However, I didn't have much trouble hitting the skills accurately each time I tried. And it's possible some of the UI like attackmodes could be changed to a swipe-style control instead of buttons, so I have some confidence we can work around issues.
That said, it's still a bit soon to tell, as 10x10 items like the lighter could cause problems yet. We decided to continue as-is for now, and wait until we could play more with the item positioning/dragging.
On the prototype front, I took a slight detour from coding to research shader support in HaxeFlixel. As it turns out, there is partial support already! An upcoming dev branch on git for HaxeFlixel includes a post-processing feature that allows arbitrary shader code to be executed on the game's render window. And the OpenFL library upon which it's built has some pretty strong OpenGL support.
That said, it still had some limitations that made more sophisticated shaders harder to do. I wanted to do a normal map with dynamic lights, for example, and setting up that shader requires bypassing HaxeFlixel to the lower-level OpenFL GL stuff. Doable, probably, but more hacky than I'd like. Still, it seems like a promising avenue to keep open as I prototype.
Finally, I got back to my item fitting prototype, and I think I've settled on a method to try first. I'm going to assign each item a grid of tile fitting rules, similar to how tiles already work. This way, I can take advantage of existing code and features to control how items fit in the ship's deck.
It's always possible this will have a limitation I'm not seeing now, but so far, it seems like as good an approach as any. I'll probably get started on that Monday. Until then, have a good weekend!
Posted on 07/30/2015 - 16:24
Hey Folks! I had a Skype interview this morning, which should be online in a week or so. In it, we discussed some of my career history and discoveries about gamedev, as well as tips for aspiring devs. It should be online in a week or two, so I'll let you know once I see it!
I resumed work on the food stat today, and so far, so good. It wasn't too hard to setup, now that I've figured out sleep, and before long, I had it working pretty much as designed. I even tried a ship layout with 5 beds, 3 fridges, and 5 crew, and it seemed fairly accurate! The crew seemed to sleep according to their schedules, and eat when they needed it.
Some interesting side-effects of the system: crew quickly developed their own favorite bunks, and always returned to "their" bed over the others. And it was cool seeing the whole crew asleep, and upon waking, making their ways to the fridge room for some breakfast. Even though the stuff under the surface is still a bit empty and arbitrary, it seemed like they had lives and knew what they were doing. Off to a promising start!
After a few more tweaks to adjust the hunger scale to be more realistic, I turned my attention to item layout.
As of now, it's possible to put beds and fridges around the ship, and it works fairly well. It doesn't, however, care if you overlap items that shouldn't. It also allows placing beds in walls and space. Not ideal.
What this means is that I need to figure out how I want to control item layout. What are the rules for placing items? What tiles can they go on, and next to? Can items go on other items? (E.g. what about lamps and desks?) And how do I differentiate items that are part of the ship (beds) vs. carried (coffee mugs)?
And while I'm at it, how do I want to handle the visual representation in-game? Right now, I just have a bed and fridge drawn at a certain orientation. Is it sufficient to simply rotate that item, like in NEO Scavenger? Will the lighting look weird if I do? Do I want to see about dynamic 2D lighting? (e.g. normal-mapped sprites)
There are some really cool effects being done out there with 2D games these days, and I'd love to be able to use them. But it may or may not be possible in HaxeFlixel. (Even though it could be done in Haxe/OpenFL.)
More on that tomorrow. For now, time to call it a day. Have a good night, all!
Posted on 07/29/2015 - 16:37
Alors, c'est officiel! Je suis un citoyen canadien!
Also in attendance: one Canadian Mountie and Wilson Fisk.
I was a bit secretive about yesterday's day off, but it was because I didn't want to announce anything in case my citizenship test had any problems. Thankfully, there were none, and as of 15:00 yesterday, I was officially granted citizenship! Many years in the making, I'm glad to finally have it completed and be a member of a country with some very cool values, and home to my wife's family.
Back in the office this morning, I resumed work on my sleeping simulation. It was almost working as designed, but it still had some issues. One major issue involved negative sleep and comfort stats causing problems with the sleep cycle trigger. And I wasn't able to stop the stats from decreasing when below 0.
Part of the problem was that it was becoming hard to keep track of trigger thresholds the way I had them setup. I basically had one threshold per trigger, with a parameter to control whether that threshold triggered if the stat crossed it in the "up," "down," or "both" directions. This worked pretty well for situations where I needed a condition above a certain threshold. (E.g. comfortable when the comfort stat is above 8, say.)
But it became unwieldy if I had NEO-Scavenger-like stats that had different conditions at different levels. E.g. well-rested becomes tired at 16, drowsy at 24, weary at 48, and blacking-out at 72. With a single threshold value, I basically needed two triggers per tiredness state: one to add the condition when crossing the low threshold and one to remove it again when crossing the next trigger's threshold.
I started to realize that it would be easier to understand and maintain if each trigger just had a minimum and maximum threshold to control when it fires. "Tired" could simply be active from 16-24 hours of sleeplessness, and one trigger both adds and removes that condition as the sleep stat increases. This also lets me have +/- infinity as thresholds, for things with no upper or lower limits.
So most of this afternoon was spent refactoring the condition system to use these min/max thresholds instead of threshold+direction. There were some bugs that needed sorting out, but it's working well now, and using less data than the previous system.
My AI would sleep when tired, and (usually) stay asleep until completely refreshed. It would even tend to fall asleep again the next day around a similar time. If it had multiple days without sleep, the sleep cycle would be longer (9-12 hours) and may not completely refresh the AI, but it'd be able to stay awake again long enough to get back into a rhythm.
And most importantly, it's easier to understand from a modding/data-entry point of view.
This turned out to be a good test for the prototype, as it exposed a weakness in the design, allowing me to iterate on it and improve it. I think I'll try adding one more system (hunger/food) to the prototype, to see if it exposes any other issues. Since it'll likely use a second ship-board item (fridge), it'll dovetail into one of the next tasks I need to tackle: formalizing the item system so it is data-driven and modular.
It might also be interesting to ramp-up the prototype to multiple AIs again, to see how their sleep and hunger interplays with the social sim. Lots of neat stuff on the horizon!
Posted on 07/27/2015 - 15:39
Hey Folks! Hope everyone had a good weekend. We had some much-needed rain here, and some cool temperatures to go with it. I got re-hooked on Cities Skylines, and was hell-bent on creating the perfect traffic pattern for a dense city. I managed to do okay so far, but I think there could be better...
Back on the prototype, I've been trying to get the sleep cycle running in a semi-realistic way.
Up until now, I've been able to get my crew to sleep when they need it, and wake when they're done. So far, so good. However, the AI's opinion of "done" wasn't very realistic. If I told them they preferred to be awake for 16 hours, they would fall asleep at 16 hours of sleep debt, sleep a tiny bit, wake for about an hour, and repeat.
Conversely, if I told them they preferred to be completely rested (i.e. 0 hours of sleep debt), they'd sleep until rested, wake, and continue sleeping and waking rapidly around 0.
What I wanted was for them to prefer being awake 16 hours, sleep for 8, and be fully-rested when done. And this meant that there probably had to be more than a single sleep counter switching sleep on and off.
So I started doing some research. What makes humans sleep? Why do we sleep for long periods at night, and can nap during the day? As it turns out, our hormone systems pump us with melatonin during night cycles, which promotes sleeping (among other things). During the day, melatonin isn't being produced, so we stay awake easily. And at night, it kicks-in again, making us sleepy (and stay asleep).
So I decided to try making a sleep condition that does just that: every 24-hours, it triggers an 8-hour period of high sleep comfort, making it both easy to fall asleep and stay asleep. So even when the crew sleeps for, say, 1.5 hours and their sleep debt reaches well-rested (~16 hours), they stay under for a while longer, until their sleep debt reaches 0 (i.e. a full-night's sleep).
So far, this seems to work pretty well. And interestingly, I can make a minor tweak to it such that this hormone sleep cycle condition can change times of day if the crew enters deep sleep outside of their normal time. (E.g. they stay awake 24 hours and sleep much later than usual, like adjusting to jet lag) Neat!
Also, since this sleep cycle condition basically uses a "sleep comfort" stat similar to NEO Scavenger, I can still do things like waking AI prematurely if temperatures change, alarms go off, etc.
The only down side now is that there seems to be a slight out-of-phase timing of actual sleep and this sleep cycle condition, meaning the sleepiness feeling continues a few hours after waking in the morning (and starting a few hours late). I want to make sure that's not a bug in the system.
And in the business of space travel, sleeping isn't so simple. It might be interesting to see if the values could be tweaked to simulate these shorter/polyphasic periods. But that's just icing. I think this may have been a successful test of the conditions system. It seems pretty robust!
Also, as a heads-up, I will be out of town tomorrow. It's a short errand, and I should be back tomorrow night (Tuesday). As such, I probably won't be checking email/messages until Wednesday morning.
Have a good one, all!
Posted on 07/24/2015 - 14:59
I've just finished uploading new test build 1.12, which includes mouse enhancements and several bug fixes.
The build is available to anyone who owns the game at bluebottlegames.com, or on Desura and Steam. Desura (and therefore, Groupees) users can use Desura Connect to gain access here, or even get their Steam keys and try it on Steam.
To access the test build on the official site, simply visit the game page, and click any of the download links below the usual Windows, Mac, and Linux buttons (look for a red "Test" button).
Steam users can access the test build by opting into the beta for it.
Updates Included in the Test Build
Test build 1.12 includes the following changes:
- Added code to drop only one item in dragged stack if right-click.
- Added code to rotate dragged item if using mousewheel.
- Added code to cleanup orphan quick recipe buttons on click.
- Changed flashlights and NV goggles to deplete when "on" even if not equipped.
- Fixed a null-pointer bug in ConfirmCraft if no current recipe set.
- Fixed a bug that caused random UVD loot to never spawn Hiya Poopy case.
- Fixed a bug that caused crash site loot to spawn soup chunks instead of cans.
- Fixed a bug in locked/off iSlab that allowed telling time.
- Fixed a bug that caused "exit" option in Rollo conversation to be missing, and only available via spacebar.
- Fixed a bug in the preloader that caused SWF version to fail transition into title screen when done loading.
- Fixed a bug that caused whole item stacks to be identified on load if one in stack was identified on save.
The major change here is the mouse update. Based on some player feedback, I added the ability to rotate items and drop single items from stacks using only the mouse. This should go a long way towards making the game playable entirely with a mouse.
The bug fixes are mostly minor, though one major null-pointer fix to crafting may reduce some of the random bugs we've been seeing.
The likelihood that this version of NEO Scavenger will work with previous saves is: likely.
As usual, the older the save game version, the less likely it is to work.
As always, let me know what you think of the changes, and if you notice any issues with the new build!
Posted on 07/23/2015 - 15:24
Today was cut a bit short by some errands, including a trip to the vet for our cat, Brak. Unfortunately, it looks like he has some sort of genetic dental decay, and some more teeth are going to have to come out. He was not pleased with the poking, prodding, and general indignities of the vet's. And I fear he'll be no more pleased in a month when he visits again only to wake-up with massive jaw ache. Poor little guy.
On the up side, the new food he was prescribed was a hit. He plowed through a whole bowl in one sitting, which is unusual! And if this surgery is anything like the last, a few days of mending will mean he's like a new cat.
During the time I did get to work today, it was on the bed, sleep, and interaction code.
One of the first things I did was to update the interaction data type to add required/forbidden conditions for "them," in addition to the existing "us" fields. This allows me to be a bit more selective about how interactions are applied. Interactions are kinda like the battlemoves in NEO Scavenger, only more general-use.
And the first application of this new field is going to be sleeping interactions with the bed. The crew checks periodically for things on their priorities list, and for each of those, checks to see if someone or something on the ship can help. In the case of sleep deprivation, they're looking for something to restore the sleep stat. Enter the bed.
The crew will then query the bed for any interactions that might improve the sleep stat, and finding one, will initiate the "SeekSleepN1" interaction. This interaction lasts about 15 minutes and has a possible outcome of "SleepAllowN1" or "SleepDenyN1." If allowed, actual sleeping will begin with phase N1, lasting another 15 minutes. Once that's up, a similar interaction exchange happens ushering in phase N2, N3, N4, and REM phases, before starting the cycle all over again.
Why the multiple phases? For one thing, I wanted to make sleeping more realistic. People don't always drop like a sack of bricks for 8 hours and wake up refreshed. Many times, people try to sleep and can't, or sleep for a while and wake themselves up. This 15-minute phase system allows for the sleeping process to self-interrupt when the conditions require it.
It also allows me to mimic the way humans sleep by differentiating phases where the human is lightly sleeping vs. deeply sleeping, and how much to restore any lost sleep during each phase. The initial phase offers no sleep bonus, while REM offers double. Therefore, getting longer stretches of sleep is more valuable than shorter naps.
Getting back to the "us" vs. "them" fields I added, this was to facilitate the interaction between crew and beds. The crew asks the bed to interact, and the bed chooses between "allow" or "deny." This choice will be controlled by whether the crew is tired enough to sleep or not. If the crew is not tired, the choice is "deny." The crew, in this case, is "them" from the bed's point of view. So the interactions "allow" and "deny" will have "tired" and "not tired" among their required conditions, respectively.
I know this seems a bit weird, the bed making decisions about if a person can sleep. But it's the way the interaction system works. Each interaction has an "us" and "them," effects it applies to both "us" and "them," and zero or more possible interaction outcomes. So one way or the other, the bed is going to be "interacting" with the crew.
It might be possible to add filler interactions on the bed's side that automatically bounce back to the crew to make the decision. I'll have to think about that.
As of now, however, I can get crew to go to sleep on a bed when tired, and cycle through the sleep phases, decreasing the sleep deprivation stat.
I should also mention that this will use different data than NEO Scavenger. In NEO Scavenger, sleep and fatigue were on the same scale, which caused some simulation shortfalls. I had to make the thresholds for things like sleep deprivation much higher than real life, since both sleep and fatigue counted against it. In this prototype, however, it'll be pure sleep, and probably another scale for fatigue.
Other than sleep, I managed to fix a few minor bugs in the prototype. Item positions were changing incorrectly when switching from crew sim to ship build mode multiple times, and a few pieces of code had to be updated to include items where they only included crew before.
I guess it was a rather productive day, after all! Just compressed into a smaller timespan than usual. Have a good night, all!
Posted on 07/22/2015 - 16:18
Hey Folks! If any of you were on Twitch today, you might've caught me on Outstarwalker's NEO Scavenger stream for GOG today. For two hours, we watched Outstarwalker chase dogs, beat up Bad Muthas, and debate the merits of cannibalism. All in her stylish dogman coat!
Once that was done, it was back to the prototype for me. I finally wrapped-up the refactoring I started yesterday, and now the game can pass shid data cleanly from one state to the other. There were quite a few gotchas in this transition, as many of the objects had to be protected from clean-up during the transitions. In other cases, data had to be forced to clean-up since they didn't make sense (e.g. removing crew when switching back to build mode)
With that done, I was able to resume working on shipboard items. My sleeping berth is now in the game, and I added the ability to choose it from the builder menu and place it around the ship. And with the data I added to it, crew will seek it out when they're tired! Pretty cool.
There are still many details not working yet, of course. For one thing, I need to verify that the sleep actually behaves like sleeping. Right now, I think it lasts forever, and that's no good. I'd like for sleep to work like NEO Scavenger, where there are such things as difficulty sleeping, full-night's rest vs. minor nap, etc.
I'll probably also need to think about things like interruptions (both from events and other crew). It seems likely that longer tasks like sleeping will be interrupted frequently by the goings-on around the ship.
There are also quite a few minor details that'll need solving. There is no sleeping animation, for example, because the walk cycle is 32x32 pixels, and sleeping would require 32x96 pixels. I may have to restructure crew spritesheets to allow for non-square sprites. Ship items also don't block pathfinding, which for beds is okay, but might not be for other items (like a sink).
And the build mode doesn't care where items are placed. They can overlap walls, go in space, or even overlap each other.
These issues are, of course, minor until more important things are sorted. Like having fun. Still none of that going on. (Though I'm starting to see potential!)
Posted on 07/21/2015 - 16:23
I decided to switch back to prototyping for a bit today.
When I last left off on Friday, I had decided to start working on the Item class, to represent onboard tools and other objects crew could interact with. I had finished up making a new class that exposed most of the same tools as a crew. Basically, the item had a list of conditions, a sprite, a name, an ID, and a list of available interactions.
However, before I could use it, I needed some way to tell the game that the item was on the ship, where it was, and what orientation it had. And it would make sense if this was setup during the ship editing process.
Unfortunately, my prototype had a very rudimentary definition of "ship" which had no way of specifying onboard items. Basically, it was just a list of tile types and overall dimensions. What I needed was a beefier ship definition that included that tile info, as well as things like items and crew on board, and where each is.
So I started working on a new Ship class to contain all this layout info.
Refactoring the prototype to work with a ship, instead of just a tilemap, turned out to be a bit of work. There were a lot of assumptions made to get the prototype working as quickly as possible, and they had to be adjusted for this new ship class. And as of now, the code compiles, but it's not quite working yet.
The good news is that this should be a big leap forward for the prototype once working. It'll allow me to specify a ship's structural layout, the items and their positions/orientations, and the list of crew on board. I can then pass that whole dataset around from game state to game state (e.g. ship editing mode, solar system flight mode, planetary lift-off mode, crew monitoring mode).
It's also a bit easier to work with, from a data point of view. The ship class can take care of a lot of "under the hood" stuff that the rest of the game shouldn't need to care about. E.g. initializing the tilemap, changing tile data, etc. Plus, I can finally start throwing items into the ship to see what the crew does with them!
First, however, I have to get it working. And that's what I'll be up to tomorrow!
Posted on 07/20/2015 - 15:15
Hey Folks! Hope everyone had a good weekend. It was a purging weekend for us, as we took loads of stuff to recycle, reuse centers, and to the dump. We still have carloads left, but it's nice to have that pile on our floor slowly shrink!
Apart from some email catch-up, most of today was spent on some NEO Scavenger bugs. I was able to use a player's save game to reproduce some pesky bugs in the crafting system (usually seen by players who peddle tannin tea to the market).
It looks like there was a problem in the quickrecipe buttons being cleaned-up when leaving the crafting screen, causing "orphan" quick recipe buttons to be left behind. These would trigger quick recipies on occasion (when entering the tile again?), but wouldn't be associated with any of the player's recipes anymore, causing a null-pointer when executed. (Eventually, leading to weird behavior in the game.)
There was also an occasional bug that appeared when tannin-brewing/selling if one switched to a manual recipe later on, such as sterilizing water. This appears to be the result of the "confirm craft" process being triggered while the game had no current recipe selected.
It's hard to tell if this second one was due to the first bug or not, as it only happens occasionally.
Whatever the case, I was able to add some "protective" code to the crafting system to basically check for these null values before proceeding. This way, it bails-out early before crashing/corrupting the game if there's a problem. It'll also now clean up so-called "orphan" buttons if it runs into them trying to trigger themselves.
If this works, it should hopefully stop two more sources of null-pointers in the game, resulting in fewer weird/random bugs!
Also, NEO Scavenger is on sale at GOG.com! For the next several days, NEO Scavenger is 33% off the regular price. So if you (or your friends) keep missing the discounts, now's your chance!
Have a good night, all!
Posted on 07/17/2015 - 16:17
I worked on a refinement to the autotiling code today, and I think it's in a much better place now.
Instead of the tiles that had to specify all possible neighbor tiles, I now have it setup to define the type of all possible neighbors. So a wall will only allow connections to other wall types, for example, instead of having to list each possible wall it could connect to.
The benefit of this is that it has made a tremendous difference in ease of maintenance for the data. I was quickly able to take yesterday's 1x1 grid tiles and add multiple new variations of the corner piece styles, and it was simple to hook up and get working. Good for the dev, and good for future modders!
I also decided to try switching the tile size from 10x10 pixels to 32x32 pixels, to match the size of the current crew sprites. Even with just a hacky scale-up in Photoshop, I think the matching scale makes a huge difference. Things look way more consistent now, and the crew looks like they're wandering a space meant for them, and not just icons on a map.
I also think that 32 pixels may be a good size to start from. Originally, I went with 10x10 because it was easy to knock-out a bunch of tile graphics. However, 32x32 leaves more room for detail and style. It'll be more work to make the art, but I think it'll be an improvement, visually. (Both in quality and ease of visual recognition for different sprites.)
As such, I think the working scale is going to be 1 pixel = 2cm. This means that a grid square (32 pixels across) is roughly 64cm across, or roughly 25 inches. Wide enough to accommodate a standard human's shoulders. This means a single grid square can contain things like a sleeping space, a seat, or other human-centered object. It may need tweaking down the road, but we'll see how this works for now.
Finally, I've decided to get started on shipboard items. My first item is going to be a sleeping berth for crew. And I've decided to make it a placeable item rather than a tile. The reason for this is because I think I'm going to need to rely on existing crew interaction/condition system to deal with crew interacting with objects, too. E.g. an "interaction" with a sleeping berth may be an 8-hour duration task that increases rest while decreasing other stats.
Using this system means I get to piggy-back on some useful features, like crew querying the map for available things to interact with, and the whole concept of "busy." And since it uses the condition system, items can apply any effects to the crew I need it to, and vice-versa (e.g. crew gets rest, and bed gets soiled).
I may still need to work on some specific tile-based items, but for now, this seems like it'll cover my needs.
That about does it for this week, though. It's beer o'clock in the Fedor household. Have a good weekend, all!