You are here

July 2016

Website and Mobile Work, and OOO

Hey Folks! Not much to report on the gamedev side today. Mostly spent time on website planning and mobile development. Though, both are approaching some really interesting milestones.

The website is now in the design phase, and we're going over font and color scheme treatments, and have most pages wireframed. Soon, we may start having some cool mockups!

And on the mobile side, Tiago is focusing on smaller bugs, as well as getting an iOS version running. It'll be interesting to see how it feels on a 10" iPad with a 4:3 screen, since all testing so far has been PC emulation, or widescreen Android smartphone/tablet.

Out of Office

Also, I'll be out of the office tomorrow until August 3rd, so my next post will likely be the 4th. I'll have internet access while away, and will try to check in periodically. Have a good week, everyone, and talk to you next Thursday!

Click to Interact and Launch UI

Hey Folks! Finally got back to some gamedev today. I returned to work on the ship equipment UI system, and I think I have a working prototype now, albeit with minor issues to sort out.

Basically, I've setup a way for the game to launch different UIs based on what the AI is doing at the time. This is the precursor to controlling important ship actions using the crew.

The way it works is that the player left-clicks the crew they want to use, then right-clicks the target item. The game will first check for any valid interactions between the AI and the item. If it finds one, it'll check to see if the AI can pathfind to that interaction's specified point on the ship (usually next to the item). If that passes, the AI is ordered to walk to the item and the interaction is queued for when it gets there.

If that interaction has a GUI specified, the interaction will raise that GUI with any parameters that were specified in the interaction's data. These params will define things like label names, min and max values, and probably, which items and stats to connect to which UI elements.

And so far, it works! I have a simple charge meter UI setup for the battery, and choosing an AI and then right-clicking on the battery causes the AI to walk across the ship, opening doors as needed. When it gets to the battery, a charge meter opens on the screen, showing real-time battery charge. Pretty cool!

Of course, it has some kinks to work out. For one thing, the UI appears as the AI is finishing the interaction, instead of when it starts interacting. Also, the UI never goes away. Also, the UI is just the first valid interaction, and should probably have some list of options present for the player to choose from (in cases where more than one UI is possible).

Also, as evidenced in this discussion from an earlier post, I have a lot of thinking to do about how the player controls the crew.

There are pros and cons to each approach, and likely, I'll have to try them out to see which feels the best. For now, the easiest will be to have the AIs autonomously self-care (i.e. eat, sleep) but have the player direct them to do more complex stuff (e.g. steer ship, change life support settings). But there may be compelling reasons to make the AI handle those more UI-centric tasks, in which case I'll need to work on a way for AIs to do these widget tasks.

Anyway, progress! This is a subtle upgrade with serious power potential. Lots of cool shipboard items to interact with through widgets now!

Epic Paperwork Continues

Hey Folks! Hope everyone had a good weekend. We're gearing-up for a camping trip later this week, so we broke out the tent and took a test nap in it. Looking forward to getting some not-computer-time :)

The parade of paperwork continues this week, as I resume transferring distribution and licensing agreements from my old personal business to the new LLC. Plus, it turns out Seattle-based LLCs have some really nice bonus features, such as State and local tax filing, business licenses for each, and other LLC requirements. I may even have to get new business cards and letterhead to protect the liability shield the LLC provides.

This is how bureaucracy spells F-U-N!

Needless to say, not much excitement to report. I think I might be able to squeeze some dev time in again tomorrow, though, so hopefully more then!

GUI Baby Steps, and Business

Another mixed dev and business day. Though, I had a special treat today!

I had a nice lunch with another indie who used to work at BioWare with me. Over beers and lunch, we chatted about such things as Pokemon Go, sales tax, indie publishers, motivation, and our current projects. We also had a really interesting talk about procedural drama. Dusty had some really cool insight into ways to string together characters' stories, as well as persistence of personalities and named characters vs. strictly procedural characters. Food for thought!

In the dev time I had this morning, I tackled a bit more of the item GUI system. I think what I'm aiming at is a system where each interaction has an optional "RaiseGUI" property. If the player selects an AI that's in an interaction with this property set, the game will show that named GUI. The widgets in that GUI will be wired to in-game data through the interaction's settings.

So if Akiko interacts with the battery using the "inspect" interaction, it can have "RaiseGUI" set to show a meter, and the meter's value will be set to the battery's current charge. So far, this seems pretty easy to do with some data files and Unity's component-based architecture. We'll see next week!

Lastly, more business stuff. Now that I'm incorporated, I have to update all of my distribution agreements with Valve, GOG, etc. So lots of paperwork to rifle through. Fortunately, it's pretty straightforward stuff. Just takes a while to sort out.

Anyway, that's all for this week. Have a good weekend, all!

Equipment UIs, and Business Stuff

Hey Folks! Short dev day today as I had to take care of some business banking stuff. But I think I've figured out where to "jam" next: equipment UIs.

Part of the experience I want to give players in this space prototype is the joy of flipping switches and turning knobs that actually mean something in the game world. I want them to enjoy examining the controls like the owner of a new car, and design/choose ships based on their "feel," and not just stats. Manual override on an airlock is actually by the airlock, not some translucent menu floating in one's field of view. And like Ripley in Alien, if you're going to self-destruct a mobile factory, you'll have to navigate the annoying self-destruct sequence through a series of failsafes, not just through a cascading on-screen menu.

For this to work, AI is going to have to be able to raise a UI when interacting with an object. E.g. if it goes to the ship's helm, it'll show the helm controls. If they approach the navigation console, they'll see the System map, orbital projections, and possibly RADAR/LADAR readings.

To work towards this, I setup a simple bar meter UI to see if I could attach it to the battery to monitor charge. And without too much effort, that's up and running. It's hooked up to a debug hotkey, and has lots of hard-coded values, but it works.

The next step is to find a way to launch the GUI when the AI reaches a control panel. And I'm thinking this will be in the interaction system. I.e. the interaction should have an optional UI it raises while running, and that UI closes when the AI finishes the interaction.

This raises a few questions, though. For one thing, what's the AI doing when using the UI? Can the AI bail out before the user is done with the UI? What if the user switches AIs?

Also, how will UI layouts and data-mapping work? If I want a UI to monitor temperatures around the ship, how to I define all the gauges' positions on-screen, their data sources, and what various buttons and knobs do when clicked? Making stuff data-driven isn't too hard, but what data format to use so it doesn't get too complex is a harder question. Especially for something like this. Which is complex :)

Anyway, that's where I'm headed next. I'll start simple, and hopefully some patterns will emerge that show me how to solidify the system. More on that later!

Batteries Working

Hey Folks! Got the batteries working today. And also a slight change to the power transmission system.

Yesterday's post prompted some useful discussion of the power system, and Malocodor's suggestion turned out to be a better approach than mine. I originally had each of the powered items check surroundings and try to draw power from them, and each of those surroundings would chain-request power back towards the source. This worked, but required the system to re-check each request.

Malocodor's recommendation was to instead map out all the power connections once, and just update it whenever conduits are added or removed. This way, powered objects just checked their last known connections without all the back-tracing. And since I already had a lot of the grid-walking code to trace rooms, I could easily make a tweaked copy to trace conduits.

And once I had setup the air pump to use power, it (correctly) stopped operating since none of the connected conduits had power. Time to add some batteries!

Yesterday's post showed the battery art I added as a placeholder, so the bones of the item were already done. All that remained was to setup the various properties on the battery to make it store power. Namely, it has a stored power limit and some placement rules that prevent stacking, etc.

Then, it was just a matter of hooking up the air pump and battery with appropriate stats. Since I'm trying to be near-future, hard sci-fi, I want the numbers to make sense. So as a baseline, I'm going with some current-tech values for things that NASA and industry use. So the battery is assumed to be a big nickel-hydride bank, like NASA uses. And for the in-game size of about 0.25 m3, that means it stores about 41kWh.

Similarly, a typical, 2-stage vacuum pump used industrially consumes about 100W. So each time "use power" is triggered, I made it consume 0.1 kW. Hooked up to the above battery, it'll run continuously for about 410 hours, or 17 days. I have no idea if that's accurate, but it seems reasonable at first glance.

Then, it was time to try it out. And I'm happy to report that it seems to work! Cutting down the battery capacity for testing to last about 15 seconds, I saw the pump run for 15 seconds, then cut out. And when I added a second battery to the network of conduits, the running time capped at 30s.

Mission successful! Probably some bugs yet to find, but good enough. Jam on!

What's next? Currently, I'm leaning towards item UIs. Each item that the AI can interact with is probably going to have a UI the player can tinker with to make stuff happen on the ship. E.g. AI can sit down at a nav panel on the ship, and it opens a UI where the player can plot their route. Or an AI standing at the outer airlock control panel can control pressurization to exit/enter the ship.

The idea here is that pressing buttons, looking at meters and flashing lights, and throwing switches that actually do stuff can be fun. Won't know until we try it, though!

More Power!

Work continues today on the power system.

I think I've got a working set of code to emulate power needs on a ship, and I'm now in the process of filling-in some content to test it. And since seeing it makes it easier to explain, here's what I have so far:


Comes in trusty Weyland Yutani blue!

The above room is a continuation of the air pump simulation from a few days ago. To recap: an air tank (orange cylinder) is to the right of an air pump in the wall, which gathers gas from the room to its left, and pumps it into the tank. The new part are the snaking blue conduits and the battery in the lower right (below the light).

As described yesterday, ship items are going to need power, and to get it they'll request power from points specified in their data. If the thing under that request point has power, it's delivered to the requester, and it runs for one more turn. If not, the requester shuts down until it can have its power needs fulfilled again.

In the example room above, the air pump needs some kWh per "turn," something like 1 kW/h. So when the pump is ready, it checks its nearby points for power input. Assuming one of those points is the tile to the right, we find a conduit, air tank, and floor there. Since the conduit is the right type, it tries to get power from that.

The conduit, however, has no power stored, so it requests power from its nearby points. Since this conduit is an "L" shape, it tries to get power from the tile "south" of it. That, in turn, tries to get power from the conduit to the right, and so on until we reach the battery. Since the battery actually has power stored, it deducts from its charge (if any), and sends a message back up the chain about how much it gave. Assuming we have enough to fulfill the pump's request, the pump triggers another "turn's" worth of action until it makes the next request.

So far, I think this'll work. It'll allow distant power sources to supply components around the ship. It also allows power to reroute around faults in the path, in case one of the conduits is damaged. More importantly, I'm hoping this will be one of the "fun" bits of ship building: planning system layouts, power needs, redundancies, etc. Then, setting the ship loose and watching it succeed, or more likely, fail.

Spectacularly :)

One of the risks of this system is performance. Each power cycle is a series of connection requests, possibly many for complex layouts. And this could eat into performance. However, I'm hoping that by keeping the rate of requests for power limited, it won't kill performance. E.g. if each item on the ship requests power once per second, that shouldn't be too bad. And if power fails on the ship, a 1-second lag time to shut-down of connected equipment won't be unrealistic.

The other, more scary, risk is that this won't be fun. I was reading Tynan Sylvester's AMA today on reddit, and one of the things he discusses is the core of a game's design. He warned against adding complexity to compensate for lack of fun, or not identifying the fun soon enough. He explained that core game concepts should be identifiable as fun early on, and can be reached by trimming out excess fat over and over until there's one irresistible experience.

I'm not sure that I'm doing this very well. I mean, I expect to enjoy this, but it's not enjoyable right now. Heck, there's not much to do besides build. And maybe watch funny AI bugs. It's no more a game than a Lego set. An unfinished, glitchy Lego set.

Then again, I think I'm building towards an experience I already know I like. Namely, Prison Architect or Rimworld within the context of a spaceship. It'll have differences, but a lot of the fun I have in those games is coming up with a new design for a prison/colony, and testing to see how well it works in practice. That's the core experience, and it may be that it cannot exist without a certain minimum number of interacting systems.

Which I guess Tynan also admits in his StarCraft example. One can strip out a lot in SC to reach the core, but the core still has several parts. 4 unit types, AI for the units, a map with resources, and an opponent. I can probably narrow down the number of systems I have to a minimum, and add code to test it with a crew in space. Maybe that should be a "game jam" goal I set for the near future?

Worth serious thought.

The Power Is Yours! Also, Sale!

Hey Folks! Hope everyone had a good weekend. Pretty low-key, here. Yard work, a park visit, Skyping with family. Maybe a quintessential summer weekend?

Back at the office, Tiago's shared his latest mobile port work, and still looking good! One of the bigger features he's working on is a zoom lens for making it easier to interact with tiny objects/UI items on small screens (or for those of us suffering from "fat finger"). This will also be a chance to look at the context menu and pop-up tooltips for things, and hopefully make them all play nice together and make the users' lives easier.

On the space prototype, I've decided to try tackling power as my next task. Ship equipment is going to require power to work. And though the gas stuff I added has many similarities with power (drawing from a source, depositing in a destination, and changing status based on whether any is available), it's different enough to warrant a closer look.

The current thinking is that I'll be doing everything in Watt-hours (or kWh, or MWh), since that's a pretty universal measure of a machine's power needs. Batteries will store kWh, machines will consume kWh while running, and generators will create kWh while running.

That can all be done using the ICS stat system, so I'm not too worried. The trickier part, though, is transporting power from the source to the destination. How will a player be able to define which areas of the ship are powered? And how machines get their power from local surroundings? If a chunk of the ship is damaged, which things lose power?

For that, I need some more spatial code, like the gas stuff. And since power travels differently than a gas, it'll probably use separate (but similar) special code.

So far, I'm working on a system where objects can have two points specified: a point from where they draw power, and a point to which other, downstream things can tap for power. Only the first is required for powered objects. The latter will be optional. Sort of like this:

source A---object1---B A---object2

The source will generate power, object1 will grab power from point "A" which overlaps the source, and object2 will grab power from object1's point "B." I'm hoping that this allows for a variety of powered system designs. E.g. object1 could be a simple conduit with input and output points, or it could be a working machine that has a way to transmit power downstream, like a daisy chain or string of lights.

Or so goes the theory.

Also, in case you missed it, NEO Scavenger's on sale again. This time, at the lowest price since launch: -75% off!


And it comes with a Steam key!

When purchasing, you can choose how much to pay, with a minimum of $3.74 USD. You can also choose to give 10% of the purchase to the Child's Play charity. Plus, you'll be supporting Indie Game Stand, who are all-around good folks.

So as usual, if you've been holding out, now may be your time :)

Air Tanks

Hey Folks! I think I've got the air tanks up and running now. I spent most of the day fixing up the code for gas pumping to be compatible with both rooms and items, and then setup an "Air Canister" item to test pumping gas into a non-room item. Here's how it looks right now:


Like a colorful tax rate table.

In the screenshot above, we're looking at a couple of rooms separated by walls and doors, an air pump, an air tank, and our trusty crewman Mann. Each grid tile has a debug overlay to help me see partial pressures of each gas present, so that's what all the numbers and red/green tint are. (Green means pressure is close to atmospheric, or breathable. Red means near vacuum.)

The air tank is the orange circle with the white bracket around it, in the "red" room. Immediately to it's left is an air pump in the wall drawing air from the room to the pump's left ("orange" room) and into the air tank on its right. Mann is standing in the "green" room, which is sealed off from both the red and orange rooms.

There are a few things going on here.

First, you can see the pressure is high in that air tank. The numbers are partial pressure of each gas in kPa, and atmospheric pressure is 101.3 kPa. So that tank is quite a bit higher than normal air pressure on Earth. Though, probably still only about half of an industrial air canister pressure when full.

That air tank is being filled from the orange room. It was originally higher pressure (like the green room), but has been sealed off with the pump running a few minutes. Given enough time, the orange room would turn closer and closer to red, though probably never reaching it due to diminishing pump performance at low pressure.

Speaking of red, the red room is a total vacuum, and is demonstrating that the air pump and air tank are sealed off from it.

Finally, we see that the pressurized rooms have mostly N2 (nitrogen), some O2 (oxygen), and trace CO2 (carbon dioxide). When the simulation started, I pumped in roughly Earth-like atmospheric constituents (so about 80/20 N2/O2). All of the CO2 you see in the image was generated by our trusty windbag, Mann. Given enough time, the ship's air will have more and more CO2 and less O2. That's where future equipment will come in, such as CO2 scrubbers, ducting, and either O2 reservoirs or O2 generation beds, to create a life support system (at least the breathable component).

The question now is, what next?

I see a few options. I could go ahead with the aforementioned life support equipment to try and create a closed system. I could also start thinking about power and electricity for the systems, and how they interact with that. There needs to be some new data added to handle asphyxiation in crew (and what happens when a crew dies).

There are also higher-level systems I haven't touched yet. I want there to be a console the crew can interact with to load a UI for navigating the Solar System. And for that matter, a system to open a UI based on crew interacting with it.

So lots to choose from. I'll let that stew over the weekend, and see what I'm leaning towards on Monday. Until then, have a good weekend!

Air Pumps, Respiration, and Filters

I did some refactoring today, to try and get the recently-added respiration code to work for things like air pumps and filters, too. I think I've got most of the code and data for it in place now, and I'm in the process of debugging it.

Basically, I took all the remaining gas functions and stats and moved them from Room to Condition Owners (COs). The idea is that life support systems will need to pump gas to and from ship equipment (like O2 canisters). And since equipment and rooms both have COs attached to them, I just made those the home for all that logic and data. COs are getting a bit heavy, but I can optimize and organize later.

So now, my COs have a few tools in their tool belt for managing thermodynamics:

  • GasExchange() - takes params for point A, point B, and flow rate. The function looks for rooms at A and B, and performs a gas exchange between them as if there is a giant hole between each. The flow rate controls the rate of exchange, so it's possible to slow or speed the equalization, if needed.
  • TempExchange() - like GasExchange, except it equalizes temperatures between A and B over time.
  • GasRespire() - Takes a huge param list defined in a new data type. Basically, this handles the transfer and/or processing/filtering of a single gas within a mixture. Things like a human breathing O2 and exhaling CO2, or a CO2 scrubber pulling CO2 from a gas mixture. Source and destination for gases can be either a room or CO (like a canister), and is defined by filters and coordinates in the param list.
  • GasPump() - Like GasRespire above, except is does the entire gas mixture and no processing/filtering. Basically, just moves gas from container A to B.

Together, this should cover breathing, leaks, room atmo mixing, scrubbing, filtering, and just about any other gas process on a ship.

I'm also hoping that this is a good starting point for interoperating ship equipment. In theory, this could allow a chain of rooms and COs to function as a complex machine. Room A could feed an air pump which moves gas to an adsorbent bed for scrubbing CO2, and another air pump pulls the scrubbed air into room B. And since the scrubber would use GasRespire() to pull CO2 out, it could be setup to gradually increase a "saturated" stat on itself each time it activated. Once this "saturated" stat reached a threshold, the scrubber would shut down or lose efficiency.

In other words, we may have our first ship repair situation! Granted, it's pretty janitorial in nature. But hey, blue-collar sci-fi isn't exactly glamorous :)

Breath of Fresh Air

The AIs are finally breathing!

I tried the "just game jam it" approach today, and so far, it's paid off. I now have a respiration command I can attach to my condition owners (COs) that lets them take a gas from the room, use it to pump up one of their stats, and expel another gas in its place. And the data files can control which rooms the gas comes from and goes to, which gas to use, the volume of gas to process, and the conversion rate of the gas. Those last two are useful for making the breathing process scale with gas pressure/concentrations, and modeling inefficiencies.

So now, I'm able to plop an AI into a room, pump it full of N2 and O2 at air-like proportions, and watch as the O2 partial pressure ticks down slowly, being replaced by CO2. Neat!

In the process, I also had to setup the network of data files for things like breathing stats, timers, and critical conditions (e.g. hypoxia), and they seem to be working correctly. Nothing fancy yet. The AI doesn't dramatically keel over when asphyxiated. But the chain of "bad-to-worse" conditions for not getting O2 are there and working, just like hunger would in NEO Scavenger.

It's not the most extensible code, but it works. And it has a lot of flexibility. So score one for game jamming?

In fact, my next task, air pumps and filters, may already be partially done since the function above is customizable. Air pumps need to move air from point a to point b, and are more or less effective based on the pressure of the source container. The above breathing function already does that. And if I choose the output gas to be the same as the input, it's basically just a pump. And if I wanted to make it a filter, I could make the output gas a nonexistent one, so input gas gets converted to nothing (and using the condition stat build-up, maybe I could convert the filter/scrubber to a used version that needs to be replaced by crew).

So far so good, but there are a few catches.

First, pumps work on the mixed gas, not just a constituent of it. I could work around this by just calling the pump command for all possible gases, but that's a bit inefficient (and hard to maintain). I could possibly add a parameter to the breathing function to work on all gas and not just one.

Another catch is that not all gas is going to come from or go to a whole room. There are going to be containers to store gas, and more than likely, there will be multiple of these in a single room. (Otherwise, there would have to be walled rooms for each container, which is a huge waste of deck space.) The breathing code could be made to check input and output points for containers first, and if none found, then use the room.

Finally, I'd have to tweak a few parameters in the code so that it is more customizable. E.g. the pump needs to add or subtract stats, not just subtract, the stat to be changed needs to be exposed as a param, and the timer condition that triggers it would need to be a param. These last few are easy to do, but do inflate the function param list quite a bit.

This is pretty doable. But the other approach might be to just have a separate pumping command. It just feels weird making it separate when so much of it is identical code.

More than anything, though, I should probably sort out that container issue. That seems like it's the biggest unknown in terms of architecture, and if solved, also opens up the most useful options. (E.g. more complex ship machinery, like water systems, propulsion, reactors, etc.)

More on that tomorrow. Have a good night, all!

Hard-Coded Thermodynamics

Hey Folks! I went ahead and hard-coded the gas exchange stuff today, as mentioned yesterday.

Basically, I removed the special "Door/Portal" class from the game, which previously handled gas exchange, and just made Condition Owners (COs) able to do this instead. They now have a list of "Update Commands," which are basically just function calls with parameters that are in the data definitions for each CO. Surprisingly, it wasn't hard to swap out this old code for new, and the room gases were updating normally again pretty soon after. It's even more extensible now, since it allows the data to define input and output points relative to the CO, instead of assuming hard-coded tile positions for the Portal/Door class.

I then set about coding a bespoke function for respiration, and quickly bogged-down again.

At first, I tried to make this generic enough to handle both breathing and air pumps. However, I soon decided that these were different enough that I should just make this first one breathing-only. That helped for a bit, and I was able to code the parts where it takes in a volume of gas, and based on room pressure, would figure out the partial pressure of the desired gas being inhaled. It then removed that gas from room A, and deposited the same amount of a different gas into room B. All stuff the parameters would control.

Unfortunately, I got stuck in the middle of these two pieces, where the inhaled gas is applied to the CO (e.g. a crew). Do I just add an equivalent amount of O2 to the CO's stats? That'd probably work, but how would it handle other gases? What about toxic gases, for example? Should I write this function to specifically check certain gases that have an effect on crew? Does that mean this function is only used by crew? Should I just have the function iterate through all gases present, try applying them to CO stats, and let the CO sort out which it accepts?

And how does this all relate to air pumps, which basically take everything in room A and pump it into room B? And for that matter, what about filtering/scrubbing air?

Paralyzed by thought again. I'm thinking the best approach is to "just game jam it" and worry about it later. But I think my brain was so fried by this afternoon I couldn't even do that. Hopefully, tomorrow is better.

Management, and Simulation Thoughts

Hey Folks! Hope everyone had a good weekend. Pretty low-key here. Though, we finally got a new bed. Yay! No more sleeping on layers of scavenged mattress topper foam and a box spring! I know, I know. How un-NEO Scavenger of me. But it was finally time to have a grown-up bed :)

Most of today was non-dev stuff. I spent some time meeting with the web developers, who are now about to start the visual design phase of the new site. We discussed colors, fonts, imagery, and navigation metaphors, and I'm excited to see what they come up with. Priority #1 is still usability, so simplicity will win over flashiness. But I'm hoping we can have both.

I also caught-up with Tiago's mobile port work, and it's moving along nicely! He fixed some major issues in the map, battle system, and even save files. It officially saves non-Flash cookies now! Well, the files are still .sol files, but no longer in the precarious Flash cookie folder. They now live in the user's AppData folder along with other real-live app data files, so are safe from cookie-cleaners. We may have a non-Flash PC version yet!

On the space prototype, I picked up where I left off working on the air pump data, and I'm still unsure if it'll work as intended. I'm starting to think this may be a case where I should just do it the cheap way and have hard-coded bits for things like air transfer, pumping, heating, etc. Like the room gas exchange is now. Trying to make this use the interaction system exclusively is getting out of hand and confusing, and maybe the interaction system can have certain keywords that spawn hard-coded functions to do complex stuff like this.

NEO Scavenger did this a lot with the conditions calling functions in the code by using keywords. I originally thought I should move away from this to enhance moddability. But I'm thinking some of this stuff is basic physics, and shouldn't need to be changed by data.

Also, the game may never exist if I try to make everything too perfect and extensible. Remember "game jam mode," Dan? Get on it!

Respiration, Air Pumps, and Partial Pressure

Hey Folks! I think I got the partial pressure stuff from yesterday figured out.

It turns out the error I was seeing yesterday was due to the way I derived room pressure after exchanging the gases and temperatures. The underlying molar gas amounts were accurate, but the pressure resulting from them was being calculated incorrectly. After some fixing, I was finally seeing rooms equalize pressure after a few seconds of being exposed to each other.

Once that was done, I could add O2 to atmospheric pressure in room A, and N2 to atmospheric pressure in room B, and open the door to watch them mix. Depending on the sizes of rooms A and B, the final partial pressures would differ, but the overall pressure in both rooms would remain atmospheric pressure (since both rooms started at that overall pressure). A bigger room A would mean the resulting O2 partial pressure is higher, while a smaller room A would be lower.

This, as a result, meant I could have AIs interact with a room, and depending on the O2 partial pressure, they could "breathe" more or less O2. If the "breathe" interaction took place in a room with 50% normal O2 partial pressure, it would only be 50% effective at maintaining O2 levels in the body.

So that's sorted, in theory anyway. I have yet to test it, but I'm pretty optimistic it'll work.

What concerns me more, however, is life support systems. They do something similar to the AI above and also have to move it around between rooms. And air pumps process a certain volume of air per unit time, not a certain molar amount. If they gobble up a liter per second, for example, that liter is either full of gas (pressurized room) or empty (vacuum). Running a pump between empty rooms does nothing, so the interaction it uses to gobble air from source and pump to destination needs to move a variable amount of gas moles depending on pressure.

Furthermore, since I have mixed gases now (e.g. N2, O2, CO2, and maybe others in the future), the interaction needs to grab moles of each constituent gas in proportions relevant to their partial pressures. After a bit of rubber duck debugging, I thought I had sorted it out. I figured I could just make the interactions reply with a number of moles guaranteed to exist in a room based on current partial pressure.

However, this turns out to be trickier than I realized. The variable size of a room means I'd have to limit my air pumping to the number of moles expected in a 1x1 room, because anything more might violate the conservation of matter.

Of course, I still have access to actual molar amounts of each gas in a room. I could probably leverage those in some way to make sure I never get more than they'd allow.

It's doable. I don't have a firm grasp on it yet, but I think all the pieces are in place. Everything except a fresh brain, that is :) So I'm off to rest it for a couple.

See you Monday!

Partial Pressure Partially Working

Hey Folks! Today I dug deeper into the system I spoke about the other day. The one where the AI can interact with gases in the room to simulate breathing, asphyxiation, and gaseous poisoning.

The theory was that I would have my AIs execute a condition periodically that checked the current room for gas levels in O2, N2, CO2, etc. If those levels were normal, the AI would be fine. If they were wrong, the AI's bodily O2 stat would deteriorate until they became hypoxic and eventually died of asphyxiation. This stat stuff is pretty easy to setup once reasonable values are figured out (through research).

The trick, however, is that mixed gases are a whole new ball of wax. My old code did a good job approximating gas exchange between rooms when that was just a single gas type. But if you have one room with CO2 and the other with an N2/O2 mixture (typical spaceship atmo), that's a slightly more complex problem.

Though, not too complex. At least in theory. Basically, the thermodynamics of gas mixing can be pretty easily treated as if the individual gases from each room's mixtures were expanding into the new combined rooms' volume. The aforementioned CO2 and N2/O2 rooms would just need to do three calculations each: one for each gas.

Okay, not too bad. I just have to change my single-gas calculations to instead use a list of gases. An hour or so of work took care of that.

Now, however, I think the room gas exchanges seem wrong. They still mix, and the overall pressure between them equalizes. But not totally. They seem to reach a point where one room has a slightly higher pressure than a connected room. So I need to figure out why.

I'm also thinking that the room will need to calculate some sort of per-gas partial pressure stat so the AI can correctly track how much O2 (and other gases) it is getting each interaction. If a huge room and a tiny room both have 50 moles of O2, that means very different things. One room has a high pressure, and is breathable, while the huge room would likely be near vacuum. And even though I have overall pressure tracked per room, this doesn't tell me what fraction of the atmosphere is O2 vs. other gases. It can be calculated, though, and perhaps the code I have to calculate overall pressure needs to be split into per-gas calcs just as the gas transfer code did.

I'll look into that tomorrow.

Certificates, Profiles, and Provisions, Oh My...

Hey Folks! Today was sort of a mixed bag of administrative and development tasks.

The admin stuff largely consisted of getting an Apple developer account setup for testing mobile games. And let's just say it's not a straightforward process. So far, I've had to:

  • create a developer account
  • register for a D-U-N-S number (and wait for them to process the request)
  • create certificate signing request
  • create multiple certificates for development and distribution
  • install certificates into my keychain
  • register the device UDIDs I intend to test with
  • install XCode on a Mac to get Intermediate Certificates
  • create app IDs
  • create a provisioning profile for both development and distribution

Thankfully, Tiago's been through this before and was able to direct me to a tutorial. Though I pity anyone who attempts to figure this stuff out on their own. It's a wonder any apps appear on the App Store!

Once that and some CRA and Dept. of Revenue tasks were completed, it was time to dig back into the prototype!

I warmed-up by fixing a bug left outstanding from last week. Doors were stealing selection focus whenever an AI opened them, and I had to change the code to only update the selection bracket if it was already on the door. (This was mainly due to doors changing models when switching modes.)

After that, I started working on code to let AIs and other objects perform interactions on rooms, and not just other AIs and objects. Basically, I expanded the interaction target from self = true/false to a list of possible target types, including self, others, room, room north, room south, room east, and room west.

The new room target types refer to either the room belonging to the tile below the AI/object, or the room attached to one of the tiles surrounding the AI/object. "North" means towards the top of the screen, "South" to the bottom, etc.

In practice, I'm hoping this will allow me to add interactions that the AI can use to breathe, heat/cool, absorb radiation, etc. For breathing, an AI would exchange gas with the "room" belonging to their current tile. Meanwhile, HVAC units could interact with both the "North" and "South" tiles' rooms. Perhaps pumping fresh O2 from a duct into a room, or CO2 from a room into a duct (with the ducts connecting elsewhere to processors). Similarly, heating/cooling functions could be modeled through directional room interactions, so objects can act as heat pumps.

In theory, anyway :) We'll see as the system develops!

NEO Scavenger Mobile Bugs

Hey Folks! Hope everyone had a good weekend. I neglected to mention Friday that this was a long weekend due to the holiday yesterday. Sorry! We didn't get to see fireworks yesterday due to a certain sleeping baby. However, she did afford us an excuse to go watch some planes landing at Boeing Field. Including a B-25 and P-51! Big, rumbly, WWII engines are cool.

Today was a non-dev day. However, it was actually pretty productive. I wrapped-up a bunch of art assets in a zip file for the web developers to look over, and then dove into NEO Scavenger mobile.

Tiago's got the app running for the most part on all devices, and we're now approaching the final stretch. Woohoo!

Current priorities include:

  • Fix the battle screen missing move choices.
  • Figuring out how to deal with different UI sizes and fonts.
  • Figuring out how to deal with small items and fat fingers.
  • Fix items not lining up with slots sometimes.
  • Fixing map alignment on some devices.

Plus, a range of more minor issues. We still have a way to go yet, but it's starting to act like a real game!

AI Using Doors; Room Atmo Using Condition System

Hey Folks! More progress today on the latest two additions to the game. And while the work doesn't include new systems, it goes quite a way towards making both of these game-ready and interactive.

First, I finished up getting the AI to work with doors. AI now can pathfind through closed doors, and if a closed door is in the path, the AI will stop, interact with it, and wait for the door to open before continuing. And in theory, the doors should adhere to all the usual interaction rules, so AI's shouldn't run into issues of both using one at the same time, etc.

There were a bunch of issues that needed fixing to get this to work, such as checking if the door is busy so AI doesn't spam open interactions on it, cleaning up old door objects when they switch (closed vs. open), and moving the UI bracket from deleted objects to the new one.

Once that was done, I started thinking about how the AIs (and eventually, other ship items) are going to interact with room gas, temperature, and pressure. Since each of those values were just numerical properties on a room, the interaction/condition system (ICS) didn't really see them. And I was reluctant to hard-code the ICS to affect those values, since the list would likely grow.

Instead, I think I found a way to convert the rooms to take advantage of the ICS by giving each of them a "condition owner" (i.e. thing that has stats and conditions and can interact). Then, each room could be given condition stats for gas amount, temperature, and pressure. AIs could then interact with the room, and depending on the room's stats for gas, temperature, and pressure, the AIs could be affected for better or worse.

For example, AI might have some reservoir of O2 they can survive on for up to 3 minutes. Each turn, that AI interacts with the current room to see what the O2 levels are. If the O2 levels are normal, nothing changes. If the O2 levels are too low, that reservoir depletes. And as it depletes, that AI goes through stages of hypoxia (similar to how hunger works in NEO Scavenger). If the O2 levels return to normal (or AI enters a room with O2), that AI's O2 reservoir stat would slowly tick up.

I think the same could be done for temperature and pressure, as well.

I think the only tricky part here will be some of the code glue to make these pieces stick together. I'll need to add some way for AI and other condition owners to get access to the room condition owner in order to interact with it. So the current method of searching for condition owners needs to include rooms now (instead of just AIs and shipboard items).

Another tricky part is keeping the complicated math out of the ICS system. Room-to-room gas transfer and temperature propagation is probably doable using ICS, but would be terrible to maintain. Instead, I'm going to hardcode that transfer rate stuff, and store the results in the ICS conditions. This way, AIs can still access the data, but the math for it is done in faster (and easier to maintain) code.

Some questions still remain, such as partial pressures for things like O2, CO2, CO, and other contaminants. I want there to be fouled atmo in certain rooms if the life support stops, or a fire breaks out. Simple gas pressure and temperature isn't enough, even though both are important to survival. Ideally, rooms would know how much of that pressure is O2 vs. other inert or toxic gases.

Probably doable, but I just haven't looked into it yet. I'm guessing the room will probably have its custom gas exchange code process all conditions with a certain prefix like StatGas___, and use that to total the overall pressure. Then, the ICS kicks-in when the AI needs to know about O2 and other specific gas amounts.

Anyway, enough about that. It's officially beer o'clock on Friday. So I'm going to go attend to that need :) Have a good one, all!