1. Deep Space Exploitation
  2. News

Deep Space Exploitation News

Mines, Giant Asteroids, and Story

[p]Hello![/p][p]There has been a lot of progress recently but not a lot of big exciting things to show off, apart from maybe the mines. Mostly I've been working on story and levels to build out a single run of the game to the length I want. I think this has also been the longest break in dev logs, which shows I've either run out of interesting things to talk about, or I've been way too stuck in the details of everything and now need to come up for air.[/p][p][/p][p]Mines![/p][p]As part of adding some more chaos and danger to the levels I worked on some exploding mines. They're quite simple, in that generally they will explode if you get too close, but combining that with physics and the ability to hide them makes for some fun and unpredictable scenarios. There's a story reason for these mines being here while pilots are engaged in peaceful mining activities, but I'll talk about that a little bit more below.[/p][p]There's a Seeker mine, which will roam around the level looking for a target, and once it finds one will follow it until close enough, and then explode! This uses the same pathfinding as the Drones, though I had to update it to be able to deal with pathfinding to a constantly moving target. I also got to test out the pathfinding's parameterisation of minimum path widths, since I wanted the Seekers to move quite close to things and not take a longer and safer path. Here's a gif of one creeping up on the player:[/p][p][/p][p]There's a very simple "touch" mine, which has four pressure points on it which when touched will detonate the mine. Pretty standard but also useful to the clever miner who can have them explode where they want. I actually ended up updating some core entity code for these guys since I wanted to be able to embed them within asteroids and have their pressure points work perfectly.[/p][p]
[/p][p]The third type is the Jumper, which are definitely my favourite (maybe for obvious reasons). They're embedded within asteroids, sometimes visibly and sometimes not, and jump out of the surface to explode as close as possible to a target. If you're fast enough you might even be able to catch one...[/p][p]
[/p][p]Giant Asteroids[/p][p]I'll quickly mention some giant asteroids that I've been adding in preparation for some more "diggy" tools I'm thinking to add. When adding these I had to update some of the game's screen wrapping code to handle entities that could be off both the top and bottom of the screen at the same time, which had just never happened before. I also found out that the wrapping code happily handles giant entities colliding with themselves![/p][p][/p][p][/p][p] (Giant banana is for illustration purposes only. I can't guarantee that there'll be a giant banana in the game.)[/p][p][/p][p]Story[/p][p]Much of the work I've been doing recently is on writing the story and events that take place, and then building out the rest of the levels for a full playthrough. I didn't start this project with the goal of writing a cool story, but I knew I needed some form of story in order to give the game structure. To that end, I wanted the story to be simple and coherent, give an actual reason for the events and scenario of the game, and then not get in the way of people just playing the game. I've heard a few people actually describe the writing as good, which is not something I expected, but I think the best thing for me is to not focus on making an amazing story, just on an overall good game.[/p][p]So the story I've been working on involves an organised resistance group, the mining corporation becoming more involved with military corporations, and general background worker exploitation. Through all of this you are trying to pay off your debt before your contract is up. This all ties together through your choices, some of which are very explicit (like replying to a mail) and some of which require a little more commitment and action from you (trying not to spoil anything here). But what I've ended up with here is a story with multiple endings, which is cool but now I have to keep track of these endings and provide some satisfying closure for each. :)[/p][p][/p][p]Full Playthrough[/p][p]I've now finished a first draft of all of the levels and general flow of the game. I've been aiming for 4-5 hours for a single playthrough, then there's replayability for different story choices and upgrade/money choices. This has been one of the most challenging parts of development for me, having to sit down and think of levels that are interesting, fresh, and let players play how they want. But I'm happy to have done it, and I'm excited to start play testing the whole thing and see how it holds together.[/p][p][/p][p]What's next (or what's left)?[/p][p]Now that finishing this project is feeling closer than ever, there are only so many things left on my todo list. So I think in roughly this order, this is how I'm going to tackle them:[/p][p]- Play Testing.
A few full playthroughs of the game as-is will help me take proper stock of everything.[/p][p]- Endings, Prologue, Epilogues.
I need to properly track each ending and see how I can make each one satisfying, then create epilogue cutscenes for each. Probably more on this in another devlog.[/p][p]- More upgrades!
Lots of ideas.[/p][p]- More tools!
Even more ideas.[/p][p]- Localisation.
I'm going to sit on this one for a bit first, not sure whether I want to do it before or after release.[/p][p][/p][p]We'll see how all of this goes :)[/p]

Devlog - Procedural Generation

[p]Hello![/p][p]Recently I've been busy working on procedural generation for levels, which is something I didn't originally plan for but started to look more attainable as time went on. Much like the previous work I did on path finding, there are some difficulties that come with doing this kind of thing for a free-form environment and not one that's nice and grid based, which I'll talk about more below. Even though I'm still planning to hand design a lot of the levels, this will really help to add some extra choice for players, and even open up the possibility for an endless mode once the main game is finished.[/p][p]Quick note on the gifs in this post: to be able to show the generation slowed down like that I hacked some stuff together (which I explain at the bottom of this post). In the actual game this generation happens in milliseconds.[/p][p][/p][p][/p][p][/p][p]Deciding on Proc-Gen[/p][p]Originally I only planned on using procedural generation for the textures of the asteroids and not the levels themselves. My idea was that since the game isn't going to be infinitely long, and procedural generation is hard to actually make good and interesting, I could hand design each level instead and reap the benefits of a human touch (like placing resources specifically to trick players or give them a huge payoff). I had a huge love of procedural generation when I first started programming, and made lots of little experiments but also wasted a lot of time trying to get the results just right when I could have been putting more effort into other things. So this was partly influenced by me not wanting to get stuck with a task I wasn't sure I could actually pull off.[/p][p]Now though, decent procedural generation started to seem more attainable. After working on the game all this time I felt I had a much better understanding of what worked and what didn't for levels, and how I could have that pieced together randomly. This is partly confidence from having hand-built a lot of levels, and partly from having more tools available to use for this (I say tools, but I mean clever code for interacting with the physical shapes of things).[/p][p]I decided to give myself one week (which turned into one and a half after other commitments) to have a serious go at it, so what you're seeing here is the result of that. I'm quite pleased with the result, and I think it can only get better with tweaks and added features.[/p][p][/p][p]Step 0 - Parameterisation[/p][p]The generation is actually quite heavily parameterised, with me specifying exactly how many asteroids of each size and type, how many resources of each type, what destruction to apply, and finally what other entities to place. Because of this, I'm a little reluctant to call this "procedural generation" since it's more just clever placement of things. When I think of procedural generation I think of the huge worlds of games like Dwarf Fortress. But this approach works well for me because I do want to really specify what goes into a level for the purpose of balance and some form of predictability.[/p][p][/p][p]Step 1 - Asteroids[/p][p]The first step is the placement of asteroids, since they're the largest objects on each level and everything revolves around them. There are four different sizes of asteroids (Large, Medium, Small, and Tiny) and currently three different types (Purple, Red, and White), with parameterisation allowing to specify exactly how many of each we want. There are also asteroid presets, which are hand designed placements of asteroids, with each asteroid shape having roughly four presets to choose from.[/p][p]Very roughly, this is the process for placing the asteroids:[/p][p]1. Select the largest asteroid size available[/p][p]2. Select an available asteroid type for this size[/p][p]3. Find a random place for this asteroid with some additional padding around it[/p][p]4. Decide whether we will use a preset[/p][p] 4.1. Find all presets which we have available asteroids for[/p][p] 4.2. Place a preset which doesn't intersect with other asteroids[/p][p]5. Decide the total number of asteroids in this cluster[/p][p]6. Place asteroids in this cluster until we reach the total number[/p][p] 6.1 Choose a random asteroid in this cluster[/p][p] 6.2 Choose a random size smaller than this asteroid that we still have availability for[/p][p] 6.3 Place a new asteroid of this size next to the current asteroid[/p][p] 6.4 Repeat until we've placed all asteroids in this cluster[/p][p]7. Repeat until we've placed all asteroids[/p][p]I find this strikes a decent balance between being random, interesting, fun to fly around, and also semi-natural looking. I'm thinking to experiment with broader rules, such as making everything more scattered or condensed.[/p][p][/p][p]Step 2 - Destruction[/p][p]Next there's the chance for some destruction to be added, so that the level looks like someone else might have been here before and done some mining. This is done before placing any resources or entities so that we don't place anything exactly where we make the destruction and make it look like someone excavated some resources but then decided not to take them. The destruction is also physically simulated so that asteroids look like they've actually been moved by what's been damaging them, and having resources/entities placed while that is happening can make things look a little too random.[/p][p]At the moment there are two types of destruction for randomisation; explosive charges, and bullet impacts. The destruction for explosive charges is positioned on the circumference of Large or Medium asteroids, since placing them on smaller ones can completely obliterate them, making it pointless to even place them. And the destruction for bullet impacts are positioned starting from an empty point in space and then casting rays out in a fan to see where bullets could impact, and then creating small destructions for those positions. After each destruction there's a random chance to place some debris associated with it, such as shrapnel from explosive charges, or un-detonated bullets from bullet impacts.[/p][p][/p][p]Step 3 - Entities[/p][p]These are the different entities that we might want in a level, like the scrap processor or random pieces of scrap lying around. I plan to add individual rules for each of these so that I can have specific results, instead of trying to come up with one master rule for everything. So if I want one level to have a container that's always empty, I might specify rule CONTAINER_EMPTY in the parameters, or if I want a later level to have a container with some good loot in I might specify rule CONTAINER_LOOT_3. [/p][p][/p][p]Step 4 - Resources[/p][p]And finally there are the resources, which are parameterised by type (Blue, Green, or Red), quantity, and the range of depths they can be placed at. Currently, there are rules stating which asteroid types a resource can be placed on (Blue crystals only on purple asteroids, for example), and for each asteroid shape I pre-compute the resource placement positions and their depths, so when it comes to placing resources we do the following:[/p][p]1. Choose a resource to place[/p][p]2. Get all asteroids this resource can be placed on[/p][p]3. Get all placement positions for the given depth range for these asteroids[/p][p]4. Choose a placement position out of these positions that doesn't overlap with an existing resource[/p][p]5. Place the resource there[/p][p]6. Repeat until all resources are placed[/p][p]This is fairly simple but allows for good distribution of resources in the level. I do want to improve this by forcing some clusters of resources, or giving a larger weighted range of depths, so you can specify that a resource could be placed at depth 1, but it's much more likely to be placed at depths 4 to 6.[/p][p][/p][p][/p][p][/p][p]Hacking these Gifs together[/p][p]I wanted to show gifs of the generation happening in somewhat slow motion, so you can see what's going on. In the actual game this generation happens very quickly (Under 100ms in debug, which makes me think I have a lot more room if I want to use more complicated logic) so I needed to slow it down and also show it happening in real time while the level is running. [/p][p]First I tried throwing it on a separate thread and locking between updates so that the main thread and the generation thread weren't fighting for the same resources, but even that didn't work because of some restrictions to using graphics components off of the main thread (I generate each asteroid's texture as it's created).[/p][p]So what I ended up doing is turning each method in the level generation into a C# Generator Method, which basically means that execution can pause and return at specific points. With this I can do everything on a single thread and wait for a timer to elapse between each level generation step or placement. Fun![/p][p][/p][p]What's Next?[/p][p]Now that I have this working I'm able to very easily add more "filler" levels between the more interested hand designed levels. It also means I can hand design more levels as whatever the procedural generation outputs is completely editable using my makeshift level editor, so if I see it generating something that I know could be better, I can do a few manual tweaks and voila.[/p][p]This also sets the game up well for a potential endless mode after release. Though I won't go as far as to promise this, because I have no idea what the state of things will be once I actually get there.[/p][p]If you've got to this point, thank you so much for reading, and I hope you found this all even slightly interesting. If you did, be sure to check out Deep Space Exploitation on Steam![/p]

Demo v0.6.6 - Scrap!

[p]Hello!
This is everything I've been up to over the past two weeks. Adding more interaction to the game, gearing up to create the full length of the game so I'll have an end-to-end that I can start refining, and of course working through improvements and feedback from people. So here are the major changes, minor changes, and bug fixes I've done for v0.6.6!

Scrap Processor Jobs
As a bit of variety and also story, I've added scrap processing jobs where you can collect items of scrap and feed them to a scrap processor which will then process them into a higher value cube. This is meant to be a bit of fun interaction but also provides a bit of opportunity for the game's story, as well as helping to enrich the game with more mission types and interactions.
This is also linked to an upgrade for the player ship, which is available in the demo but hidden as a little secret...



Destruction Code Update
I've updated the code used for creating asteroid destructions so that now it can take arbitrary shapes as input (Up until now it was only circles). This was necessary now so that I could allow any shaped item to be attached to an asteroid and then be dislodged when hit and leave only a hole of its own shape.
This also prepares things very well for shaped charges and other things that will leave a non-circular impact on asteroids.
I've also improved destruction so that there are no false pieces of asteroids left over. By which I mean pieces of asteroids that are drawn but don't actually have any physical presence backing them up. This happened quite a lot when using the gatling gun repeatedly on one area of an asteroid.

Tutorial Rework
I've had the massive fortune of being able to watch a few streamers and youtubers play the game recently, and I noticed that the tutorial definitely needed improving. The main problem was that it was too easy to miss the sections explaining the Scanner, since you could blow right through them without even reading.
I've reworked things now so that you have to go through the scanner explanation first before your mining gun activates, since what I saw before was as soon as the mining gun would activate people would just keep blasting and they would accidently complete the scanner tutorial steps.

Level Editor Updates
I've updated the makeshift level editor I use so that items can be chosen and placed much more easily and starting destructions can also be added.
This is a super makeshift, solo-dev, style level editor that uses a bunch of confusing hotkeys and outputs code to a text file that I just copy/paste into the class for the level. Which is all fine because it's only me who's going to be using it :)
I uploaded a little video of it here:
[dynamiclink][/dynamiclink]
Maximised Windows
Another thing I saw when watching streamers play was an annoying issue where if you try to maximise the game window (not fullscreen) on 1920x1080 the game's integer scaling will kick in and force the game resolution to the integer below, effectively making the game appear rendered much smaller in the middle of the window.
This was happening because the title bar takes up some pixels and actually makes the window height about 1051, which the integer scaling doesn't like.
This went unnoticed forever because both of my monitors are 1920x1200, so it's my fault for not testing natively with the most resolution!
The simple fix was to give a little vertical tolerance to the integer scaling, so you can lose some pixels off the top and bottom of the screen before it will kick in and change the actual resolution.



Other Changes
- Default tool hotkeys now use backtick for Activator Tool, then correct number keys for tools
- SFX and UI volumes default to 75%
- Tutorial tells you that you can rebind controls
- Increased physical size of player ship cargo hold, so picking up certain items is easier now
- Volume selectors and Debt Repayment amount selectors now change in higher increments when holding down buttons but still move in single increments when tapping.
- Market now shows tool ammo amounts and cost before buying
- Debug overlay (via backtick) is no longer available in release builds
- Any item can now be attached to an asteroid
- Changed confusing "TL_..." style statuses back to "TOOL_..."
- Improved checks for entities stuck inside other entities, should now kick in faster on actual instances and less altogether on false positives
- Added check for unsold resources in cargo before starting a job. A popup will show asking if you want to continue
- Improved physics particle performance drastically in worst case scenarios
- When buying an item in the market you are now prompted over whether you want to place it in your cargo or storage
- Loans will now cover any negative credits you have, plus 100
- Some items will now appear in the market earlier
- Storage slot count reduced to make it more important to buy the upgrade
- Debt repayment page starts with the amount selector selected
- Re-ordered the terminal pages so that Inventory is before any other page where you can spend credits, so you can go straight to selling your resources and then go to spend the credits instead of going up and down

Fixes
- Can no longer rotate asteroids with (invisible) mouse-over and scroll
- Laser reflections are now limited in number, this fixes a crash where the laser start is stuck inside an object and reflects infinitely
- Unused extraction ship bays are now "filled in", this stops the player glitching into them and getting stuck if they're positioned on the edge of the map when the extraction ship enters
- Fix for laser sight line effect being accumulating over a number of days
- Tools no longer stay active if held down when extracting
- Late extraction fines are now actually applied (time below zero was not making its way to the debrief page!)
- Property damage fines weren't being reset when you restarted a job
[/p]

Demo v0.6.5 - Next Fest Feedback

[p]Hello!
Next Fest has been pretty intense so far. A lot of feedback and chatting with players about the game. Here's a collection of tweaks, bug fixes, and even a couple of minor features I managed to get in for version 0.6.5 of the demo.[/p][p]Next Fest is still in full swing, so if you haven't played the demo yet, please do and let me know what you think![/p][p]Laser Sight
Special mention for the laser sight, which I'm really happy with (it reflects and lights up particles!).[/p][p][/p][p]Features
- Laser sight upgrade
- Volume settings are now split between SFX, UI, and Music, and can be set from 0 to 100 (previously 0 to 10). This should help streamers who have more sensitive setups.[/p][p]Balance
- Hammer easier to control
- Some items are cheaper now
- Crystals sell for more
- Don't show cycle tool reminder on charge training day
- Charge training hints at key for dropping charges from cargo
- Added status notification for an empty tool slot
- Lowered damage necessary to force a container open
- Increased time limits across all days
- Scanner tutorial step now requires you to get closer to the scanned resource
- Some wording changes in mail messages[/p][p]Fixes
- Default key bindings are set properly, instead of the debug ones
- DPI Awareness is now working again (proper resolution scaling when you have Windows scaling set)
- Activator tool sprite now drawn on the correct layer
- Possible fix for losing BASS audio after PC wakes up from sleep, plus additional logging around this in case the issue persists
- Stopped null tool drawing pink sprite
- Fix for culture variant text comparisons. This was causing crashes due to Font validation on PCs with certain locale settings
- Log file uses 24h time instead of incorrectly using 12h
- Hammer retract animation now plays properly
- Mail reply scroll bar no longer shows on other mail pages when there are no replies
- Additional logging around entity wrapping and asteroid destruction to help with an investigation into a wrapping bug
- Extraction ship typo when extracting ("EXTRACING" -> "EXTRACTING")[/p]

Devlog - Pixel Art Laser Effect

[p]Hello!
One frequently requested ship upgrade in the game is a kind of laser sight (and lasers in general!) to make lining up shots easier. So in preparation for Next Fest I thought I'd try and get this in, along with some of the cool ideas I had for it. I think it turned out really nicely and paves the way for mining lasers to be added soon. I thought I'd give a little explainer of how I went about creating this effect, since it's not too complicated and only really requires knowledge of stencil buffers.

Before I get into it, I'll quickly mention that everything I talk about here is live in the demo that's currently on here Steam. Next Fest is a big deal for tiny indies like me, so wishlisting the game and sharing something about it around this time would really be awesome.



Step 0 - What do we want?
Most of all, this effect needs to be useful but not overwhelming. A big bright red line across the screen would be really dominating and take visual precedence over other things in the scene. Next, it needs to look convincingly like a thin beam of light and not some debug overlay. And finally, we want some cool simulation-like details, like lighting up other things along its path and reflections.
[/p][p][/p][p]
Step 1 - Tracing the path
To trace the path of the laser I use ray casts against the physics objects in the game world (I've avoided calling these lasers ray traced, even though I'm technically tracing them with rays). I start from the player ship in its current facing direction, find the closest intersecting entity, then either stop there if the entity is non-reflective (like the asteroids) or continue from the intersection point using the normal of the intersection to calculate the new direction of the laser. The tracing continues like this until it runs out of distance.

For each ray cast we store data about the position, direction, and what it intersected with (if it intersected at all), which we then use for drawing everything.

One caveat to all of this is that I wanted the lasers to wrap around the game world like everything else, so at the start of each ray cast I calculate the distance to the edge of the play area in the current direction, and only cast the ray for that distance. If the ray reaches that full distance without intersecting anything then it means we have to wrap around to the other side, in which case we continue with a new ray cast with the starting position adjusted.

Step 2 - Basic Drawing
The basics of the effect are the fading out and fading in lines at the start and end of each segment of the laser, and the glow of the laser on the entity it collides with. The fading lines are draw point-by-point using Bresenham's line algorithm, this lets me draw the line without any aliasing (so it's guaranteed to be 1 pixel width) and also allows for better control over the fading out of the colour on the line (currently the fading is linear, but I'm thinking to bucket it so it has more of a pixelated feel). The glow where the laser collides with an entity is done by first writing the colliding entity's sprite to the stencil buffer, then simply drawing a sprite for the glow using that stencil (If you're not familiar with stencilling, check out this OpenGL explainer: https://learnopengl.com/Advanced-OpenGL/Stencil-testing).

This gives us our basic laser effect, which works well and gives us everything we need exception for a few extra details.

Step 3 - Particles

One cool thing about lasers in real life is seeing them light up dust in the air, or lighting up a line straight through smoke, so it would also be cool to have that happen with this laser effect. This is done in a similar manner to the glow on the colliding entities. First we write all particles to the stencil buffer, and then we draw a line for the laser using that stencil. This particular line we draw is done using a sprite which is stretched out along the line of the laser, this lets us get a wider and softer glow, and is also much more efficient than tracing out the whole thing point by point.

Step 4 - Background Glow
Finally, I thought it would be nice if you could actually see the laser in the background of the destroyed asteroids, as if the laser were coming super close to the background but not actually hitting it. Much like step 3, this is done by writing the asteroid backgrounds to the stencil buffer and then drawing a very faint line with a stretched out sprite using that stencil.

Steps 3 and 4 are both done simultaneously for all lasers so that we only have to write the particles and asteroids to the stencil buffer once per frame.
[/p][p][/p][p][/p][p][/p][p]
What's next?
There's plenty more I'm thinking to do with this, like having the laser refract from some entities instead of just reflect, or having the reflection only happen at certain angles. I've realised this is the kind of thing I love most about game dev, just messing around with little effects and then seeing how they can contribute to the fiction and gameplay of the whole game.

The majority of the work done for the laser sight upgrade is kept in a reusable laser effect, which I'm planning to use for more lasers (especially a mining laser). This is quite versatile as the effect collects data for each segment, such as distance and intersecting entities, which can be used to calculate damage or perhaps activate things.

Thanks very much for reading :)[/p]