Jump to content
  • Advertisement

MagForceSeven

Member
  • Content Count

    32
  • Joined

  • Last visited

Community Reputation

524 Good

About MagForceSeven

  • Rank
    Member

Personal Information

  • Role
    Programmer
  • Interests
    Design
    Programming

Recent Profile Visitors

3873 profile views
  1. MagForceSeven

    Compile time tricks

    Hmm, that's definitely an interesting case I hadn't considered. I've only ever using it at scopes where an actual array declaration is present such that the pointer decay presented there can't possibly have occurred. A run-time scope like that shouldn't be hiding the decay and making it look like it enforces a restriction that it doesn't really, but it's hard to truly argue the validity of example code. Even if the function was written better it doesn't change the fact that one solution generates a compile error and one doesn't. Like Green_Baron, I'm not sure I understand your use of the word "random" here. It's elementary or middle school math: Joe has 10 pounds of watermelon. If each watermelon weighs 2 pounds, how many does he have? It's just math. Is it just random because a person is deciding to do math on two numbers? Possible user error, of course but I wouldn't go as far as to say "prone" to error. It's not one I can say I've ever seen made using the sizeof solution. I appreciate both your insights, though I'm honestly not sure that it'll change anything for the very narrow use-case I personally am solving for. But it's a good discussion that helps another programmer out. This isn't to close this conversation, I'd love to keep going if there's more to discuss (such as Juliean's reply to my question). SMAC is one of my favorites too, but I've only been working there for about 5 years so I didn't contribute to that one. At Firaxis I first worked on XCom 2 and then the two(ish) expansions War of the Chosen and the Tactical Legacy Pack. I forgot about my signature (had them turned off for some reason) so I'm not even a systems programmer anymore, jumped back to gameplay for this next project.
  2. It seemed best to start another thread for this instead of derailing the thread the conversation started in and maybe to get some other opinions. That's definitely clever, but it feels like you're just trading one compiler trick for a different compiler trick. Do you think this one is better because it's somehow "more C++" than the sizeof version? I have two issues with this code. Firstly I think it's too complicated and clever for it's own good. Even setting aside the new-ness of constexpr, this requires an understanding of templates and template parameter deduction that can take a while to understand. I have a hard enough time with other programmers doing templates right with trivial type deduction that this could make their head explode. Secondly, now that this is a function it's got to live somewhere which means either duplicating it in every header that uses it (bad) or putting it in it's own header (or a utilities header) and including it. This point is more personal preference than anything else since it feels like such a trivial operation to include a header for. I've definitely seen code that wraps the sizeof trick in a macro, but I think that's silly too since that has the same dependency problem as this function. I don't think many people would make a macro/function to wrap "+= 2" just because it happens to occur in multiple places in the code. I don't want to come off as argumentative here @a light breeze. I'm not claiming to be right or that you're wrong or that there's even a right or wrong to be decided here. I'm honestly just very interested in the why of how people decided the things they find acceptable or not. And when someone uses a phrase like "has no place" I immediately want to explore that!
  3. MagForceSeven

    September Update

    Recap For September I wanted to 1) hook up my UI to make actual state changes in the game and 2) add a UI for active projects. Results I'd say things went great! I actually got the UI hooked up relatively quickly and was able to take a lot of time for the projects. I even got a little further and was able to add a passage of time that allows for actually completing projects as well. Here you can see the three new UI elements of my strategy layer game mode: The Shipyard button to the upper-ish left, the Time UI on the lower left and the Projects scroll bar to the lower right. The Marketplace still has all the instantaneous transactions that can be used to trade resources back and forth. The starting "Stardate" of 413469 doesn't really mean anything, it was just a random 6-digit number. Here's the Projects UI after accessing the Shipyard and selecting to build a Battleship, Cruiser, Destroyer and Frigate. You'll notice that some of the resources have changed too indicating that resources were spent to queue up those construction projects. The first number after the project is the total days until completion (project time plus preceding queue time), the next is the individual project time. The next three grey boxes are the queue controls (from left to right) move up, move down and cancel. I wasn't motivated enough to find art for them right at the moment. The Destroyer project used to be the third priority, now it's number two (using the 'move up' button). You can see that both the Destroyer's and Cruiser's total time to completion have been updated to reflect the new priority order. The Destroyer project is now the number one priority (this time using the 'move down' button on the Battleship project). Again, the total time to completion for the re-ordered projects has been updated. The Cruiser project was canceled and the total completion time for the later project (Construct Frigate) has had it's completion time updated. This is after passing three days, Stardate 413472. The Destroyer project has been removed and the Battleship project only has 1 day removed from it's remaining time. At this point if you opened up the Launch Mission or Configure ships UI's, there would be a three Destroyer class ships (two starting ships and the one constructed by the project). Trust me I hit a few technical debt things, but nothing from my backlog. Just things directly related to what I was doing with the UI for the projects work. I also did an interesting (to me) shift of some code from one class to another (related) class. This was a bit of an experiment to see what the code would look like with this change. My game state is stored in a pretty similar way to my project at work and wanted to see if moving this API would improve the use and reliability of the code. I think it does so I committed the change to my project and started a side project at work of a similar refactor. October Goals It's time to move onto something not transaction related, three months is a long time to be working on the same feature even if it is only part-time. It would be nice if I could keep it to two, one for gameplay and one for UI (at least when dealing with strategy systems). If I could get all the gameplay and UI done in a single month that'd be cool but I'm trying my best to set myself up for working on this project when I'm not feeling up to it. Don't want to burn out on development. My main goal is to work on a Strategy Map. My vision is basically a graph where the star systems are the nodes and the edges are the valid transits between them, something like: The real UI should obviously look a bit better, but it should give you an idea. I laid some groundwork for this last month, so I have state and definitions available for the Star Systems and Routes. I also stubbed in classes that will be used as the bases for my tactical and strategy map generators. Most of this sprint should be implementing a first (fairly trivial) strategy map generator and building a UI to display the state data I've already defined. Games I'm Playing Still playing Fate/Grand Order and Fire Emblem. My second playthrough has been interesting if a little boring. The first half of the game appears to be more or less identical regardless of the house that you're playing so that's a little boring. Plus everyone is way over-leveled because I can do way more extra battles than I could in the first go-around. I just got past the time skip so I'm hoping the story diverges a bit more from here on out. Both my Blue Lions playthrough and this Golden Deer playthrough have been Normal/Casual. I'll probably jump right to Madding/Casual for the last two story lines when I play them.
  4. MagForceSeven

    Defining function using a Macro?

    Maybe this is off-topic, but I'm curious as to what the alternative would be? I'm not aware of any standard language feature that has replaced this particular trick. Arguably in the original it seems weird to have both a NULL_TRANSITION array entry and a count of the number of elements, but for a statically sized array what is a better option is there for having a compile-time constant for a compile-time array? The only one that I can think of would be never use static arrays and only ever use std::vector (or whatever dynamic array is available in your engine, like TArray in UE or whatever vector replacement EA STL has) and that just seems misguided. While I usually use the dynamic array that I have available, there are cases where that's just overkill or doesn't meet the compile-time requirements required. I've mostly used this in combination with static_assert to validate (at compile time) that some static array size matches the length of an enumeration. The old static assert trick was to define an array that had size 0 or 1 based on a compile-time boolean condition. If the condition was false, the array would be sized to 0 which is illegal and caused a compile error. That trick no longer has a place in modern C++ precisely because static_assert is now a language feature that directly provides the feature.
  5. I agree with Green_Baron. Yes it works, yes it's technically valid C++ and yes there are plenty of examples of it being used (I'd add Unreal Engine to the list there). However I think it's poor style, I don't use the practice on my projects and generally discouraged it's use in our coding style for the project I'm on at work. Firstly I believe it's very helpful to have all the dependencies basically listed at the top of the tile (either as an include or forward declaration). Secondly I don't see the need to repeat oneself when the type is used multiple times within the same header. Thirdly it's incompatible with types in namespaces. At the very least an inline forward declaration of a namespaced class would look ridiculous, but there may not be a syntax that actually compiles. Lastly it reduces the changes required for refactors as you only have to change the one declaration instead of every instance in the file. As for it polluting the global namespace, I don't see a forward declaration as doing that. If the actual declaration is in the global namespace you've already "polluted" it. Adding the type to the space again doesn't pollute it more. If you're running into a typename collision because of forward declarations, you're going to eventually run into a typename collision because of the actual declarations. I am generally willing to accept it in the Unreal code I work with either because a) it's not worth screwing up integration merges from Epic or b) it's auto=generated code so the auto-generation code would replace them on a refactor and it arguably makes it easier to write the generation if you're not having to do multiple passes to figure out dependencies just to generate forward declarations.
  6. MagForceSeven

    August Update

    Recap For August I wanted to finish up with transactions, building a UI that could execute the system I built in July. Results Again I did okay. With a little tip from one of the UI engineers at work I was able to get my widgets working for a UI that can display and trigger a transaction. The part I didn't get to was the actual execution of the transaction to change the state of my game. Here you can see the new button (on the left) I added for accessing the "Marketplace" and the UI element (on the right) I added to show the current resource counts available to the player. Here's the screen for the Marketplace. I went for transactions that would create new ships instead of resource exchanges. You can even see the last transaction is a project that requires a duration to complete. The unreadable little box is the tool tip for the button to activate the transaction. And the final screen has the debug text that I currently have showing up when the button is clicked. The name of the transaction is included in the string as "proof" that the all the relevant data is being routed to the right places for eventual activation. I also addressed a couple technical debt issues: I removed a few direct dependencies between the system that deal with the tile location of the cursor, the system that tracks the current selection, the system that deals with targeting and the system that deals with the turn order. Instead those functions route through my custom event manager. Added some validation to my event manager events so that the manager can handle invalid events systemically and not pass those events on to the systems listening for those events. New Design Spec I also wanted to get out in front of a design problem that I know I'm going to have. I currently expect to have some limited number of spots per mission for ships to send on a mission, but I don't really want it to devolve to "take my X-biggest ships" every time. What I've more or less settled on is a two-fold system for limiting ship deployments. The first is a limiter based on ship sizes, I'm calling it "tonnage" for now. Each ship will have a tonnage ranking (based mostly on size) and the total for all the ships taken on the mission must be below the tonnage limit for the mission. Hopefully this will encourage including a few smaller ships on missions instead of just a couple big ships. There will probably be a few ways to upgrade this limit, but they will be very few and it will vary primarily on the mission type/location. The second limiter would be a more traditional unit count limit. This limiter is meant to represent command and control systems and the effectiveness of actually controlling lots of ships. This limit will be more constant, usually the same for most missions, but will have ways to upgrade it globally or even based on the equipment of the ships taken on the mission. I'll keep thinking about it for a while, I've got a couple more parts to add to tactical before I start working on an implementation. I'm happy to hear any thoughts or comments that might make this better. September Goals The next step is finishing up the wiring of the UI to my other systems so that pressing the buttons actually does something (other than printing to the screen). I'll also need a new UI element that shows the active projects created through a transaction screen. I'll also continue to address small tasks from my technical debt list. Games I'm Playing Picked up the new Fire Emblem at the end of July and have spent a good chunk of time playing (the save says ~120hrs ). Finished one of the 4 story lines (Blue Lions) and have started up my second playthrough (Golden Deer this time). Should be faster, they've got an interesting NewGame+ system that lets you pull progress from previous playthroughs. It's a pretty good game and I highly recommend it. My only real complaints are the class system can be a little bit unbalanced and the way they've shifted the weapon triangle into skills feels really off.
  7. MagForceSeven

    C++

    Absolutely. Both at work and for a hobby project I primarily work in C++ when using the Unreal Engine. There's obviously some work that has to be done in Blueprint, but you can make that as much or as little as you want. At work the amount varies based on engineering discipline (UI uses it more than some others). At home I also primarily use it for UI but will also use it for the mission scripting when I get around to it.
  8. MagForceSeven

    I'm quite happy

    Welcome to the data mines brother. Hopefully you're able find the right back and forth with your side projects. I definitely try to use it to smooth over work related things. Like during a sprint planning week where I'm in too many meetings it's really nice to come home in the evening and have code to work on that doesn't require a meeting with anyone. Even better is when I have something at home or work that makes me excited to integrate that into the other. A lot of what I have my side project for is as a test-bed for experimentation so that I can take more fully formed ideas of how something should work or what a system should look like before committing resources at work. Or I learn some weird Unreal tidbit and add it to my backlog of things to have an excuse to try.
  9. MagForceSeven

    July Update

    Slow, but steady seems to be the name of the game. Recap In July I wanted to finish up with my transaction system. Results I did okay. I was hoping to at least get started on the UI side of things but just didn't have the time. I did finish all the initial gameplay elements that I'll need but that's about it. Since I didn't do any new UI, there aren't any pretty pictures so instead I'll discuss the transaction system that I put together. I actually started by spending some time taking a look at the Actions/Weapon definitions that I already have and use for the actions you can take in Tactical. In a lot of ways the transactions are analogous as the actions that you can take during the Strategic portion of the game. So it seemed appropriate that maybe there was something that could be shared between the two. In the end I decided against it. There's a fundamental difference between the two (at least when I was considering it), and that is state. Weapon definitions have accompanying state for remembering ammo counts or cooldowns or any other gameplay element. Transactions shouldn't. They will modify state for sure, like how much of a resource you have, but they themselves are just kind of fire-and-forget. With that decision out of the way I started on setting up the actual transaction definition. The transactions are meant to be pretty simple so it's basically just a set of inputs and a set of outputs. Unreal has a pretty interesting mechanism available for member of asset types called instancing that allows having object pointers that can be configured in data to create an instance of a selected type. Then you can setup that type so that you can also edit the instance as part of that asset as well. Where this comes in with transactions is that those sets of inputs or outputs can be sets of a base type (which defines the basic API for an input or output), mark them up to be treated as instanced and bam! to add a new input or output type you just have to derive off the right type and you can plug it into any existing transaction. The other nifty thing is that since it's all reflection powered I can have the transaction code "live" in my StrategyTech plugin and define all the concrete versions of the inputs and outputs in the game plugin. This isn't the first time I'm doing this, the weapons work pretty similarly for the things that they can do to mutate the state of the game, but it is a pattern that works pretty well given the way the Unreal engine is setup. I also wanted to setup up transactions that had a little state, but only after you executed them (in contrast to weapons that have state all the time). I called these Projects and they are transactions that have a temporal element. I thought about making time just another input type, but couldn't make that work since it could impact how every other input/output of the transaction has to work. So instead I made a derived type of transaction and overrode a few functions. It also meant that I built in to the input/output types the possibility of multi-step execution. They each support a Start (for when the transaction is executed), a Refund (if the project is cancelled) and a Finalize (when it becomes no longer possible to refund). There's also a helper that calls Start immediately followed by Finalize, this is what the base transactions do since there's not supposed to be any opportunity to refund them. Lastly there's a class of objects created by the inputs and outputs that act as receipts of a sort to track what the parameter actually did that can be used by Refund or even by a UI. These classes aren't quite one-to-one with the input/output classes but pretty close. They are shared by the same inputs and output types that manipulate the same type of data. So, while there are separate classes for using a Resource as an input vs using a Resource as an output, both classes can use the same receipt type. This becomes more important when the input or output relates to information that you can't easily rebuild just by looking at the static transaction data. For example, I already made an output type that can be used for spaceship construction. The output type can't hold onto any sort of reference to it (since it's static/const). So the receipt type does that. I also did a few of the issues from my technical debt backlog. Not many, but they a lot of small things that I can work on during the week without feeling to burdened by work or what needs to be going on at home. August Sprint More transactions, but this time I'll be working on the UI and actually executing the transactions. I'll need to make a few test transactions so that'll probably be super simple, 1:1 resource conversion options. I'll also add something really simple to allow completion of projects since I don't have an actual "passage of time" mechanic yet. Games I'm Playing Fate Grand Order as always. Picked up Fire Emblem: Three Houses and it is a blast. I'm a little worried that the narrative is a little too "on rails" with no way to delay the next story mission if you need to grind out some experience or money. It hasn't been a problem so far, but I've delayed story progression in previous ones, so we'll have to see.
  10. MagForceSeven

    The only constant in life is change.

    While not entirely untrue, it would be unfair to paint with such a wide brush. On the one hand I do see disproportionate amounts of news related to game industry work conditions, but those also tend to be industry related news sources that wouldn't report on similar problems in other industries (or report on the on-time no crunch because it's not news). In other news sources I definitely see reports of abusive practices towards Amazon warehouse workers and various gig economy workers so I don't think there's anything particularly unique about the game studios. I suspect that any workplace with salaried employees and harsh deadlines has potential for abuse. Software of any kind can exacerbate the issue by often being a process of invention which doesn't always schedule well. There are definitely good places out there if you're willing to give them a chance.
  11. MagForceSeven

    June Update

    Welcome back! So my June "sprint" (I guess that's what we'll call these) went pretty well goal wise. I may have under-shot for the month, but it's tough when you can't be exactly sure how much time you will have devote to your project. Recap My main goals for June were to be able to select ships to take into combat and to be able to select the weapons that a ship had equipped/installed. A stretch goal was to get rolling on a back end that could support crafting, building and other similar resource transactions. Results UI Goals I was able to accomplish my main goals and worked on a couple UI screens that allow doing those selections and causing game state changes that propagate into tactical and back to strategy. Here you can see just the basic strategy layer screen (which isn't really that impressive with only a couple buttons). Here you can see the starship loadout screen where you can select different ships and then choose the weapons in each slot. The ideal goal would be something more like the paper doll kind of UI's in more traditional RPG's, but that's probably a ways off. Here's the starship selection screen with some ships selected. Once all the spots are filled, the Deploy button becomes enabled which will load into the tactical map. Overall I'm happy with the way these turned out for now. I did run into one annoying bit with UE4 UI. I posted about it here, but didn't really get any traction. The fundamental issue was that I made a new widget type for those drop downs (basically a version of UE4's combo box, but that can store some user data along with each entry). Now, UE4 has two fundamental basis for UI elements Widget and UserWidget. The problem I was having is that I wanted my new type to work in ways that neither base is allowed to completely work on it's own. Widgets are self-contained (contain no sub-Widgets1) and are placeable from the UI Designer. However Widgets cannot be created and added to a UI dynamically, for that you need a UserWidget. Since my version of a drop down started out as basically a copy of the UE4 combo box, it was a widget. Once I encountered the limitation on dynamic creation, I figured what the heck and changed mine to derive from UserWidget instead. With that I was able to do the fleet selection UI and was happy. Later I ran into a problem that when building the loadout UI because I wanted to place my drop down directly in the Designer and it turned out I couldn't place one for some reason. I really thought I was going to have to do some crazy and annoying things to make everything work the way I wanted (which I lay out in my help post I link to), but while talking through the problem with a guy at work I realized that I was able to place other UserWidgets through the designer and it turns out that while native UserWidgets can't be place in the Designer, blueprint ones can. So I left my drop down a UserWidget and created a blueprint of the class that acts only as a way to interact with the designer. Another outcome of that talk was that I probably shouldn't have even bothered with my drop down and instead used one of the other built in UI widgets, the List View. I looked into it a little bit and it does look like it might be a better solution but for now I've just added a note in my project's backlog (ie a text document). Other Goals I got started on the whole transaction back end by creating definition types and test data for resources that will be used as the main kind of inputs to the system, but that's about as far as I got. Unplanned Accomplishments I was able to finish the UI changes about halfway through the month so I ended up letting myself get a little distracted by some other things. While working up the resource definitions, I wanted them to show up better in the UE4 Content Browser and since we've done it at work I knew it wasn't a big deal. The piece that was missing was that none of my plugins had been setup yet to support an editor module. UE4 has a pretty robust runtime linking system for separating libraries from each other as well as separating parts of libraries that should only be loaded certain kinds of builds (like things that can only be loaded when there's an editor running). I've been running on 4.19 for a while so I upgraded to 4.22. Since I'm using a source build this took a bit to rebuild the engine plugins, but it's not a big deal. In theory I could probably even switch back to a precompiled engine version since the one engine change I've made I didn't even port from my 4.19 depot to my 4.22 depot. It's a change that's been obsoleted by a system change that I made improving how I handle my custom event data passing. For now though it's nice knowing it's there even if only for reference. Turns out 4.22 can't be run on Visual Studio 2015, so I also need to update my copy of Visual Studio Community. I went ahead and just jumped right up to 2019. I haven't been as good as I want to be with commenting. I'm pretty good about writing implementations that are pretty small and self documenting, but I find it helps to have more comments in headers for member and method declarations. So I opened up all my source files and improved the commenting in most of them2, a lot were actually pretty good and didn't require anything new. This also gave me a chance to step back and look at some of the code more holistically and reconsider implementations that may have made sense at the time but might no longer be ideal given other support systems and structures that have been written in the meantime. Things like when my custom event handler could be a better option than the UE4 delegates. A couple of things I just cleaned up right then but mostly I added a lot of things to my backlog as technical debt work looking at fixing. Most of them are small items that will be good if I have a short time available to spend, but none of them actively inhibit my ability to move forward on any gameplay feature. July Sprint This month is going to be tricky. A four day weekend, two weekends of trips with my girlfriend, one weekend of a my girlfriend ditching me for her own trip, some house guests and other general summertime activities. Generally I plan to pick back up on the transaction/recipe system. I expect I should be able to finish the gamplay part but may not finish with the UI. I will also probably address a couple (or a few) of the technical debt items that I found, but I'm going to do my best to not let that list distract me too much. Games I'm Playing Really just Fate Grand Order this month. I may have played a mission from Fire Emblem. I'm really looking forward to the new Fire Emblem coming out on Switch at the end of the month and it comes out just in time that I might have a chance to play it on a road trip that weekend. Footnotes Wigets here refer only to the UWidgets class. Unreal also has another set of UI widget types for Slate. Usually a UWidget is implemented as some collection of Slate Widgets. However my point here is that a UWidget does not contain other UWidgets, that's the purpose of UserWidget. At least as far as I have been led to understand. Besides the main SRPG project, I've got two plugins StrategyTech (stuff I could make another strategy game with) and CoreTech (stuff I could use for making any sort of game). SRPG currently has 141 source files and 80 asset files (blueprints and textures), StrategyTech has 162 and CoreTech has 18 files. That feels like a lot, but they're all pretty small. I was also going to give some other stats, but in Visual Studio I can't find any built in analytics for C++. Let me know if you have any recommendations (they don't have to be Visual Studio integrated ones).
  12. MagForceSeven

    Unreal Widget Help

    I posted this problem to Epic's Answerhub, but thought I might post here as well. I'm having some difficulty with the differences between widgets and user widgets. I have a custom control that I would like to both be able to place through the designer and create/place dynamically. If I make the control a Widget, I can place it through the designer but can't create it dynamically (the Create Widget node seems to require a UserWidget type as does the native CreateNewWidget). If I make the control a UserWidget, I can create it dynamically but it no longer displays as available in the UMG palette to place through the designer. A possible work around is to make it a widget and create a user widget that wraps but that seems, quite honestly, dumb. In that case, either every access to the control must break the encapsulation of the wrapping UserWidget or the UserWidget must duplicate the control's API as boiler plate pass through functions. Neither is a path I feel particularly happy with. My temporary solution is to have my custom control be a user widget and dynamically spawn/position it during the pre-construct event as a replacement for placement in the designer, but it kind of defeats the purpose of having the designer.
  13. MagForceSeven

    May Update

    Hello again! Let's keep this train rolling, though I don't have anything to fancy to discuss. The month was pretty mixed with some travel, some busy weekends, and some time when my girlfriend out of town. Update If you recall from the April Update, my next goal was the basis of a strategy layer that would bind together the string of tactical battles. I didn't quite get as far as I was hoping when writing my last update, but I got pretty close. The only part that I'm really missing is the ability to make choices in strategy that are reflected in tactical. The structure is there though with respect to data being filled out as part of strategy and passed through to initialize the tactical setup. It just happens to be hard-coded instead of being hooked up to a UI. No pictures this time since the only addition is a screen with a single button that launches into the tactical map I've already shown. So the goals for June (that seems the best way to go about these right now) are 1) finish up the strategy-tactical loop by adding the ability to select which ships are going into combat and 2) adding a UI that allows modifying the weapon selection on a specific ship. A stretch goal would be getting started on a transaction or recipe Definition that would be basis for (primarily) strategy actions that transform one set resources into some other resource as part of buying, building or crafting things. Games I'm Playing Fate/Grand Order - always Steam World Quest - finished Battletech - not much time to make any progress here Fire Emblem Fates - this is the one from 2015, but I never did finish it. But when you've got 6 hours to kill on a plane with no power outlets (stupid Southwest) you play what you have charged batteries.
  14. MagForceSeven

    April Update

    My friend @slayemin made a good suggestion after my last journal post which was to be sure to post on a regular schedule. Seems obvious, but sometimes someone's got to say the obvious thing. I'm hoping to keep on a monthly schedule at this point, I even planned to have this posted last weekend but had a technical snafu and had to re-write almost all of it. I think that gives me enough time to make some sort of share-able progress. Personally it's always been a little frustrating how much (or little) I can get done on a hobby project. I probably could have done this whole month's worth of work in a few days, maybe a week, if I were working full-time. There isn't really anything to be done about it, for a hobby project I have to be happy with what I can accomplish in the time I have available. Burnout is potentially a real issue, but it's a nice change to work on a project where I can decide and execute. No consensus, no meetings, just work. Asset Mangement UE4 has a pretty slick asset management tool available call the AssetManager (introduced in 4.17 I believe) that does a lot of really great things but it also has a couple really annoying features. The first is that it treats asset types (which exist as normal UE4 C++ classes) differently than the rest of the engine treats types. For example if you were to ask the engine to iterate all Equipment, you'd visit all the Weapons and Armor in the game, but if you ask the AssetManager for all the Equipment it's loaded it will only give you back assets that are the exact type match. The other is that because of this you have to add an ini setting for every asset type you want the AssetManager to support. Now these are really only an issue because basically every one of my assets right now derive from a single type that I call DataDefinition. A DataDefinition is a pretty classic Flyweight pattern and is the shared static data that all versions of the same object would have. On X2 they were called Templates, at Volition they were called Infos, but everyone seems to have their own version. Mine also act as a sort of factory for game objects, but that's a discussion for another blog. The Definition was an asset so that all the derived types would be able to leverage the AssetManager to do the bulk of asset management for them, unfortunately the interface the AssetManager provides isn't how I want to access my Definitions. As with most of the UE4 engine types, the AssetManager is designed to be derived from and extended. So I had previously done that and added a whole new API for dealing with Definitions. After having loaded all the definitions at startup (more on that later) I keep track of them in my own maps so that I query them based on classes and get the instances back that I expect (like all the Weapon and Armor when I ask for Equipment). I also made my Definition API only provide access to const instances because the whole point of the static data is that it shouldn't be getting changed during run-time (they're still plenty editable by a user in the Editor though). That basically solved my first issue with the AssetManager. The thing that I did this month was attempt to fix my other issue with the AssetManager which was the ini configuration for each type that was derived from DataDefinition. I was basically able to hook into the AssetManager before it looks for assets and update the list programatically by going through the UE4 reflection to add entries for every class that is a child of DataDefinition but didn't' have an entry already specified in the ini file. For those that were missing, I looked for the nearest parent type that was included. This way I can just have a config setting for DataDefinition for now, but if I add a type that should live someplace else, I could add a specific entry for that type only when I need it and not as boilerplate when adding any type that derives from DataDefinition. I was pretty happy with it and so reimplemented it at work since we've already had a number of bugs caused by missing ini entries. Definition Loading You may think it's crazy to load all my DataDefinitions at the start of the game, but that's the beauty of them being assets within the AssetManager. Firstly, it really helps with game play to have the full breadth of game options available all the time even if there isn't an instance running around the world. Secondly the Definitions themselves are small, almost tiny, and all of the really heavy data like textures or models or sounds are other assets that aren't immediately loaded. Plasma Weapon Most of what I've been working on this month has been a new weapon currently being called a Plasma Bolt. I designed it to require quite a few specific elements I wanted to include support for: The Plasma Bolt requires no energy to fire (already supported) but does require ammo (already supported) Plasma Bolt ammo starts at zero (already supported) Includes a supporting action that allows spending energy to create Plasma Bolt ammo Damage increases for additional ammo above the minimum requirement to fire the weapon Damage decreases based on distance between the source and target Firing the Plasma Bolt uses up all the ammo the weapon has I ended up working my way up from the bottom of the list. Adding a toggle to the ammo feature was trivial. It was also pretty quick to add the two damage modifiers. I wrote a nifty structure of int/float pairs that can be used to calculate a value. One form of calculation is a just a linear interpolation of the input in-between the int's to generate a value between the floats, this is the version I currently use for the damage reduction by range. The other version uses the same data but for every multiple of an int in the value it adds that multiple of the float as the output. It starts at the high values and works backwards so that it will use an entry for 5 before using the 1 entry 5 times. The biggest change was for the supporting action. I already had a weapon definition that included a lot of what an action would have to have: various display elements, cost handling, game state mutation, etc. But there was also an awful lot that I didn't really need like everything related to targeting. The game play changes were again pretty easy and straight forward, it was the UI that took me a while. I had already made a button that could be used with a weapon and display the icon and stat values, but now a weapon should actually be a collection of those buttons, one for the weapon and a few for it's supporting actions. That took awhile to restructure to having an action button and a weapon button that contained action buttons and showed a hide them based on hover events. The most annoying bit I ran into was that apparently you don't get hover events from disabled buttons. Since the action button was already intercepting the events from the basic button it contained to trigger it's own delegates to anyone interested, I resorted to just adding an invisible button on top that is never disabled, but uses the state of the other button to decide if it should inform listeners about a click event. It's probably something worth revisiting eventually, but not now. Here's the redone UI, but like any good refactor it's looks basically the same. You can see the Plasma Bolt is currently disabled due to the lack of ammo available to fire. When hovered you can see the extra action button shows up. After clicking the action button, the Plasma Bolt now has 2 ammo available and can fire (that's the minimum). What's Next So now that I think that I've got enough structure and support for the tactical mode, I'm going to be moving onto a strategy layer that can string tactical battles together. It should be mostly UI, so I've already started trying to get more familiar with some of the other UI elements. Up til now, I've mostly been making do with buttons and static text boxes. Ideally, I'd like to be able to load into one map with a UI, make a few minor choices (like fleet configuration), load into my tactical map and have those choices be represented in the tactical map. Games I'm Playing Fate/Grand Order - my one mobile game. Battletech - Yeah, the one from last year. Got a key through someone at work recently and finally am getting around to it. Steamworld Quest - A few guys were talking about it at work and it seemed up my alley. Not too far yet. Looking at picking up Steamworld Heist too, that one looks like it was interesting as well.
  15. MagForceSeven

    Back (Provisionally)

    So, it looks like it's been a little over two years since the last time that I updated this blog. It doesn't feel that long ago, but the calendar tells no lies. I think I'll start with some general updates on what I have been up to since my last post. Or maybe it could be called my list of excuses? Probably either... or both. Finished work on the expansion to XCom 2, called War of the Chosen. There were some long hours but nothing on the order of some of the high profile crunch stories that have recently been in the news. At least for me. Was received very well by the community and that's always makes the time you put in worth it. It's already hard enough trying to work on a side project in addition to a full time job, but it doubly tough towards the end of projects. Even if there aren't longer hours, the process of finishing is always seems more exhausting than the normal day to day. Started work on my next project at Firaxis (I'll just refer to it as Project Firaxis or PF in these blogs). While others worked on a throwaway prototype, a couple of us started laying the some of the groundwork and structure that would be needed regardless of the finer details the prototype lead to. The biggest change was switching over to build it in UE4. XCom and XCom 2 were built on a modified UE3 engine (pretty common knowledge) but UE3 is getting pretty old and isn't being supported by third parties well or at all anymore. The switch isn't exactly a secret, we're actually hiring for UE4 experience right now in a couple openings (hint, hint, hint). Towards the end of '17 I was pulled off PF to work on what would be released as the Tactical Legacy Pack. It was meant to be content heavy so they didn't want many full time engineers supporting it which meant it boiled down to a UI programmer (and there was a lot of new UI) and me (doing everything else). That took over a good chunk of '18 and since it was meant for a super-short turn around we kind of went straight into 'finishing mode'. I continued to contribute the non-prototype portion of PF as much as my Legacy Pack schedule would allow since it was expected I be going back to that project eventually. As the Legacy Pack wound down I was asked to fill the spot of Lead Gameplay Engineer on PF. That's a bit of a change from Systems Programming but I've always been slightly more aligned with gameplay systems programming than what one might consider "proper" systems programming. It's been a whole lot of fun and I've felt like I've been able to have been able to shape the overall technical architecture of our game in a solid direction. The not so great part has been that almost from the start we've been having to deliver back-to-back-to-back milestones to our publisher so we've been having to settle for expedited solutions instead of solid ones. Recently we've had the breathing room to start addressing some of the debt those milestones accrued. All that brings me to what I'm working on these days. For the most part, I haven't really touched the project that I was showing off in my previous journal entries. Even as a systems guy at heart, there are places that I just don't want to have to go like rendering engines, physics, audio systems, animation, etc. For where I was in that project and the things I wanted to do those were starting to be real hurdles (especially my rendering engine). However about the time that I was really starting to feel that way some of the preliminary discussions were taking place for PF, mostly along the lines of could we shepherd along a UE3 build or did we need to jump to UE4. It became pretty clear that we did need to and that PF would be in UE4. Now, I learn best by doing and trying out things so I went ahead and downloaded UE4 at home so that I could have a test bed at home to mess around and learn about UE4 before needing that info at work. Plus it would allow me to focus much more on gameplay systems then the minutiae of supporting systems (no offense animation or graphics programmers that are out there). After a minor stumbling block with the basic download, I pulled the engine source from github and got a buildable project going. Based on my local source control, my first UE4 change was July '17 and I've been making incremental updates since then. It's still hard with a full time job, other obligations and trying to no burn myself out on programming (I hear that's a think that can happen ) so it's doesn't actually look like a project with a year and a half of changes. With that I present SRPG (Strategy Role Playing Game): You may say that looks an awfully like the game that I had been building my home-rolled engine and you'd be right. It's still the game that I basically want to be making just in a different engine. I even ported quite a bit of my code (primary dealing with the hexes) over into my UE4 project. The main difference is that instead of being a test bed of a pure component architecture that mine was, it's organized in a way much more similar to what I deal with at work (not exactly of course, but similar) so that systems and patterns that I try out at home are more easily applicable to work. It doesn't hurt that it makes it easier to apply the things I learn at work to my game either. The biggest difference between old project and SRPG is that you'll notice that SRPG actually has something that looks like a UI instead of a bunch of random display strings. Chalk that one up to for UE4 blueprints. All the icons I got from game-icons.net. It also does have a few additional gameplay features like ammo, cooldowns and obstacles that weren't in the OldVersion. I even started a separate todo file for my UE4 project(s). I think I'm getting pretty close in my tactical element that it may be time to start working on a meta element for in between tactical battles. Tactical still needs objectives, mission scripting, map scripting and (probably) a fog of war. And the map needs to be way bigger. And AI. And... And... And... so not done-done but enough that I could add another axis of gameplay.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!