Last essay I posted about how we might think of using the power of a linear RPG in a nonlinear way: we can use predefined arcs to strongly seed random content. I got a fair number of people saying "how?", which is not surprising because my explanation was "It's easy... (There, I just cut twenty pages from this essay.)"
Well, here are those twenty pages.
We need to generate random content as the player explores, but the issue is that we're not really trying to create "a random dungeon". Each content chunk that unfolds is huge and bombastic, in linear-RPG fashion. We don't enter a random level of a dungeon: we go to a whole new star system with a bunch of plot events woven into it.
This is both easier and harder. It's easier because this part is so much easier than generating random dungeons. It's harder because we do, eventually, have to generate random dungeons.
The heuristic for generating content is simple: while it can be largely random, it needs to "make sense" to the player.
One method of doing this is keyword filtering. So all the pieces we use (factions, types of places, scripted NPCs, events) have plus and minus keywords.
For example, a toxic jungle planet might have +colonize, +toxin. This means the planet generates those keywords.
By filtering to keep things matching keywords, we can link the planet to subsequent (or prior) pieces of content. When placing something on the planet, we would choose something that hits at least one of those keywords - for example, a new colony. It has the keywords +colonize, +economy, -monsters, -toxin.
The new colony matches the colonize keyword and conflicts with the toxin keyword, both of which are considered good things from a storytelling perspective. So we know that any quest lines involving the colony can "spread" to the wilderness of the planet either in alliance (+colonize) or conflict (!toxin), which allows us to generate minor sidequests such as "Go find toxin samples" or "go help our scouts look for more colonizable locations".
Creating a big list of such sidequests is pretty straightforward, and can use dangling dialog fragments that get hooked into whatever faction is involved. It doesn't much matter whether the colony is full of humans or elves or quarians - anyone can say "go find toxin samples" and have their combat units seeded into a generic map.
The key to this operation is that now there are more keywords in play. The planet alone only had two: colonize and toxin. Now we have economy and monsters as well, and can place elements that match any of those. This can be used for "large" pieces of content (an orbital trade station that has the +economy tag) or "small" content (a sidequest where a batch of monsters is discovered, but it's just a sidequest).
You can see how this creates a web.
Moreover, we've just been talking about places, but each place has to be inhabited by at least one faction, which grows the keywords even further. If it's a quarian colony, that's radically different from a human colony, and that will be reflected in the keywords in play, which in turn will change the sidequests you'll discover.
The quarian keywords are pretty complex, with tags like "+life-support" and "+scrounge". These keywords are unlikely to match very many big places, but they will generate sidequests such as "the life support is offline!" and "scrounge us up some stuff". They may also generate NPCs involved with those keywords, or sub-maps such as garbage depots and life support facilities.
These submaps and quests would feel random and arbitrary if linked into a human colony, since the humans exist to talk about underdog newcomers struggling to integrate. But those missions are core to the quarian experience, so it'd feel pretty good and suitable no matter the exact situation.
Subquests can involve just one place, but in general we'll want to create threads. We should engineer our subquests to do just that by having keyword-driven subquests that involve multiple places, probably all linked by the same keyword, although often inverted (IE, a +monsters and a -monsters location: monsters flood from one place to the other.)
Simple example: the quarians might have a life support problem at their on-world colony, but if there's also a quarian ship in orbit, they both have that keyword. We can use a two-site variant on the mission, perhaps "we need life support components from the ship" or "both have life support failing for the same reason" or even "the ship's life support is failing and we'll need to bring the crew to the colony as it explodes!"
(There's no reason a sidequest can't alter a location, either by destroying it, changing it to a different location, adding/removing keywords, etc. We just need to mark those quests with suitable dialog tidbits to make the player aware that they're about to Change Things and give them an option to back off for a while.)
By bringing multiple sites into a sidequest, we create a reason for players to move. Backtracking sometimes has a bad connotation, but in this case it's absolutely vital to provide a sense of place, a sense that things exist in the same world. Because of this, our sidequests should often have "feelers" written into them - for example, a human on the trading station above the planet might say "the colonists on the planet have been ordering a lot of toxin filters, but we're totally out..."
These can be opportunistic optional elements. IE, the sidequest is (1 +life-support location) with a bunch of keyword feelers for luring the player in, like (+economy: "Totally out of those toxin filters") and (+cutting-edge: "Our filters aren't compatible with their old junk...") None of the feelers is necessary: you can simply trigger the mission by vising the location. But they link the location to the rest of the universe and make it feel real.
That's the simplest secret: linking the random elements together to make them feel real. Whether that's by having missions that span several locations/factions or having a mission that simply gets mentioned in other places.
When generating content, it's also helpful to generate depth-first instead of breadth-first. That is, rather than generating each planet of the solar system, then generating the things on each planet, you should instead start with the most important planet, generate a location on it, generate sublocations for that location, generate a new location, etc. Then generate the next planet when that planet's filled up, etc.
The reason for that is the keyword density. If you generate all the planets without any subelements, each generated planet is only going to "read" the early planet keywords and the star system's base keywords. IE, things like "radiation" and "inhabitable", but not things like "scrounge" or "economy".
By generating the densest areas first, you allow the outlying locations to support them. By the time we get around to generating the moons of the gas giant, we have a big list of keywords. Populating the moon, we'll be able to filter for matches against existing content, giving us moon bases that support the overall arc of the core content. IE, we'll have a moon base related to economy or life-support or whatever, rather than just a random generic moon base.
Visiting that moon base will show us a small selection of sidequests related to the specifics of the base (+economy: "Get two corporations to play nice together", +economy: "pirate attacks are interfering-->moon base destroyed"), but also a bevy of feelers reaching out to content in other places ("The colonists keep ordering toxin filters, we're out of them!", "I've heard there's monsters on the planet, big things." "Man, did you hear about the derelict they found in the asteroid belt?!")
Well, there are a lot more details involved in actually implementing that system, such as determining what kinds of content can exist within what kinds of content, how to cram actual maps into those spaces, how to convert maps from combat mazes into walkable areas and back, etc. But hopefully you have the basic idea: it's all about keywords and piggybacking those keywords to connect objects.
I hope you get that, because we're going to kick it up a few notches.
One thing worth remembering is that we're fundamentally a linear RPG. The area the player can kick around in is targeted to a specific tactical situation, with specific ideal levels and equipment. The player will kick around that area as long as they want, and only let the game move forward when they want to allow it.
A lot of events and missions have outcomes that matter, at least a little. These things should be clearly marked so that the player doesn't accidentally stomp on their own stomping ground. For example, if the "failing life support" mission will result in the ship being lost, be sure that the mission start trigger gives the player an opportunity to back off.
But more than that, outcomes frequently trigger new missions.
This is important, because we want to present a specific (medium-low) sidequest density. It's possible to generate an infinite number of sidequests, especially when we have three factions in a location and the result is 15 different keywords. So... we lock some of the sidequests to keep the number the player is faced with under control.
The key here is that some sidequests have a notable outcome - for example, exploding the ship, or introducing a new keyword. These are good excuses to scuttle the existing sidequests and introduce the next batch. This can be due to the passage of time... or due to direct causality in the case of introducing a new keyword, even if the "new" keyword already exists.
For example, you go to the quarian colony. You fight monsters (+monsters), settle a zoning dispute (+colonize), and scavenge up mining rig parts (+scrounge). But when you decide to tackle the life support sidequest, you get a subtle warning, since you get the option to back out before you start. When you start, it turns out to also be affecting the ship above and, by the end, the ship has exploded and the crew has joined the colony (--> add +colonize). Scrap the leftover sidequests and introduce the next set.
Although the +colonize keyword already existed, now that it has be re-added, it's relatively easy to mark any new +colonize missions as resulting from that disaster, as described by dialog fragments in the disastrous mission. IE "We've been stranded down here, and it's been tough to keep things together..." then transition over to the new mission's dialog "... my child has gone missing, please find her!" Even if the dialog is a bit disjointed, it creates a sense of continuity.
This sense of forward progress is pretty tangible and fun, but even more important, it allows us to create a core arc for the entire content pack.
As I mentioned in the previous essay, your various main characters will represent core arcs. You may also have other core arcs that aren't character-centric, although you might not need them.
These arcs contain batches of content that get slotted into new content opportunistically. These create keywords before the content is even created to begin with, and that means the content will likely be created with those keywords matched in.
For example, Tali's working her way up her "quarian destiny" arc, and this particular event is about examining a new habitable world and seeing if it's suitable for quarians (and finding out it isn't). In addition to a bunch of specific content (maps, conversations, etc) it comes with keywords: +inhabitable, +toxic.
Well, we create the star system. Those keywords mean nothing to a star. We start to create the first planet.
We automatically filter for existing keywords, and we come up with a list of planets that are either inhabitable, toxic, or both. If we create a planet that is inhabitable and toxic, the quarian arc is confirmed and immediately slotted in, with any locations in the arc being instantly established as if they were randomly generated. This will, in turn, drive the rest of the system to create compatible elements and a web of missions that are properly themed.
If there never is a location with a suitable combination of +inhabitable, +toxic, the arc is left on the back burner and it'll try again later, maybe next content chunk.
We can afford to be laid-back about it because we probably have 4 or 5 arcs vying for our attention, and at least one of them is likely to find a suitable setup. We can even program the arcs to have flexible sub-events that can happen if we don't fill the main event, although the autogenerated events are probably fine.
The big advantage of arc events is when they get really involved and dominate the content. For example, near the end of Tali's arc, we have a dedicated location where we fight across a geth carrier group, and then after that another dedicated location where we go to Tali's homeworld and do all that stuff about hacking the geth and then fending them off, etc. While other random content may be wedged into the cracks, the majority of those locations are set in stone, and the progression should feel very consciously-chosen and solid.
One way to duplicate that feel is to have action setpieces - missions that end in epic encounters.
Many locations can have setpieces designed into them, and the setpieces can have a variety of zesty encounters programmed into them. Quests can opportunistically dump you into these setpieces for the finale, and they can be populated by the proper factions as required.
For example, a mining base might have maps for mines, refineries, corporate barracks, and a cargo dock. Each of those maps have setpieces: an underground rail system, an area full of conveyors and pouring molten stone, endless rows of destructable beds and tables, or a cargo ship desperately trying to take off.
Action finales are programmed into those locations, not into the missions that are climaxing. The underground rails normally feature track-switch puzzles, but in an action finale, it's a race through the dark while fighting off other cars. The refineries normally have the machine area blocked off, but in the action finale it's a battle across the conveyors while molten rocks splashes everywhere. The barracks normally feature a maze of flimsy-walled rooms, but in the finale it's about soldiers (or monsters, whatever) smashing down those thin walls and sending cheap furniture flying into heaps. The cargo area normally has a cargo ship sitting in it, but during the finale its turrets are firing and exhaust ports belching as it strains against the docking clamps...
Because these events are flexible, they can either be graded by impressiveness or have their impressiveness scaled to match the requirements. Every time a mission in a content chunk has a finale, the next finale should try to be one step up.
So if our first significant mission ends up in the cargo dock, the ship might be belching smoke and asking for permission to launch, but not actually doing anything substantial. But if it's the tenth significant mission, it'll be firing turrets, blazing the main engines, belching exhaust, and pulling around the docking clamp arms in dangerous sweeping patterns, maybe even on a timer.
Although there's no fundamental connection between the quests that cause the rising action, the fact that the rising action is rising should be enough to carry the content.
The question is: what's the transition to the next content? What's the final boss?
This would probably have to depend on your game, but my instinct is that there is a bank of generic content arcs, represented by a councilmember's interest in the location. Assuming there's no core character arc, a random councilmember arc is brought into play and serves the same purpose. These arcs are suitably generic, but always culminate in a final battle of some kind - for example, "exterminate the pirates in this region" or "find out if there really is an gene-smuggling going on" or even the innocuous-sounding "lay the foundation for a trade agreement".
Anyway, that's the bulk of the technical stuff I skipped over.
Let's see, the only things I can think of that I skipped are the specifics of the player's experience in each major content chunk.
Remember that this is a linear RPG and that grinding is a thing: make sure there are plenty of permanent enemy maps the player can grind on.
Also remember that missions can only take control away from the player when the player volunteers for it... but that they shouldn't feel shy about doing that once the player does! I gave an example about an exploding ship, but the same holds true for missions that split the party or force the player to crash-land for a while or blow up a world they used to visit or whatever.
The two biggest times the player volunteers are A) when they defeat the end boss and B) when they set course for the new star system. Therefore, the first mission of a content chunk and the last moments of a content chunk should take control away most aggressively, to show the coolest things and make the most important changes.
Showing posts with label technical. Show all posts
Showing posts with label technical. Show all posts
Wednesday, June 22, 2016
Friday, September 06, 2013
Clarity in Zero Gravity
(This is a long technical post)
As you hopefully know, I'm developing a thing called Astrophobia. It's a game about living on a space station, and it has relatively real-feeling zero gravity stuff going on.
The difficulty lies in what gameplay to create. See, the feeling of being someone stuck on a space station is pretty compelling, but there's no inherent gameplay in changing how the player moves around. It feels very different, but it affords no particular skill challenges. At least, not in any way I can make feel meaty and fun. Most of the actual difficulties of navigating a space station I've abstracted out, because you can't control a digital avatar to the degree required to make it truly realistic.
My original idea was to make the gameplay about creating and managing a space station that deals with vaguely real-feeling hard-scifi challenges, such as maintaining mining vessels or entertaining space tourists or serving as a deep space radio relay.
However, the creation of a space station is actually not easy.
Oh, the mechanics are easy enough. I've already implemented them. You can place rooms, work the systems, and so on. But in terms of headspace, it feels tenuous and difficult. The system I was going to use, which involves colored cables running through the base, is very hard to grasp from inside the base.
It would be quite simple to do from outside the base. Blueprints on a table, draw some lines, check some boxes. Easy to understand. The cognitive load is lessened by the use of tools. That is, the tool of a map.
I did implement a map in the game, and you can use it to build the base. But it feels... wrong. It doesn't feel like you're living in a space station.
After having actually "lived" in a space station - that is, having built a few in the game world and floated around inside of them - I can say that construction isn't part of the feel. Sure, maintenance, attaching things, detaching things - yeah. But actually commissioning new modules and deciding how fundamental wiring is done? That's not part of the experience. I should have realized it immediately, of course: that sort of design work isn't part of any "live in a place" experience. Living in a place is about living in a place, and designing is unrelated.
So I was thinking about breaking the game in half.
Designing a facility (or a module for a facility) is a huge amount of deep fun, and living in the thing you've built is a huge source of deep fun, too. So I really think that I need to split the game in two.
I'm thinking you've got the "living in space" section, but then you've also got the "ground support designing stuff" section. I like the idea of cycles, of a team living on a base for six months, then returning home. And you get to design the add-on or the next base that will be there for the arriving fresh new team.
I like the idea of making the designing of the facility feel as organic and real as living in the facility. To that end, I'm thinking of a design system that feels like pencils on graph paper. This sounds like a detail, but it's not: I'm talking about sticking the design to a 2D, line-centric approach. It feels fitting: the personal portion of the game extends traditional 2D into 3D, so it seems suiting that the traditional 3D designing tools are brought down to 2D.
This constraint isn't really a limitation so much as an advantage born out of the game's overall constraints. Space station modules are, fundamentally, a very constrained design space. For example, they are all basically tubes running along a given axis.
Let's say you want to design an inflatable hab. You could do this by simply choosing that material and drawing a line. Our graph-paper constraint understands you've chosen a structural material and want it to be that radius at those points, and you instantly have a fundamental structure for your module. If you want a rigid cubic tube, draw a line after choosing that, and you've got it. Draw BOTH, and you'll have an inflatable outer hab around a rigid cubic box.
Line controls exist to help you if you want straights, smooth curves, or mirrored modules, obviously. And adjusting them is as easy as grabbing the line and moving it.
Once the fundamental structure is laid down, it's a matter of putting in the things you want to put in. Here a simple, Kerbal-like method of lateral/radial symmetry can be used, or you can manually work with "the far wall" or "the near wall" to place objects that aren't mirrored. So if you want your inflatable hab to have soft beds in it, you can select them, pump the radial symmetry, and then click on the hab. An array of beds will be placed in a ring around the core axis. Exterior solar panels? Same thing, except they automatically get placed on the outside of the wall.
You don't need the added complexity of seeing the hab in 3D, at least not in the basic design system. You don't need to place beds by clicking in a 3D space. The design constraints of the module allow you to place the bed in 2D knowing full well exactly where it'll actually show up. Similarly, since everything needs to be attached to a wall, there's never any confusion about where it'll end up in space. Just cycle through the walls (two for our basic modules, four for our double-layer example) and whatever you place will be placed on that wall with whatever symmetry you've selected putting it in other areas as needed.
Then put in connectors of your choice so your module can connect to other modules. Design those, too. Send it all up at once, and the end result is that these one-axis simple-to-design modules end up as a catacomb of your own design. Which you then live in.
This very easy to use system can allow players to build whatever modules they need or want, and also allows for easy modding as people add more parts, ports, and structural elements. But is is easy to transition from the lineart design to a final, functional mesh?
Well, yes.
Many of the things you added are static modeled. The beds are not dynamically built, just dynamically placed and rotated.
The only mesh that has to be generated is the fundamental structural mesh. This isn't as hard as it sounds, though: create one "slice" of the material, correctly modeled and UV-mapped. Make sure it's got symmetric verts on each side. We can simply take that mesh and duplicate it over and over, each time lining up the left edge of the next bit with the right edge of the previous bit. Scaling up and down happens over the course of the mesh - if X is our spinal axis, then we simply scale all the verts towards the preferred scale depending on their X component.
The difficult part of the fundamental structural mesh is complex structures. For example, what if you want windows? What if your inflatable hab should have big plastic windows in it, ignoring radiation concerns?
The easy way to do this is to have different materials. You'd have three: an opaque mesh slice, a window mesh slice, and a transition mesh slice. However, this can get very complex if you want something like circular windows (rather than ribs that are windows). I think that freeform window placement is probably something to hold off on, but it probably wouldn't be THAT difficult to place them like beds or solar panels, except that instead of just placing meshes, they cut holes in the wall before placing their mesh.
With the technical concerns addressed (or handwaved), I can talk about gameplay.
Right now, I like the idea of having to live in the base for a specific duty cycle - three months, six months, a year, two years - it'll depend on what the player decides and the expense of switching crews, as well as the level of medical support available to the astronauts. However, because of that long timespan, the game obviously cannot be played entirely real-time.
I'm thinking that you can play as much as you like in real time, but there are various things you can do to enter an automatic time-advance. Sometimes these would be short - going to bed would advance you eight hours, perhaps. But they could also be long: simply clicking "go" on your weekly schedule could advance a whole week if nothing breaks in the middle. I want to reward time spent actually wandering the facility and living in it, so I think that "design research" points steadily tick up as you work in real time, second-by-second. Obviously this can be gamed by just leaving the game running in the background, but I'm not to concerned about that kind of exploit. There are plenty of tasks to do in real time if you want to - repairs, maintenance, EVA, even just eating or hanging out with other astronauts. Also, you can switch between multiple teams on multiple space stations...
Design research points are obviously spent in the design phase. I'm thinking they augment the idea of cash: you earn cash by having your space facility actually do something. The cash fee for sending up new modules (whether for a new station or to attach to an existing station) is simply based on weight, nothing more. However, every component has a design difficulty attached to it as well, and if you can't meet that fee, you can't figure out how to work it into the module and it doesn't pass testing. IE, you can't launch. There are obvious opportunities for tradeoff here, with something like a lightweight inflatable wall having a high design cost, but a heavy metal tube having a low design cost.
There might also be other kinds of resources, but we're not going to worry about that yet. That's for mods.
When designing a space station, you need to take into account how it's going to work and what it needs to accomplish. In the beginning that might be mostly just figuring out how to keep astronauts alive. But you'll need to expand. Support tourists, mining fleets, deep space probes, etc. All of these bring in the cash while testing your design capabilities. The more challenging variants don't require bigger stations, but better designs. Share designs with your friends, as well - even invite them aboard.
But when it comes to actual design, an important factor is how the station actually works. In order for a design to be "better" or "worse" it needs to be better or worse at something.
Previously I had designed the systems to be about consuming vast amounts of space, so spatial optimization (especially regarding material transfers) was the primary concern. However, with this refit that doesn't really suit. What I would like to do, if possible, is make it so that the individual modules end up really tightly bound together, so that you'll never really consider a module as a completely independent entity.
Let me start with the concept of a control panel. I like the idea of a clunky control panel for this system, rather than the adaptive intelligent computer system I developed. I like the idea that when you launch a module, you have buttons and levers and lights which represent different functions included in the structure of the module. You can transfer between modules, too - the hardpoints will have a dozen or so "wire" points which will count as contiguous when modules are connected.
In previous gameplay prototypes, it was about optimizing space with time, such that various operations might share the same space as long as they didn't share the same time. I think that's still valid, but it can't have the "pumping" feel because that relied on designing the spaces to interleave physically, which is not part of the new design system. Instead, I think the new system is going to be about managing degradation.
That is, you could run the smelter and the die-caster at the same time, but their combined smoke will choke your filters and their failure chance will spike. The vibration and heat will tax both your astronauts and the hab itself, causing slow leaks, cracked electronics, and so on.
I like this idea, because it highlights the joins between modules, giving you freedom to express yourself within a module, and then attempt to optimize how you put modules together and try to maintain them. Obviously, basic supply management is also going to be an issue... but within any one hab, the player should feel free to go with the specific design they feel happy with, rather than worrying that a cabinet is half an inch off of optimal. The pressures are on inter-module and supplies, not intra-module.
That said, controlling operations is going to be important, but it needs to be something which can be scheduled and worked through with an accelerated simulation, rather than painstakingly performed in real time each time. So my thought is that each piece of an operation is very well understood and you can literally schedule them by just dropping basic functionality ("turn on smelter") into a timetable. The controls which can perform that task are automatically detected, and the actual NPC activity which does those operations can be computed. "How long does it take Ralph to get from the smelting panel to the casting panel? There's an airlock in the way? Shit, I have to design this better, there's a wasted hour there..."
Of course, it can also be done manually.
One key left unmentioned so far is the idea of things breaking down. In my previous gameplay, that really wasn't part of the equation. But in this system, it's critically important, because breaking down is one of the major things that happens if you don't optimize well. Part of your design needs to take into account what happens when something breaks down - for example, is there a backup system? In addition, how easy is it to get to that system and repair it? Do you have replacement parts? These are questions that a beginner probably won't care about, but when you start to design large systems for smelting or whatever, it starts to be a concern.
Anyway, those are my thoughts on Astrophobia today. This weekend, I'll put together the module construction system.
As you hopefully know, I'm developing a thing called Astrophobia. It's a game about living on a space station, and it has relatively real-feeling zero gravity stuff going on.
The difficulty lies in what gameplay to create. See, the feeling of being someone stuck on a space station is pretty compelling, but there's no inherent gameplay in changing how the player moves around. It feels very different, but it affords no particular skill challenges. At least, not in any way I can make feel meaty and fun. Most of the actual difficulties of navigating a space station I've abstracted out, because you can't control a digital avatar to the degree required to make it truly realistic.
My original idea was to make the gameplay about creating and managing a space station that deals with vaguely real-feeling hard-scifi challenges, such as maintaining mining vessels or entertaining space tourists or serving as a deep space radio relay.
However, the creation of a space station is actually not easy.
Oh, the mechanics are easy enough. I've already implemented them. You can place rooms, work the systems, and so on. But in terms of headspace, it feels tenuous and difficult. The system I was going to use, which involves colored cables running through the base, is very hard to grasp from inside the base.
It would be quite simple to do from outside the base. Blueprints on a table, draw some lines, check some boxes. Easy to understand. The cognitive load is lessened by the use of tools. That is, the tool of a map.
I did implement a map in the game, and you can use it to build the base. But it feels... wrong. It doesn't feel like you're living in a space station.
After having actually "lived" in a space station - that is, having built a few in the game world and floated around inside of them - I can say that construction isn't part of the feel. Sure, maintenance, attaching things, detaching things - yeah. But actually commissioning new modules and deciding how fundamental wiring is done? That's not part of the experience. I should have realized it immediately, of course: that sort of design work isn't part of any "live in a place" experience. Living in a place is about living in a place, and designing is unrelated.
So I was thinking about breaking the game in half.
Designing a facility (or a module for a facility) is a huge amount of deep fun, and living in the thing you've built is a huge source of deep fun, too. So I really think that I need to split the game in two.
I'm thinking you've got the "living in space" section, but then you've also got the "ground support designing stuff" section. I like the idea of cycles, of a team living on a base for six months, then returning home. And you get to design the add-on or the next base that will be there for the arriving fresh new team.
I like the idea of making the designing of the facility feel as organic and real as living in the facility. To that end, I'm thinking of a design system that feels like pencils on graph paper. This sounds like a detail, but it's not: I'm talking about sticking the design to a 2D, line-centric approach. It feels fitting: the personal portion of the game extends traditional 2D into 3D, so it seems suiting that the traditional 3D designing tools are brought down to 2D.
This constraint isn't really a limitation so much as an advantage born out of the game's overall constraints. Space station modules are, fundamentally, a very constrained design space. For example, they are all basically tubes running along a given axis.
Let's say you want to design an inflatable hab. You could do this by simply choosing that material and drawing a line. Our graph-paper constraint understands you've chosen a structural material and want it to be that radius at those points, and you instantly have a fundamental structure for your module. If you want a rigid cubic tube, draw a line after choosing that, and you've got it. Draw BOTH, and you'll have an inflatable outer hab around a rigid cubic box.
Line controls exist to help you if you want straights, smooth curves, or mirrored modules, obviously. And adjusting them is as easy as grabbing the line and moving it.
Once the fundamental structure is laid down, it's a matter of putting in the things you want to put in. Here a simple, Kerbal-like method of lateral/radial symmetry can be used, or you can manually work with "the far wall" or "the near wall" to place objects that aren't mirrored. So if you want your inflatable hab to have soft beds in it, you can select them, pump the radial symmetry, and then click on the hab. An array of beds will be placed in a ring around the core axis. Exterior solar panels? Same thing, except they automatically get placed on the outside of the wall.
You don't need the added complexity of seeing the hab in 3D, at least not in the basic design system. You don't need to place beds by clicking in a 3D space. The design constraints of the module allow you to place the bed in 2D knowing full well exactly where it'll actually show up. Similarly, since everything needs to be attached to a wall, there's never any confusion about where it'll end up in space. Just cycle through the walls (two for our basic modules, four for our double-layer example) and whatever you place will be placed on that wall with whatever symmetry you've selected putting it in other areas as needed.
Then put in connectors of your choice so your module can connect to other modules. Design those, too. Send it all up at once, and the end result is that these one-axis simple-to-design modules end up as a catacomb of your own design. Which you then live in.
This very easy to use system can allow players to build whatever modules they need or want, and also allows for easy modding as people add more parts, ports, and structural elements. But is is easy to transition from the lineart design to a final, functional mesh?
Well, yes.
Many of the things you added are static modeled. The beds are not dynamically built, just dynamically placed and rotated.
The only mesh that has to be generated is the fundamental structural mesh. This isn't as hard as it sounds, though: create one "slice" of the material, correctly modeled and UV-mapped. Make sure it's got symmetric verts on each side. We can simply take that mesh and duplicate it over and over, each time lining up the left edge of the next bit with the right edge of the previous bit. Scaling up and down happens over the course of the mesh - if X is our spinal axis, then we simply scale all the verts towards the preferred scale depending on their X component.
The difficult part of the fundamental structural mesh is complex structures. For example, what if you want windows? What if your inflatable hab should have big plastic windows in it, ignoring radiation concerns?
The easy way to do this is to have different materials. You'd have three: an opaque mesh slice, a window mesh slice, and a transition mesh slice. However, this can get very complex if you want something like circular windows (rather than ribs that are windows). I think that freeform window placement is probably something to hold off on, but it probably wouldn't be THAT difficult to place them like beds or solar panels, except that instead of just placing meshes, they cut holes in the wall before placing their mesh.
With the technical concerns addressed (or handwaved), I can talk about gameplay.
Right now, I like the idea of having to live in the base for a specific duty cycle - three months, six months, a year, two years - it'll depend on what the player decides and the expense of switching crews, as well as the level of medical support available to the astronauts. However, because of that long timespan, the game obviously cannot be played entirely real-time.
I'm thinking that you can play as much as you like in real time, but there are various things you can do to enter an automatic time-advance. Sometimes these would be short - going to bed would advance you eight hours, perhaps. But they could also be long: simply clicking "go" on your weekly schedule could advance a whole week if nothing breaks in the middle. I want to reward time spent actually wandering the facility and living in it, so I think that "design research" points steadily tick up as you work in real time, second-by-second. Obviously this can be gamed by just leaving the game running in the background, but I'm not to concerned about that kind of exploit. There are plenty of tasks to do in real time if you want to - repairs, maintenance, EVA, even just eating or hanging out with other astronauts. Also, you can switch between multiple teams on multiple space stations...
Design research points are obviously spent in the design phase. I'm thinking they augment the idea of cash: you earn cash by having your space facility actually do something. The cash fee for sending up new modules (whether for a new station or to attach to an existing station) is simply based on weight, nothing more. However, every component has a design difficulty attached to it as well, and if you can't meet that fee, you can't figure out how to work it into the module and it doesn't pass testing. IE, you can't launch. There are obvious opportunities for tradeoff here, with something like a lightweight inflatable wall having a high design cost, but a heavy metal tube having a low design cost.
There might also be other kinds of resources, but we're not going to worry about that yet. That's for mods.
When designing a space station, you need to take into account how it's going to work and what it needs to accomplish. In the beginning that might be mostly just figuring out how to keep astronauts alive. But you'll need to expand. Support tourists, mining fleets, deep space probes, etc. All of these bring in the cash while testing your design capabilities. The more challenging variants don't require bigger stations, but better designs. Share designs with your friends, as well - even invite them aboard.
But when it comes to actual design, an important factor is how the station actually works. In order for a design to be "better" or "worse" it needs to be better or worse at something.
Previously I had designed the systems to be about consuming vast amounts of space, so spatial optimization (especially regarding material transfers) was the primary concern. However, with this refit that doesn't really suit. What I would like to do, if possible, is make it so that the individual modules end up really tightly bound together, so that you'll never really consider a module as a completely independent entity.
Let me start with the concept of a control panel. I like the idea of a clunky control panel for this system, rather than the adaptive intelligent computer system I developed. I like the idea that when you launch a module, you have buttons and levers and lights which represent different functions included in the structure of the module. You can transfer between modules, too - the hardpoints will have a dozen or so "wire" points which will count as contiguous when modules are connected.
In previous gameplay prototypes, it was about optimizing space with time, such that various operations might share the same space as long as they didn't share the same time. I think that's still valid, but it can't have the "pumping" feel because that relied on designing the spaces to interleave physically, which is not part of the new design system. Instead, I think the new system is going to be about managing degradation.
That is, you could run the smelter and the die-caster at the same time, but their combined smoke will choke your filters and their failure chance will spike. The vibration and heat will tax both your astronauts and the hab itself, causing slow leaks, cracked electronics, and so on.
I like this idea, because it highlights the joins between modules, giving you freedom to express yourself within a module, and then attempt to optimize how you put modules together and try to maintain them. Obviously, basic supply management is also going to be an issue... but within any one hab, the player should feel free to go with the specific design they feel happy with, rather than worrying that a cabinet is half an inch off of optimal. The pressures are on inter-module and supplies, not intra-module.
That said, controlling operations is going to be important, but it needs to be something which can be scheduled and worked through with an accelerated simulation, rather than painstakingly performed in real time each time. So my thought is that each piece of an operation is very well understood and you can literally schedule them by just dropping basic functionality ("turn on smelter") into a timetable. The controls which can perform that task are automatically detected, and the actual NPC activity which does those operations can be computed. "How long does it take Ralph to get from the smelting panel to the casting panel? There's an airlock in the way? Shit, I have to design this better, there's a wasted hour there..."
Of course, it can also be done manually.
One key left unmentioned so far is the idea of things breaking down. In my previous gameplay, that really wasn't part of the equation. But in this system, it's critically important, because breaking down is one of the major things that happens if you don't optimize well. Part of your design needs to take into account what happens when something breaks down - for example, is there a backup system? In addition, how easy is it to get to that system and repair it? Do you have replacement parts? These are questions that a beginner probably won't care about, but when you start to design large systems for smelting or whatever, it starts to be a concern.
Anyway, those are my thoughts on Astrophobia today. This weekend, I'll put together the module construction system.
Monday, August 19, 2013
Starship Game Design Discussion
I've been really thinking a lot about the kinds of gameplay you can get out of different kinds of design/construction games. So I've come up with a new idea for a game, which I'm codenaming "Rocketload". I'm going to discuss the design here, and although it's in public, it's mostly to cement it in my head. Feel free to comment if you somehow find it interesting.
The game has two fundamental pieces that work in tandem. There's a payload design/delivery system, and research system. They support each other and both operate in the same timescales in universe time. IE, if you launch a new payload, you could fast forward until it arrives... but all the other facilities and research projects and rockets will progress apace.
The rocket part of the game is component construction followed by staged launching, but not like Kerbal. Rather than constructing a physical rocket, you would construct a logical rocket. We're going to abstract out the physics because otherwise we wouldn't be able to simulate a hundred payloads simultaneously, which we're going to need to be able to do. Your highly trained rocket engineers will turn the logical design into a concrete design and send it into space for you, as you watch.
That's because the focus of our game is not on rocket physics, but on creating a massive network of spaceborn facilities. The focus is on facilities, not on rockets. The rockets just act as a constraint on your ability to put facilities in places.
Designing a rocket is a simple matter: the design section is a bunch of horizontal bars. Let's say we want to design something like Sputnik: it goes "beep beep" as it orbits the earth.
We grab the "beeper" object and put it on one of those bars. Next to it shows up the warning "Requires 1 mAh/day, no power source" or something similar. So we drag our smallest battery (1 Ah) and put it on the bar below the beeper. The simplistic logic of the bars instantly understands that the battery is available to power the beeper. So the beeper's warning would change to "42 day limit". That's how long it'd be until the battery runs out of juice.
We need to put it in orbit. For that we'll need a rocket engine, so we choose a launch-grade engine and put it below the battery. We could add as many launch-grade engines as we want, but one will do. We also have to add some fuel, so we'll put it on the same row to link it to that engine. To help us with this, at any point we can designate a target for our launch by clicking in the solar system map - a low orbit over our home planet.
A burn pattern would appear - a line of varying color to denote burn points, and whether there is enough fuel for them as loaded. When the target is assigned, the engine bar has a note attached with a fuel cost vs how much fuel you've got loaded up. You can launch without enough fuel, if you like - the assumption is that you'd pick it up somewhere out in deep space before you needed it.
So it's a much simpler setup than Kerbal, all about simple logical connectivity.
But there is some complexity hidden in the wings. For example, let's say we want to put it in orbit around the moon instead of ourselves. One option would be to simply click on a lunar orbit instead of a homeworld orbit. However, the engine costs for this would be annoying. So let's change out the launch-grade engine for the smallest engine we have, and much less fuel. The burn pattern blinks error - you can't reach escape velocity with this. But we can package the whole thing up as a stage by simply clicking on the little "-{" button that encompasses those three bars. Then we add a launch-grade engine and some fuel to a fourth bar, and the system understands it is responsible for launching the other payload, including the small rocket and its fuel. So we click on earth orbit for this one.
This stage's burn pattern is from the surface to orbit. The inner stage's burn pattern is now from orbit to orbit - something the small engine can handle.
Of course, you can continue to edit the stages. Add fuel to the inner stage. Remove fuel. Add a new rocket. Layer on as many stages as you want and put the satellite around Pluto - although it'll run out of juice at 42 days, so you're not likely to still be able to hear it.
Now this was a simple beeping satellite that creates only a very modest number of science points, and it'll run out of battery before anything goes wrong. But the primary concern with facilities is maintenance. Stuff breaking. Everything has a degradation rate, with degradation being that rate added over time. It will break when it hits 100 degradation, so something with 1 degradation/day will break in 100 days without maintenance. Our beeper and tiny battery probably have 0.01/day degradation rate...
This degradation rate really changes how you try to build facilities, because you have to take into account their failure rate and pattern. Humans can maintain (reduce degradation rate 90%) and repair (reduce degradation total from 90 to 50 at the cost of spare parts), so having a manned mission can radically extend the longevity, although all that life support is heavy. Also, humans act as a science lab or construction center, so if you want to do offworld research/construction, you'll need folks in orbit.
However, the degradation rate is not 100% static. Rocket engines produce a specific amount of vibration, and that's doubled or so when traveling through an atmosphere. Vibration causes degradation to the rest of the system, but not equally: each layer absorbs some of the vibration, reducing the effect on the next layer. So, in our "beepy satellite around the moon" example, once we got to earth orbit and our launch stage detached, we would see that our small engine for reaching lunar orbit would have quite a lot of degradation, our battery less, and our beepy thing least. Our small engine produces only a small amount of vibration, so it's unlikely to cause our battery to fail.
This should give facility/starship design some fun complexity, especially when you start to consider docking, replacing parts with other parts, strapping on add-ons in deep space, and so on. It can rival Kerbal in terms of complexity, but the complexity is all on the space side rather than the liftoff side. Scattering facilities and probes all over the star system for science, materials-gathering, construction, culture, staging... yeah!
Of course, the other side of the game is the science half. It makes the facilities matter.
While it's always a fun impulse to build a space station for the sake of building a space station, it's important to the longevity of the game to have that space station matter in the game world. And this is where science comes into play.
Let's say that your scanny probe picked up a new kind of resource while orbiting earth: a resource called "paired ions" or somesuch. The scientific explanation doesn't matter, all that matters is that it's something new and you want to bring it home. So you need a collector for it.
So we go home and build a new kind of rocket part - a deep space "paired ion" collector and storage tank.
We do this by using the device creation system, which looks just like the standard payload system, except you're using logical components rather than rocket components. Our device would be a tank (defaulting to standard alloys and intended to contain paired ions) with a deep space intake pointed into it (defaulting to standard electronics, and intended to ingest paired ions).
Just like that, we have the plans for a device. Except that device is going to be really, really slow or awkwardly huge, because it's a passive collector, and passive collectors are rough. So let's put in some electricity. We could add a battery (a tank containing electricity), but it'd make more sense to just specify an electrical intake, allowing us to power the collector from any kind of electrical source we want to design into our rocket. There. Our efficiency skyrocketed.
Of course, this is just an idea for a device. It's not finished. In order to actually create the device, we need to add in some research elements. The basic idea of any R&D project is that you start off by researching (using science inputs), and then you transition to engineering and final design (using material inputs). Science inputs basically build up "momentum", and then you bleed off momentum with the material inputs until you reach 0 and stop. The more science input, the better the engineering of the final result. The more material input, the larger/more materials. In both cases, momentum is based more on time running rather than actual amount of science/material, so juggle things to be more effective.
This is reflected by simply dragging science and/or material inputs onto whatever components you want them to be attached to.
One science input is the facility that detects the paired ions in the first place. Let's attach that to our ion collector part. This is a good match, because our detection facility is detecting the same resource. The two are well-matched, and therefore the research will be more effective than the momentum would imply. This should give us a really high-quality collector!
We also have a satellite orbiting the earth going "beep beep beep". We could add that to another component, such as the electrical input or the tank itself. But there's not any particularly good reason to do that - it'd add momentum for minimal benefit. We also can't add it to the collector: only one science input per device. We go ahead and add it to the electrical input just in case we want to use it, even though it's unlikely. Still, that means we can't use it in another project. One science project at a time.
To decelerate we need to add materials. We'll add a stock alloy material to all three elements, since we can throttle them as we please and don't have to use them if we don't want to.
Our project is then a matter of throttling up on the ion detection research input and leaving it throttled up as long as we want. We can go do other things, leave it "baking".
After a while, when we feel we've done enough research, we can throttle up on the storage tank's materials. This will cut research - you can only do research or development at any given time, not both. This will steadily decelerate us, and in the end we'll have spent all our acceleration on our collector, making a very high-quality collector, and all our deceleration on our tank, which will give us a very large tank.
The final stats also have to include degradation and price as well, and it's all worked out with simple algorithms. This system would have a noticeable degradation, because it has a high-tech part that isn't very big. If we had decelerated on the collector instead of the tank, our collector would be much bigger (and even more effective), and have a lower degradation rate due to the extra space and material used. Of course, our tank would be tiny.
And then the part gets added to our manifest and we can put it on a rocket, fly it out there, do our collecting, and then bring it back to our orbital base or land it back at home using parachutes.
Of course, it can get quite interesting. For example, what if that detecting station crapped out partway into our research cycle? Would we continue to accelerate using just the "beep beep" satellite so we could have a larger final product, or would we settle for a runty final device?
Also, paired ions are a material. When we get back a tankload, we might build an engine that uses paired ions as fuel. We might then use paired ions as a development material to decelerate the research. But this uses up our limited supply. What if we run out before we finish decelerating? Do we let the project idle along while we go fetch more?
All told, I think this combination of systems allows us to take our own approach to developing our space network. It also allows us to occupy the same space as other players (if we want) while still having distinct technologies. The combination of device function, research sources, and materials should make developing new devices fun, and keeping your space facilities operational in the face of degradation should keep things spicy.
The key to all of this, the hidden purpose behind this design, is mods.
See, using this system, mods are very easy to make.
If you want to add a laserbeam comm array mod, then you would add the laser beam pieces into the base device options. Then, not only can you distribute your default laser comm devices, but other people can use them in other kinds of devices. For example, powering their laser with jet fuel, or having a laser input control their light show. This should allow people to combine mods very easily as well, since the various mods will have device options that can be combined into one final device rather than being distinct objects that must always remain separate. The key lies in the simple but robust method of connecting elements to each other.
That's the hope, anyway.
The game has two fundamental pieces that work in tandem. There's a payload design/delivery system, and research system. They support each other and both operate in the same timescales in universe time. IE, if you launch a new payload, you could fast forward until it arrives... but all the other facilities and research projects and rockets will progress apace.
The rocket part of the game is component construction followed by staged launching, but not like Kerbal. Rather than constructing a physical rocket, you would construct a logical rocket. We're going to abstract out the physics because otherwise we wouldn't be able to simulate a hundred payloads simultaneously, which we're going to need to be able to do. Your highly trained rocket engineers will turn the logical design into a concrete design and send it into space for you, as you watch.
That's because the focus of our game is not on rocket physics, but on creating a massive network of spaceborn facilities. The focus is on facilities, not on rockets. The rockets just act as a constraint on your ability to put facilities in places.
Designing a rocket is a simple matter: the design section is a bunch of horizontal bars. Let's say we want to design something like Sputnik: it goes "beep beep" as it orbits the earth.
We grab the "beeper" object and put it on one of those bars. Next to it shows up the warning "Requires 1 mAh/day, no power source" or something similar. So we drag our smallest battery (1 Ah) and put it on the bar below the beeper. The simplistic logic of the bars instantly understands that the battery is available to power the beeper. So the beeper's warning would change to "42 day limit". That's how long it'd be until the battery runs out of juice.
We need to put it in orbit. For that we'll need a rocket engine, so we choose a launch-grade engine and put it below the battery. We could add as many launch-grade engines as we want, but one will do. We also have to add some fuel, so we'll put it on the same row to link it to that engine. To help us with this, at any point we can designate a target for our launch by clicking in the solar system map - a low orbit over our home planet.
A burn pattern would appear - a line of varying color to denote burn points, and whether there is enough fuel for them as loaded. When the target is assigned, the engine bar has a note attached with a fuel cost vs how much fuel you've got loaded up. You can launch without enough fuel, if you like - the assumption is that you'd pick it up somewhere out in deep space before you needed it.
So it's a much simpler setup than Kerbal, all about simple logical connectivity.
But there is some complexity hidden in the wings. For example, let's say we want to put it in orbit around the moon instead of ourselves. One option would be to simply click on a lunar orbit instead of a homeworld orbit. However, the engine costs for this would be annoying. So let's change out the launch-grade engine for the smallest engine we have, and much less fuel. The burn pattern blinks error - you can't reach escape velocity with this. But we can package the whole thing up as a stage by simply clicking on the little "-{" button that encompasses those three bars. Then we add a launch-grade engine and some fuel to a fourth bar, and the system understands it is responsible for launching the other payload, including the small rocket and its fuel. So we click on earth orbit for this one.
This stage's burn pattern is from the surface to orbit. The inner stage's burn pattern is now from orbit to orbit - something the small engine can handle.
Of course, you can continue to edit the stages. Add fuel to the inner stage. Remove fuel. Add a new rocket. Layer on as many stages as you want and put the satellite around Pluto - although it'll run out of juice at 42 days, so you're not likely to still be able to hear it.
Now this was a simple beeping satellite that creates only a very modest number of science points, and it'll run out of battery before anything goes wrong. But the primary concern with facilities is maintenance. Stuff breaking. Everything has a degradation rate, with degradation being that rate added over time. It will break when it hits 100 degradation, so something with 1 degradation/day will break in 100 days without maintenance. Our beeper and tiny battery probably have 0.01/day degradation rate...
This degradation rate really changes how you try to build facilities, because you have to take into account their failure rate and pattern. Humans can maintain (reduce degradation rate 90%) and repair (reduce degradation total from 90 to 50 at the cost of spare parts), so having a manned mission can radically extend the longevity, although all that life support is heavy. Also, humans act as a science lab or construction center, so if you want to do offworld research/construction, you'll need folks in orbit.
However, the degradation rate is not 100% static. Rocket engines produce a specific amount of vibration, and that's doubled or so when traveling through an atmosphere. Vibration causes degradation to the rest of the system, but not equally: each layer absorbs some of the vibration, reducing the effect on the next layer. So, in our "beepy satellite around the moon" example, once we got to earth orbit and our launch stage detached, we would see that our small engine for reaching lunar orbit would have quite a lot of degradation, our battery less, and our beepy thing least. Our small engine produces only a small amount of vibration, so it's unlikely to cause our battery to fail.
This should give facility/starship design some fun complexity, especially when you start to consider docking, replacing parts with other parts, strapping on add-ons in deep space, and so on. It can rival Kerbal in terms of complexity, but the complexity is all on the space side rather than the liftoff side. Scattering facilities and probes all over the star system for science, materials-gathering, construction, culture, staging... yeah!
Of course, the other side of the game is the science half. It makes the facilities matter.
While it's always a fun impulse to build a space station for the sake of building a space station, it's important to the longevity of the game to have that space station matter in the game world. And this is where science comes into play.
Let's say that your scanny probe picked up a new kind of resource while orbiting earth: a resource called "paired ions" or somesuch. The scientific explanation doesn't matter, all that matters is that it's something new and you want to bring it home. So you need a collector for it.
So we go home and build a new kind of rocket part - a deep space "paired ion" collector and storage tank.
We do this by using the device creation system, which looks just like the standard payload system, except you're using logical components rather than rocket components. Our device would be a tank (defaulting to standard alloys and intended to contain paired ions) with a deep space intake pointed into it (defaulting to standard electronics, and intended to ingest paired ions).
Just like that, we have the plans for a device. Except that device is going to be really, really slow or awkwardly huge, because it's a passive collector, and passive collectors are rough. So let's put in some electricity. We could add a battery (a tank containing electricity), but it'd make more sense to just specify an electrical intake, allowing us to power the collector from any kind of electrical source we want to design into our rocket. There. Our efficiency skyrocketed.
Of course, this is just an idea for a device. It's not finished. In order to actually create the device, we need to add in some research elements. The basic idea of any R&D project is that you start off by researching (using science inputs), and then you transition to engineering and final design (using material inputs). Science inputs basically build up "momentum", and then you bleed off momentum with the material inputs until you reach 0 and stop. The more science input, the better the engineering of the final result. The more material input, the larger/more materials. In both cases, momentum is based more on time running rather than actual amount of science/material, so juggle things to be more effective.
This is reflected by simply dragging science and/or material inputs onto whatever components you want them to be attached to.
One science input is the facility that detects the paired ions in the first place. Let's attach that to our ion collector part. This is a good match, because our detection facility is detecting the same resource. The two are well-matched, and therefore the research will be more effective than the momentum would imply. This should give us a really high-quality collector!
We also have a satellite orbiting the earth going "beep beep beep". We could add that to another component, such as the electrical input or the tank itself. But there's not any particularly good reason to do that - it'd add momentum for minimal benefit. We also can't add it to the collector: only one science input per device. We go ahead and add it to the electrical input just in case we want to use it, even though it's unlikely. Still, that means we can't use it in another project. One science project at a time.
To decelerate we need to add materials. We'll add a stock alloy material to all three elements, since we can throttle them as we please and don't have to use them if we don't want to.
Our project is then a matter of throttling up on the ion detection research input and leaving it throttled up as long as we want. We can go do other things, leave it "baking".
After a while, when we feel we've done enough research, we can throttle up on the storage tank's materials. This will cut research - you can only do research or development at any given time, not both. This will steadily decelerate us, and in the end we'll have spent all our acceleration on our collector, making a very high-quality collector, and all our deceleration on our tank, which will give us a very large tank.
The final stats also have to include degradation and price as well, and it's all worked out with simple algorithms. This system would have a noticeable degradation, because it has a high-tech part that isn't very big. If we had decelerated on the collector instead of the tank, our collector would be much bigger (and even more effective), and have a lower degradation rate due to the extra space and material used. Of course, our tank would be tiny.
And then the part gets added to our manifest and we can put it on a rocket, fly it out there, do our collecting, and then bring it back to our orbital base or land it back at home using parachutes.
Of course, it can get quite interesting. For example, what if that detecting station crapped out partway into our research cycle? Would we continue to accelerate using just the "beep beep" satellite so we could have a larger final product, or would we settle for a runty final device?
Also, paired ions are a material. When we get back a tankload, we might build an engine that uses paired ions as fuel. We might then use paired ions as a development material to decelerate the research. But this uses up our limited supply. What if we run out before we finish decelerating? Do we let the project idle along while we go fetch more?
All told, I think this combination of systems allows us to take our own approach to developing our space network. It also allows us to occupy the same space as other players (if we want) while still having distinct technologies. The combination of device function, research sources, and materials should make developing new devices fun, and keeping your space facilities operational in the face of degradation should keep things spicy.
The key to all of this, the hidden purpose behind this design, is mods.
See, using this system, mods are very easy to make.
If you want to add a laserbeam comm array mod, then you would add the laser beam pieces into the base device options. Then, not only can you distribute your default laser comm devices, but other people can use them in other kinds of devices. For example, powering their laser with jet fuel, or having a laser input control their light show. This should allow people to combine mods very easily as well, since the various mods will have device options that can be combined into one final device rather than being distinct objects that must always remain separate. The key lies in the simple but robust method of connecting elements to each other.
That's the hope, anyway.
Tuesday, April 16, 2013
Avatars with Layers
This is a technical implementation post.
I'm slowly creating a Unity avatar generator, so this is a post about avatar generation.
There seem to be a lot of different opinions about how to do it, but most of them seem to be either mired in the past or extremely limited. I plan to use three methods to allow users to construct their avatars. Keep in mind that users will be able to submit content and use it on their avatars, so this is a framework rather than a specific set of options. This means that we can't use any of the cheap outs like you get in the various superhero MMORPGs.
First: you can stack texture layers. Or, more accurately, material layers.
This would be used for skin tight stuff, such as tank tops, necklaces, socks, and so on. These simply require a texture with transparency, a bump map, and an optional set of material parameters if you want to make it have different shader parameters (for example, to get the look of a spandex bodysuit). This is simply stacked on top of the underlying materials, allowing underlying materials to show through.
In addition, you can use this for simple decal work - scars, tattoos, robo-skin, whatever.
The little secret to this is the use of bumpmap blending.
It's quite easy to calculate out a single, final bumpmap by layering each bump map on top of the preceding bumpmap and fading it. This allows us to get a real feel for layers. For example, if you wear a chunky necklace and then a light shirt, the normals for the necklace will be used on the part of the shirt overlaying the necklace. So even though the necklace is partly hidden beneath the shirt, it doesn't vanish, it creates a little mound under the fabric.
This trick isn't critical or anything, but it's easy and adds a bit of fun realism. It also paves the way for more advanced techniques, both those listed below and things like wet or damaged clothes, nonhuman skin types, and so on. It's also important because Unity doesn't seem to support bump map transparency, so that has to be calculated by us anyway.
Second: your outermost "tight" layer determines your base mesh.
The human body is split into three mesh segments: head, upper body, and lower body. When you wear a piece of clothing, it overrides the default mesh with the correct mesh. So if you wear a T-shirt, the upper body is overridden with a mesh that has the correct sleeves. However, if you then put a long-sleeve shirt over the T-shirt, the upper body mesh becomes the long-sleeve-shirt mesh. The texture for the mesh is just like above, where there is lots of transparencies to allow the underlying skin texture to show through where needed.
These meshes are simply customizations of the base mesh, and have the same shape keys attached to them. This means that if your "muscle" slider was set to max and you put on a T-shirt, you'll still have a muscly body. Obviously it would be possible to have a mesh which didn't descend from the same topology - you could theoretically do some really crazy stuff and completely override the defaults. That's fine, that's kind of the point.
The UV mapping of these meshes has to match the original UV mapping. The reason is that we need to be able to use the underlying layers correctly, and also use this layer as an underlying layer. For example, you have a neck tattoo. You put on a T-shirt. Your mesh changes, part of your tattoo is hidden beneath the shirt texture. You put on the long sleeved shirt, your mesh changes again. While the T-shirt's mesh is gone, the T-shirts texture and normal map are not. So the neck of the shirt shows in the V of the button-up shirt, and there are subtle hints of wrinkles and mass at the neck, hem, and shoulders where the T-shirt had bump mapping.
Obviously, this has a few restrictions. For example, if you put a T-shirt on over the long-sleeved shirt, the long-sleeved shirt sleeves will be painted on your bare arm rather than having mass. I think that's fine.
Third: non-tight layers are layered meshes.
If you wear something which is poofy or doesn't adhere to your body, it's a separate mesh mapped to the same skeleton. So if you put a jacket on over your long-sleeved shirt, your shirt mesh remains your shirt mesh, and the jacket is a separate mesh. This can lead to issues if your sleeves are particularly poofy or something, but it's far less problematic than most alternatives.
Similarly, your hair is an add-on mesh. Your chunky arm pouch. Your skirt. Your boots. Your wings. These are all just add-on meshes. There's no guarantee they'll all get along, but that's part of you designing your avatars. If you stick wings on and put a coat on, you're going to have wings magically sticking through your coat. Live with it, or make a new kind of coat.
Of course, you could apply decals to these as well. Put a patch on your leather jacket.
Final thoughts
This is what I'm intending to make. It's actually not complicated, I've tested the feasibility of each of these with proof of concepts. It's just a lot of work.
A lot, especially because it's all database-based.
I really need to take maybe two weeks off work and just do this.
I'm slowly creating a Unity avatar generator, so this is a post about avatar generation.
There seem to be a lot of different opinions about how to do it, but most of them seem to be either mired in the past or extremely limited. I plan to use three methods to allow users to construct their avatars. Keep in mind that users will be able to submit content and use it on their avatars, so this is a framework rather than a specific set of options. This means that we can't use any of the cheap outs like you get in the various superhero MMORPGs.
First: you can stack texture layers. Or, more accurately, material layers.
This would be used for skin tight stuff, such as tank tops, necklaces, socks, and so on. These simply require a texture with transparency, a bump map, and an optional set of material parameters if you want to make it have different shader parameters (for example, to get the look of a spandex bodysuit). This is simply stacked on top of the underlying materials, allowing underlying materials to show through.
In addition, you can use this for simple decal work - scars, tattoos, robo-skin, whatever.
The little secret to this is the use of bumpmap blending.
It's quite easy to calculate out a single, final bumpmap by layering each bump map on top of the preceding bumpmap and fading it. This allows us to get a real feel for layers. For example, if you wear a chunky necklace and then a light shirt, the normals for the necklace will be used on the part of the shirt overlaying the necklace. So even though the necklace is partly hidden beneath the shirt, it doesn't vanish, it creates a little mound under the fabric.
This trick isn't critical or anything, but it's easy and adds a bit of fun realism. It also paves the way for more advanced techniques, both those listed below and things like wet or damaged clothes, nonhuman skin types, and so on. It's also important because Unity doesn't seem to support bump map transparency, so that has to be calculated by us anyway.
Second: your outermost "tight" layer determines your base mesh.
The human body is split into three mesh segments: head, upper body, and lower body. When you wear a piece of clothing, it overrides the default mesh with the correct mesh. So if you wear a T-shirt, the upper body is overridden with a mesh that has the correct sleeves. However, if you then put a long-sleeve shirt over the T-shirt, the upper body mesh becomes the long-sleeve-shirt mesh. The texture for the mesh is just like above, where there is lots of transparencies to allow the underlying skin texture to show through where needed.
These meshes are simply customizations of the base mesh, and have the same shape keys attached to them. This means that if your "muscle" slider was set to max and you put on a T-shirt, you'll still have a muscly body. Obviously it would be possible to have a mesh which didn't descend from the same topology - you could theoretically do some really crazy stuff and completely override the defaults. That's fine, that's kind of the point.
The UV mapping of these meshes has to match the original UV mapping. The reason is that we need to be able to use the underlying layers correctly, and also use this layer as an underlying layer. For example, you have a neck tattoo. You put on a T-shirt. Your mesh changes, part of your tattoo is hidden beneath the shirt texture. You put on the long sleeved shirt, your mesh changes again. While the T-shirt's mesh is gone, the T-shirts texture and normal map are not. So the neck of the shirt shows in the V of the button-up shirt, and there are subtle hints of wrinkles and mass at the neck, hem, and shoulders where the T-shirt had bump mapping.
Obviously, this has a few restrictions. For example, if you put a T-shirt on over the long-sleeved shirt, the long-sleeved shirt sleeves will be painted on your bare arm rather than having mass. I think that's fine.
Third: non-tight layers are layered meshes.
If you wear something which is poofy or doesn't adhere to your body, it's a separate mesh mapped to the same skeleton. So if you put a jacket on over your long-sleeved shirt, your shirt mesh remains your shirt mesh, and the jacket is a separate mesh. This can lead to issues if your sleeves are particularly poofy or something, but it's far less problematic than most alternatives.
Similarly, your hair is an add-on mesh. Your chunky arm pouch. Your skirt. Your boots. Your wings. These are all just add-on meshes. There's no guarantee they'll all get along, but that's part of you designing your avatars. If you stick wings on and put a coat on, you're going to have wings magically sticking through your coat. Live with it, or make a new kind of coat.
Of course, you could apply decals to these as well. Put a patch on your leather jacket.
Final thoughts
This is what I'm intending to make. It's actually not complicated, I've tested the feasibility of each of these with proof of concepts. It's just a lot of work.
A lot, especially because it's all database-based.
I really need to take maybe two weeks off work and just do this.
Sunday, November 09, 2008
Space Navigation
This is a technical essay for beginners on the subject of AI navigation in space games.
A few weeks ago, I tried to build a space-fleet-combat-game. In the process, I learned a whole lot about how to get an AI to navigate in space. Recently, one of my friends tried the same thing, and I realized it might be worth doing an introductory essay on space navigation, plotting intercept courses, taking into account gravity wells, etc.
Proper space games, whether Star Control 2-style or Wing Commander-style, have a few factors that make them completely different from other games. First, the main engines point directly backwards and turning isn't instant. Second, you keep going on the same vector: no (or very low) friction.
This totally destroys the old fashioned interception calculations that you might use for a first-person-shooter or RPG, because as time passes, the target will be in a different location relative to you (whether it's you, he, or both that are moving).
The easiest way I found to calculate out a basic intercept course is as follows:
Get the distance between you and your target. Divide it by your average speed. That is the ETA.
Calculate the new positions of you and your target at ETA, but cap your vector at a certain constant number of seconds (3 is good for most action space games). IE, if the enemy is moving x+1m/s, in ten seconds he'll be at x+10m. However, if you are moving at x+1m/s, in ten seconds you'll be at x+3m, because your vector vanishes after three seconds. We negate our own vector because we plan on changing it radically.
Now, determine how long it would take to reach these virtual positions. IE, how quickly you can turn to the proper heading and close at speed. Do not bother taking into account your current vector. This is the estimated course (EC).
If the EC is roughly the same length as the ETA, go for it. If it's significantly different, increase or decrease your ETA significantly and try again until you find an EC that works or your ETA becomes stupid (error out).
This system works in most space games because most space games have a maximum speed cap. If your maximum speed is 100m/s and you're traveling at x+100m/s, accelerating along the z axis will make you arc away from that and to z+100m/s, no x velocity at all. This is true both of 2D and 3D space games: most of them impose this artificial speed cap so that people have a hope of being able to navigate intuitively.
The slower you turn and the longer it takes to reach your maximum speed, the more of a factor your current velocity will be, and the longer your personal velocity cut-off time should be. In addition, when calculating your estimated course (EC), you should take into account that your average speed will be lower than your maximum speed because you have to accelerate - and if your acceleration is slow, that will be more important. Obviously, the longer the thrust, the closer to your maximum speed your average speed will be.
...
Now, if you're like me, you're the sort of person who doesn't want a speed cap. If you're traveling at x+100m/s and you start thrusting along z, you'll reach x+100m/s & z+100m/s. No speed cap except maybe light speed.
This makes navigation difficult because you have to factor in your vector much more strongly, often moving to negate it. On the surface, you should just be able to do away with the velocity cutoff. However, it's not quite that simple.
First, you need to calculate not just where the enemy ship will be at ETA based on his current vector, but also based on his acceleration. If a ship is accelerating away, you need to take that into account or you'll be hopelessly off course.
Second, this system produces radically inappropriate intercept speeds. You'll blow by your enemy doing 0.3c, you won't even see the bastard as he blips by. So you need to put in some kind of rough vector matching mixed into the basic intercept package. It's possible to program, but the actual physics of the matter make it highly difficult: unless your ship has many times the thrust of the ship you're intercepting, it will take you a long, long time to close and match vectors. And if you've got any human-controlled ships, forget it!
Another factor in this kind of game is the light-speed cap, which is a common thing to want to include. The idea is that the speed cap is light speed, and the closer you get to light speed, the more thrust it takes to change your vector.
There are a lot of problems with this. In basics, this means that your current velocity will screw up your acceleration. Plotting an intercept course may involve having to slow down so you can accelerate along another vector.
Of course, the truth is that the issue is radically more complex than that, because you're always operating from your own frame of reference. You aren't going 0.9c: everything else is. The light speed limit is no good for gameplay unless you (A) are a physicist or (B) throw away any realism it may have had.
...
With the described system, basic navigation is possible. However, most games want more advanced navigation: they want to be able to orbit planets, do gravitational slingshots, present broadsides, interpose specific faces of their ships, ram (and avoid ramming), etc, etc, etc.
Each of these things requires some pretty significant tweaking... and, of course, the basic calculations presented here are not exactly optimized. They give pretty rough (but functional) intercepts.
There's the basics. Hope it helps.
A few weeks ago, I tried to build a space-fleet-combat-game. In the process, I learned a whole lot about how to get an AI to navigate in space. Recently, one of my friends tried the same thing, and I realized it might be worth doing an introductory essay on space navigation, plotting intercept courses, taking into account gravity wells, etc.
Proper space games, whether Star Control 2-style or Wing Commander-style, have a few factors that make them completely different from other games. First, the main engines point directly backwards and turning isn't instant. Second, you keep going on the same vector: no (or very low) friction.
This totally destroys the old fashioned interception calculations that you might use for a first-person-shooter or RPG, because as time passes, the target will be in a different location relative to you (whether it's you, he, or both that are moving).
The easiest way I found to calculate out a basic intercept course is as follows:
Get the distance between you and your target. Divide it by your average speed. That is the ETA.
Calculate the new positions of you and your target at ETA, but cap your vector at a certain constant number of seconds (3 is good for most action space games). IE, if the enemy is moving x+1m/s, in ten seconds he'll be at x+10m. However, if you are moving at x+1m/s, in ten seconds you'll be at x+3m, because your vector vanishes after three seconds. We negate our own vector because we plan on changing it radically.
Now, determine how long it would take to reach these virtual positions. IE, how quickly you can turn to the proper heading and close at speed. Do not bother taking into account your current vector. This is the estimated course (EC).
If the EC is roughly the same length as the ETA, go for it. If it's significantly different, increase or decrease your ETA significantly and try again until you find an EC that works or your ETA becomes stupid (error out).
This system works in most space games because most space games have a maximum speed cap. If your maximum speed is 100m/s and you're traveling at x+100m/s, accelerating along the z axis will make you arc away from that and to z+100m/s, no x velocity at all. This is true both of 2D and 3D space games: most of them impose this artificial speed cap so that people have a hope of being able to navigate intuitively.
The slower you turn and the longer it takes to reach your maximum speed, the more of a factor your current velocity will be, and the longer your personal velocity cut-off time should be. In addition, when calculating your estimated course (EC), you should take into account that your average speed will be lower than your maximum speed because you have to accelerate - and if your acceleration is slow, that will be more important. Obviously, the longer the thrust, the closer to your maximum speed your average speed will be.
...
Now, if you're like me, you're the sort of person who doesn't want a speed cap. If you're traveling at x+100m/s and you start thrusting along z, you'll reach x+100m/s & z+100m/s. No speed cap except maybe light speed.
This makes navigation difficult because you have to factor in your vector much more strongly, often moving to negate it. On the surface, you should just be able to do away with the velocity cutoff. However, it's not quite that simple.
First, you need to calculate not just where the enemy ship will be at ETA based on his current vector, but also based on his acceleration. If a ship is accelerating away, you need to take that into account or you'll be hopelessly off course.
Second, this system produces radically inappropriate intercept speeds. You'll blow by your enemy doing 0.3c, you won't even see the bastard as he blips by. So you need to put in some kind of rough vector matching mixed into the basic intercept package. It's possible to program, but the actual physics of the matter make it highly difficult: unless your ship has many times the thrust of the ship you're intercepting, it will take you a long, long time to close and match vectors. And if you've got any human-controlled ships, forget it!
Another factor in this kind of game is the light-speed cap, which is a common thing to want to include. The idea is that the speed cap is light speed, and the closer you get to light speed, the more thrust it takes to change your vector.
There are a lot of problems with this. In basics, this means that your current velocity will screw up your acceleration. Plotting an intercept course may involve having to slow down so you can accelerate along another vector.
Of course, the truth is that the issue is radically more complex than that, because you're always operating from your own frame of reference. You aren't going 0.9c: everything else is. The light speed limit is no good for gameplay unless you (A) are a physicist or (B) throw away any realism it may have had.
...
With the described system, basic navigation is possible. However, most games want more advanced navigation: they want to be able to orbit planets, do gravitational slingshots, present broadsides, interpose specific faces of their ships, ram (and avoid ramming), etc, etc, etc.
Each of these things requires some pretty significant tweaking... and, of course, the basic calculations presented here are not exactly optimized. They give pretty rough (but functional) intercepts.
There's the basics. Hope it helps.
Subscribe to:
Posts (Atom)