Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1395992 Posts in 67324 Topics- by 60456 Members - Latest Member: Mersy

October 19, 2021, 04:02:43 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogs[Star Stretching Light Speed Effect Explanation] Massive Ship Battle Game
Pages: 1 [2]
Print
Author Topic: [Star Stretching Light Speed Effect Explanation] Massive Ship Battle Game  (Read 3192 times)
enigma27
Level 0
**


View Profile
« Reply #20 on: August 29, 2021, 07:57:01 AM »

 Coffee





What should satellites do gameplay wise? What about generators? Turrets are obvious
I made these models before having an idea of what they will do in regards to the player.

I set up the turret so that it follows the player and fires at them, if on an opposing team.
There were some challenges getting this working well enough.
The turrets are kind of like balls in a socket.
Ultimately the way they turn is defined by quaternions.
But still I needed to track the player to fire at them, which had quite a few bugs.
Example: Turrets could have strange roll behaviors when flying over them.

As for satellites, I wasn't sure what they should do.
Ultimately I settled on having them heal friendly ships.
So, in it is ideal for you to destroy the enemy satellites, so that they do not keep enemies alive while fighting.

As for the generators, they are used to provide shields for other objectives.
If you destroy all the generators, then shields will be lost on the satellites and turrets; making them easier to destroy.

Once all the objectives are destroyed, you can destroy the main enemy ship.
This is the primary game objective. Take down the enemy carriers before they take down yours.

Logged

I like to make tutorials and devblogs. youtube: https://www.youtube.com/channel/UC9CQOdT1A9JlAks0-PF5vvw
moller trumbore ray triangle intersection:
https://youtu.be/fK1RPmF_zjQ?list=PL22CMuqloY0pRNhvBXowdpMtEin8-RFtb
enigma27
Level 0
**


View Profile
« Reply #21 on: September 05, 2021, 06:21:21 AM »





Using profiling to inform coding decisions; a real life example.
To start off, I added the ability for ships to respawn. Giving some forgiveness if the player dies.
That works by adding a spawn component to the entity that needs to respawn fighter ships.
When respawning, you need to know how long you must wait. Which requires text.

So, I created a text rendering system.
I didn't really want to deal with using fonts or any of that.
I had an idea to create a digial clock font and I wanted to test that out.
This works by having quads that are either on or off.
We can define letters based on turning on certain quads.

But I wanted to use some rendering tricks to make this faster.
So for each letter, I used a bitvector to compact what should and should not be rendered.
In the vertex shader, I collapse quads based on this bitvector.
this lets me have a single draw call per letter glyph.

But I wanted to take this a bit further.
What if we could have a single draw call for an entire text block?
I used OpenGL instancing to achieve that.
I pack all of the bitvectors into a single array on the CPU.
Then I do a large instance render in a single draw call, yielding all the text rendered.

This is great... but can we render all text in a single draw call?
Here is where I used batching. Each text block prepares all its data and then requests a render.
But accumulate this data and batch it together.
Then when it is done we invoke one large draw call to render all text at once.
(technically, there is a cut off and it will render all batched calls if some threshold is met)

So, in terms of speed single glyphs should be slower than instancing and instancing should be slower than batching.
But this is not what I observed.
I used visual studio's c++ profiling to find the bottleneck.
Turns out it was a silly bug I should have caught, A previous approaches loop was meant to be removed but still remained multiplying the amount of work done by each character in the string.

I used renderdoc to ensure that the draw calls were looking correct.
I created a stress test level to push the system to the limits and determine if things were working.
I saw massive performance improvements using the batching system.
Logged

I like to make tutorials and devblogs. youtube: https://www.youtube.com/channel/UC9CQOdT1A9JlAks0-PF5vvw
moller trumbore ray triangle intersection:
https://youtu.be/fK1RPmF_zjQ?list=PL22CMuqloY0pRNhvBXowdpMtEin8-RFtb
enigma27
Level 0
**


View Profile
« Reply #22 on: September 12, 2021, 07:32:14 AM »

A from-scratch C++ dynamic 3D animating UI system using spatial hash grid!
I've defined my game's main menu using this system.
Buttons are constructed from shared "lasers".
That is, when we go a screen, the buttons request lasers to make up their shape.
These lasers are requested from a pool, and are interpolated to position from offscreen.
This means that the UI can form in slightly different ways each time, based on previous interactions with the pool (eg sometimes the top border of a button can come from the right, but other times it can come from the bottom).





The text is also animated by hand.
Previously, I created an efficient rendering digital clock font system.
That digital clock system used bitvectors to turn on and off specific quads.
To animate the text, I bitshift the bitvector that determines which quads are turned on/off.
This gives the effect of scrambling the text.
Eventually the bitvector becomes all zeros, which means no text is rendered.
So, to turn the text off, we bitshift away from the correct vector.
To turn the text on, we bitshift towards the correct bitvector.

I have created a Campaign screen used linear single player experience.
I took inspiration from star fox n64 where you could choose your path between planets.
You start off with 3 planet choices to choose from.
Each planet has some limited number of outgoing connections.
If you play and complete that level successfully, then you unlock that planet's outgoing connections.
When levels unlock, their planet gains color and is selectable.
This is how you can create a custom path to the final level.

I have created a "campaign config" which is a json that defines the layout of these levels, and their outgoing connections.

There is also a "save game config" which a json file saved that defines the levels you have completed.

I also created a skirmish screen.
Here, you can set up a custom match with custom parameters, for quick play.

I've also created a dedicated screen for mods!
The entire game is built so that you can add custom models.

I also went ahead and created a game settings page.
While there are not many setting yet, I want to get a place that they can be easily added to.
I built a slider using the custom laser/text ui system.
I used vector math, which projects a vector from-the-corner-to-your-mouse onto the slider line vector.

The entire UI system is build in 3D.
I leveraged my spatial hash system to build it.
All widgets are assigned to cells.
When the mouse moves, it does a cell-ray-cast to determine the populated cells that are under mouse cursor.
It then tests against the cells to find if any widgets are under the mouse cursor, and fires the appropriate virtuals if so (eg OnHovered).
There are some potential optimizations left to be done with that system.

And lastly, I added an exit screen.
It has about as many features as you would imagine for an exit screen.
"Exit" or "Cancel".

I consider most of the work for the main menu UI system to be complete at this point.


Logged

I like to make tutorials and devblogs. youtube: https://www.youtube.com/channel/UC9CQOdT1A9JlAks0-PF5vvw
moller trumbore ray triangle intersection:
https://youtu.be/fK1RPmF_zjQ?list=PL22CMuqloY0pRNhvBXowdpMtEin8-RFtb
enigma27
Level 0
**


View Profile
« Reply #23 on: September 18, 2021, 06:52:03 AM »

Making the game fun with AI and a useful HUD.

The HUD now has helpful elements like health, energy, and game stats.
But I found the debug lines to the ships that were attacking me, actually made the game more enjoyable.
So I polished that up and made a real HUD system that has the debug lines.
To make the ships more visible, I added a red highlight over them using the stencil buffer.

I also created a tool that let's me get a bird's eye view of AI dog fighting.
Having that made it much easier to iterate and change AI behavior.

There were several issues when AI actually fought a player, that were not present in AI vs AI dogfights.
The AI ships were stay too close to the player.
So I added some logic to help space the AI out.
I made this more graceful by having the effect applied weighted on distance.

But tweaking the AI proved difficult.
It was either too hard or too easy.
I decided to blend between the easy AI and the hard AI over time.
This made the enemy ships feel much more dynamic.

Another problem I encountered was that the player could end up in a state that it didn't naturally get much action with the AI controlled ships.
So I created a system checked every so often if the player was in combat.
If it wasn't, then it would assign a nearby ship to engage the player.
This created a constant feeling of pressure on the player, that it was being attacked.

While I added the ability for objectives to function in a previous update, they didn't have a natural targeting system.
But just having objectives target nearby ships isn't as simple as it sounds.
Querying an arbitrary number of spatial hash grid cells each frame is expensive.
So rather, I came up with the idea to amortize the targeting over multiple frames.
I was already doing a walk over all the ships each frame.
So I decided that for this walk, it would process 4 ships for targeting.
This meant that for a given frame, only a few objective processing actually happened.
This works and I can't even notice it with the objectives.
They just work at no noticeable performance cost.
That is, instead of being O(ships + objectives) is O(ships + 4) which is O(ships);
And since each frame already walks O(ships) we're not adding anything to the runtime complexity.

I also needed the AI to naturally take down the enemy carrier ship.
That can only happen if the ship has all its objects (turrets, satellites, and generators) destroyed.
So now enemy AI fighter ships will do bomb runs on the carrier ship objectives.
This is implemented as a special case in the AI fighter behavior tree.

One problem is that the player could just destroy many objectives without really being challenged.
To solve this, when a carrier ship loses an objective, it spawns a new fighter ship to fight the player that destroyed the objective.
This newly spawned ship have their "avoidance" so the fly closer to the carrier ship; this makes them much more deadly towards the player, at the cost of that they sometimes collide with the carrier ship.



Logged

I like to make tutorials and devblogs. youtube: https://www.youtube.com/channel/UC9CQOdT1A9JlAks0-PF5vvw
moller trumbore ray triangle intersection:
https://youtu.be/fK1RPmF_zjQ?list=PL22CMuqloY0pRNhvBXowdpMtEin8-RFtb
enigma27
Level 0
**


View Profile
« Reply #24 on: September 28, 2021, 03:44:43 PM »

Adding audio to my engine.
I used OpenAL as the API is similar to OpenGL, the graphics API of this project.
I've added sounds to ship engines, lasers, explosions, UI, and more.
OpenAL makes Doppler effects easy, it just works out of the box.
I know there isn't sound in space, but I'm take a more stylized approach and wanted sounds.

I also made the audio system work with time dilation.
We can scale the pitch of audio by the current time dilation factor.
This has the effect of making the sounds sound deeper in slowmo, and higher in fast speed.

I created the entire system with a top down approach.
To know how it works, you can to the AudioSystem::tickAudioPipeline function.

I also created some debugging tools.
You can enable a cheat that creates visual shapes at emitter locations.
This can be used to get an idea of what is causing a sound and where it is at.
I also created conditional logging that can be used to track emitter states.
This type of logging was perhaps the most useful in diagnosing problems.



Logged

I like to make tutorials and devblogs. youtube: https://www.youtube.com/channel/UC9CQOdT1A9JlAks0-PF5vvw
moller trumbore ray triangle intersection:
https://youtu.be/fK1RPmF_zjQ?list=PL22CMuqloY0pRNhvBXowdpMtEin8-RFtb
enigma27
Level 0
**


View Profile
« Reply #25 on: October 07, 2021, 03:13:51 PM »






I've refactored the rendering system in my engine.
The old way of rendering was complete in SDR.
In this update I created a separate off screen framebuffer that everything is rendered to first.
This offscreen framebuffer is a float framebuffer, and can store values outside of the normal [0,1] range.
This allows me to store realistic lighting values.
Before the imagine is rendered on screen, the offscreen framebuffer is put on the main framebuffer and mapped back to a [0,1] range using Reinhard tone mapping.

To make things look better I added a simple bloom implementation.
It just collects anything emitting light greater than some specified value.
A series of Horizontal and Vertical Gaussian blurs are applied to the high light value colors and then blended back onto the final image.

I added a fire effect behind the ship to give illusion that something is actually pushing the ship forward.
Logged

I like to make tutorials and devblogs. youtube: https://www.youtube.com/channel/UC9CQOdT1A9JlAks0-PF5vvw
moller trumbore ray triangle intersection:
https://youtu.be/fK1RPmF_zjQ?list=PL22CMuqloY0pRNhvBXowdpMtEin8-RFtb
enigma27
Level 0
**


View Profile
« Reply #26 on: October 12, 2021, 05:14:15 AM »





The Space Jump effect is pretty simple when looking at its individual components.

Previously I created a 3D star field for the environmental rendering.
I use the 3D locations of these stars in the effect.
When the effect starts, I start cranking up the light emitted for each star.
This is done by just multiplying their light color by a larger value, which is captured in the HDR frame buffer.
Next I stretch out the stars.
This is done by creating a scale matrix that is applied before the stars have been rotated and positioned.
The effect wouldn't be complete without audio.
While I'm no audio engineer, and the sounds could be better, I'm happy with where I landed on them.

I was using time dilation to test things, and I realized that it would actually be a pretty cool game mechanic.
So I made it a first class ability.
For every three enemy fighter ships you destroy, you are given a single slow motion ability.
This ability can be saved for pressing times, such as when you are destroying objectives and have the more difficult hunter ships on your tail.

I felt the environment was a bit lacking, so I added asteroids.
The AI needs to avoid them, so it wasn't as simple as throwing a static mesh into the world and calling it done.
So, I made a system called avoidance meshes.
These meshes have "avoidance spheres" that use the system I made so that the AI would not fly into the large carrier ships.
You can go to the mod menu and create these for your own mods.
You can specify the mesh to use and hand tweak where the avoidance spheres are placed.
I've tried very hard to make the entire game, at least in terms of content, built through the mod tools.

And that wraps it up for this update!
Logged

I like to make tutorials and devblogs. youtube: https://www.youtube.com/channel/UC9CQOdT1A9JlAks0-PF5vvw
moller trumbore ray triangle intersection:
https://youtu.be/fK1RPmF_zjQ?list=PL22CMuqloY0pRNhvBXowdpMtEin8-RFtb
Pages: 1 [2]
Print
Jump to:  

Theme orange-lt created by panic