Die to Survive - Railshooter

Here is a short video of a last test i did before changing to the new gore-system and new models that comes with it.
I also addet for now:

  • Option to chose if you want to use auto reload
  • Option to display points at impact point or not
    I hope to have the new version ready to go tomorrow.
1 Like

The new demo is out now. Sadly i noticed a bug with the displaying of the points, so i needet to remove it because this was the final build an i simply dont have the time to fix it (only a few hours left).
But the most important new gore system and the new models for it are in there, beside a few other improvements.

Die to Survive on Steam (steampowered.com)

1 Like

Played RE4 remake recently I like what they did with the shooting range, you get a handgun which shoots through multiple enemies, sniper for precision, shotgun for multiple guys but you also got to make sure you hit special parts for bonus points and avoid hitting good guys. Could be a mode, or randomized, or something :).

Looking good btw. Just wondering why you have a revolver icon on a different handgun hehe (0:22).

Was just checking this, thank you for pointing this out. Seems like i recordet the video before i changed this. It is the right image for the gun now :slight_smile:

I did not play RE4, but the weapons i am still not sure how to handle them. But i noticed i made another mistake with adding them directly to the player. I think i would be much easier to handle changes if i change this to a component.
I set the weapons very early this way and did not touch it much sins then beside expaning.

After quite a while and testing a lot of different things and a lot of coding to change and improve things the game needs i finally have something to share again. It is more about the experience and how controling the menus.
The primary focus and goal was to control the whole game with a lightgun.

So the widgets are much bigger now as i get anoyed myself to hit the to little buttons to use certain options. Still WIP but this is very close to how it will look now in the end.

I also redo the whole challenge system to be more flexible. Basicly i can now change everything for every game mode and difficulty per level to give a more in deep system to have a lot to do.

1 Like

Hi there @Thorsten09 ! Welcome back to posting with us here on the forums!

After getting caught up on this project, I’m very curious to see how it continues to progress! Games like this bring back memories from when I was just a small kid, haha. It’s beautiful what you’ve created and I love seeing your quick advancements!

Keep up the good work, you got this!

1 Like

Glad to see you back at it.

Thank you that is exactly want i wanna do, he idea is to create a game like the old lightgun shooter.
But i also know how easy you reach the final of the game and get the 100% if you like this kind of games.
This is the reason why i gone so far now where i can basicly create now endlesss challenges combiened with difficulty and game modes.
Not sure how i will use it in the end but there is a lot of potential in replayablilty if you like to do challenges like me.

1 Like

Thank you, i try to bring it now to the finish line. Will still take a few month. But feels like now the last part about how keep people playing and have fun is ready.
Need to rework the whole UI though, almost all feedback i got was from people who use lightguns.

I also try to keep the people happy and like to play just this one more round.
This is why i came up with this crazy ammount of challenges where i can mix all togehter.

1 Like

So a modular gamemode subsystem?

Yes i guess you could call it this way. It is very flexible now.

First you chose a Game mode (Like what you see within the first example picture). Based on this the structure of the challenges will be set,
For example: if you do a „time mode“ run the most what will make sence is to sort the leaderboard for the fastet time you finish the level.
This is also the base structure of how all the following settings will be based on.
So if i have an crazy idea like a Dimsember the most body parts gam mode the following will be based on this.

The second would be the level selection. Here i can set the challenges that needet for the selected level. I used a scrollbox to be felexible to add what ever challenge i create. Each level is done independent from other levels.

The third is the difficulty. This way you can also change the challenges and of course the numbers that are needet (so you can have 4 at the moment for each level)
You can tweak the challenges and also the game itself with more/less enemies for example.

The whole system can easy be tweaked around the game mode/level/difficulty.

The downside is it really slows down the setup of this in blueprints. It is really slow because you have as a base at the moment 4 GameModes, 12 Levels (seperated into 6 normal level and 6 boss level to make at a later point simple boss rushes if i want to) and 4 Difficultys. So 4 * 12 * 4 = 192 base. And then comes the challenges also … So you can multiply the data with 10+ what make this to be more then 2k in the end.

At the moment i rework also the leadboards, because this will also need the same ammount of them. And of course the system i have in place to calculate things like accuracy, limb counter and so on.

But i also know it will be kinda a nightmare to test and set up this all with this crazy ammount of posibilitys. Maybe it will be best to make something like early access. I cant really see this done on my own alone without a lot of input.


1 Like

Here is also a pic of the leaderboard setup i test today. Maybe it is easier to see how the selection works there.

Edit:
Turns out to do the Leadboard this way is almost impossible. I should have calculate before testing. This way i end up with almost 100k data in a single game mode struct. It´s just not doable. So i need to find a better way to store the leaderboards. Sounds good and easy to handle on paper but it is definitely not the way to do this.

Guess will need to go back to try the DataAssets again even if i hade problems with using them the time i tried (not the usage but compiling almost crushed the project a few times).
But it seems like this is the way to go for something like this.

1 Like

Remote Database?

1 Like

This i was thinking to do some sort of weekly or add new stuff. But i dont want to do all online. Was only thinking about such for later maybe.

I really want to avoid DataAsset, at least the use of it within Blueprints. Need to look deeper into this if this all can be done only with cpp. I guess it should/must work, but i just not know how to do it at the moment.

Still wraping my head around to use only structs. You cant save DataAssets directly with changed values into a savegame as far as i know.

For now i play a little with my thoughts and how to arange it a way to be easy expandable and also possible without the need of blueprints to set it up.
A little image of my thoughts. Just moving around the things i need a little to figure out a way to make it work the way i want.

You can’t load the entire leaderboard on the client if you have lots of players.
Typically, you will have a server that deals with this, that serves something like:

  • top 10 entries
  • 10 entries around current player’s best score
  • 10 entries around current player’s current score

Those, you can easily supply to the client.

How to implement a correct “You’re in 8,901,234th place!” counter for a large leaderboard is actually an interesting challenge in itself, so maybe you should use Steam or EOS or something that already does this for you …

1 Like

Thank you for the suggestions, i really appreciate it.
I will definitly do Steam and EOS leaderboards at a some point, so people can see how well the do compared with other players online.

The leaderboard is more a logical problem i struggle a little with at the moment.
I want to have for all levels and the dificultys a own leaderboard. To handel this easy, Structs array based looked like the best way (just easy to run a loop with). but the cascading effect make it to big. not for the data this is kinda easy to do with array. but i noticed if the data gets to big, the setup of the different challenges are very slow within a blueprint(the movement of the mouse and typing). Have to say at the moment i have all set to “editanywhere” for testing and changing thinks fast. maybe this is also a problem did not test it, just poped up in my mind while typing.

This is why it looks to me option 1 would be to do this only in cpp without including it into the blueprint version of the game instance.
Or option 2 use DataAssest to set all up and handel it a way to get the informations after the selection. But the data (as far as i know) would need to move to a struct anyway for the savegame.

Another way i have in mind would be to have a base version of the struct and call after the selection of a level the savegame every time and update the data (but i do not like the idea).
Still playing with ideas even if the sound stupid to myself, more like a brainstorming about this theme at the moment.

You are right ,the leaderboard itself is local and does not really need more the 10 entries . Was also thinking to have only 5 but 10 is kinda standart.
I already have a function in place where i check if the score is high enough to be in the list (wich i have only 10 entries). After this i order the leaderboard new and store the results.

Edit:

Was doing the math to see how i could optimise the raw data. The first i noticed was, 4 Dificulty is nice to have but not really needet. Now i think 2 would be enough or maybe 3.
This alone could cut the data in half.
Next i will to have a look into the variables i use, maybe i can delete some or change some things to get ridd of a few of them.

This whole thing just got a little out of control in term of size, i bet there are some things in there i just used as kinda placeholder as i build this. Like the dif levels was just to have 4 already in place and i also only use 12 of the 20 challenges right now.

1 Like

One option is to store just the tuples of (datetime, player, challenge, difficulty, score) and then let the UI sort it out with filtering. If it’s for local players, they are unlikely to get more than a few hundred tuples, so it’s unlikely to get very unwieldy. If it ends up being too large, you can prune the oldest or the worst or duplicates with worse scores.

1 Like

Here is something i test at the moment to use less data.
As i know (Primary)DataAssets are very powerfull to set base values i will try again to use them (hopefully without chrashes).

The idea of the test is to have an Array of PDA´s and the DA´s that are stored inside in the Blueprint for each GameMode.
Then just move the selected PDA into a cpp function to read the data out of it and set based on this the level to play with GameMode/Dif/Challenges.

Still testing a good way, maybe using a simple int system as i already do to use a switch inside cpp will do the trick. This way i can avoid set up data in a blueprint and instead use the DA´s for this, in the end thats what they for.
Will see if they can be used as some sort of TMP before sending the data finally to the savegame if a level is finished.

It is also without a problem possible to have variables inside you do not use right now if you only save the data. It´s just for testing this at the moment.

I also have reduced the Variables in the final struct down to 10 for the moment so cut them in half basicly. Was getting rid of formatet text for example. This can be done as it is right now but only for displaying the results then.
Still just testing what i can do, i want in the end to have a system that is easy to expand and tweak.

Thank you, i guess i do something similar already.

I sort the highscores and after this i check if the player score is higher then “ALevel_ST[iLevelNr_IN].AHighscores_Score_ST.Last().iScore”. If so, i set the new score into and sort again (all clamped to be 10 entries) and finaly i save it.

Little Code Snipet

### Edit ###
I changed for testing the setup to use PDA´s/DA´s. Works pretty well for now. It is now based on selection. The base setup runs pure within cpp. LevelSet->GameMode->EachLevel->PDA::DA. This way i need for each Level 1DA that is stored and selected within 1PDA.
Looks like easy to do more or less. Still not understand fully on how only use DA´s without the Blueprint interaction and PDA´s. This is why i use it this way for now, and this works fine.

Was also thinking how to store the data, because it will load only once. Maybe an simple actor who stores only the structs for this? Still testing, but quite happy at the moment how it works.

Also want to change the whol function to run cpp pure. Was just running into problems with TSubclassOf<> to add the widgets the should be created. This is why it is mixed with Blueprint.

Here is the code if someone is interested in how it is done so far (still WIP and a little to much though)

Code to select data from a PDA based on Vars and previous selections with a function that can be called within Blueprints

void UCommonActivatableWidget_Base::FLevel_Challenges_ForScrollBox_PDA_IN(TArray<UGameMode_PrimaryDataAsset*> PDA_AsArray_IN, UGameMode_PrimaryDataAsset* PDA_IN, int iDif_IN,
FMenuST Images_ST_IN, TArray& AChallenges_OUT,
UTexture2D*& imgChallengeFinisehd_OUT, UTexture2D*& imgChallengeNotFinisehd_OUT, int& iDif_OUT,
FName& NameOfTheChallenge_OUT, float& fValueAlreadyFinished_OUT, float& fValueNeedToFinish_OUT)
{
// Get Selected GameMode Categorie( ?? Standard:: 1 = Story ?? )
int iGameModeSelected = DTS_GameInstance_Ref->GameProfile_ST.GameSettings_ST.iGameMode_Categorie_Selected;
// Get Selected Dif Level (Standard:: 0 = Normal)
int iDifSelected = DTS_GameInstance_Ref->GameProfile_ST.GameSettings_ST.iGameMode_Dif_Selected;
iDif_OUT = iDifSelected;
// Set the Number of the Level to Play (Get from GameInstance where Data is stored after loading Player/Game Profile)
int iLevelToPlayNr = DTS_GameInstance_Ref->GameProfile_ST.GameSettings_ST.iLevelToPlay_Nr;

// Zum feststellen wie lange der eigentliche Array ist der durchlaufen werden muss um aktive Challenges zu finden
// (bChallengeActive = true)
int iTMP_ArrayLenght_Challenges;

UE_LOG(LogTemp, Warning, TEXT("---> Selected Level to play Nr::   %d"), iLevelToPlayNr); // Debug
UE_LOG(LogTemp, Warning, TEXT("---> PDA Array.Num(%d)"), PDA_AsArray_IN.Num()); // Debug

// Check if Array lenght of selected iLevelToPlay is bigger then the Array lenght of the PDA_AsArray_IN[]
// Then check if the Data within PDA_AsArray_IN[] is valid (is the Array filled with an associated DA ?)
if (PDA_AsArray_IN.Num() > iLevelToPlayNr && PDA_AsArray_IN[iLevelToPlayNr] != nullptr)
{
	//PDA_AsArray_IN[iLevelToPlayNr];
	AChallenges_OUT = PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST;

	// GameMode wurde bereits "Selected" und in DTS_GameInstance festgelegt -> jetzt die Länge des Arrays mit allen Challenges "getten"
	iTMP_ArrayLenght_Challenges = PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST.Num();
	// Alle gefunden Challenges zur verarbeitung im BP ausgeben mit "AChallenges_OUT"
	AChallenges_OUT = PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST;

// Get all available Challenges of the current Level and fill Array with Data
for (int i = 0; iTMP_ArrayLenght_Challenges > i; i++)
{
	bool bChallengeActive = PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].bChallengeActive;
	bool bChallengeFinished = PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].bChallengeFinished;

	//UE_LOG(LogTemp, Display, TEXT("i before IF -   %d"), i); // Debug
	if (bChallengeActive == true)
	{
		NameOfTheChallenge_OUT = PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].nNameOfTheChallenge;

		// Set Values for AlreadyFinished and NeedToFinish for selected Dif
		PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].fChallenge_ValueAlreadyFinished_InUse =
			PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].AfChallenge_ValueAlreadyFinished_Dif[iDifSelected];

		PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].fChallenge_ValueNeedToFinish_InUse =
			PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].AfChallenge_ValueNeedToFinish_Dif[iDifSelected];

		// Set Values Bool if Challenge is finished for selected Dif
		PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].bChallengeFinished =
			PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].AbChallengeFinished_Dif[iDifSelected];

		UE_LOG(LogTemp, Warning, TEXT("fChallenge_ValueAlreadyFinished_InUse -> Finished:: = %d"),
			PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].fChallenge_ValueAlreadyFinished_InUse); // Debug
		UE_LOG(LogTemp, Warning, TEXT("fChallenge_ValueNeedToFinish_InUse:: --> still to finish:: =  %d"),
			PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].fChallenge_ValueNeedToFinish_InUse); // Debug

		// Set Test Value for debug only (check if new Value is written into DA)
		PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST[i].fChallenge_ValueNeedToFinish_InUse = 5000.0f; // Debug

		// Set the all Values for the BP output to create Widgets inside the BP (ToDo:: change to cpp only)
		AChallenges_OUT = PDA_AsArray_IN[iLevelToPlayNr]->Challenges_ST.AChallenges_ST;

		UE_LOG(LogTemp, Error, TEXT(" Challenge Nr -> Array.Num( %d ) of the active Challenge"), i);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("ELSE :: Challenge --> Array.Num( %d )  NOT active "), i); // Debug
	}

} // For Loop END

} // END ### if (PDA_AsArray_IN.Num() >= iLevelToPlayNr)
else
{
	UE_LOG(LogTemp, Error, TEXT("NO Level(PDA[]) available for selected Level:: ( %d ) check if DA for selected Level is insert imto associated PDA Array Position ( %d )"), iLevelToPlayNr, iLevelToPlayNr); // Debug
}

UE_LOG(LogTemp, Warning, TEXT("AChallenges_OUT.SetNum() -   %d"), iTMP_ArrayLenght_Challenges); // Debug

// Get Images from "BP Struct(Setup in Parrent)" as Input to Display if Challenge is Finished or not (BG Image)
imgChallengeFinisehd_OUT = Images_ST_IN.AImages_Challenges[0].imgChallenges_Finished;
imgChallengeNotFinisehd_OUT = Images_ST_IN.AImages_Challenges[0].imgChallenges_NotFinished;

}

Ok i noticed it is a little hard to read this way, but i guess you get at least the idea :slight_smile:

Hey @Thorsten09 how are you doing?