November '20 Update

Published December 05, 2020
Advertisement

Well we're into the home stretch of the year now. Thanksgiving (at least for us in the U.S) is behind and the various December holidays in front of us. I've got a tree and lights up with a little more decorating to come. This'll be the first year I haven't gone home for a winter holiday so that's going to feel really strange and a bit sad.

Recap

  • Implement the Verify virtual across other definition types
  • Another custom blueprint node
  • Research Effects and actual research content
  • A UI that allows players to actually interact with the research gameplay

Results

Things went pretty great! Everything I planned to get done was pretty much done before my Thanksgiving vacation! I really expected the UI to take me much longer and I'm not really sure if I'm getting better at UE4's UMG stuff or if the screen was just simpler than I imagined. Probably a little bit of both.

Verify Implementations and a Custom Blueprint Node

As I mentioned in the last blog, I was already done with these by the time I wrote the blog. There's not very much of technical interest here. The custom node can together really fast since it could be a sub-type of another custom node I already have designed to do most of the work. Extending the Verify was also good, it even found and caught a bit of a bug with the research content I added later on in the sprint so I think it will pay a lot of dividends to keep these functions up-to-date as the functionality of Data Definitions increase. It also seems as though I'll want to add a similar system to my gameplay effects to catch configuration errors there as well and since the gameplay effects can be invoked from a custom blueprint node (because of course they can ?) I'll want to figure out a version that works in that context as well.

Research Effects and Content

The first collection of research that I've added is for unlocking ship classes by size. Before working on research I had it setup so that the ship classes were unlocked directly, which was fine, but I decided wasn't going to be as flexible as I wanted. I really didn't want to need to deal with different factions with each research result, firstly it would make the research itself a configuration nightmare and secondly it would make any sort of DLC type content more problematic. I know, I know, I'll probably never even publish this thing so why bother worrying about DLC? And the answer is that while I'm perfectly happy not to publish it, I'd like to build it as if I would. And it's not like I'm building out some crazy DLC or CDN system that will never get used. I'm just making certain decisions that, among other things, make part of that problem easier if I ever get to it. It's not even entirely conscious I don't think, just one of those things my engineer brain considers at this point. Bleed through from professional development I guess. Anyway, I tweaked it so that the factions know about all their ship classes and each ship class has a sizing category, like Battleship or Cruiser, and the research is able to unlock those sizes for building. I also left in the ability for classes to be unlocked at run-time so that you could be rewarded with or reverse engineer ships not normally available to your faction, though you'll still be restricted in actually building them until you've researched the proper technology. I created content for all the ship size categories I think I'll need for a while, sizes ranging from Frigates to Dreadnoughts, strike craft sizes, non-combat types, stations, etc. More than I necessarily need right now, but ones that I have a pretty high confidence that I'll actually need. Then I made the actual research content for the Engineering Branch of research and created research that unlocked each of the regular ship and strike craft classes.

Research UI Screen

The biggie, or so I thought.

So there are a number of things going on here to discuss

  • Moving from left to right you'll see the general break down of research that I laid out in the October Update.
    • Research Branches that have resources allocated to them and are working quietly all the time. I've cheated the Engineering Branch so that it's already leveled up once.
    • Technology which is functioning as a more class tech-tree research showing what is actively being researched at the top and the other possible options below. Because Engineering has been completed once, it already has another possible technology that could be researched. The ones currently shown are the placeholders still present but it could have unlocked the next shipbuilding technology!
    • Lastly refinements that can apply minor gameplay boosts, immediately and for a non-temporal research cost.
    • Nothing here's been balanced, just numbers that allow the system to function more or less.
  • At first I had some issues with the active project in the technology column. I wanted to be able to insert a new widget into that scroll box but that's not supported. All the solutions I found online involve either removing all the children, reordering them and then re-adding them or a weird double rotation so that the scroll box was upside down, but the widgets inside were then counter-rotated to appear right side up. That wasn't exactly an insertion solution but came up in the searches. I started with the remove-reinsert but eventually replaced that with a actual widget. You might be able to tell that the “Active Projects” box isn't actually in the scroll box. It's actually in the same vertical panel as the scroll box. This makes it easier to add to and means that if the “Active Projects” list is empty, it can collapse itself so it's not visible. It looks like an insert without actually being an insert.
  • You may also notice all the “pretty” borders. At first everything was running together in a way that made the readability of the screen a bit hard. This screen in particular made me finally figure out how the border widget worked. I had tried a few times in the past because it seemed like the thing to use (and not try and create my own crazy outliner widget), but each time I couldn't seem to get it to do what I wanted. I finally watched a youtube tutorial (which I don't usually do) that got me on the right track. I even added a “nice” border around the whole screen as well to sandbox it against the dimmed out hud behind it. Once I had this figured out I made a pass through all my other screens doing layout passes. Some just needed borders, some I reworked the layouts to be based on vertical boxes instead of canvas layouts. Eventually that border will be something more interesting and stylized for my game's art style (whatever that is) but for now it's fine. In the following picture you can see the before and after of the Ship Configuration Screen and how adding the borders makes it “read” a little bit better.

Bonus: Blueprint Node Tutorial and Improvements

I mentioned in the last blog that I should write a tutorial for creating custom blueprint nodes instead of just relying on what a Blueprint Callable function can do. Since I felt like I was pretty ahead of the game I actually spent the week after my post to write that up. I even learned a couple new things in the process of trying to write something really helpful. I have a friend proof reading it now and hopefully I'll be able to submit it here later this month! One of the things that it made me do was evaluate applying things that I had learned more recently to some of the nodes that I had made early on and were missing some useful virtual function overrides.

The other things with blueprint nodes I did was address a gripe I've had with some of Epic's blueprint nodes since the start. Take this example:

The Cast node is obviously built into the Engine and the “Get State Object Revision” uses the ExpandEnumAsExecs meta-tag to make a blueprint callable function with multiple output exec lines. Another good example is the validated version of getting a variable that has the same layout (Good/Bad/Value) as these two nodes. My gripe has been that if you use all the pins in a reasonable way there is no way to avoid line crossings of one way or another. I get that in a complicated enough graph you may not be able to completely eliminate crossings, but here you have three lines from one node immediately used and if you need them all you're hosed. So I applied the general knowledge of custom nodes that I've built up (and my access to the Engine Source) and made a few tweaks so that now my graphs look like this:

Much nicer, don't you think? The fundamental change being to group pins based on function (success & value) instead of by type (success & failure). Most of the nodes were pretty easy to change as the pin order isn't particularly relevant to the actual functioning of the blueprint node. None of the hookups generally care where in the list of pins a desired pin exists. I generally just inserted a snippet of code to reorder the Pins array of the node during the AllocateDefaultPins function. I could have also physically moved the pin creation, but that would have lead to more difficult integrations of future engine updates. "Get State Object Revision" was slightly more complicated as I didn't want to have to make custom nodes for any function with exec out pins. So instead I went the route of a custom meta-tag that could inform the generic function node how to order the pins (in addition to the Expand meta telling it what to create). Here I ran into a circumstance where the Pins array order was assumed and had to make a follow-up fix when something that was working before no longer did! Right now you can only re-associate all the non-exec pins with a single one of the exec pins, but since I don't need anything else I didn't worry too much about that limitation. I left myself a note in my backlog to improve this if/when I need multiple outputs and outputs should be more granularly grouped with different exec pins. I also made a pass at a few on my own custom nodes to follow the same reasoning of how to group pins, but there I could just move the order the pins were created in instead of reorder them after the fact.

Bonus: Minor Technical Debt

Because I wrapped up so much earlier, I was able to hit quite a few technical debt issues I had lying around. Including ones that had only just come up while working on the things for this sprint. Those were things in my backlog that I added as I worked that I wasn't really sure I'd be able to get to. A happy surprise! These were mostly outstanding issues with my Event dispatcher and Visualization management processes.

Goals

Overall the Strategic layer of the game is coming together pretty nicely. There is still gameplay that I'd like to add, but they all feel like really nice extensions and not necessarily a core element of the game. Right now you could (in theory with the right content) move around the “universe”, engage in combat to get new resources, then use those resources to build/improve more ships to take on harder missions to get more resources to make better ships for harder missions, etc, etc, etc. The really core loop of the game. So it's probably time to bounce back to tactical again. I thought it had been a really long time since I did any work there but going back through this blog I was amazed that there was in-fact tactical work more recently than I remember. I think it's the Covid lockdown really messing with my sense of time.

  • So the BIG thing I'll be adding is status effects. I've mentioned the State Effects that I have a little that I can use to apply state changes to the model data of my game. Those are great and really flexible, but they're limited (on purpose) to instantaneous type of effects, deal damage, spawn ship, etc. Where as status effects are the things you usually see in tactics games that last a few turns: poison, burn, various buffs and debuffs. Anyone familiar with these types of games playing mine would almost immediately notice their absence. So I'll be addressing that.
    • In a bit of a departure I'll probably end up building something quite a bit more comprehensive than I actually need right this moment. I've talked about my process for writing code for this project a little bit before and it's usually to apply the minimum amount of changes required for the immediate task. This is a great approach when you don't really know the space or extents of what you're building. I'm sort of designing on the fly so I don't have the kind of design docs I would at work that would allow me to do a solid technical design up-front. However when you are building something you're familiar with you can be a lot more confidant about what you're building and that code that you're writing won't be totally useless (or worse wrong). For example, if you were writing a custom vector (math, not the container) there'd really be no reason to omit the math functions like addition or subtraction that you're sure you're going to need. Similarly I've already had to maintain or build two similar systems for XCom2 and my current project at work so I have a pretty good idea of the pieces it should have and how those pieces should interact. This isn't quite the same thing as the Second System Syndrome where you build a new one that is over-engineered. It's more like a refactor where a heap of code has build up in an evolutionary way (probably with edits from many authors) and you're able to rebuild it as a singular vision where all the pieces mesh together better. Again because of the timing of this blog post I've already started on the general framework for the persistent effects as I call them and already there's a certain beauty in this implementation that is missing from the analogous system at work. Some things I'd probably love to refactor at work to match, but it probably won't be appropriate.
    • My first two use cases will be Hull Breach (which will cause a boost to damage applied to the hex-side of the breach) and Low Power (which will reduce the amount of energy available to the ship at the start of it's turn). I hope to make Hull Breach more integral into the damage process. While will still be able to be applied directly by a weapon, I'd like for it to have a possibility of being applied by any damage that is applied that makes it through the armor stat for that side of the ship. Probably some random chance that is proportional to the amount of armor remaining on the side.
    • This will also involve UI work (though not nearly as complicated as the strategy layer screens) to communicate the information to the player both at the time that the effect is applied and as it persists.
  • 4.26 just dropped. I'm still on 4.24 so it's probably time to upgrade. They made a pretty big change in 4.25 with respect to the reflection information and I have a few cases where my use of that information is pretty important so I've been avoiding it a little. I know the fixes aren't terrible as we upgraded to 4.25 at work some time ago and I know there's a pretty straight forward mapping of old to new.
  • My current method for tracking my backlog, task and bugs basically amounts to a text document that is checked into source control with everything else. I've been looking for a tasking tool that I could migrate all that too. For a while I've been hesitant because I was hoping to find something I could run locally. Not because I'm particularly worried about the information being out in the wider world, just that I didn't want an internet connection to be required to make any sorts of update to project data (or meta-data I guess in this case). I think I'm over that or at least tired of trying to find a solution that fits that narrow requirement. I've checked out a few online scrummy/agile/kanban online tools, I've kind of liked HacknPlan and Codecks so I'll look at them more and give one of them a shot.
  • More minor technical debt solutions to address some short-term engineering decisions.

With the holidays I've actually got quite a bit of time off happening. I probably shouldn't spend it all working on my game, but realistically I'll probably spend quite a bit of it on this project.

Changelog

Because I had so much small stuff not really worth discussing I thought it might be nice to share my actual changelog of all the submissions I made into source control over the month. I'll start leaving that here at the end of the dev blog to make it easy to skip/ignore. Hopefully this is interesting to someone out there!

  • 1107 Commit to November Sprint work.
    • As I mentioned, my backlog/task tracking is just a text file in Perforce. So when I commit to work for my sprints I literally am committing something into source control!
  • 1108 Improved asset checking message functions. Add Verify implementations to Project and Star Route Definitions.
  • 1109 Add Verify implementations to other definitions.
  • 1110 Create a placeholder visualization and hook it up to a couple of visualization slots that expect there to be valid visualizations. Use a placeholder blueprint to make it easier to find in the future when "real" visualizations are desired.
  • 1111 Create a utility that can be used to reorder node pins
  • 1112 Incremental improvements to the Dependent Output Type base node: *Divorce the Accessor function type from the primary input type. *Add a control that can prevent the node from being converted to a pure node. *Add a hook that allows derived nodes to wire additional input parameters to the accessor function.
  • 1113 Create a custom node as the blueprint accessor for Find State Object For Definition.
  • 1114 Create a category for "ship" sizes. Create the general variety the game is expecting to have as well as sizes for stellar objects (like the asteroid), stations, non-combat ships (like transports) and strike craft (eventually). Update existing ship starship configurations.
  • 1115 Add DisplayNames for the ship categories.
  • 1116 Create research for the various levels of ship building
  • 1117 Add a flag that suppresses the creation of strategic faction state data. Switch up how ships classes are unlocked for construction - based on unlocking the size classifications instead of the ship classes itself.
  • 1118 Tweak vis marker creation so that if all that derived types need to do is allocate a sub-type, that's handled already (assuming that GetVisMarkerType is overridden).
  • 1119 Create a new sub-branch of StateEffects for strategy specific state mutations.
  • 1120 Create a strategic effect that can unlock ship class categories for building. Configure all the shipbuilding technologies to unlock one or more of the ship class categories.
  • 1121 Create the skeleton of the research screen. Make it accessible in the strategy HUD.
  • 1122 Fill out the UI element of the research screen for managing the resource allocations to the branches of research.
  • 1123 Allow for narrower access to the available research within a research branch.
  • 1124 Improve blueprint usability of the transaction option structure.
  • 1125 Update transaction utilities to collapse the input or output boxes if there are no widgets. Update the transaction widget to hide the header if there are no column widgets.
  • 1126 Create a widget that can display the refinements from a particular branch. Create instances of that widget from the research screen for each branch. Update backlog.
  • 1127 Fix research cost manipulation of the cost map.
  • 1128 Separate the project queue api to allow access to current vs pending
  • 1129 Properly configure the OpenDialog node to only be valid on ubergraphs and in macros. Add backlog task for engine modification for better macro compatibility with custom latent nodes.
  • 1130 Add a way for project queues to be more configurable as to where new projects are put. Update the Research Queue to push new projects to the front of the queue. Fix indexing errors in the project queue accesses.
  • 1131 Initial pass at Technology panel of the Research UI. Create a widget for the display of the available research projects and create one for each research branch. Create a separate widget for the display of research projects (instead of reusing the transaction widget). Create instances of that widget for the in-progress research as well as any of the queued research projects being displayed as part of the branch.
  • 1132 [[UE4 ENGINE]] Tweak the validated variable 'Get' to put the invalid execution pin after the variable pin (when running in impure mode). Improves graph layout, preventing crossings of Invalid exec line with the Valid exec line or the variable line.
  • 1133 Tweak blueprints with validated variable gets for improved graph layout now possible.
  • 1134 Tweak the display of pending research projects so that they look the same and possible transactions when no progress has been made on them.
  • 1135 Move state changing functions out of the Strategy HUD and into the relevant state object type as static functions.
  • 1136 Add state modification that can jump a project to the head of it's queue. Tweak the project static functions parameter name. Update the click handler for the research to jump the project to the head of the queue.
  • 1137 Live update the active research project as other research is clicked on.
  • 1138 Fix a bug with the repair screen by adding a Super call.
  • 1139 When trying to insert into the TechScroll, remove all the children before reinserting them in the new order. It seems to work without this (the children just get reordered) but this is probably more technically correct.
  • 1140 Replace a bunch of calls to RemoveChild with calls to RemoveFromParent. There's no reason to have to remember where that widget was (even if it's technically known)
  • 1141 Get rid of the duplication between blueprint callable GetID and the blueprint readonly property.
  • 1142 Address loading warnings about primary asset types. Resave all data definitions.
  • 1143 Update backlog
  • 1144 Add support to allow screens to override the CloseScreen functionality in case they want to be able to interrupt and cancel the operation.
  • 1145 Add an override the Research Screen of CloseScreen. Check that there's at least 1 active research project in progress and confirm with the player if they wish to close the screen when they're not researching anything.
  • 1146 Reorder the pins of a couple of custom node types so that they're grouped by function and not by type. This creates nodes that are less likely to cause line crossings in blueprint graphs.
  • 1147 [[UE4 ENGINE]] More Engine K2Node tweaks so that output pins are more reasonably grouped with the execution pin they're related to. Create a new meta tag so that functions using the ExpandEnumAsExec markup can configure the location of any output variable.
  • 1148 Apply the new function meta tag so that function outputs are grouped together with the right exec line.
  • 1149 Assign the starship construction technologies to the Engineering progression.
  • 1150 Add in basic shipbuilding as a starting tech (even though the player will generally start with it). Allows tech prereq checks to be fully evaluatable. +1 for asset check messages.
  • 1151 Make a pass at all existing custom nodes and make sure they have categories and icons.
  • 1152 [[UE4 ENGINE]] Add a hook so that custom blueprint nodes that are essentially latent can be treated that way by macro/tunnel node metadata without requiring the engine to have the type information for all node types.
  • 1153 Update the dialog and visualization nodes with the new function so that they are treated as latent from macros.
  • 1154 AutoRegistration nodes shouldn't go in macros.
  • 1155 [[UE4 ENGINE]] Oops. The function call node had a few places where pin order was assumed, so it was hooking up the wrong function outputs.
  • 1156 Remove an ensure that doesn't really make any sense. You should be able to queue up a new result context at any point.
  • 1157 Add blueprint utility functions to the VisMarker for transforming its sources and targets from IDs to state objects.
  • 1158 Add visualization support to project queues. Create and hook a visualization for the research queue. When research completes, pop up dialog boxes for each of the completed projects.
  • 1159 Update the core hud to return a hud widget instead of just a user widget. Add a new ui static utility to get at the current hud widget.
  • 1160 Add a mechanism that allows a screen to be queued so that once the entire visualization sequence is complete.
  • 1161 Update the research progress visualization. Fix a bug that triggered the post-dialogs process too early. Add to the post-dialogs process the queueing of the Research screen if there are no active research projects remaining.
  • 1162 Make another pass at display names for screens and widget classes and blueprints.
  • 1163 Update backlog
  • 1164 Add some missing validation to the registration of event listeners
  • 1165 Create a standardized border widget for quick use throughout SRPG widgets
  • 1166 Make a pass through the Research screen and related widgets introducing borders and addressing padding between widgets.
  • 1167 Apply borders to dialog boxes and the pause menu.
  • 1168 Make a pass on the strategy hud and screens apply borders and re-organizing a few to be vertical/horizontal box bases instead of just canvas panels.
  • 1169 Add borders to the speed control and dialog boxes.
  • 1170 Update a variable name from the Two Option dialog box so that it displays as "OK Text" instead of "OKText" in blueprint.
  • 1171 Add blueprint accessors to some gameplay data. Add a user setting to control whether or not a player should be warned when ending their turn with any ships with movement points remaining. Add a dialog that will can warn the player about remaining movement points.
  • 1172 Rejigger the Get State Object custom node to make it easier to add versions for State Frames and Result Contexts.
  • 1173 Create State Frame versions of the Get State Object and Get State Interface nodes.
  • 1174 Add versions of Get State Object and Get State Interface for Result Contexts. Fix an issue that had non-History versions not actually working the way they should. Update some blueprints to use the new nodes instead of the old ones.
  • 1175 Reorganize the state object k2node code into separate source files. Update the underlying native calls with _K2 suffixes instead of _BP.
  • 1176 Tweak a member string name lookup to be something that is will error at compile time if related code changes.
  • 1177 Add support to GetStateObject so that it can convert arrays of object ids into pointers based on other conversion configuration.
  • 1178 Add a priority to the event listener. Process listeners from high to low priority. Update the RegisterForEvent and AutoEventRegistration nodes with priority properties.
  • 1179 Some formatting and commenting improvements to the EventManager.
  • 1180 Add a result & visualization for the progress made when completing a branch.
  • 1181 Reattach a MapForEach input that wasn't remembering it's type information across Editor instances.
  • 1182 Fill out the BranchProgress visualization with some dialog boxes.
  • 1183 Fix a bug with the native version of ArrayForEach. Went un-noticed because nearly all prior uses involved a reroute-node which preserved type information.
  • 1184 Add a widget between the header and scroll box of the technology section. This handles the management of active research projects instead of the research screen doing it.
  • 1185 Move the research screen and all it's widgets to its own folder.
  • 1186 Update a couple missing comments
  • 1187 Add visualization hooks to support the activation of the visualization window for events.
Previous Entry October '20 Update
Next Entry December '20 Update
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement