Hello all. This week was spent mostly on technical stuff and programming, but I did make one simple 3D model too. Here’s a detailed list of what I did:
Crowbar 3D Model
1- I made a simple 3D model of a crowbar, it’s 288 Triangles total. I wanted it to be a reference to the half-life series.
I also used the blueprints I made previously to make it only appear on rare occasions, so it’s very easy to miss. I changed the code a little bit, for better off-screen detection, with adjustable margins. Here I used a negative margin values, so objects are considered off-screen even when they’re not, because I also wanted some of the dream “wonkiness” to be barely visible near the edges of the screen.
This example was captured by coincidence, I was trying to show the crowbar up close, but it disappeared out of existence in front of my eyes. That’s exactly the kind of interaction I hope some players will get with this or other objects.
Steamdeck
I got myself a steamdeck, since it’s the hardware class I want to optimize my game for. I’m actually very impressed, I’m getting good framerates, a lot more than I was expecting. 85FPS at the native resolution without having to make quality compromises. Granted it’s a simple scene, but it’s still a lot more than I expected.
I used static lighting, but that’s what I’m going to use for my game anyway, Lumen is just too slow and has a lot of graphical artifacts for my taste.
I also tested a native Linux build, to see how much performance I’m losing to the Proton compatibility layer, and I got ~95-100FPS, compared to ~85 on the Windows build. I will continue to use Windows builds for performance testing, but a native Linux build is planned for the final release.
Interaction and Dialog system
The majority of this week was spent on this. I took the item description system I had and reworked it, now it takes data tables and has complex interactions. So instead of programming every interaction individually with blueprints, I made an “interpreter” that reads from a data table (basically an Excel file) and executes that instead.
Here’s a video showing the system interpreting the datatable above. Here it just demonstrates the dialog and “go to” functionalities. A “go to” can be set to jump ahead to a specific scenario, useful for things like the “choose your own adventure” books, or to point back to a previous line, in case the dialog is exhausted and I want to repeat a specific line indefinitely. I also made the interaction icon become grey if you reach the last dialog line and there’s nothing else to show.
More objects can share the same data table, and each have their own progression. This can be useful for example if I want to have many object descriptions in one data table, all I have to do is have all the lines I need in the data table, and set the starting line for each object.
Another type of interaction is “change camera”. Unlike “Dialog”, this doesn’t end the interaction, and it immediately loads the next line. It’s useful to point at an object of interest when you talk with an NPC for example.
I also made a “Milestone” system, which is a save state in a way. It is used to save/set progression. Unlike “Current Line Number” that is incremented to the next line on every interaction (except “Go To”, which sets it to the desired line number), the milestone is only updated manually.
In this example, the milestone value is initially 1, but line #2 sets it to 4. Line 4 is just some dialog, then line 5 is called, which just tells the game to go back to the milestone value. Since the value is 4, it will repeat the same text every time you interact with it, until something changes it.
I programmed a platform to set the milestone of that specific object to line #6. So now when you interact with it, instead of going back to like 4, it will read line 6. Here’s a video demonstrating it
This is just a simple example, but it can be used for example to make an NPC angry at you if you do something or positively interact with someone they don’t like.
Tests #5 and #6 are about passing interaction to another object/NPC. This is for example when you interact with someone in a group, and someone else will start speaking.
Test #5 is a normal pass, it doesn’t set any specific line, only the other actor name
Test #6 sets a specific line when passing to another actor. The field “Content” contains the name of the actor, and “Extra A” sets the specific line in its data table, in this case line #3
And this is the data table of the target actor. As you can see, the line #3 says you’ve interacted with the coffee grinder object (what passed the interaction to it).
The last type of interaction I implemented is the question type. It can either have two answers (yes/no and custom) or three.
This example shows a simple question that doesn’t set any milestone or jump to a branch. In other words : it doesn’t matter which option you pick, what comes after that is the same (in this case asking the question again).
I used the fields “Extra A”, “Extra B” and “Extra C” to store the answer text, and the number before the “%” is the line to go to, if that option is picked. “6%Yes” will take you to the line 6 if chosen, for example.
While inconsequential choices are good, some questions need to have consequences. In this test, your answer will be final and it will lock you in a branch. The only difference is that there’s a “Go To” or “Set Milestone” that takes you to the lines for that branch. The question “do you like strawberries” will never be asked again
And finally a multi choice action. It’s not too different from a two choice or yes/no question, so I kept this example simple.
Those are the interaction types I have programmed this week. I need to finish a “reputation” or “friendliness” or whatever I end up calling it, which is just a check to see if an NPC likes you enough. I also need for a way to get and set world flags (things like “did the player buy this item” or “player is in the good ending route” or whatever), and then I’ll have all the tools I need for storytelling. I’m not sure yet how the save system works in Unreal, so I’ll keep the data temporary.
There are other features like “set facial expression”, “start animation”, “start cutscene”…etc, but those are not necessary, and I’ll leave them for later.
The system is starting to get complex, I should clean it up and organize it better. But I’ll finish making it first
That’s all for this week. Thanks for reading, and I’ll hopefully see you again next week.