Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us $3,400 per month for bandwidth bills alone, and since we don't believe in shoving popup ads to our registered users, we try to make the money back through forum registrations.
«15 »
  • Post
  • Reply
Elentor
Dec 14, 2004



Alright, barring anything incredibly dumb I might have missed I'm done with the interface. Every feature I wanted is in.



One last minute feature I did was make it so the background of the item name is colored hinting the item level. These follow the typical RPG rainbow: white/green/blue/purple plus red/orange. The colors change gradually between the tiers. They also fade away as your item level grows/matches the item's level.

Adbot
ADBOT LOVES YOU

Elentor
Dec 14, 2004



Chapter 16 - Hard Work & Some Stats


So what have I been working on?

I'm a few days late on starting working on ships but not behind schedule for Alpha - Some of the previously mentioned hooks took me a bit further than I intended. I think in one or two more days I'll have finished what I consider to be the bare minimum for the GUI. Yes, I'm still working on it. Hey, it's a lot of stuff.

The lack of posting hasn't much to do with the lack of working, if anything it's the opposite. There's so much to do. Writing a procedural game is, as it turns out, really, really hard. There are hundreds of systems that connect to each other. The design documents need to be overly well organized lest I lose track of them.

And because there's so much going on, I try to implement a system as soon as I design or solve it. This is done primarily because if I don't, it'll eventually leave my brain's short term memory and I'll have to look at the document again, so it's easier to follow a stream-of-thought and do things as they come since I already keep a backlog of everything I have to do anyway.

This has been the case for the Shop for a while. I've added the function to buy items and ships as you can see from the previous chapter, but I needed to add the function to pull a random item from the item pool, since I was creating the items and ships manually.



An example - Rolling Random Items

This needs to be done now rather than later. The ability to pull a random item is important since enemy ships will drop them as well. So I need a few things:


* An algorithm to drop the items. I already had a few things in mind, but I hadn't decided on the final formula. So items in the spreadsheet have a "rarity" value for example since I knew how rare I wanted each one of them to be, but the value did nothing thus far.

* From which pool is the item gonna be taken? There are multiple factions, so what gives? Are you only gonna find items from a single faction in a shop? That doesn't make sense in some situations. What if you're buying an item from a smuggler or a thief?

* Are all shops equal? I already created a few different shop archetypes, and it makes sense that some shops should sell better things than others.


The items have their drops balanced around 3 elements: Rarity, Level and Exoticity. Since stages already have an attribute called Threat which is basically how difficult they are for their current level, and shops need to be able to provide you good/worse items, I unified every item-agnostic value into a modifier called "Quality".

So internally, stages with higher threat send a request for a random item of higher quality, shops of higher quality do the same, and so on. An item has a % of drop compared to the other items in the same pool based on:

1) Its rarity. This was straightforward to code.
2) The level difference between the item and the source. I had a formula in place but since I had to revisit this, it was weird to balance. I already knew what I wanted and posted it before, that I wanted items that have a high-level base not to drop early on. Remember that items scale with their item level so this has mostly to do with the pool of items available. I ended up settling with a formula that works like this:

* You have a 100% chance multiplier against items of same level as the source. These fall off to 25% against items 20 levels higher, 1% against items 40 levels higher, and 0% against items 50 levels and above.
* A level 0 item has a 30% chance multiplier when dropping from a level 240 source.
* A level 0 item has a 50% chance multiplier when dropping from a level 100 source.

This should add a nice variance so that as you progress in the game you'll see newer stuff more often than not, and older items should become more uncommon but not too uncommon.

3) Its exoticity. The falloff here is much harsher than the level falloff because there are fewer exotic items. A level 0 exoticity item will always have a 100% multiplier.

* An exoticity 0 source will give you respectively, 100%, 58%, 30%, 13% and 4% against 0/1/2/3/4 exoticity. You won't be able to drop anything above that.
* An exoticity 5 source gives you a 58% multiplier to an exo5 item, down to 4% to an exo8.
* An exoticity 10 source gives you a 30% multiplier to an exo10 item.

I didn't talk about the item rarity, but it's the more aggressive formula of the bunch. The Quality value greatly reduces the impact of an item's rarity. Quality also increases the amount of traits (affixes) and their average power/modifiers. To put it in ARPG terms, a higher Quality roll has more chances of giving you a Rare or Magic item compared to a Common item.



Current Project Stats

The current stats of the project are:

Lines of Code - 27,182
Script Files - 159 Files, 3.44 Mb
//of which 40 files and ~600 Kbs are dedicated to Procedural Generators
I'm excluding a 1.5 Mb pure text file that contains baked values for
math operations to speed up the ship generation.

Pure Text DB (Items, Weapons, Names) - 40 files, 672Kb
Spreadsheets - 33 files, 3.71 Mb
Design Documents (Pure Text) - 32 files, 28.3 Kb
//As you can see, I tend to organize my thoughts a lot better in spreadsheets.

After refactoring all the major systems I still can't help but wonder just how unoptimized (or optimized) the whole thing is. The good thing is that a solid 95% of the game is already solved in my head and I don't see any roadblocks. The bad thing is the sheer amount of things that I have to keep refreshed.

Somehow I'm not burned (yet). Seeing everything work is kinda refreshing. I am, however, finding a bit hard to dedicate this much time to the project and yet find it in myself to also write the updates. When I think of the project, I start writing about it, and then I get excited about coding it. Part of me wants to keep coding!



The Road Thus Far

Looking back at August, I think in the past months the current build is a lot more stable. If you've been following my project.log the amount of updates tagged as "bug fixes" is pretty huge.

I said it before, but man, it's hard working on procedural generation. Every game has bugs but ProcGen seems to be prone to a crazy amount of glitches simply by virtue of the fact you're using abstractions to create stuff and any oversight will screw you up. And algorithms that revolve around randomness can have their own quirks. This brings me back to how many bugs and oversights games like Diablo have. What impresses me the most, right now, is how many bugs and oversights they don't have.

I wish I had some actual references and parameters as to how concise the whole thing is. For example, for the scope of the project, I'm not sure whether the amount of code done is good, bad or ugly. Prioritizing is something that worries me a lot. Namely how much I should be working right now on tech vs how much I should be coding gameplay. I'm usually against spending a lot of time on tech, but this is still something that bothers me.

So over the past few months we implemented:

Ship Game Objects
Combat Mechanics and Stats
Enemy Ship AI
Major work on the GUI
Inventory
Shop and Item Buy/Sell Mechanisms
Functional Menu -> Stage -> Menu Loop

Fixed a range of bugs all over - Game is pretty stable right now
Refactored a dozen classes - Hugely improved maintenance, scalability and performance
State Machines
Backend for the Stage Generator

Proper roadmap and scheduling
Game Design documents for a bunch of upcoming features

Looking back at the amount of features like this makes me feel like the pacing is good, but I still get this itch to get to work on the stages and fill in the content. But I need to be patient.

As for the end of November, this is the end result:



It was good progress overall. I didn't work on the star and area panels. I wrote some design documents for them and I kinda realized that if I started it right now it'd take another month of things hooking up to each other. They're not gonna be essential for the first and second Alpha builds, I might add them if I find some spare time but until then I want to keep moving and not spend too much time in one single thing. Luckily I'm a bit ahead of the schedule since I already worked on the Item Drop System which was planned for January.

I'll do a few more updates on the LP and then work on them spaceships. We should have a solid 20 days of some spaceship work. Hopefully I can fix some of the pending bugs. I feel like this is actually a relief because I'm fine with where the spaceships are right now, so even if all the experimental tech fail, it won't be a huge deal. This is the last bit of "experimental" tech before I get into filling in the rest of systems/content. It'll be a nice change of pace from the frantic crazy work from the past few weeks and we'll see the results.

But before that, I need to show you guys, well, November's work. So hang on a bit.



NEXT TIME:

GUI Showcase!

Elentor fucked around with this message at 05:11 on Dec 28, 2017

Elentor
Dec 14, 2004



I should be posting a few more updates this weekend wrapping up my work on the interface. Afterwards, a few of the upcoming ship generator updates are "live" journals since I was writing them as I coded and all the bug fixes seem to have plot twists in them so you'll get to see my reaction and a taste of how miserable exciting being a game-dev is!

Elentor
Dec 14, 2004



Chapter 17 - Facing the Interface, Part I


So what have I been working on?

I think I went into painstaking detail about how hard getting the interface right was, there's been a few chapters dedicated to it. So let's jump right into it. This was the first image of the Let's Play:




Panel Functionality

The Stage Hub has two panels. They share the same functionality, and you can switch between tabs (Ship Data, Shop, Item Data) and Subtabs that vary. Let's take a look at the main menu that you see as soon as you load a new game.



The Ship Data allows you to see the inventory (now with non-placeholder icons!) and some overall stats of your ship. The DPS (Damage-per-Second) and EHP (Effective Health Points) are shown right away. You can see in the menu which options are available or not. Not every stage is gonna have a shop.

Since the Ship Panel is the first thing you see, let's talk about it.


The Ship Data tab

The Ship data has three subtabs - Summary, Offensive Stats and Defensive Stats. It was important for me to let the player quickly appraise important stuff if they wanted. You don't need to go in detail if you don't want. Still, I did not want to oversimplify things, I want to make a game that is fun for me and I like character sheets.



Right in the ship summary, you have:

* The basic stats information (Hull, Shield, Armor, Average Resistances, Evasion)
* Other information that might be relevant (Energy, Speed, Jump Range)
* The ship's size (pretty important since a smaller ship is better at dodging)
* The jump range (how far the ship can go between stages)
* The average DPS and EHP for quick reference.

Traits are like affixes in RPG games. Each item can have up to 4 random traits. Some items and ships come with custom/unique traits built-in. I haven't gotten around them yet, they're used internally for some things (like adding HP to asteroids) so they're functional but I haven't implemented them as random stats on your items yet.

I did a lot of work in the inventory. In the original draft, the slots were shown like this:



It worked (Take a look at Weapon Mounts) but it seemed redundant since I already had the layout for the item icons in place. So I removed the text and worked on the icons instead.



When selecting a different ship you'll see which slots remain, which slots you gain (highlighted green) and which slots you lose (highlighted red)



The ship and item levels are color coded (white - lime - green - teal - blue - purple - pink - orange - yellow, so basically a rainbow starting from white and going through the traditional rarity scheme we're used). The colors have soft transitions between the colors instead of thresholds. If you take a look at the inventory list, you'll see that the item level is shown in the background color as well. The intensity of the color also changes depending on how higher the ship/item level is compared to yours.

One of the cool features I added is the ability to view the Shop items from the inventory screen, not just the shop screen. You can see that in the above screenshot. If a shop is selling a ship, you can buy it, if a shop is selling a weapon, you can buy it from the inventory screen, and so on.

Additionally, if you gain slots wherein you can equip items you already have, the DPS of the new ship preview will show the maximum potential DPS between all items you have in your inventory, excluding items you already have equipped in compatible slots. There are several hotkeys that modify this value. Backquote/Tilde (the button to the left of 1 in your keyboard) prevents the game from previewing these potential items and compare ships using only the items present in your current ship.




Ctrl disables all items and compares the raw stats between both ships:



And holding Alt shows the % increase. Alt also modifiers the preview with Control/Tilde. This makes for an incredibly powerful comparison tool between different ships:



The EPS shows how much Energy per Second the energy recharges, as well as how long it takes to recharge from 0 to full in seconds. The lower the energy, the slower the Shield recharges and the lower the weapon damage, though some weapons are more energy efficient than others (more on this later).

One thing of note is the Jump Range:



Jump Range is how far your ship can move through the squares in the big space grid. Ships have 7 different range values, from 0 (meaning you repeat the area in which you're in) to 6 (meaning you move up to 6 squares across in the grid). After each stage you get to choose from a new pool of stages from a random area around your ship. Having a high jump range can be interesting for someone looking to explore the universe as there are missions that require you to go to more remote places. Having a super low jump range can be interesting if you found a good area that you want to farm.

The Jump Range value shown is the average. To the side you have 7 leds indicating the relative chance of each individual jump range. If you hold Alt, however...



You get to see the difference between Jump Ranges. A blue value means a higher chance, a red value means a lower chance. You can see the Mine Brotherhood on average will move one block more often than the Spoony Goon, but the difference is very small. If the difference is huge, these leds will lighten up like Christmas trees.

Speaking of colors, that last image should show you that the stat comparison is also color coded. +100% gets a stronger green than +6%, etc.



Anyway, that's it for the main ship summary. The second ship subtab shows some more detailed information.



The second tab shows your ship zoomed out, the weapons activated shooting stuff (so you can also preview how a new ship's weapon mounts are set up) and a bunch of stats that may or may not be relevant.

EPS shows the current energy being regenerated, the amount of energy being spent, and the final net energy. Since it's green in this image it means that the net is positive and that you'll be at a full bar at all times! Needless to say this won't be a common occurrence, unless your weapons are extremely low level.

Here you can also see the elemental distribution of your weapons. This was a pain to get right but it's pretty neat I think.




Elements:
There are 8 elements in the game - Physical, Fire, Cold, Wind, Electric, Light, Dark, Poison. I haven't decided fully on their RP names yet (probably Kinetic, Thermal, Coolant/Negentropic, ECM/Sonar, EMP, Gravitonic, Acid - I might as well also say screw it and just go with the raw medieval fantasy names for fun) but I thought adding on-the-nose elements would be pretty cool. Some stuff fits pretty well - laser deals Fire damage which is usually the case already, Ion cannons a la the ones in Star Wars deal EMP damage, and so on.

While I haven't added stat ailments yet, Elemental Resistances and all the formulas related to them are something I coded in this month. There's a big unified damage formula that makes my life a lot easier now when testing stuff, so damage types and resistances are already in and functional.

I want to leave here that holy crap it was a lot more trouble coding this than I expected. There are so many things that can modify these things. What if a weapon or an item has a trait that adds +5 fire damage to every weapon you have? Some traits are local, some might be global. I had to unify a lot of combat formulas for the code to be simple, painless and make sense, so in a way all these interface elements forced me to write a clean combat system.



The Weapon Mounts panel shows the characteristics of each individual slot. These are their animations, the amount of mounts associated (for example, that 2xA on the primary weapon slot means that it has two different mounts, and that it [A]lternates between them).

Weapon Budget is an internal value for how many weapon slots the ship can have. At least I intended it to remain internal, but I think it's something worth exposing. There's the used budget and maximum budget. The way it works is that first the maximum budget is rolled based on the ship's level, and different slots cost different budget amounts. The ship will then randomly be assigned weapon slots until all the remaining slots cost more than the leftover budget.



Coincidentally, most end ships use 255 budget as the next thresholds can be a bit higher than that. The reason I want to expose these values is because, when mixing ships, their maximum budget will be taken into account.

So a ship might have rolled oppressively bad slots but still have a really good maximum budget.



The last subtab is for defense stats. Here you can see your elemental resistances, your EHP in more detail. You can also see how much damage your armor prevents against different damage values. These are always 15,25,50 as fixed values, and then 3 dynamic values based off your HP.

When comparing % improvement, the dynamic values of a different ship will "smart compare" with how your armor would fare against the new values.

It's also where you can spin your ship



Looking at this old gif you can see a transition between two ships mid-spin. Spinning ships is cool.


Appraising Ships:


During this period I kinda ended up reworking how combat mechanics work and added a few more RPG elements to it as you may have noticed. Still no critical strikes for anyone though, and no evasion for enemy ships. Shmups tend to have plenty of cheat death mechanics but it would feel very wrong for the player to land a hit and have the hit not register.

Otherwise I'm pretty satisfied with all the stuff that differentiate the ships. You have:
Offense: Weapon Slots, Weapon Mount Setup, Energy & Energy Regen
Defense: Your EHP (HP, Shield, Armor, Elemental Resistances, Evasion), Speed, Ship Size
Other: Jump Range, Aesthetics, Traits, Upgrade Potential

Defense can ultimately be simplified through your Effective HP. I like splitting it across multiple values though.

The offensive characteristics of the ships are interesting. The mid-tier ships (what you'll get for the bulk of the game) should give you 4-5 slots. The late game ships should give you 5-6 slots.

Weapon Mounts are generally normalized. If you have 4 weapon mounts and they're set to Alternating mode like an X-Wing's then it doesn't really matter if it's one, two or four, they're there just for the cool factor. There are advantages to having some multiple mounts. Mounts that shoot simultaneously normalize their base damage, but not bonus damage, for example. I think the interesting element about Weapon Mounts is not just their stats, but whether you think weirdly placed mounts are worth it or not. Their positioning is a huge intangible element that I'm really happy to be in the game.


Defense-wise, Shields have a pretty good advantage in that they regenerate passively, at a very fast pace initially. The Shield Regen is really good and some of it is %-based, so shields in general are lower than Hull values. They take slightly less elemental damage overall. Shields, however, are not affected by Armor and Armor is pretty good at protecting you from physical damage, so there's a trade-off.

Both Shield Regen and Weapon Damage are affected by your current Energy Ratio. Their values scale down from 75% energy to 0% energy, so the more Energy and the higher your Energy Regen, the better off you are. Primary and Secondary Weapons have an attribute called Energy Efficiency which is how much they're affected by low energy.


In general, Upgrade Potential refers to all elements that make a ship interesting to keep even if if you're not using it. Traits have a chance of being kept when you reroll or combine ships, the maximum Weapon Budget is used when rerolling it as well, and so on. Bad weapon mount positioning is not an attribute that is typically seen, but it can be a dealbreaker in an otherwise good ship, or not if you want to use that ship for rerolling later on.


In other words:

I'm a huge nerd for damage formulas and rotations and that kind of stuff, so for me it's important that the game have some interesting theorycrafting potential. The way I play games usually go like this - if the game has an upfront burden of learning complicated things, I'm seldom interested. I prefer games that are intuitive at first. The game has to allow me to shut my brain down when playing it from start to finish and play it on auto. If I'm heavily invested in the game, I have a lot of fun geeking the hell out of it, writing my own simulators to try stuff out. It gives me an incredible amount of fun. I don't want to water down stuff because that's not what I like what to play, I want to apply this philosophy to every game I make. I want to eat my own dog food.

Because of the way I laid out the formulas I think there's a lot of interesting potential for theorycrafting. There are advantages and disadvantages to having fast/slow sources of damage. Elements have their own ailments, and so on. If things get too complicated or not, I'll remove them as I playtest.

I intend to make every combat formula public once the Alpha is released. My idea is to offer a simple game guide with the toggle to see the detailed formulas and mechanisms exposed eventually. At the very least I intend to include a .txt with the basics before I get to that. For the procgen, universe generation and the likes, I prefer to let players figure out rather than spoiling the fun.

One of the ideas I had is that when you press F1 it takes you to a help page referring to the subject on top of your mouse pointer at the time you pressed F1. I think this can be pretty cool.

Anyway that's it for now!


NEXT TIME:

More Interface!

nielsm
Jun 1, 2009




Fallen Rib

I can't help but comment on some of the UX design:

Why are there two panes showing ships on the main menu, both just having header "Ship Data"? What's the difference between them? When you dig into the menu and explain some of the features, it becomes more apparent that it's (probably?) comparison between what you have now and what you're examining/building. You should probably change the headings to indicate their purpose.

The "tabs" are also unclear IMO. Faint blue LEDs in the corner don't scream "clickable to switch pages", they look more like a gauge of some sort to me. I would suggest using some icons, and more typical visual design for tabs with "foreground" and "background" styling for background/borders/shadows, but it might be a bit of a departure from the rest of the UI.
Similar for the green indicator opposite the blue... I assume it switches between multiple ships in your inventory?

Elentor
Dec 14, 2004



nielsm posted:

I can't help but comment on some of the UX design:

Why are there two panes showing ships on the main menu, both just having header "Ship Data"? What's the difference between them? When you dig into the menu and explain some of the features, it becomes more apparent that it's (probably?) comparison between what you have now and what you're examining/building. You should probably change the headings to indicate their purpose.

The "tabs" are also unclear IMO. Faint blue LEDs in the corner don't scream "clickable to switch pages", they look more like a gauge of some sort to me. I would suggest using some icons, and more typical visual design for tabs with "foreground" and "background" styling for background/borders/shadows, but it might be a bit of a departure from the rest of the UI.
Similar for the green indicator opposite the blue... I assume it switches between multiple ships in your inventory?

These are fair questions.

The second tab is not gonna be showing Ship Data in the main menu. It's there right now as a filler, the second tab is going to be showing stuff relevant to your current mission/quest/area. It will show Ship Data again when comparing ships, in which case the first tab will show your current ship and the second tab will show the selected ship as you figured out.

The tabbing leds are a placeholder right now, which is why I didn't go into any detail re: their design. I want them to look like actual tabs in the future to make it obvious that they're, well, tabs. When I was designing the title of the panel I needed something to debug the current tab selection and I just put a standard unity image there. But they're confusing even to me because the little leds don't tell you anything about them and while they fulfill their debug purpose they completely suck as design elements. They little leds will be completely replaced eventually, so I didn't even mention them.

I agree that I need a better indicator to indicate what is showing your selection and what is showing your currently equipped ship/item. I'll be thinking about it in the back of my head over the next weeks but I'm more than up for suggestions! Thank you very much for the feedback.

Elentor fucked around with this message at 08:54 on Dec 28, 2017

Feldherren
Feb 21, 2011


You could just change the Ship Data header to 'Equipped' or 'Piloted', or something like that, for the current ship, and 'Selected' or 'Comparing' for the ship you're comparing. You could also change the background colour of each panel (though I'm not sure what colours would indicate 'in use' and 'not in use').

Elentor
Dec 14, 2004



Chapter 18 - Facing the Interface, Part II


Item Panel

Going in the Equipment menu we get to see a list of our currently equipped items, with the Item Data to the right.



One of the current UI issues is that I don't think there's a very clear distinction between the panels. It's not obvious at quick glance whether you're reading a panel about an item or a ship. I think if I color-code the panel backgrounds that should make it more obvious.



Maybe adding a stronger connection between the two windows, like this?



Or maybe connecting them entirely, like this. I'm still debating.

Either way, the Item Data panel works just like the Ship Data. You can compare values between the items, the Alt hotkey also works to compare % values.



I intend for the second subtab of the Item Panel to show some flavor text and the item model. I'm not sure how far I'll go with this. I like the idea but it'll really depend on how much time it'll take me.

I posted this on my project.log a while ago:





Again, really experimental stuff. I'm having a lot of fun with the fluff, but I'm not sure how far I'll go with it.



Trying different background colors to make easier to distinguish between the panels. I also added (Equipped) and (Selected) to the header per Feldherren's suggestion. I still think there needs to be a more visually obvious way to distinguish them, I'm committed to improve the readability over time so suggestions are always welcome.


Shop



Every now and then you'll encounter a shop. I spent a good chunk of November and early December working on Shop features.

The idea is that the shops have random options. Some of the shop features are ideas I had, others are ideas that came from the Making Games Megathread, my project.log or the fine folks at IRC, so thanks to everyone who gave me ideas/helped along the way.

Right off the bat I start at the Debug Shop with a few pre-established options. So far I've implemented Buy/Sell Ships, Buy/Sell Items, Reroll Ship Name and Reroll Shop for debug purposes.



Rerolling a Ship Name right now uses the Mining convention. Which is the only naming generator I have right now for ships. However...





I did add a random name generator for the shop. Right now there are shop templates, and I implemented two templates: Dropped Goods (basically free loot) and Junkyard (usually low quality items at discount price).





One of the things I implemented was an idea from TooMuchAbstraction to "humanize" prices.



Most of the times prices are going to be rounded, or end in 99, and so on. From my log:

quote:

Instead of a single shop type with a random roll between the functions, I wrote a bunch of different shop types. Different factions have different chances of featuring some of these shop types, and each shop type has its own gimmicks. There are 14 shop types total. A "market" type will have a lot of things ending in 99 (thanks TMA for that), while an illegal arms dealer I imagine going all "where are my two hundred thousand dollars" in you and rounding up the price.

Here's a sample of the behind-the-scenes code:



There's a lot of detail behind how the shops work. This is one of the features with which I'm happiest so far.

You might have noticed some of the shop portraits look slightly different from each other. One of the things I did was add the ability for names to carry tags and values.

The Shop NameGen works under simpler rules than the Ship NameGen. There are adjectives and nouns. Right now there are 112 adjectives x 100 nouns for junkyards (but there are more than 11200 combinations because the namegen can, albeit rarely, pull adjectives from the common shared list), and 180 adjectives x 150 nouns for Dropped Goods. I know this is a pretty minor feature but have you ever tried to fill a list of synonyms for the words box, crate or junkyard? Things start simple and before you know it you're on the deep end of the internet reading about skinner boxes and the history of trash compactors.



So the word database can carry tags and values, like I said, and these are pretty meaningless on their own. The Portrait shader, however, can interpret them. So the word toxic carries with it a hexadecimal value for green, for example, and a float value that the shader interprets as an animation speed. The end result is that the box in the portrait pulses green.

I'll probably use this feature on ships eventually, the Shop portrait was a way to quickly debug if it was working correctly. Word tags don't necessarily need to be about colors, they can be about anything, it's up for the interpreter to decide what to do with them.


NEXT TIME:

Updates on the Ship Generator!

Anticheese
Feb 13, 2008

$60,000,000 sexbot




Have you considered crowdsourcing your flavour text? I'd be happy to take a crack at filling in some entries on a spreadsheet with some guidelines.

EponymousMrYar
Jan 4, 2015

The enemy of my enemy is my enemy.


Regarding distinction between panels, the second example is probably the best but the biggest eye-glazing issue is that the foreground and background colors blend in a bit. Maybe have the beige header and footer follow the item rarity colors?

Regarding fluff the 'general description' followed by 'personal account' is perfectly fine, not only does it develop the universe fluff it also develops the main character a bit too. You can stick all sorts of hints in there, from past dealings to 'behind the scenes' mentions to irritable snark.

Elentor
Dec 14, 2004



EponymousMrYar posted:

Regarding distinction between panels, the second example is probably the best but the biggest eye-glazing issue is that the foreground and background colors blend in a bit. Maybe have the beige header and footer follow the item rarity colors?

You're right, I definitely need to increase contrast between them. I'll play around, see what I can do.


Anticheese posted:

Have you considered crowdsourcing your flavour text? I'd be happy to take a crack at filling in some entries on a spreadsheet with some guidelines.

I like that idea a lot. When I get to focusing on the items I might do that.

Elentor
Dec 14, 2004



Chapter 19 - Improving the ShipGen: Collisions


Collision in games is a delicate subject. It's the kind of thing that can consume a lot of resources and processing power. Think about it - how do you go checking of two objects are colliding? If they're 2D objects in a pixelated game, maybe you can check if two sprites are occupying the same space, or touching. But how would you check that, either? Do you need to check every pixel of every sprite against every pixel of every sprite? Depending on how you do the math and the resolution of the objects, you'll see that things can get out of control quickly.

One of the ways to simplify collision, in general, is to split a scene in sectors, and make it so you only check collision between objects that are completely or partially contained in a sector.





In 3D this subdivision is called an Octree because instead of splitting each square in 4, you're splitting a cube in 8.

But I digress. What's of interest to us is how we are gonna set up the collision for the ships. All this octree stuff is cool and all but Unity is (I hope) already doing that behind the scenes. Plus there are other behind-the-scenes things, like setting up layers so that objects only check collision against some other certain objects (so that projectiles don't waste their time checking collision against projectiles, for example) that already done.

What we do need to figure out is how ships are gonna fit in all this. These ships are gonna get complex mesh-wise, and we cannot simply check every triangle against every triangle, we'll be dealing with thousands of triangles and even with a smart Octree, that can still get expensive. We also can't simply check the ship boundaries because they're complex objects.



Even if we wanted to use the mesh itself, we still run a pretty big problem. Collision needs to understand volume, and a triangle in itself is not telling us everything. What if an object completely enters another? No two triangles are colliding, and yet it's important to know if such a situation is happening because our movement calculations are discrete, not continuous. That means that if a projectile is going fast enough, one frame it might be outside a ship, and the next frame it might be completely inside a ship. There are oh so many bugs and oversights that derive from this in the history of video-games.

Because of volume issues, amongst other things, a game engine will usually collapse a mesh into a convex object to simplify the calculations. Meaning that a ship like this:



Might end up looking with boundaries like this:



Which, while better than a big cube surrounding the ship, is still very inaccurate.

If our ships were not procedural, we could manually set up a bunch of simple geometric forms to create a compound collider. That would be the more correct approach.




Collapsing Ships into Boxes

Collision between perfect geometric forms (cubes, cylinders) can be done parametrically, so checking if two perfectly round spheres are intersecting is easier to do than checking if two low-poly objects shaped spherically are colliding with each other. In fact, one of the simplest and most intuitive forms of collision is between two perfect spheres/circles. Since every point in a sphere is equidistant from the center, checking if two spheres are colliding with each other is a matter of tracing the distance between the sphere positions then subtracting their radii.

So for a compound collider, it's ideal to use simple, non-mesh colliders. We're going to use cubes. Because of the performance and practicality, voxelization is the process I ended up choosing. The idea here is, we're gonna convert our own ship into a bunch of primitive forms (specifically cubes) dynamically. We're gonna voxelize the poo poo out of our ships and make their collision meshes blocky, Minecraft-style.


This process is going to take some extra time during the ship generation, as one might expect. It doesn't come for free. Luckily, we only need to do it once, so a small cost in loading time in order to greatly improve both the frame rate AND the collision precision seems good to me.

Now how small is that cost? I have no idea.

So that I don't have to reinvent the wheel, I bought an asset that already performs voxelization. The idea is to see how it performs and tweak its code in order to achieve the desired performance.

This LP chapter is slightly different. From here on, I wrote the rest of this chapter in real-time as I coded.


Live Journal:

quote:

Debug:
Risk's Work - Calculating:
SpatialTree Built in 00:00:19.4522301
Boxes analyzed in 00:00:00.0002009
Merged in 00:00:00.0004250

Yeah, this is so totally not gonna work. Risk's Work is the ship's name. The SpatialTree took over 19 seconds to build. For reference, the ships are taking 10-13 milliseconds to spawn.

I start delving into the code and seeing what parts of it I can eliminate. I start reducing the amount of triangles that the script is taking into account when building the tree.

First optimization:
SpatialTree Built in 00:00:17.3089411

Second optimization:
SpatialTree Built in 00:00:01.2215652

Third optimization:
Changed max polygons to 600 per model
Total duration: 00:00:00.2742295

As I reduced the amount of triangles from 8000 to 600, the duration fell down to 270ms. It's a huge improvement, but it's still a lot more than the ship itself takes to spawn. One of the things I did was making the resolution of the cube very low. This is how it looks set to 4x4x4 = 64 cubes:



It's not terrible, but it's not great either. The hardest part is calculating the spatial tree, not collapsing the spatial tree into the final boxes. The Palladium Inventor ship has bounding boxes that might prove a little too much. Let's see how's the mesh performance right now. The Palladium Inventor was taking 6.7 seconds before my optimizations. Now with 64 cubes:

quote:

Palladium Inventor - Calculating:
4362 Triangles
SpatialTree Built in 00:00:00.1215812 (96%)
Boxes analyzed in 00:00:00.0001050 (0.08%)
Merged in 00:00:00.0002397 (0.18%)
Total duration: 00:00:00.1265796

Yeah, spatial generation is still annoyingly heavy. This is a full second right there for 8 ships. The good thing is, the collider generation timer is super low, so we might be able to improve their quality a bit! Let's improve the density of the collider box from 64 cubes to 256.

quote:

Total duration: 00:00:00.1522841




That's a 20% increase, a lot more than I expected. Let's try dropping to 216.


quote:

Total duration: 00:00:00.1450774



A ~10% increase instead. I can live with that. We still need to reduce the time spent further though. I'm really not happy about it taking 140 milliseconds as that pretty much 10 times the length of the model generation.

Let's visualize how the voxelization is looking with only 600 triangles:



You know, I'm honestly impressed at how little degradation there was by undercutting these models from 4k-8k to 600 triangles. Their volume seems perfectly intact.

Also, here's the duration for the Palladium Inventor for 20x20x20 = 8000 cubes:

quote:

Risk's Work - Calculating:
Total duration: 00:00:00.1590855

That's barely more than 256 cubes. Since the generator knows whether a ship is player-owned or NPC-owned, I'm considering increasing the cube density for the player while decreasing for the enemies. This should make hitting enemies easier while making the collision on your ship more fair.

Anyway, let's check the troublesome enemy that was taking 17 seconds to spawn, now with all these optimizations.

quote:

Risk's Work - Calculating:
Total duration: 00:00:00.3147556



Yeah, that's a problem case. Seems like the enemies more tightly packed are more troublesome because they'll generate more cubes. Back to 216 cubes:

quote:

Risk's Work - Calculating:
Total duration: 00:00:00.2850471



Ugh what an annoying ship! It's so heavy.

Here's what I'm gonna attempt: Let's try cutting the upper and lower triangles from a model. You know just put them out of the equation. Since the gameplay is 2D, those vertical wings don't really need to be accounted for, and bulkier ships like this only need a few polygons in the center.

quote:

Risk's Work - Calculating:
Total duration: 00:00:00.3258379

Yeah, that didn't work. That actually slowed it down, somehow. Performing a height check on the triangles take a long time. Instead, I'll just really cut down the amount of max triangles since the crux of the problem seems to be the raw loops being executed on them. Let's get it down from 600 to 50 just to see what the hell happens.

quote:

Palladium Inventor - Calculating:
Total duration: 00:00:00.0237235

That's 23 ms. Well that's more than 6 times faster, for starters. Now the boxes take more time than the actual spatial tree. Let's see the bounding boxes...



What the actual hell. How is there no degradation? Why is it so precise? What is this foul magic

Ok, let me generate a few random ships. Maybe we're lucking out.



Why is it working?




So taking a look at the code, I realize that the iteration is only adding the triangles to perform a very, very slow check for concavities that we're not using. So I just disable the whole thing altogether, and set the box density back to 256, what the hell.

quote:

Palladium Inventor - Calculating:
Total duration: 00:00:00.0084406



And it works. Perfectly. Under 10ms. What about the super heavy ship that was costing us a grand total of seventeen seconds?

quote:

Risk's Work - Calculating:
Total duration: 00:00:00.0125442





gently caress.

So yeah, I just had to delete a line of code that performs something useless and the performance increased by literally more than a thousand times. This was an incredible exercise in pointlessness and I could not have hoped for a better outcome for this chapter. I hope I gave you a genuine taste of what coding a game feels like!


NEXT TIME:

More Bugs! Another live chapter of me fixing ShipGen stuff! Greeble!

Elentor fucked around with this message at 05:49 on Dec 30, 2017

nielsm
Jun 1, 2009




Fallen Rib

Interesting.
My first thought would be to have static mesh colliders for each of the prefab parts ships are built from, and basically just use the sum of those. (Very similar to how collisions in Kerbal Space Program work.) Would that still result in too complex colliders, or in some other way make the pipeline hard to manage?

Elentor
Dec 14, 2004



nielsm posted:

Interesting.
My first thought would be to have static mesh colliders for each of the prefab parts ships are built from, and basically just use the sum of those. (Very similar to how collisions in Kerbal Space Program work.) Would that still result in too complex colliders, or in some other way make the pipeline hard to manage?

I thought about that, but I think having compound box colliders would be better in the long run because they have a maximum complexity I can define. The mesh colliders have a multitude of issues, one of which is how big some of these ships may get (like capital ships with multiple parts), or how dense and detailed the meshes might get.

Ultimately, I thought voxelizing was the best compromise and one that frees me from being afraid of performance issues when designing the model parts. As long as loading times don't get out of control, although my biggest concern right now is the memory footprint of the ships.

Elentor fucked around with this message at 10:48 on Dec 30, 2017

Elentor
Dec 14, 2004



Chapter 20 - Improving the ShipGen: Greeble


There are three major issues with greeble right now.

The first issue is that greeble adds volume to the ship. Because there are ship variants (like the same ship getting more detailed if you upgrade it), and because size is normalized and a ship's center of mass changes, that means that the more greeble, the bigger the difference in size and offset between two ships.



The second is that greeble adds triangles to the voxelization process. Sometimes, a lot of triangles. That slows the process down as they're way smaller than the resolution of the spatialtree cubes we're using anyway.

The third is that for some unknown reason, greeble sometimes just floats. I don't know why is that. We need to investigate and find out.



The first and second issues can be solved in a single stroke. Right now the entire model is being collapsed into a single mesh. Instead, we'll split it in two meshes - The main model, and the greeble. We'll then use the main model for the size and position normalization, and for the collider voxelization, and ignore the greeble completely.


Splitting Greeble

Splitting greeble involved very few modifications to the ship-spawning code. I added a simple tag to genes to implicate that an object is a doodad, called from a simple command:

quote:

gene.SetIsDoodad(true);

This simply adds the model to a list after it is spawned, and when the ship is being collapsed, the objects in that list are separated. They're then collapsed into a different object.






That was relatively easy. No big surprises. Let's see if the sizes and offsets are now working properly.



Hoozah! Well that solves the problem. Now on to the next problem, we need to find out the bug that's causing random parts to float.


The Mystery of the Floating Greeble

Like last chapter, I wrote this part in real time as I tried to solve the mystery.

My initial theory is that the greeble is running out of connectors in the ship and somehow the code that fallbacks to reusing connectors is not working, the greeble is defaulting to the 0,0,0 coordinate and because of the ship offset that ends up being in the middle of nowhere.

However after a very quick debug, I find out that that's not the case. I was 90% sure it was that. The code is working fine. My new theory is that the greeble isn't being interpolated properly. See, the way I'm positioning them is by randomly interpolating between the four vertices of a quadrangle that serves as a connector, so the greeble can spawn anywhere inside it. I write a quick code to show the points of every connector being used by a greeble in the Spoony Goon.



This is a bit abstract but uh, I can see the cockpit section matching but the rest of it doesn't. Let's recreate these polygons from zero and add the greeble on top of them.



Hmm everything seems to be in. The free floating stuff you see in this screenshot is connected to connectors that are not showing their backface to the camera, which is normal. The ship seems to be fine.

So why is there stuff floating? The issue then... doesn't seem to be on the greeble itself? Which is kinda weird. I disable the debug visualization.

Right now there are two instructions that add extra parts, called AddAppendages and AddDetails. AddDetails is the one scattering all the little greeble around. Just to double check that AddDetails isn't doing anything wrong, let's disable AddAppendages.



Yeah, this isn't right. Let's do the opposite now. Let's disable the greeble and keep the appendages.



The appendages are fine. So the problem is the greeble. But why? Why is it showing properly in the debug but not in the final model?

Taking a look at the AddDetails function, it seems fine. There's some step somewhere that's screwing things up. Let's turn debug back on, but without AddAppendages.





Ignoring the fact that the side "wings" are not being used (something to investigate later), the first thing that seems wrong is the scale of the objects. The doodads look fine on the debug, but when scaled up they go outside of the ship boundaries.

My initial suspicion is that the pivot of the scaling is wrong, somehow. The greeble gene has an instruction to scale them up 3 to 4 times, so let's see what happens when we disable that scaling.



My stars. Seems like we found our problem. The scaling is messing things up. Which means something is wrong with the scaling pivot. Knowing where to look should make things a lot easier.

Looking at the code, I realize that the current logic is:

1) Set pivot as the center of the original connector
2) Scale object
3) Reset Pivot

If we're offsetting the greeble from the center of the connector, then that means scaling it from the center of the connector no longer works. So we'll write a piece of code to use the offset point as the pivot instead.



This is a lot better. Other than one floating object the issue seems mostly fixed. Taking a look at said object in Maya, I saw that the object was severely misaligned, so it has nothing to do with the code. I fixed it and I think that's it for floating stuff.



Nothing floating, all good. Now let's turn appendages back on and see what happens.



Come on. Okay, that was two misaligned objects, not just one.



A few adjusts later in Maya again and we got this. Looking good! Everything looks fine and dandy.

Now let's see what happens if we add a bit more greeble, for the sake of stress testing.










Come on.




Okay, I'm completely lost. After a quick testing I found out the AddDetails function was spawning cockpits. What the hell?


quote:

new DNAInstruction(MIType.GetModelFromCollections,
new StringRoll[]{
new StringRoll("DoodadsSimple", 160),
new StringRoll("DoodadsMedium", 80),
new StringRoll("DoodadsAll", 40),
}),

This is the instruction being sent in AddDetails. It asks for a model out of three possible collections, DoodadsSimple, DoodadsMedium, DoodadsAll.

quote:

List<StringRoll> doodadsSimple = new List<StringRoll>();
doodadsSimple.Add(new StringRoll("Doodads_Detail", 50));
doodadsSimple.Add(new StringRoll("Doodads_Panels", 10));

List<StringRoll> doodadsMedium = new List<StringRoll>();
doodadsMedium.Add(new StringRoll("Doodads_Detail", 50));
doodadsMedium.Add(new StringRoll("Doodads_Greeble", 30));
doodadsMedium.Add(new StringRoll("Doodads_Panels", 20));

List<StringRoll> doodadsAll = new List<StringRoll>();
doodadsAll.Add(new StringRoll("Doodads_Detail", 50));
doodadsAll.Add(new StringRoll("Doodads_Greeble", 40));
doodadsAll.Add(new StringRoll("Doodads_Panels", 20));
doodadsAll.Add(new StringRoll("Doodads_Mechanical", 20));

These in turn are the collections. DoodadsSimple can pick a model from the doodads_detail or doodads_panels model groups. They don't include the "Cockpits" model group.

In fact as far as I'm aware, Cockpits aren't the default value for anything, and are not used absolutely anywhere outside of the one function that requests the cockpit. So what gives?



Scaling the AddDetails instruction up also increases the cockpit size. So the cockpit is being treated as a greeble.

So checkups:

1) At no point the collection string is being set to "Cockpits".
2) It's not a model being left over from the debug functions.
3) Object calls are from DoodadsMedium, Simple and All, at the correct proportions.
4) The AddCockpit function is only being called once, for the actual cockpit of the ship.

Let's see if something is not right with one of the groups. If we can find which group is spawning the cockpit, maybe we can replicate the error at will.



Pictured is the ship, one greeble away from having a gigantic cockpit stuck on top of it.

So the last object spawned before screwing things up comes from DoodadsSimple, which pools from DoodadsDetail and DoodadsPanels. Checking their folders and models they seem fine. Let me see if there's something funky with the prefabs - nope, they seem fine as well. I'm very confused.

At this point I'm going deeper to see where I can pinpoint the problem. I debug the GetModel function from the Database. This is the last call:

quote:

Get from Collection: DoodadsSimple
Get from ModelGroup: Doodads_Detail
Get Model: doodadsdetail42

What the hell is doodadsdetail42



Ughhhhhhfwhfffnsd why won't this model leave me alone, it's been giving me nightmares all night.






Okay, after a while digging into it, I found the problem. The issue was in the model database builder.



See that Model ID? Each model has a unique ID. There are hundreds of model parts. There's no way a random greeble should have the ID 1.
When I fixed that little greeble in Maya I had the database update it, however due to an oversight it was assigned a non-unique model ID (which matched the cockpit). The unique model IDs are used for me to have a quick integer reference when creating symmetry groups, it's an internal process designed to speed up some calculations.

So yeah, due to an oversight the database didn't assign a unique id when updating an object. I fixed the database to make sure that no matter what happens, every object gets to have an unique ID.

Also in the meanwhile I found the very dumb programming oversight that prevented the side wings from spawning greeble. They just weren't added to the list of stuff that can have greeble. That's fixed now. Now that everything seems in order I change the seeding of the greeble a bit and voila, the Spoony Goon in all its glory:



And there you go. No more floating objects!


NEXT TIME:

More improvements on the ShipGen! Model Skins!

Elentor fucked around with this message at 10:48 on Dec 31, 2017

EponymousMrYar
Jan 4, 2015

The enemy of my enemy is my enemy.


Ahhhh hahahaha.

Fix one thing, break two others

Elentor
Dec 14, 2004



I think for a moment my face went hahaha. To be fair I think a lot more stuff would break from these changes, it all went a lot better than I expected. The bugs however were not the kinds of bugs I expected at all.

Happy New Year y'all.

Elentor fucked around with this message at 07:35 on Jan 2, 2018

Elentor
Dec 14, 2004



Chapter 21 - Improving the ShipGen: Model Replacement


Now I want to implement something slightly diferent, model replacement. The idea is to have skins that replace the base models I've been using so that I don't have to manually set them up in the database again, because the process for doing that is painful. The models need information on a lot of things, like where the connectors are, what are the odds each model is gonna be picked, a bunch of variables and it's better to have a few base pieces so when I pump models I don't have to spend so much time on overhead.

Plus with model replacement a single part can be replaced by different parts, which should give me a lot of creative freedom.

Right now the pipeline for ship creation is:

1) Create Ship
2) Bake UV
3) Separate Greeble from the Ship
4) Collapse Ship and Greeble into separate meshes
5) Voxelize Ship
6) Do other stuff

The problem with the current pipeline is that in order to keep overhead and memory consumption at a minimum, I'll have to voxelize the replacement model. Which makes sense, but kinda puts a bump to the plans if the replacement models are meant to be of higher-definition. I'm not sure how slow the whole process will be.

The good news is - While fixing the last bug on the database, I found some code I could optimize, and the ship creation time was improved in almost 50%! Some of the ships that were taking 13ms are now taking 9ms even with voxelization. That's a huge, huge gain in speed and as a bonus it even reduced memory consumption by a lot. This should give us some space to play with replacement models.

Anyway, let's get to work. I wrote some code to load objects from the new ModelReplacement folders. I don't want these models to have anything special in them right now. Which means I'll have to create a list of model replacements externally. So something like, saying in a separate file that cockpit01 can become cockpit01_hd, cockpit01_hd2, and so on. It might be a bit of work but I don't want to automate this because I want to make models that can be reused by multiple parts.

So I create a class called MPGModelReplacementList, which will hold all the necessary information. Each faction will have their own instances of that class and they'll return different replacement models.

I made this slightly different model to test a replacement.



I already have a list of models indexed by their id, I'm gonna try to loop through them. Since I wrote this stuff one year ago I don't actually remember if the symmetry groups are indexed as well, so we're about to find out.

A few lines of code later, and...



Welp, doesn't look like it worked.

At this point I should stop getting lazy and delve further into the code I wrote a year ago. The model collapser is probably ignoring the new models and I kinda need to figure out why.

I think I'll change my approach. There's a lot of things linked to and from the objects. Instead of manually copying them, I'll just change the mesh of the old part to the new part. That should do the trick.



Welp.

Doing a quick console log on the DoModelReplacement() function I find out that it's not being called, which means a ModelReplacementList (MRL for short) is not being passed. There's supposed to be a MRL for each ShipType and the Player ship has its own ship type.

(A few minutes later)

Ah hell, I realize what I did wrong. I had updated a deprecated script. During my last refactoring of the DNA system I unified everything into a single script and I was using the old one. I should probably delete it.



Uhhmm, something definitely happened, but it's not what I wanted. I get why the colors changed, though, the PRNG moved when trying to choose a replacement model, which means it got to that point. This is easy to fix, I just need to use a different PRNG stream so that the model replacement doesn't interfere with the rest of the generation. The good news is that something is happening, so hooray.

(A few minutes later)

code:
GameObject goRef = mpgObject.modelIDList[item.Key][i].gameObject;
GameObject go = mrl.InstantiateModelReplacement(item.Key, r);

MeshFilter mf = goRef.GetComponent<MeshFilter>();
                    if (mf != null)
                    {
                        mf.mesh = go.GetComponent<MeshFilter>().mesh;
                    }
This is trying to take the mesh from the replacement model and add to the original model, but something I forgot is that the ship parts themselves don't have meshes. They have references to meshes.

I ponder upon this for a while because my first instinct is thinking "did I overcomplicate this?" but then it dawns on me that this is perfect for what I need. Elentor from one year ago, I'm glad you didn't screw things up. Since the data is not tied to the mesh I don't have to do crazy shenanigans switching components. The data structure is mesh-agnostic and can remain intact and all I need to do is change the reference. It makes everything a whole lot simpler.

So I do just that, and voila!



It works! Another one for the list of stuff that was way more painless than I expected.

The colors are not right, though. Again, this is just a matter of knowing how to play with the RNG states. A few tweaks later:





And the feature is done! This feels great, I thought this feature would take a lot longer to implement.


Objects with Custom Textures

I've been thinking - right now the ships need a much better procedural texture, but what if that still won't be enough?

So my idea is to have a single, large texture with a bunch of different materials in it that I can use for reference. Then in the vertex painting I'd assign a specific color that the shader would interpret as a command to read from a different texture.

However, since the UV is baked in real-time for the entire object, that means the object-to-texture correlation would be lost. We need a second set of UV mappings for the same object: One that will be baked, and one that will not and always refer to the same pixels.

Now we just need to figure out which textur...





Well let's see if we can think of something else.

Maybe we can create a third set of objects (Ship, Greeble, CustomTextured). This way we would also take away one texture map from what already is a very busy shader. Yes, that sounds like it could work.

Now we do need to figure out how to decide whether an object uses a custom material or not. I thought vertex paint but then I realized that I can instead use an alpha in the custom texture to let the object fall through to a random texture, and add the UV of parts I want randomly textured use that alpha. This way I can use the same vertex painting convention for all models. If textures get too distorted, we'll change that.

Something that we can do is group these objects by material. So that we can keep adding materials in the future and not be limited by a single texture. This means there might be more than a single customtexture model per ship, but I'm fine with that. I know I'll regret saying this but I don't think draw calls will skyrocket.

So the replacement models can have submodels. I'm thinking of splitting them away and making it so submodels named "S" having shared materials, and submodels named "U" having unique materials. If I don't collapse the unique objects, that also means they could have animations. Hummmm...

I need parts to serve as my guinea pigs.



This one will do nice.



I sketch something on Maya and then I proceed to texture it on Substance Painter. Since I want it to contrast with the current material I make it a rough metal. I add a rubber material to the tube and handpaint some oil in it. After converting the model, it's time to see the results!



I'm really happy with this!

Now it's time to go the extra mile and see if I can implement custom models. I have an idea that might work.

(A while later)



Aaand it works!



I honestly thought these features would be a far bigger headache. Model Replacement and Animated models were something that I wanted, but didn't see myself doing anytime soon until I refactored the code and realized that it wasn't that impossible. Oh, yeah, did I mention animated?



As of this latest feature, the model generator smartly knows which models to bake and which models to separate! This allows me to do these things, at the cost of higher draw calls.

https://i.imgur.com/Sg60TIU.mp4

With great power comes a lot of draw calls, as someone said. But it does look really neat.



Anyway that's it, hope you had as much fun reading as I had coding this stuff!


NEXT TIME:

Textures! New Ship Shader! New Ship Parts! Ships that might look entirely different!

Elentor fucked around with this message at 15:15 on Jan 2, 2018

Pooncha
Feb 15, 2014

Making the impossible possumable

Delurking to say I enjoyed reading these updates and looking into your problem-solving processes.

EponymousMrYar
Jan 4, 2015

The enemy of my enemy is my enemy.


Custom animations on a model and the polish added just make me want to scream "IT'S ALIIIIIVE!"

Synthbuttrange
May 6, 2007



This is turning out really nice

Elentor
Dec 14, 2004



Thanks a lot guys. It's motivating to have feedback.


EponymousMrYar posted:

Custom animations on a model and the polish added just make me want to scream "IT'S ALIIIIIVE!"

Thanks man. Seeing the animation work was something even I didn't expect. It was kinda magical. I still have pipe dreams for the distant future but after one year of work I think I have finally put all the base shipgen features that I wanted. For everything I could hope to include in The Sky Is Dead (or even if I wanted to sell the shipgen) I think it's feature-complete and it's surreal to think of that because of how long I've been working on it.

Now that this aspect of the development is done, I hope you guys don't mind me reflecting a bit on it. The whole thing started over a year ago and when I started I didn't expect to give up, but I had fairly realistic expectations that I would make something basic and then move on because I'd probably hit a problem too hard for my newbie programmer rear end to solve.



This is from Chapter 4 and it's the earliest doodle I still have from when I was planning the generator. I still don't remember what I was thinking or why I thought scribbling 6/2 = 3 was important, what the hell my stream of thought was. I think it had to do with solving the problem of defining arbitrary symmetry axes while having only a single normal as a reference, something that I didn't even consider to be a problem until I ran into it.

Some of the early problems were crazy and I still can't believe I powered through them. I don't think I talked much about it in this LP (or maybe I did and I don't remember, it's been a few months already and 20 chapters), but the UVW Packing problem was by far the hardest thing I've had to deal with. Again, I'm not sure if I've posted this before or not, but anyway:



And an image of my first functional attempt at solving it, before a lot of optimization:



I did not know until I was done with it that this is part of a broader class of math problems called packing problems. Specifically:

quote:

Packing rectangles

Different rectangles in a rectangle

The problem of packing multiple rectangles of varying widths and heights in an enclosing rectangle of minimum area (but with no boundaries on the enclosing rectangle's width or height) has an important application in combining images into a single larger image. A web page that loads a single larger image often renders faster in the browser than the same page loading multiple small images, due to the overhead involved in requesting each image from the web server.

An example of a fast algorithm that packs rectangles of varying widths and heights into an enclosing rectangle of minimum area is here.

Looking at it now, my solution ended up being somewhat similar to the one referenced by wikipedia, in a bit of convergence of ideas. It's the kind of thing I would have loved to know beforehand, but that I don't regret not knowing because ultimately I think it added to my experience trying to solve these problems on my own.

Also I still love my first ship output:



It looks so bad but the fact that it even work and did what it was told to do was like a miracle at the time.

Fish Noise
Jul 25, 2012

IT'S ME, BURROWS!

IT WAS ME ALL ALONG, BURROWS!


I know I keep saying it but goddamn this is the coolest

Elentor
Dec 14, 2004



Thanks a lot!

Right now the thread kinda caught up with my progress. I'm taking a bit of a rest for a few days. With the full shipgen program (and a lot of backups of my progress to this point), the hub interface done (which may suck but it works and that's what I need for the moment), the combat system done, it feels like all that is left is the actual content. As per my planning my next course of action is doing the imperial ships, the items, and the stages. I'd like the next update to come in 1-2 weeks.


In the meanwhile I'd like to ask you guys something.

Regarding thread activity, I understand that a lot of people lurk, but I take silence as a sign that something could be improved. I considered moving the thread to the Games forum. I don't know how good of an idea that is or not because the Games forum moves pretty fast, but it's not like the LP forum doesn't move relatively fast either. However, I think that's a cop out. I always preach to put yourself to blame first if you want to improve. Silence is just a form of feedback, but it is a form of feedback that requires the content creator to be proactive in order to interpret it, which I want to do.

So my first assumption is that there's not more interaction either because the majority of the people find the LP boring, or because there's just not content that is engaging enough to reply. I'm thinking that in contrast with a more traditional LP, people have things to talk about. So far most of the LP has been technical stuff and I imagine there's not much to reply since this is for the most part a dev diary. If you read my previous LP you should know that even if I stick to a more standardized format, I don't shy away from experimenting, and this thread is a huge experiment. The first LPs I read had a lot of community interaction, which is something that's a bit lost, but even when one is LPing an existing game there's an existing product for people to discuss. So I'd like to improve on the format, both for myself (so I can have more feedback on the game) as for the readers (so they can have a more entertaining/engaging thread).

If you're reading this and following the thread, I'd like to know your two cents. Do I have updates that are just not interesting? Are they all an interesting read but fundamentally not engaging in their nature? Should I open the dev more, be more specific, more technical, less technical, and so on? Is it just because I'm doing back-end coding and the content aspect should be more engaging?

For what is worth, I'll keep updating regardless. I enjoy writing and I'm fairly determined (even if the LP take years to complete), but I understand that I'm not without flaws, so feel free to comment on how to improve the format.

Elentor fucked around with this message at 15:04 on Jan 5, 2018

TooMuchAbstraction
Oct 14, 2012

Hubris

Fun Shoe

I'm reading and enjoying what I read, I just don't have much to contribute. My experience with LPs, both as a reader and as an author, is that this is commonly true: most people just don't have much to say unless they've personally played the game being discussed, which is obviously impossible here. But you have 12000 views of this thread. There are people reading it.

If you want to get more thread activity from other people, then give them something to discuss. This doesn't necessarily have to be a vote, it can be things like "I'm considering implementing a system to do X, what do you think?" or "what's you're favorite spaceship design that you don't think most people know about?" or "what's your favorite shmup mechanic?" etc. etc. etc. Your request for ways to improve the LP is, coincidentally, one such thing, so I expect to see plenty of replies here people!

Rosalie_A
Oct 30, 2011


Honestly I don't post because I'm usually reading this on the app and screw long form responses from a phone keyboard.

This actually has been incredibly interesting, though, which is more than I can say for anything I'd reply with.

SIGSEGV
Nov 4, 2010


I'm reading and while I could go "yeah, that's programing for you!" every time code gets a bit wonky, it wouldn't add interesting.

I'm fairly sure putting it in games would just drown it under the fast moving megathreads.

klafbang
Nov 18, 2009


Clapping Larry

I don't think anything's wrong with the content. It is just heavier material than somebody yelling obscenities at a Mario game, so I typically get around to updates when I have the time and not when taking a dump at work and feel less like commenting days or more after an update has been posted.

Also, I don't want the record to show that I have strong opinions about quaternions because I don't.

There was another LP by somebody making a game a couple of years ago... Don't recall how that went down, but they were a bit further in development and showed off gameplay.

nielsm
Jun 1, 2009




Fallen Rib

Echoing TooMuchAbstraction, you need more active prompts for participation. It's super interesting, but there isn't really much to fanboy over or discuss at this point.

Maybe you can produce a "demo" showing off a little thing, like the Spore creature maker, or Worlds Adrift island creator. Since the random ships are a big point, something to generate ships and let participants rate or bucketize them in some manner might be useful too? It could feed into a Markov-chain-style table of parts and relative positions that go well together for various purposes.

Feldherren
Feb 21, 2011


I dabble in game design, but you've actually produced something so that puts you quite ahead of me. Unless I see something obvious to point out, I generally think you know better what you're doing than I do; it's your game, after all. So far it's all been pretty interesting to me, and the problem-solving is something I can appreciate both as a programmer in my actual job and regarding that dabbling of mine.

Everyone's point about needing something to discuss seems pretty accurate, given I only chipped in when you mentioned an issue and I had something to suggest.
I think one of the things other LPs have that your one doesn't, and that may be reducing the likelihood of readers participating, is ... for 99.9% of the rest of the LPs out there, someone else will have played the game in question and hence have their own experiences with the game to relate to and go 'wow, I didn't know you could do that' or 'you missed X' about. Since you're making the game in question, this obviously isn't possible to that degree yet, but when you have something of a game to play, making that available to readers might lead to more input.

biosterous
Feb 23, 2013






I am enjoying this thread a lot! I like reading your thought process and I like seeing the spaceships happen. I don't really have anything to say after each update, though - my knowledge of code is at the point where I can follow what you're saying without getting lost, but not good enough to really say anything. I'm always happy to see a new update, but I never have much to say beyond "I like the spaceships, please keep doing the spaceships like you already plan to."

Basically,

TooMuchAbstraction posted:

I'm reading and enjoying what I read, I just don't have much to contribute.

Dreadwroth
Dec 12, 2009

by R. Guyovich


The last time I messed around in any game design poo poo was back when they released Neverwinter Nights and you could build things in the Aurora engine. I was pretty proud of myself when I figured out how to have these seagulls in the fishing village I was working on following patrol paths using flags. So I'm really enjoying this thread a lot, but like other people have said I don't know enough about game development to really add anything.

CrazySalamander
Nov 5, 2009


I agree with the other posters that there haven't really been a lot of explicit spots for thread participation. If you want to see more posting rather than lurking here you're probably going to have to include jumping off points for people, whether that is in the form of thread contests or something else.

Captain Foo
May 11, 2004

we vibin'
we slidin'
we breathin'
we dyin'


Clever Betty

Hi yes I'm aggressively lurking this thread and am really enjoying it

EponymousMrYar
Jan 4, 2015

The enemy of my enemy is my enemy.


Being mostly Game Design stuff is something that limits audience participation because it's one thing to talk about and dissect game design from a finished product (in addition to 'man when I played this this thing happened and it was wicked,) it's another to watch it in action and see a game come together from that.

Feldherren posted:

I dabble in game design, but you've actually produced something so that puts you quite ahead of me. Unless I see something obvious to point out, I generally think you know better what you're doing than I do; it's your game, after all. So far it's all been pretty interesting to me, and the problem-solving is something I can appreciate both as a programmer in my actual job and regarding that dabbling of mine.

That doesn't stop me from throwing out comments just to try and keep things moving
Although I'm also learning from what Elentor's posting. It's about time for me to buckle down and really look at Blender to make some prototype assets to drop into Unity.

Fish Noise
Jul 25, 2012

IT'S ME, BURROWS!

IT WAS ME ALL ALONG, BURROWS!


TooMuchAbstraction posted:

I'm reading and enjoying what I read, I just don't have much to contribute.
This, again. I'm holding down the brakes pretty hard on how much I want to go "THAT'S REAL COOL" and "HAHA, COMPUTERS" at everything so as to not just turn into noiseposting.

oystertoadfish
Jun 16, 2003



I like and read this thread

for the record

Elentor
Dec 14, 2004



That's a lot of positive reaction. Thanks a lot guys.

EponymousMrYar posted:

Although I'm also learning from what Elentor's posting. It's about time for me to buckle down and really look at Blender to make some prototype assets to drop into Unity.

I'm glad to be able to inspire in some sort. I've also been meaning to learn Blender. When Blender was first released it was so barebones, and nowadays it just looks so complete and in many ways downright better than the applications I'm using.

TooMuchAbstraction posted:

Your request for ways to improve the LP is, coincidentally, one such thing, so I expect to see plenty of replies here people!

Well, you were right.


I intend to open up the item flavor text for contribution in a few weeks, it seems like a really dope idea. I wanted to know before that if there was anything else I was missing.

VodeAndreas
Apr 30, 2009



Clapping Larry

Hi - another lurker.

I like your step by step breakdowns of your troubleshooting process so keep doing those at least?

Adbot
ADBOT LOVES YOU

Woebin
Feb 6, 2006



I mostly lurk in any LP I follow, because I rarely feel like I have much to add (and if I have something that comes to mind but someone else brings it up, I feel like it's not adding anything if I repeat it). That said, I really enjoy this thread so far, and I'm a big fan of PCG stuff in general (I'm one of those people who want to make roguelikes but never actually get going).

As for improvements to the thread, I guess inviting tangential discussion could engage readers more? Like inviting people to show off their favorite spaceship designs from fiction for instance.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply
«15 »