MagForceSeven

Members
  • Content count

    14
  • Joined

  • Last visited

Community Reputation

516 Good

About MagForceSeven

  • Rank
    Member

Personal Information

  • Interests
    Design
    Programming
  1. Spellbound: October Update

    I'm really happy to hear that you've recognized that particular trap. It's one of those tough choices that is hard for someone on the outside to convince you of and have to learn how to recognize it for yourself. Game development can easily get pulled into traps where you think you're building simulations but simulations are complicated. I think one of the best lessons I've learned is to try and recognize when the illusion of simulation is good enough. However, it is worth keeping in mind that your impetus for the machine learning was coming from a good place: reducing system maintenance and iteration time of new features. It sounds like it's worth it to continue ways to explore how to make your AI scripts in ways that don't require as much rework when you add new features. And it sounds like your writing tasks line up nicely with NaNoWriMo which just started. There are probably some great resources to help springboard your writing efforts, even if you're not planning a novel. Great update!
  2. Spellbound: September Update

    Your description of an AI decision graph sounds a lot like Behavior Trees. Is that something that you've looked into at all? I know you're in Unreal 4, I believe it's got some form of built in support for them. Or do you see there being some core difference between the two concepts?
  3. Principles of Debugging Effectively

    One more thing.  Like I mentioned in my original post, I tend to have to fix bugs in code that I don't know that well which usually leaves me with insufficient knowledge to form any sort of hypothesis in the first place so I have to fall back on the facts of empirical results.  So if there's a 12 failure locations I have to instrument them all because I'll have little to no systemic knowledge that allows for any sort of culling.
  4. Principles of Debugging Effectively

      I guess my point is that when using the debugger I'm not trying to make hypotheses and test.  I'm trying to work from empirical events.  It can't be wrong because I just watched it do the thing that causes the problem (or causes the sequence of events to occur that cause the problem).  If a variable is wrong, don't hypothesize about why it's wrong, set breakpoints or other catches so that the moment that it becomes wrong you drop into the debugger to see empirical cause.  This makes the answer to the question "Why?" not a hypothesis but fact. I agree that they are related processes, but for some bugs it's faster (sometimes lots if depending on the repro steps).  For example, say that a variable is the wrong value and it's set from places A, B & C.  You could hypothesis that it's B, change B, reproduce to verify your hypothesis which may or may not be right.  Or you could trap A, B & C.  See that C, for a fact, is setting it incorrectly and fix C.  Now sometimes proper abstractions help with this.  When a is private with a Setter, you implicitly trap all change cases.  But not all code is that convenient.  Even if there are 10+ reasons, computers are great a complicated checks and when you have the source you can make all sorts of temporary local changes to catch problems that you never have to actually check in.  Trap them all! Fundamentally this is what assertions are for, proactively identifying conditions that will cause problems further along the line if allowed to persist and stopping execution or logging it so that they can be identified and fixed. In addition, hypotheses have no place in a bug report.  A bug report is an empirical report of something not functioning in the expected manner.  They may have needed to build a hypothesis to build steps they could reasonably reproduce the effect, but it's the repro steps that belong in the bug and not their working hypothesis.  The distinction can be mostly easily seen retroactively when the problem has been found and the listed repro steps include things that have no actual impact reproduction.  I've sent many bugs back to test (or onto other programmers) with modified repro steps saying that one or more of the steps are unneeded to actually reproduce the problem. I think there is a place and time for both methods of testing (and as it happens we're primarily in bug-fix mode at the office right now so this is right in the forefront of my mind).  The Scientific Method is great/useful for black-box testing (QA) and for low reproduction rate problems.  This "Mindy Method" is primarily for white-box testing (ie. when you have the source) and high repro rate issues.  It really only helps if you can cause the problem to happen repeatedly to power the "Why? Because..." loop. I'm not saying my screwdriver is better than your hammer.  I'm just saying that I've had a lot more success handling screws with a screwdriver than with a hammer.
  5. Principles of Debugging Effectively

    I agree with a lot of that in-theory.  In practice I've found it less useful but I think that's because of working in a different environment.  Which is to say a collaborative studio environment as opposed to a one-man or small team.  The main issue is in order to come up with a hypothesis you have to have some level of understanding of how things are supposed to work so that hypothesis about potential failure points.  I've routinely gotten bugs from QA or other devs that include hypotheses of what is wrong that make no sense when you know how the system works. And I'm asked on way too many occasions to find & fix bugs in code I have only a passing familiarity with.  Definitely not enough to form a hypothesis about what is broken. For those types of bugs I've come up with the "Mindy Process", named after Mindy from the "Buttons and Mindy" segments of Animaniacs.  If you're not familiar with that character, part of her shtick was asking someone a question and then responding to every answer with "Why?"  (I swear I tried to find a video to explain it better with little luck). 1) Reproduce 2) Why are we doing that? 3) Oh, that's why.  Is that supposed to happen? 4a) No? Make it not do that 4b) Yes? Something must be wrong earlier.  Goto 2. 5) Reproduce That process looks kind of like the loop of "Why? Because... Why? Because..." that Mindy gets into. Now this mainly useful when you're able to work with a debugger and can break, step, inspect everything and watch what the program does live.  It also tends to much less useful the lower the reproduction rate is since you have to be able to stop the program when the case you care about is going wrong.
  6. Journal #11: Combat Update

      They do a little.  I haven't made any effort in that area quite yet, partly because I'm pretty sure I need to do something drastic like swap out my whole rendering solution to something else.
  7. Journal #11: Combat Update

    Combat In my last entry I mentioned the few things that were really remaining for my tactical gameplay. I spent the time since working on the weapons issue. I added a few more weapons definition entries and updated the ship definitions to be the owner of the weapon slots. Those slots define limitations of that weapon location on the ship like the maximum available firing arc. I also updated my prototype harness so that a bunch of the testing stuff that was in there has been removed and all that remains is stuff that should move forward as part of the tactical game. I make a copy of it first so that I still had a version with that testing stuff that I could go back to though if I need it. Seemed like a good idea to include some new pictures. The red tiles are those in the arc, a blue tile is the cursor highlight when it's within the arc and a green tile is the cursor highlight when it's outside the arc. The lower right still has the text indicating which player's turn it is and the upper right has a display string indicating the name of the arc being used. Here you can see multiple weapons & weapon selection with two different firing arcs coming from the same ship. I think I have a some technical debt to address before I move onto either of the other two tactical features I mentioned in my last post. The main one is support for STL containers in my reflection system. I need it for a few cases, but the bothersome case right now is that I can't properly initialize my ship definition weapon slots from the data file. And the temporary solution involves a const_cast which is usually an indicator you're doing something weird. Random I did a few other random things I switched all the copy constructor or assignments from private & unimplemented to public and using the "= delete" modifiers (see Readings section below) I added some macros to make it a little easier to use my function delegate object. There was a bit of type data duplication, especially when creating a pointer to a class member function. It's a lot easier to use and look at now. I added a placeholder for localization. This may sound a bit crazy, but I'm having to add a lot of to-be localized strings at work so it's at the forefront of my mind and it's one of the things the Unreal makes pretty painless to do when you're working in UnrealScript. Since I don't actually need localization quite yet the entirety of my localization header consists of: typedef std::string localized_string. This way I can at easily identify the things that are display strings and when a real solution goes in (if ever) the compiler should catch just about everything that needs to be updated for me. Readings I've had a few technical books on my desk to read for quite a while and have spent a good chunk of the new year working my way through them. They've been Effective Modern C++ and Effective STL, both by Scott Meyers, and C++ Gotchas, by Stephen Dewhurst. C++ Gotchas was a little tough sometimes because it was written in 2003 so it's pretty ancient for the tech world. It would have been a better read for me while in college and a few of the "gotchas" aren't really as big of an issue if you're using C++11 or C++14. I've only just started Effective STL but it looks like it's also pretty ancient by tech lifetimes (2001) but I've only just started it so we'll see how well it actually holds up. Effective Modern C++ was pretty great. There were a few things I knew in the back of my head from looking writeups about the new features. My home codebase is still pretty small so it's easy for me to blast in some types of language changes. I had previously already gone through my code and replaced NULL usage with nullptr. As I mentioned above, using "= delete" instead of private unimplemented functions I'm on board with (since it more clear on intent and generates a compiler error instead of a linker one), so I made that change as well. I added a couple of things to my todo list for improvements that I might be able to make to certain things using certain features. I'll probably make a pass to add the override keyword in all the appropriate places as well as start using it for all new code. While reading C++ Gotchas and Effective Modern C++, I've played around with the notion of writing up a coding style guide for my home codebase. I contributed a bit when we revamped the one at Volition to bring it into the world of C++ and it was kind of fun. It would be nice to have something like that around if I ever tried to get someone else to contribute to my projects. Random C++ Gotchas musings The "Pimpl Idiom" is also called the "Cheshire Cat Technique"?! How did I never hear this?! That is such a cooler name! The example code for the pimpl idiom was pretty standard except that the structure used as the implementation had private members and accessor functions. What is the purpose in that? You're already isolated from the client code through the private-ness of the pointer and the API of the public data structure. I seems weird to then force your own code to go through a second API for data access. Maybe it was just copy/paste. It suggested using 0 over NULL due to implementation differences in the macro. I couldn't get behind that. NULL indicates intent to the reader in a much clearer fashion. Shouldn't be an issue going forward as everyone should be using the built-in nullptr.
  8. Journal #10: Combat

    Over the last few weeks I've made some good incremental progress on the combat in my little strategy game. 1) I added shields to both my starship class definition as well as to the starship data component. (We're in space so what fun is space combat without shields of some kind). 2) I added a new component to act as a damage interface. In other engines you might have an IDamageable that the component would be able to derive from in addition to the regular damage tree. At the moment I don't support multiple inheritance with my component definitions (I'm developing in C++ so there no real distinguishing between what you're deriving from). I'm okay with this for now. For now in my engine it's just a separate component on the entity with a delegate that can be called. I considered the more traditional derivation with a virtual function, but opted for something that involves a little less boilerplate code to do something slightly different. If I hadn't already had this delegate structure sitting around (I mentioned it in my first post as being based on the impossibly fast C++ delegates found here) I probably would have done it that way. 3) Fixed some bugs in a couple of previously unused functions and added a few new small helpers to some of my other systems that were needed in order to make all the new combat bits work the way that I wanted them to. 4) Added to my Todo list because every time a programmer writes code, they find related things they want to fix or add to. Some are technical debt, some aren't. Combat Now, I'm a huge fan of Star Trek (if you don't recognize my avatar image, that's were it's from) and I wanted my damage to have a bit of the feel I got from watching the combat of that show (mainly TNG/DS9/Voyager). To that end I want basically 3 things when it comes time to apply damage to a ship in my game. 1) Below a certain point, a weapon should do nothing. 2) Within a certain range, the shield takes the majority of the damage. 3) Above that range the shields take extra damage. Currently I'm basing that all these on the ratio of the weapons power to the shields power. So the more powerful the shield vs the weapon, the more effective the shield. For now I have it all coded, but it's hard to tell at this point the "fun" since it's all pretty garbage numbers. A few other things: 1) Each ship has 6 shield entries, one for each side of the hexagon that it's occupying. Right now they all start at the same value, but eventually I plan on that changing. 2) Some combat could apply damage to multiple shields at once. In this case (for now) it divides the damage equally among all the shields but still uses the full damage to determine the power ratio for how to apply the damage to the shield. 3) Right now once you get through the shields, the ship just has a bucket of hit points that is decremented by damage. Eventually I'd like that to be applied to ship systems and affected by armor for that hex side as well. Somewhat in the vein of Star Fleet Battles & similar games. What's Next I feel like I'm really only missing three things from my tactical combat: 1) Real/diverse weapons. Right now all my ships have the same weapon with the same stats. Plus the weapon is using the general purpose stats component (Journal #6). Neither of which is ideal. 2) Energy use model. The idea is that each ship generates points from it's various power supplies and then moving and using weapons reduces that amount. Kind of like the action points used in the original X-COM games (not the new ones by Firaxis). Right now all the ships start the turn with 2 points. The place holder weapon costs 1 and movement (to any space on the board) costs 1. Technically I do have a placeholder value in the weapon for a cost but it's set to 1. The movement should use up power proportional to distance traveled with, I think, some max travel limit that is smaller than the total power available. Obviously the number of points a ship will start out with will have to be much higher than 2, but it was a good placeholder. 3) Pathing turning limits. I have basic A* pathfinding though the hex grid already. The part that is missing is that currently a ship can basically path to where ever it wants. The models have a facing, but if they're told to move to the tile right behind them they will rotate in place and then move forward into the tile. That may be fine for some games (and possibly even fine for mine for some ship types like fighters if they get added) but I want my combat to be maneuver driven. It's meant to mesh with the shield arcs and (eventual) weapon firing arcs. I think that once I get those pieces in place I'll feel good about where the tactical game sits and I'd like to move onto an overarching strategy element that would bind all the tactical combat into a cohesive whole. Then I can go about refining the interplay between those two elements into an actual game!
  9. Journal #9

    January has not been particularly kind to me. It started with getting sick (you always seem to pickup a bug of some kind from planes) and after getting over that I had wisdom teeth extraction to look forward to and recover from. In fact, I'm currently writing this entry on the last day of my 4 day weekend to recover from that particular adventure. Thankfully everything on that front has gone super smoothly and am doing really well. So on to the parts that everyone here is way more interesting to the folks here. I started 2017 with the decision that I wanted to move on adding elements that are more about gameplay than development utilities. As much as I like that sort of work, it's time to move onto things to actually making a game. I'll swing back to utilities for a change of pace or as needed to support gameplay. As I mentioned in Journal #6, I'm working on a tactical strategy game. I've got some basic movement supported already, so the main missing tactical element is combat. I added (for now) another stats component (also Journal #6) to act as the data for a weapon attached to the each unit. For now all the ships have the same weapon with the same values. The stats my weapons are starting out with are Range (how far it can deal damage), Power (how much damage it does) and Cost (how much of the ship's supply stat is used to use). Since I don't really have a good solution for UI, I'm outputting most feedback that would be UI updates to the standard out for now. I added to the starship data definition (Journal #7) to include the mesh information and then reordered my object construction so that given one of those definitions I could construct an object. I also swapped out the generic stats component that I was using for the ship's runtime data (health and power) with a component specific to the job of tracking starship data. Since this component was meant to have a reference to the data definition it was created from, I added support to my reflection system so that it knew about the data definition library. That way the JSON data I use can include a serialization safe string (as opposed to a doing crazy things with pointers) that the reflection system knows how to turn into a definition entry pointer. Lastly, for use on my starship component I wrote up a data structure for gameplay stats (not to be confused with the stats component) and modifiers to those stats. In a typical RPG this would be used for values like Strength or Agility or the like. The modifiers would be things applied by equipment (like +50 Str or +25%) while they are equipped. For now the modifiers only support addition and multiplication. The stat starts with a base value that is the value when there are no modifiers, then multipliers are applied and then the additions to calculate the maximum value for that stat. It also keeps track of the current value over time. So in the case of a Health stat, it's tracking your current health, maximum health, base health and all the modifiers to the base that determine what your maximum actually is. We'll see how that goes for now. New todos: - Logging: I can generate output to the debug window but it's not really a log. At some point I'll want a logging solution that can save to a file and do some basic filtering on what output is saved. - Reflection: Support for dynamic arrays. My reflection system already supports normal C arrays but to finish my gameplay stats structure it needs to support dynamic arrays (std::vector). I haven't decided yet if I'll just do support for vector or if I'll try to implement something that is more general right off the bat. - Console: I realized I forgot to include scripts in list of console todos. It's nice to be able to write up a series of console commands in a text file that you can then reference repeatedly and across multiple executions. The console I worked with at Volition supported this and it was super useful. - Strong typedef: This was something I introduced at Volition and thought I had a version of it here at home. When working in C++, typedefs are great but in a great many circumstances they just aren't typesafe enough. For this reason I wrote up (as have many others include one that is part of boost) a macro that simply wraps an instance of a type in a struct to prevent general type conversions from happening when you don't want them to. I need to find some time to recreate that in my home project. I guess I didn't need it, but I'd like to use it as part of how the stats and their modifiers interact with the clients that are applying the modifiers. New project idea: - I mentioned in my first post a tool I had been working on for the Fantasy Flight game, Descent. A campaign tracker. Well I started collecting and playing another game by Fantasy Flight called Star Wars: Armada. I think it would be very interesting to put together a tool to help keep track of things there. It could even spiral out to three tools, Fleet Construction, Combat tracker, Campaign tracker (campaign play being a thing that was just released). I'd need to work on upgrading my copy of the wxWidgets library since the one I currently have isn't compatible with the version of Visual Studio I'm currently on. Really just an idea right now. Edit: I am aware of online tools for this game in regards to Fleet Construction so it might not be the highest priority tool of the three. Well, that's it for January of 2017!
  10. Journal #8

    Howdy GameDev.net! Welcome to 2017! It's been tough finding time over the last month, December is a tough month to carve out personal time. That's not to say I didn't get anything done, just not a whole lot in my hobby code. I was hoping to have some more time during my Christmas vacation but instead spent most of it sightseeing Seattle with my girlfriend. And I seem to have picked up a bit of a bug on our way back and writing code while sick and/or medicated is tough. The thing that I did get accomplished was a small refactor of my input code. When I had originally written it, I had included an API for working with keybindings. But since I wasn't actually using it anywhere it wasn't really battle-tested as it were. My input library included an enumeration for identifying the actions to be bound to, but that wasn't really extensible or flexible enough to be used in multiple projects without hard-coding game-specific references into the library. So I rewrote that API so that instead of mapping an enumeration to keys, I map strings to key combinations. Well not arbitrary key combinations, just a key plus some combination of alt, control and shift. As with all things programming, this worked pretty well except for one tiny detail. It turned out that (given the way I wanted to be able to write the client code) if I had two bindings, one bound to and one bound to + , then pressing the + would trigger both bindings! Imagine pressing ctrl+c to copy some text and it also added a 'c' to the document. That wouldn't do. My current solution is a priority system based on the number of modifiers. The potential downside is that when checking a particular keybinding, I also need to check all other keybindings associated with the same key and more associated modifiers. 'Potential' downside, at worst there are currently only 8 possible combinations of keys possible for any given key with modifiers. It's currently only 8 because I don't make any distinction between the left & right versions of the modifier keys. I don't expect anyone would every possibly bind all eight combinations of a key to a game command, but even in the worst case checking 8 combinations shouldn't be a big deal. Anyway, the priority mechanism means that if there is a key-binding for + and it's down, then anything bound to just won't be triggered. Similarly if ++ is down, then + won't be triggered. And this is just for active keybindings, so if the only thing bound to is without any modifiers, holding down one of the modifier keys will have zero effect on the input reporting. Here's looking forward to much new code in 2017!
  11. Spellbound: December Update

    As a solo developer, what benefits do you get from maintaining an office?  If work that you're not doing personally is contracted out and completed remotely anyway I don't see why you would spend on something like that.  The few indie developers I've had any view into (though documentaries, not personal contact) seem to eschew that sort of cost until they have released in a way that allows for a revenue stream that actually supports those costs.  It seems like that is a relatively simple cost to remove, but maybe the realities of VR development are a large enough departure from regular software development.   Also, with respect to voice acting: you should consider looking into text to speech.  We've been using it to some degree to generate temporary assets until we got actual voice actors, but from the little that I've seen from the Windows documentation it seems like there is some good potential for independent developers like you to use it in place of actors.  And to be clear, I'm not suggesting on-the-fly text to speech as part of the shipped game.  What I am suggesting is a one-time system that allows you to output audio files that are played by the game the same as if the audio had been created by a person.  Perhaps it's not ideal, but it might be good enough so that you could delay the costs (time & money) of dealing with that.   All-in-all a great update and I'm looking forward to 2017!
  12. Journal #7

    I hope that everyone (at least in the US) had a good holiday. I took the week off from work and while I couldn't devote the entire time to working on my hobby code I was able to get a nice chunk of something done. First I took some code that I had written for my component system and generalized it a bit so that I could reuse it. I call it an 'instantiator' and it's designed to do two things. The first is to act as an object pool, managing resource allocations and memory reuse as instances are needed and discarded. The second function is to manage some super-simple type information to allow for fast and safe type checking and casting. The instantiator comes in two flavors 'virtual' and 'concrete', the virtual instantiator just does the type stuff and acts as a kind of place holder. It also acts as the base instantiator type, defines a static public interface that the client systems go through and defines the private virtual interface that the concrete instantiators implement to do all the allocation stuff. Lastly the virtual instantiator defines a static array of instantiator pointers that it uses to route all the static API calls to the instantiator for the desired class. The concrete instantiator inherits from the virtual one picking up the type information support and implementing the virtual memory management interface. Now to support all this, the classes using the instantiator (which relies heavily on templates) have a few required members to them for things like class name strings and other static members. I've setup macros to simplify a lot of these things, but really all's that left to do is declare a type and then declare an instance of either a virtual or concrete instantiator for that type in a cpp file at file scope. The constructor for instantiator then registers itself (during pre-main construction) into the static array of instantiators. The basic gist of the implementation looks like this:class virtual_instantiator{private: // a few class identification members std::vector parenting_types; static virtual_instantiator *set[ MAX_TYPES ]; virtual type* alloc_internal( ); virtual void free_internal( type* ); // other various system virtual callspublic: static type* alloc( ); static void free( type* ); static bool is_type_of( is_type, of_type ); // static versions of the other virtual system calls virtual_instantiator( type, parent_type, classname );};class concrete_instantiator : public virtual_instantiator{private: // memory allocation stuffprotected: // implementations of virtual interfacespublic: concrete_instantiator( );}; This obviously doesn't compile. I've attached the full header to this journal entry if you're interested. During system initialization (inside main) a static function is called for the virtual_instantiator which then calls the initialization function for all the instantiator instances. One of the primary things that happens here is filling in the parenting_types vector of bools. This basically makes a copy of the bools from the instantiator for the parent type and then sets the bool for the current type. Then anytime that I want to know if one type is part of another's tree it's just a bit check. As part of the instance allocation, I also store the most derived type into a variable of the instance so that I know what it was allocated as. Some limitations: it only supports single inheritance and it's currently limited to an unsigned short (65535) worth of different types. Other than that the tree of classes can be as deep or as wide as I want it to be. The single inheritance limitation doesn't bother me personally and 65K of types seems more than enough for one game (since any game specific type ids could be used for different types in different projects). Now, I had originally written this whole setup pretty specifically for the creation and management of components and it was working quite well. But I decided that I would also like it to manage my data driven type definitions, things like class or weapon stats. So I refactored what I already had a bit (mostly adding more templates) so that my components and data definitions used the same code but used different instances of the static instantiator array. This refactored version is what is attached to this journal. I was also pleased that for the most part this worked out relatively painlessly. I did have to do some looking up of more recent C++ template features to get a couple things working the way I wanted in other headers but learning that stuff is one of the reasons I want to make an effort on this hobby code. The main effort of my holiday coding was actually writing up the code for my data definitions types. This code consists of two parts, the data_definitions base class and a class I named definition_library. The data_definition class was mostly a bit of copy/paste from the component class; all the bits and pieces that are required to interact with the instantiator and the macro for declaring derived types. The definition_library wraps up access to the instantiator (forcing an additional construction requirement), handles parsing of certain json files into data_definition instances and manages a mapping of string names to the data definitions (the name being the additional construction requirement). The main thing I decided I wanted to really enforce is that when accessing any of the definitions that have already been created, was that they should be const. If you create an instance at runtime, the creation interface does return a non-const instance, but once you let that go and get it by name through the library, the only way to do it will give you const data. My reasoning behind this is that the definition structures are intended as application-static data. Once the game is running and has loaded up that data it should be treated as unchanging. Now for purposes of development it probably makes sense that I can tweak some of those numbers at runtime. For now, that task has been relegated to my todo list. I'll always have the option of making type specific console commands for the definitions that I specifically want to be able to tweak, but I think I'd like to find a way to leverage my reflection system to write a single console command as part of the definition library that can modify any member of any type. Lastly, once I had all that setup I built my initial test case of a type that actually derived from data_definition and had instances that were created when a file was loaded. Continuing the theme of game design I'm working through, the data definition was the start of information about ship classes. Right now it just has a hull class (cruiser, battleship, etc) and an optional modifier (command, missile, escort). Happy to answer any questions about anything in this writeup. I know I probably touched nerves of a few people mentioning components and/or reflection without going into a whole lot of detail. I do plan to do a journal about them at some point, so you can look forward to that. Probably save that for a week when I don't have a chance to write much code or make a major addition to them.
  13. Journal #6: Kryptonite

    I'm back! I told you Sid Meier's Civilization was my Kryptonite and it basically stole my last two weekends playing it. The first weekend was no real surprise and I had planned to just play it all weekend. But I got sucked in again the following one while doing a few productive things like laundry. In any case it's a very good continuation of the franchise and worth a look if you like that sort of game. Now, onto what I worked on this last week. I decided to put more console work off to the side (with appropriate notations on my todo list) in favor of something a little more in the vein of a gameplay feature. So to that end I implemented what is the core gameplay loop of a tactical strategy game (along the lines of XCom or Final Fantasy Tactics). Now I obviously already had the game loop doing all the windows messaging, managing frame processing and rendering. This was the gameplay loop to control the player's interaction with the game. I added a new component and couple objects to act as players. Right now this component consists of an array of handles which are the ships controlled by that player. I also added a new component to handle unit stats and added that to all the ships that I had created and added them to one of the two players. The stats component isn't particularly complicated right now, just an arbitrary mapping of keys & values. Long term I don't expect that gameplay will rely heavily on this, but it's really nice for experimentation and prototyping. And it's not unit/spaceship specific. Right now all the ships have two stats: Power & Supply. The game loop then consists of: Player Turn Start - Set all that player's ships supply stat to their power stat value Move unit - User clicks another tile, path the unit to that tile, decrement supply by 1 When supply reduced to zero, move the selection to the next unit Continue moving units and rotating the selection until all units controlled by player have a 0 supply stat When there are no units with available supply, move to the next player and return to step 1 This should be fairly recognizable to strategy game players and it's nice to have moved my program closer to "game" territory. I also added a few other related elements like: tabbing to rotate the selection of the current unit preventing pathing from occurring when the current unit has a 0 supply stat preventing the current unit from becoming one controlled by other players if you clicked a tile that had a unit you didn't own in it. Using the mouse to change unit selection was already supported. This is the point at which I would/should have a video to show off the various unit moves and player turn transitions but I haven't familarized myself with video capture tools quite yet.
  14. Spellbound: October Update

    Awesome!   I'm happy to take whatever credit you want to give me for that versioning notion, but I'm just passing on a fairly standard software development operations practice.  One major thing though, the amount of time that something takes to fix needs to be significantly weighed against what you're fixing and any accidental side effects that could be introduced into the build.  Spending a day or two fixing a crash that a significant segment of your users are encountering is definitely something to include in the release build.   And don't forget to integrate those release side fixes back into the developer version at some point.  And perhaps a note of how it should really be fixed in the developer build because patch fixes aren't always the best way to solve the problem.  Usually they're just the most expedient.
  15. Journal #5: Not a Holiday

    I didn't have a whole lot of time this week. Instead there was a trip to a Renn Faire and touring a US Navy missile cruiser as part of Baltimore Fleet Week. I did find a little time to implement a search feature to my console. It searches through both the name and the description (or just one depending on the input parameters) and outputs the name of all the results to the console history. Now this isn't particularly exciting I know, but what I found along the way was a little bothersome. It turns out that there is not a case insensitive version of 'strstr'. Usually for every flavor of string function I've ever run across there's a version 'strcmp' and a version 'stricmp'. And I couldn't find a 'stristr', and a little Google searching latter confirmed there isn't one! That's crazy. So I wrote one really quick. I'm going to try to find another small thing I can work on this week because I won't have time during the weekend. Civilization 6 comes out Friday and that series is my Kryptonite. Seriously, I've taken days off from work in previous years to play it. So I'm going to be sitting on my butt all weekend playing it this time.