Phew! What a week. After multiple days of driving, flying, crossing time zones, speaking French, and navigating bureaucracy, our cross-country trip is complete. Looks like we may be cleared for moving to the US! Now begins a new laundry list of things that need doing before we can uproot and relocate. Lawyers, accountants, movers, landlords...we're in for some fun now!
Also, to make sure things were not too boring upon my return, the website died. By all accounts, it was a spammer clogging the system via a security hole, and the hosting provider suspended the website until we could root it out. It took a few hours, but I think we've cleaned the offending spam script and patched the hole(s). Still, we'll be keeping an eye on things just to be sure. Sorry about that!
And despite the whirlwind of activity above, I still managed to get some tinkering done on the prototype. The main feature is status text above each crew to help me see what's going on:
Long-time readers will recognize this from the old Haxe version of the prototype. This is basically the same AI code running in Unity, with UI text floating above each crew member. I hastily added some code to spawn extra crew with a keypress, and can fill up my ship layout and watch them go.
As usual, it wasn't too hard to port. The main issues were learning how Unity handles UI vs. the way Haxe/Flixel did.
So far, I think the main issues are some visual glitches. I've got the UI text setup to stack vertically if it overlaps, but it breaks if there are more than two crew on the ship. (Which I think is a simple error in my code.)
Also, the timing of the UI text updates is a bit off from when the AI is acting. The last action sometimes lingers over the crew too long, and other times, the text appears and disappears too fast to read. Still other times, the text doesn't update until too late, often after the action has happened.
I need to sort this out for more accurate testing/debugging. It might be that I can't rely on the timing of the action queue being cleared. Or I may need to do some special handling to make sure actions aren't firing before the AI has pathfinded to its goal.
But the good news is that these issues are more shallow and shouldn't be hard to fix conceptually. Just details. A more complicated and challenging task lies beyond that: figuring out how to present these AI interactions to the player so they can watch it for entertainment.
Talking heads on the bottom of the screen, with a dialog scrolling past?
Roguelike general message log with all on-screen participants sorted chronologically?
Text bubbled above each AI?
Let the user focus on individual conversations and hide the rest?
Hey Folks! I managed to get the rest of the AI stuff ported and compiling, and spent most of the day working out the bugs. As of now, it's nearly working as designed:
Surprisingly, the biggest issue I'm running into seems to be null pointers from not initializing various things. I think the way Unity calls Start() and Update() is not the way I think they are called. Namely, Update() seems to be called arbitrarily before Start() on my classes, and I'm finding I need to do a lot of hand-holding to make sure each class is initialized before it's operated on. Probably, I just need to roll my own initialization and update code, and call them manually.
We're not quite at the point where AI is interacting with each other, grabbing food, etc. However, the AI is wandering around the ship, and periodically checking against its own priorities for what to do next. The next thing I need to fix is this decision code so there are no null pointers.
It's sort of implied above, but this all takes place in a new game mode called "CrewSim," as opposed to "ShipEdit" where the ship parts are arranged and saved. I managed to get these modes to talk to each other, so one can build a ship, switch to crew sim mode, watch stuff, and switch back to continue editing the ship.
This sort of mode-changing is something I hadn't done before in Unity, and it wasn't too hard. It also forced me to clean up the organization of more code, so it lives in more logical places when it needs to be shared between modes.
Not too shabby! I'll have to sort out that AI decision stuff next, and see where the simulation stands!
Out of the Office
Also, I'm afraid I'm going to be out of the office again. Sorry about that. More immigration stuff for Rochelle, inconveniently not local to us. The plus side is we'll at least be seeing my family while there, which doesn't happen often due to their distance from us.
Anyway, I'll be trying to work on the road again, but internet access may be spotty along the way. I should be back to normal on the 29th. (Until immigration's next trick whisks me away, I guess.)
Have a good weekend, all. And see you when I return!
Hey Folks! Hope everyone had a good weekend. Ours was mostly okay, though I got a weird headache last evening which developed into feeling sick. It seemed to dissipate late in the night, though, and I feel much better today (thankfully!).
Today's work is a continuation of what I started last week. Namely, getting the crew, item, condition, interaction, relation, trigger, and condition owner classes moved from Haxe/Flixel over to C#/Unity. Progress is still pretty steady, as the syntax is similar enough. The main speedbumps I'm hitting are when old Haxe code runs afoul of Unity's component model.
Technically, I think almost all the old code can run as-is in Unity (I.e. using interfaces, class inheritance, etc.). However, the "Unity way" of having game objects with components offered some opportunities to refactor old code to be more organized and maintainable.
For example, I used to have an IConditionOwner interface class which Crew, Items, and Relations all implemented. This allowed me to do similar operations on each of those classes such as adding/removing more crew/items, or searching them for compatible items/crew.
However, using the component model, I can make a condition owner (a.k.a. CondOwner) component class, and just add that to both Crew and Item classes. This allows me to keep all the Condition-processing stuff in a single class, instead of having to update copies in each of the Crew, Item, and Relation classes any time I made a change.
It also meant I could do away with the Relation class, and just make it an empty game object with the CondOwner component.
I've also been separating other components out where it seems logical. E.g. the pathfinding code in Crew is now a component, so any object can take advantage of it if needed.
This is a new way of coding for me, so I'm still getting the hang of it. But it seems to be a better fit for a lot of what I was trying to do than my old way of having lots of duplicate code and bloated classes. I guess we'll see if that refactoring results in better code soon enough :)
So far, I think I've got the majority of these classes ported over, and I'm just hammering out the last dents before getting it to compile. I'm totally expecting some crashes the first few times I run this raft of new code, so bug-fixing will be the order of the day after that.
However, once those steps are done, I'm hoping we'll see the return of crew walking around and interacting with each other!
Hey Folks! Since it had been a while, I decided to tackle a few NEO Scavenger issues this morning. And in my remaining time, I began the heavy-lifting that is porting old crew/AI-needs code from HaxeFlixel to Unity.
First of all, Kaaven mentioned that it'd be nice to omit certain map labels from the minimap, as they were getting difficult to see when too close together (as in the DMC area). So I looked into that, and it didn't take long to add a new option for making labels only appear on the main map. Basically, the old format was:
20x164=Gyges Cryo Facility
and the new format is:
20x164=Gyges Cryo Facility=1
That last "=1" is the new bit. The game will interpret "=1" to mean the label appears both on the main map and minimap, "=0" means just the main map, and if that last bit is omitted, it'll assume default old behavior (both maps), for backwards compatibility. I also edited the labels around the DMC so only the Glow/Gates will appear on the minimap, since it was hard to read if any others appeared there.
Also, while I was in there, I noticed a way to fix the issue with charged items showing the wrong charge count in encounters, so I fixed that. Yay bonus fix!
I also tried to track down a few other reported bugs, but had trouble reproducing them in the debugger. So I'll have to try again later once I have more info.
Back on the prototype, I fixed the crew rotation so it now faces the right direction when walking. I also fixed a minor bug in the item placement editor, which forgot to rotate the item's placement grid on the new cursor item if you placed something with a non-zero rotation. And I made a tweak to the item selection code to make sure it selects from top to bottom when deleting, so it doesn't delete a floor from under a bed, for example.
Once that was done, I began work on the long, tedious process of porting old AI code to the new Unity project. Fortunately, a lot of the syntax is similar, so this isn't too hard. But there are enough differences in syntax and architecture to require more thought.
So far, I've got most of the CondOwner class covered (anything which is interactive and can have conditions), and large parts of CondTrigger (condition trigger rules), Condition, and Interaction. Because of Unity's component model, some of these will have to work differently. (E.g. I can't just instantiate an item and add it to a crew's inventory, as it would appear in the game without special handling)
I think it'll be a couple days' worth of work to get any visible progress here. But the upshot is that the progress should come in the form of crew wandering around and interacting with each other.
Oh! And one other thing. On a whim, I decided to try spawning a couple dozen crew and checking the framerate with each one generating heatmap pathfinding info over and over. Good news! No framerate drops! And since the number of crew on a typical ship is likely to be way less than this, I shouldn't have to worry about pathfinding performance. Pathfinding quality, however...
But enough about that. The weekend is here. It's pizza time! Have a good one, all, and see you Monday!
Hey Folks! I think I've got the heatmap pathfinding working, for now.
Introducing a "passable" property to each tile avoids the bug I described yesterday when I tried to make walls cost more to traverse. Instead, if the tile is impassable, the heatmap code just ignores it, so they don't pollute nearby tiles with incorrect path values. As a result, I can get a whole map processed with numbers increasing each grid square away from the destination!
The next step was to see if I can get crew to follow it. And before that can happen, I need to introduce the concept of crew to the code.
I started out by ripping the mesh-creation code from items, since both items and crew are going to use similar code to create display mesh in the engine. This is where Unity's component-based architecture pays off, since I can just create a "SpriteMesh" class that both Items and Crew can share. I just create either an Item or a Crew object, and tack-on a SpriteMesh component, and voila! Each can now have procedurally-generated mesh in the game.
After I extracted that code, I created a simple Crew class that could track current position, destination, and heatmap info. For now, I'm storing the heatmap on the crew for simplicity. I could easily move this over to the ship, though, and just store heatmaps for each goal on the ship as-needed. (Assuming those heatmaps remain valid, that is. If any obstacles can appear and/or move, heatmaps become out of date.)
A little bit of tinkering later, and my Crew object was able to pick a destination at random and move to it! Except it was so fast that it looked like The Flash blipping in and out of every tile on the ship in rapid succession. To fix this, I turned down the movement speed of the Crew, and I could follow more closely. It kind of cuts corners now, but that may not be a bad thing.
The next thing I started was changing the Crew's orientation to match the direction of movement. And I almost have this working now. Except, the rotation is mirrored when traveling in the X+ direction. I'll have to dig into it to see why, but I suspect there's a sign error somewhere, or else an arctan correction that's missing.
In other news, I stumbled across an interesting crew sprite solution today. @Ellian, a talented pixel artist, was tweeting about a set of top-down sprites he did for a cancelled project. They had a clean pixel art style, movable parts/joints, and swappable parts/clothes. And best of all, it required no 3D modeling/rigging/keyframing/rendering!
This is a video of the early prototype in action:
His channel has a few other videos, including one for character creation with swappable parts, and a character select screen where the characters are much larger and easier to see.
It's not perfect, of course. For one thing, the animations look a little like the heroes are wading through water. And there may be a limit to the types of animations those parts can produce (e.g. prone). And rotating sprites in 3D will look a bit weird, since "real" pixel art would have different animation frames per rotation.
Still, though, this offers a ton of customizability in terms of clothing, equipment, and even character builds (male, female, burly, thin). And it's way simpler than trying to model, rig, and animate each of these combos in 3D.
That said, I'm taking a break from experimenting with art styles for now. I feel like I've been noodling on that for so long that I'm ignoring more important things, like gameplay. I can always come back to the character art and change it later. But this warrants a bookmark for further review.
Tomorrow, I may dip into some NEO Scavenger stuff (bugs/modding). And if time permits, I'll probably continue fleshing-out the Crew class to do more of the stuff the old HaxeFlixel prototype did. (AI seeking needs, interacting with each other and items.)
Hey Folks! Hope everyone had a good weekend. Our last four days were unfortunately largely spent driving, in hotels, or in waiting rooms. One of the benefits of immigration! It's good to be back at home, though, and decompressing.
Despite the tedious roadtrip, I did manage to break out the laptop in the evenings after checking-into each hotel. But first:
I guess the cat's really out of the bag now, huh? This is simultaneously really exciting and scary. Exciting because more people suddenly were made aware of my next project, and better yet, seem excited by it! Scary because, well, I haven't built it yet :) Hopefully, expectations won't outstrip what I can build!
As for progress, I've tried tackling a few things. I looked into alternatives for making crew sprites, fixed a few bugs in crew sprites, worked on pathfinding code, and fixed some hardware-related bugs.
After chatting with some friends, it was starting to look like hand-painting normal maps on animated sprites was, as my friend put it, "maybe insane." Even just drawing them would be a ton of work, as the number of animations increased.
Now, having worked on 3D characters in my last job, I was loathe to try and tackle this. 3D is no joke, and it can take an army of people to produce and maintain the content for anything but the simplest of games. However, since my view was top-down orthographic, and low-res, maybe it was worth a look.
I set about grabbing the first low-res human mesh I could find, and found this helpful example by Clint Bellanger. And this useful Blender tutorial helped me setup a normal-mapped material for rendering the scene as a normal map. A few camera and rendering setting tweaks, a quick-n-dirty UV unwrap and texture splash, and here's what we get:
What we see above is an in-game shot of a rendered sprite (top) vs. a hand-painted sprite (bottom). For reference, I included a few insets along the right to show what the rendered normal map, Blender model, and UV unwraps look like. It is low, low res, and low-effort at this point. I'm not thinking this is ready for prime time or anything, but for the amount of effort I spent painting blue, brown, and black on that unwrap, the results aren't terrible.
The main problems I see are a lack of crispness in the rendered mesh, and some garbled areas where there are tiny details in the render. But I spent way more time painting details on that hand-painted crew than I did on the solid-color clothes of the rendered one. So there may be hope yet.
Also, all this fiddling with sprites revealed a bug in my shadow code. I was generating shadow mesh incorrectly, resulting in weird holes, and self-shadowing due to the height of the crew, its shadow, and lights in the scene. So this experiment helped solve some rendering issues, even if I don't go with it.
This is going to need more investigation, and probably some art with more care put into it, in order for me to compare more fairly.
Moving on, I also spent a bunch of time working on pathfinding. The heatmap algorithm finally started generating good data, and I began working on walls. And this is where I noticed a problem.
The way I was dealing with walls, I just gave them a +10 pathfinding cost per tile, where normal floor would be +1 per tile. I was thinking this would make AI prefer floor over walls.
Instead, what I discovered was that the heatmap algorithm would break in situations where the walls blocked the majority (but not all) of shortest paths to the goal. It looks like my simple, brute-force heatmap approach is actually not so simple. I may have to explore more traditional approaches, such as A* or Dijkstra's methods. Or maybe my queue just prioritizes wrong. We'll have to see.
Finally, I ran into an alarming bug while on the road. Using my laptop to dev for the first time, the Unity graphics were garbled all to hell. In a panic, I started Googling "Unity textures messed up" before I realized it could be a driver issue. Sure enough, my Bootcamp driver for the MacBook was out of date, and manually installing an update helped. Some minor mesh importing and other setting changes in Unity did the rest, and I was back in business.
Not as productive as I would've normally liked in a 5-day period, but not bad considering the road trip. Hopefully, we'll be back to more or less normal tomorrow. Have a good night, all!
Hey Folks! With the ship layout and lighting starting to materialize, I decided to take a step back and do some thinking about how the simulation will interact with it. E.g. crew movement and physical properties.
One of the first questions I had was whether I could make the crew sprites consistent with the ship lighting. This would mean generating/painting normal maps for their sprites. I took my earlier prototype's idle sprite, and pieced together a normal map for it, then created an item using this sprite that I could place around the ship. Here's how it looks:
They're not moving around yet, or hooked up to any AI. Just statues for now. However, I was happy to see that their highlights seemed to work okay, and the shadow casting as well.
I guess the real question is whether this will be sustainable when it comes to animations like the walk cycle, etc. And for that, I'm not sure. It wasn't hard to create this normal map using a reference normal map sphere smushed and stretched to fit head, shoulders, and body. But doing that for frames of an animation with irregularly-shaped parts may be tricky and/or tedious. I might have to explore more automated solutions.
In addition to this, I decided to look up Unity pathfinding, to see what was available. Unity's built-in pathfinding, NavMesh, appears to only work with rooms/terrain laid out in the editor. Since the ship is generated by the user at runtime, and they won't have Unity's editor/exporter, I'll have to try something else.
There are a million other ways to do pathfinding, many of which are in the Asset Store. However, I remembered one from HaxeFlixel which seemed pretty simple to build and had good performance. Namely, the heatmap pathfinding algorithm.
Roughly speaking, a heatmap pathfinding algorithm just uses a grid to keep track of which squares are closer to or further from a destination. You choose a destination square, and the algorithm walks away from that square to every other square, and records the number of steps in each square. Then, you're left with a grid of numbers telling you how far each is from the goal. The AI then just has to look at its current square, and the squares around it, and choose one with a lower number. It does this comparison each step until the grid it's standing on is 0 steps away.
It's not necessarily the most efficient, as the heatmap needs updating each time the goal changes. So a moving goal can be costly, and each AI with a different goal will need a different heatmap.
But it has some useful benefits. As already mentioned, it's super easy to implement. Also, it means anything on the ship can use the same heatmap if they share the same goal. (E.g. swarming) The heatmap can modify the "step" cost of each grid square based on things in it (so different "terrain" types can have different costs). And I might even be able to tweak squares as crew and other things pass through them, so AI avoids obstacles in real time.
But mostly, I'm choosing it because it's easy/fast :) And for the size of ship grid we're dealing with, generating a heatmap is so fast as to be negligible.
So far, I have the rough framework in place for calculating the heatmap, and I'm working out the bugs now so it steers around obstacles better.
Out of Office
One more thing. I'll be out of the office until Wednesday next week. So no devlog posts Monday/Tuesday, and I may be slow to respond to anything that comes up. I'll be back to normal on Wednesday, though.
Hope everyone has a good weekend, and I'll see you Wednesday!
Hey Folks! I've made some nice visual progress today cleaning up the item placement and lighting. Have a look!
Most of these pieces are familiar to those who've been following my devlog. The difference here is that I reworked the normal maps on all the items, and cleaned-up some light/shadow parameters for them.
One of the big highlights is the bed. The bed is my first attempt at hand-painting a more complex normal (i.e. bump) map. Normal maps are just images where red is used to control left/right surface direction, and green controls up/down.
Usually, they're created automatically by using a 3D mesh tool like 3DStudio, Zbrush, etc. The artist makes a mesh or bump surface in their tool of choice, and it generates appropriate normal maps. There are also plugins for Photoshop, and even pixel-art-based normal map tools out there.
In my case, I basically just painted the bed as if it was grayscale and lit from the right. Then used that as the red channel. Repeat as if it was lit from below, and use that for the green channel. Finally, draw a grayscale blue channel as if lit from the camera's view, so parts facing you are RGB=128,128,255 (gray blue) and parts facing sideways are RGB=128,128,128 (gray).
The result is that lights will highlight and shadow the surface as if it is bumpy. Notice the top bed in the image above has blue on one side of the pillow, and orange on the other. And the surface of the bed looks rumpled. I didn't have to work too hard to paint that. A lot of it was just rough penciling with a thick brush to create texture, with some blobs of light and dark in appropriate channels.
Is that sustainable? Maybe. Might not be too much harder than drawing the light/shadow into the sprite manually. Especially once you get the hang of it.
You can also use a reference image like this to pick colors for different faces/directions, and just paint with that:
Note: This image was cobbled together from here among other places. I've adjusted the color channels to work in Unity, though, so it may not be compatible with other apps without some tweaking.
Will modders be able to do this? Yes, but they might find easier ways to do so. The aforementioned tools are only some of the literally dozens out there, ranging from free to expensive, that will do normal maps regardless of your skill level. And picking and painting using the reference image above isn't too bad. So I think modders will manage. And worst-case scenario: just make the normal map all RGB=128,128,255, and it behaves like a flat sprite without bumps.
Apart from the above, I also added a "Clear Scene" button for convenience. And I started working on more complex rules for placing items. I was starting to run into situations where items would overlap despite the "forbidden" socket info each had. Items may need to set multiple socket types per grid to get the right kind of placement. But I'll need to think about that some more.
Believe it or not, today was a less productive day than yesterday. I had a lot of stumbling and work/rework today. It just looks prettier :)
Hey Folks! Still more work on the item placement code today. Getting items to appear on-screen when I click was just the start. Now I have to deal with rotations, overlaps, and other placement rules.
The first order of business was to fix the broken socket data on placed items. The code wasn't adding anything to the scene/ship when a part was added, so I had to hook that up.
Then, when I was able to place items according to socket rules, I started to notice something: my overlay grid indicators were blocking my view. They were also catching lighting/shadows instead of rendering like UI items. So I had to adjust their materials to be less opaque, and use a sprite shader. I also made some tweaks such that the red/blue placement indicators don't depth-fight against the white ship grid indicators. They shared the same z-value, so I teased them apart a bit to make red/blue appear on top of the ship below. I also added a hotkey to hide the ship grid, for convenience/debugging.
Once that was done, it was easier to align and place things, and that's when I noticed an issue placing the bed: the grid placement was wrong when the item was rotated 90 or 270 degrees. The cause? Unity's left-handed coordinate system. When I rotated the part "clockwise" 90 degrees, I assumed that was in a right-handed system, and the grid sockets were rotating opposite the sprite. Oops! Easy fix, thankfully.
Then, I had to make sure the sockets were cleaned-up if a part was removed, so I inserted some code to do that.
By this point, I was starting to be able to make complex layouts again, with rotated items. And this is where I decided to tackle the lighting issue I mentioned yesterday. Namely, lights were "high" enough on the ship to spill over the tops of walls a bit.
This turned out to be a multi-part problem, and took a while to sort out. First of all, the lights themselves were based on a template light that was offset -0.6 in the Z direction (towards the camera). Not a problem all by itself, as the walls are supposed to be -1.0 units high.
The problem was due to the way the walls were defined. They had pivots/origins in the center of their mass. So since they were 1.0 units on a side, and the pivot was in the middle (0.5, 0.5, 0.5), placing the wall at Z=0.0 means the wall only came 0.5 units above the floor. I had to tweak the mesh in Blender, as well as wrestle with Unity's editor, to finally get the wall resting on the floor instead of inside it. (And with the texture flipped in the horizontal direction, due to the LH coordinate system.)
Phew! With that done, I finally had some walls that completely blocked light, and the tops of the walls received no illumination from ship's lights. Doing so would normally mean the tops were pitch black, but I added an ambient light the other day, and this gave everything a bit of illumination, regardless.
Since we're supposed to be in space, I decided to try replacing that with a directional light similar to a distant sun. There's now a dim light from the lower left corner of the screen, and it's just enough towards the camera to shine down a bit on the ship parts so their tops get a dim illumination.
Though now that I look at it, I'm thinking I may have to dip the sunlight back towards the ecliptic so it only illuminates the ship's sides. Right now, it's illuminating the tops of interior walls, and that should probably be more ambient. Making a note to self now.
Anyway, after that, I fixed-up the ship saving/loading code so it adds sockets appropriately. And once that was done, it was time to tackle item overlaps.
Items currently require certain sockets to be in place for them to be installed, and this works pretty well. But one situation it doesn't solve is overlaps. I can place two floors in the exact same place, and that doesn't make sense.
I wasn't sure how I wanted to solve this at first, as it's probably more complex than it appears. E.g. what about things like clothes and food? Should they stack in a grid? Or what about food on a table on a floor on a frame?
So far, the best I came up with was to add "forbidden" socket info to each part's grid info. So now, an item has both "required" grid info and "forbidden" grid info. If either of these rules is violated, the item won't place. This way, a floor can add floor sockets to the grid underneath it, and future floors can forbid any grids with floor sockets present.
It should work in theory for most of the above example cases. And in practice, it almost works. I'm seeing a few weird red grids where I wouldn't expect them right now, so more work on that needed tomorrow.
Overall, a pretty productive day, now that I look back on it. Hopefully, we'll have more like this!
Hey Folks! Work continues on the item placement code.
Today, I managed to finish the system for placing ship grid tiles wherever items are laid. It'll start by placing tiles to cover the first item, and any newly-placed items will expand the grid to cover their area. This is a bit of a change from the HaxeFlixel prototype I made, which set the grid bounds beforehand and couldn't change them. I'm thinking this'll be more useful for players who don't know how large the ship will be until they put pieces on the page. It'll just expand as-needed, and I'll probably add a "trim" feature to cleanup unnecessary grid tiles once they save the ship.
Once the ship grid was being created, it was time to start handling placement rules. Like with the HaxeFlixel prototype, I went with simple red/blue grid indicators to show who the current item fits the grid:
Above, there are 16 floor tiles on the right, and a bed on the left. The floor tiles have their grid helpers (white box overlays) displayed for debug purposes, and the bed shows blue where the placement rules are okay, and red where they're not. In this case, the bed must be placed with floor tiles below and to the right, and a wall to the left, so it has red boxes to show this.
So far, so good. However, there's still a bug in there that prevents the red from turning blue, even when the tiles below are appropriate. I think this may be due to items not updating the socket info for the ship grid. (Basically, they're putting down empty tiles, without socket info.)
I'll have to dig into that tomorrow.
One other minor thing I decided to do was increase ambient lighting a bit. By default, the ambient light was black. So any placed item would be also black until lights were placed. This is realistic, but makes editing a bit hard.
It also meant I had to place lights higher than the wall heights so each wall's "top" (the part pointing towards the camera) wouldn't be black. Unfortunately, this causes some artifacts in the lighting (color banding across the tops), plus spill-over in certain arrangements.
I want to see if making ambient light a dim beige will alleviate these issues, making editing easier, and allowing me to sit the lights lower in the ship. We'll have to see if that works, in practice.
Hey Folks! Happy New Year! Since the game's been out for over a year, and pretty stable for most of it, I decided to "go dark" for two weeks, hoping to recharge my batteries. Now that I'm back, I think it had the desired effect. I found myself getting more and more inspired each day I was away, and I feel pretty excited about getting back to development!
Of course, I've also got about two weeks' emails and threads to catch up on. But such is dev life :)
Today, I decided to use my first few hours to get straight into prototyping code. I'm realizing that my most productive time tends to be before lunch, so I wanted to try and harness that for the heaviest mental tasks.
I focused on setting-up a tile/grid system for the ship editor. Getting the parts to align to a grid was one thing, but I also want them to behave according to several placement and operational rules. I want items to lock together only in certain ways, I want some items not to overlap, and when the game is running, I'll want to track things like atmo pressure, temperature, and other stats.
The old HaxeFlixel prototype used a tilemap for placement, and I think that still makes sense. Plus, I think I can use that same tilemap to control the game stats like atmo, temp, and other vitals when the ship is "live." Neighboring tiles can exchange atmo values, propagate radiation, etc.
I've managed to get a lot of the framework down for this. Fortunately, borrowing code from the HaxeFlixel prototype seems to be pretty easy. Not exactly the same, but close enough for me to massage into shape. And a lot of the hard problems are already solved there, so it's just hooking them up and porting the Haxe to C#. Nothing quite functional yet, but we're getting there.
After lunch, I decided to start tackling my inbox, forums, etc. I have a lot of messages awaiting attention, and I'm wading through those now.
Part of that is to address several NEO Scavenger issues which were reported recently.
First of all, I tried loading a save file that required mods and it caused null pointers everywhere trying to load items that didn't exist in my vanilla game. This gave me a chance to patch-up some areas with better error-handling. I tried to add null-pointer handling code to each of these problem areas, so hopefully it'll reduce the number of random null-pointers we see in the wild (particularly with mods).
While looking into the above, I also noticed the way my mod remapper code handles gaps in IDs is bad. If there is a null recipe in the recipe list, for example, and the treasure table calls for a random recipe scrap, there's a chance it tries to load a null recipe's info, causing a null pointer bug.
I added some code in there to generate a "Missing Recipe" scrap in this case. This will prevent the null pointer issue, though reverse-engineering which mod caused it when the error occurs turned out to be trickier than I hoped. I wanted to have the scrap say, "Missing Recipe: FoD ID 38" but my remapper code isn't really designed to give the reverse-lookup ID :)
Anyway, the above fixes may clear up many of the issues players are seeing, particularly in mods. I'll probably sit on these changes a while longer in case others come up, and do a patch when enough have collected.
Overall, a pretty productive first day back! Not a lot to show for it yet, but quite a few things were knocked of my list. Hopefully, tomorrow will have more interesting prototype stuff to show off, and I can finally pare down the list of outstanding messages.