Taking Exception to Exceptions in Tasks

Awhile back I converted most of the client framework to be much more MVVM-ish. Part of this turned over proxy management to a ProxyModel class. In so doing, the mechanisms for getting the server’s user list and latest text-chat messages for the user were converted to functions designed to work in a free-threaded manner (in response to callbacks from the server).

Since all the communication between the server and the client is now handled without the WPF dispatcher thread getting involved (and better, the Login Dialog uses a call to the ProxyModel that invokes UserList and GetMessages through a TaskFactory.StartNew), it has come to my attention that I am not observing exceptions thrown from within the confines of the task-scheduler created threads.

What used to pop-up a “friendly” Ikosa exception dialog on a failed login attempt now simply crashes the client process as the when the task is garbage collected, the thrown (unobserved) exceptions are AppDomain poison. This has become my next “must-fix”…


Home on the Ranged Target Cover

I had gotten to the point over the weekend where I was fairly comfortable with the final state of melee cover checks (with its weird alternate source points when attacking downward while standing on a ledge), and really began testing the ranged cover checks. What helped me in testing was adding the interaction alterations (for the attack interaction) to the status feedback so that the client could see cover and concealment affecting the attack. I’m going to need to examine the StepStatus a lot more closely to “pretty-up” the structure, and ensure that the right amount of information is sent to each client. I’m also going to need to put a facility to always send observed-activity info to various clients when an actor acts (right now, I only use ObservedActivityInfo when making an OpportunisticInquiry).

But anyway, back to ranged attacks. I noticed that a creature whose feet were blocked by only a small step was getting a lot of cover lines flagged (so that they could get a +4 cover bonus to armor-rating). I tried to compensate for this at first by proportionally moving the bottom points of the lowest cells upwards towards the top points, but this still kept them behind the step in certain cases.

Then, I planned to do some magic with checking the back-most low point(s) if the front-most low points were blocked. But I finally decided on boosting the low points upward again by an “absolute” amount relative to a fraction of the creature size (similar to how land movement has a maximum up-step size beyond which a climb check is needed, and representing the “bulk/core” of the creature’s body), rather than a fraction of the vector between low and high. If the low point boost is longer than the vector between low and high points, than the low point is simply omitted from the target corner set.

In the light amount of testing I performed, this seems like the best balance so far. But I’ll need more testing, and ultimately I need to vary the amount of low-point boost by creature body type, and whether the creature is prone or not.


(Slightly) Uphill Battle

Returning to the Ikosa Framework’s rules for cover; in addition to the special point identification mechanism for downward melee strikes, there are some special adjustments made to melee source corner points when melee attacks are made on the same level.

The main reason for adjustments to handle the cases when the source and target cell are on the same level, but the target is on a “slightly” higher step. In this case, the “front”-lower corner(s) of the source cell must go through the low step, creating cover. When attacking a target cell on the same level (based on cell-specific gravity), Ikosa adjusts the lower corners upward by 30% towards the upper corners on the same up-down edge. (It also adjusts the upper corners down 5%).

Currently these percent factors are hard-coded, but may likely be calculated by other factors in the future.

The “modeled” result is that a melee attack against a target on a platform less than 1.5 feet higher than the attacker does not automatically get penalized by cover.

(Note: when any component of a melee attack is upward or downward, these adjustments are not applied. Also, reach/ranged attacks originate from a single point, so there is no need to adjust source corners).


Turn-Based Realities, LLC

Just started the process to create a business in Pennsylvania (about 35 days, since I didn’t take LegalZoom up on their “gold package” 7-10 day hand-delivered to state offices offer).

I grow weary of waiting; so as soon as I can (a song I’ve sung before), I’m going to open up free downloads of the client and host packages I use in testing the Ikosa Framework. I just need to (re-)finish the melee and ranged tactical cover checks using the new source/target corners strategies, strip out the channel security from the Net.TCP channel configuration (so clients don’t need to muck about with certificates for encryption), and build some ClickOnce installers for client and server.

…and find some time to do all that 🙂


Covering Melee Corners

Traditional PnP tactical cover rules have some gray areas when it comes to complex 3-dimensional topography and large creatures. Mostly these are swept under the generalizations from the “flatness” of tradition PnP play. However, the Ikosa Framework must calculate cover within predictable constraints and more highly variable conditions.

For instance, melee cover (which can only occur when attacking into an adjacent cell) generally requires all “corners” of the source cell to have unhindered line of effect to the target cell. Assuming an attacking creature stands on a block of solid ground 5 foot higher than an adjacent target creature (such that the target creature is “diagonally-down” from the attacker), then lines from the back of the attacker must be blocked by the solid ground to attack the target; in exactly the same way as when attacking around a corner. It is unlikely that a game-master would rule the lower target had cover from the attacker standing on a higher platform, especially since attacking from higher ground typically gives a +1 to attack.

The Ikosa Framework has strategies to deal with this situation (and some processing optimizations).

Optimization first: When calculating cover (melee or reach/ranged) Ikosa must check lines between “corners” of the source (cell or point) and target (cell or cells) for terrain blockage or cover inducing effects in the cells being traversed by the lines.

To reduce processing, Ikosa only examines points that will reach from source to target without going through the source or target (thus culling certain points from consideration). This can be determined by looking at the relative integer cell coordinates between source and target cells to determine which faces are exposed to each other. When two cells are face to face, 4 points from the source and 4 points from the target are considered. When edge to edge, 6 and 6, and when corner to corner, 7 points each. Also, for reach/ranged attacks, there are additional target points possible (since for larger creatures the entire creature is being targeted, which spans many cells), but also additional culling (so that only points exposed to the source point) are considered.

For the downward attack mentioned above, Ikosa detects the gravity direction of the attacker and whether the terrain supports the attacker (thus creatures in flight above the surface are excluded from this test) and then excludes those faces from consideration if they would otherwise be needed. As a result, only attacker points that face-outward toward the target on the non gravitationally bound attacker face are used. In this case, only 4 points are considered (if the target is adjacent and down) or 6 (if target is diagonal and down).

If the attacker were in a cell 5 feet lower, however, the gravitationally bound face isn’t facing the target anyway, and since the all the target’s points are still usable, the higher target would have cover.


The Past Week

Opportunistic attacks are now working fairly well. I’ve managed to trigger them off on movement from a threatened cube and by trying to use a ranged weapon in a threatened cube. Also tested: not being able to make an opportunistic attack if the target has cover, and only being able to attack when wielding a weapon that can make such an attack. Haven’t played with reach weapons yet.

I also discovered (and fixed) a problem with some of the attack handlers, in that I had a handler chain defined for a base class (AttackData) that prevented the chains for more specific attack types (MeleeAttackData, ReachAttackData and RangedAttackData) from activating. I ended up changing the interaction handler chain matching algorithm to work with exact type matches, rather than IsAssignableFrom(). Had to also make sure I wasn’t orphaning any use cases.

Lastly (and I still have to fix this), I discovered that a target standing on a low step could trigger a Cover alteration, resulting in a +4 to Armor Rating for the target. This is because the cubic region’s lower corners are blocked by the solid material of the cell. I’m going to look into using adjusted coordinates for determining extents for a target (rather than blindly using the cube corners) based on the IPhysical properties and intra-locator positioning (including Offsets)…and I’m going to put some stuff in to account for low barriers (2′ high or less) by trying some alternate point testing under “certain” conditions.


Model View View-Model

Finally got (most) of the client-side features back together under a more MVVM-like pattern (still haven’t adopted the RelayCommand style yet…). Now, I can more easily get additional data into the Opportunistic Inquiry Prerequisite dialog, since I won’t have to climb through data contexts and control-bound properties to find the data from the framework. I can just bind it in…

I also inched the “bio” part of my Kickstarter project a little bit farther. Every day I see more and more games on Kickstarter, quite a few of which are sandbox and adventure games. There’s an upside and a downside to that, the downside is in launching my project too late (which is comical to me as I “launched” about 7 years ago with the code, or 30+ years ago with the concept), and getting lost in the sea of games. The upside is that the project funds sought looks like they are realistic to keep the developers eating (which is a requirement of mine as well), without having to work in a factory.


Model View Something…

I started the client UI (and proxy code) for the Ikosa Framework quite some time ago. Since the whole framework has been under development since early 2006 (six years) the client UI is probably no younger than about early 2007 (I could look it up in my Vol 1 or 2 of my notebooks if I had the inclination).

Anyway, WPF hit the scene with .NET 3 in late 2006, so I was working in unexplored territory (with my mental models at least, if not in accepted “best practices”). Correspondingly, much of the client-side framework was (and still is) fairly hodgepodge. I slowly came around to RoutedCommands (fantastic things), and DataTemplates (and DataTemplateSelectors!), and some data-binding.

Mainly what held me back from pervasive data-binding was that most of the instances I had to visualize were coming from the proxies as DataContracts. These were not implementing INotifyPropertyChanged, or INotifyCollectionChanged, and it wasn’t obvious (in my bone-headed way) how to make this “work” with a data-model controlled on the other end of the WPF channel. I may also have been reluctant to wrap data-contract classes (yet again) for WPF, since I already had to pack and unpack them in the host-side for processing in the Ikosa setting.

However, once I got around to the opportunistic attack prerequisite, I saw that to visualize the options well, I needed to provide useful information from elsewhere in my data “model”, which could be “found” scattered in a loose-confederation of DataContexts, POCO properties (set via constructor or assigned after an event fired) and some DependencyProperties mostly all parked on various controls of the UI, some templated, some not.

Then I decided to change all that…(or most of it)…over Easter Weekend, while also trying to assist two black belts testing for second degree next weekend, driving back and forth to Reading, PA twice (about 5 hours total), and having a rather pleasant Easter at my parents.

So far, I have a stable build. But am seeing that I’ll have to deal with some ObservableCollections that I (now) understand won’t work across threads. And I have some server-side debugging to do (I also altered the hosting model to allow a single user to control multiple actors, in theory). What I have started as a MVVM, but I started adding more “C” (as in Controller) type functions, since I was moving them off of the UI controls where they were before.

All in all, despite the fact I broke my system (client and host), I am satisfied that the foundation is becoming better.


Face? Book?

Finally became a part of the Facebook nation. Mainly to help with proving to people who may eventually pledge on Kickstarter that I am real.


Semi-Automatic Attacks

Reworked some of the GetTargets() code in the host when unpacking attack aim targets from the client. Given that a melee attack provides a target cell, I was able to automatically select a target if no explicit target ID was given. (I still have to work the code to “randomly” pick a target if two targets are in the same cell, but that’s a minor detail). This makes automatic melee attacks much easier to perform, as the client no longer has to select the target in order to make a melee attack.

I also got automatic ranged attacks up and working (but the client must select a target, since ranged attacks are not typically into the adjacent cell). I had to fix some things with the critical damage multiplier for projectiles/ammunition, but all should be good now.

Even though opportunistic attacks have been on my “tactical radar” for awhile now. They are now the next thing to tackle directly.