Finally finished off and published the first (non-bloggish) page of a “series” of pages I’ll be adding to (eventually) that I’d collected thoughts on about optimization stuff in the Ikosa Framework.
Spell components (component pouch, devotional symbol and verbal).
Map redraw on invisibility state changes.
Creatures: bugbear, hobgoblin, orc, kobold, half-orc, gnoll, ogre, grimlock (light-sensitivity, weapon proficiencies, giant-type)
Classes: barbarian, rogue, ranger
Tacticals and class-features: evasion, improved evasion, rage, trap-sense, sneak-attack, uncanny-dodge, flanking, overrun, legal-position checks
Prerequisites now part of LocalViewer instead of a docked tool window, fixed some minor problems with responsiveness of controls,
Made single option, check and save prerequisites work with button arrays instead of combo-boxes.
Fixed poisonous natural weapon process flow and binding on spider’s bite attack.
I also spent some time working on trying to work out non-tactical settings and regional settings; but nothing that I can add into the core of the experience just yet.
After playing around with tactical movement (which I’ll hopefully be getting back to shortly), I spent a few weeks playing around with magic item creation. Rather than go through the litany of development, I’ll cut to the finale: the ring of invisibility; a somewhat classic trope of fantasy.
I’ve had basic support for invisibility built-in for quite some time as the creature awareness system needs to be able to determine what can and cannot be seen. What I hadn’t completed (or worked on) until the past week weeks was the invisibility spell, nor magic items (nor apparently any in-game actions to put on or take off body-slotted items).
So here we are now:
The command-word activation isn’t currently running through an environment interaction, I haven’t completely normalized how the sounds propagation works or which actions require verbalizing (apart from spells with verbal components). One of the many things on my to-do list.
One of the oddities of the invisibility spell is that it requires a will-save:
Well, if I saw myself before, I don’t see myself now…
Just to get an outside perspective, I’ll switch to another viewer, Spidey the spider…
Looking through spidey’s eyes and checking his awarenesses, the Wiz is definitely gone…
Removing the ring will deactivate the invisibility effect…
Well, I can obviously see myself again, now to check Spidey…
I have that loosing awareness doesn’t clear the targeting queue in the UI. That’s a minor problem since on the server you still won’t be able to target directly. Mostly needs some client UI work since the targeting system is all client-side.
Alright, first a little explanation: the title refers to a method in the BaseMonsterClass that handles changing the creature’s size down one step, such as going from Medium to Small or Small to Tiny. Now for some background: I have been working on targeting and activity building for a few weeks now. I’m pretty comfortable with how it’s shaped up (more on that later), but while using it I discovered a little problem with the melee-strike range for the animated objects that fall into the “tiny” category.
An animated object with 1 power-die is small, an animated object with a partial power-die is tiny. The system and workshop handle this by allowing the creature to have an option when editing the 1st power-die to pick a partial power-die instead of a full one. The BaseMonsterClass has the capacity to use standard or custom size ranges to control and modify the body when the size should change due to power-dice change in the editor. StepUpSize worked just fine, it uses the size range information to add additional values to physical creature ability scores and natural armor. The natural reach is, however a fixed value (not a change value).
So…when I wrote StepDownSize, I copied StepUpSize and pasted, using the previous size range and subtracting them out (I just had to change the additions to subtractions). However, the natural ranges were not something that could be size reversed, so I ended up assigning the old larger size reach to the smaller body. Tiny animated objects could reach 1 cube away. Simple enough fix once I realized it…
I have a targeting system and activity builder I’ve been working on to pick targets for actions. One target type that I’d been working on a lot over the last month was attack targeting. I’ve got it fairly well along, so I figured I’d go back and apply a similar design principle to awareness targeting.
Attack targeting requires making attack rolls and needs to know certain things about the type of attack such as whether the attack is with a hand held weapon in melee range versus a reach or ranged weapon, and the effective attack launch points. Awareness targeting requires a simple selection of creatures or objects of which one is aware. I already had a basic system that used all the things the actor is aware of in a drop-down list, but wanted it to work more like attack targeting in which if I pre-select items, they are the only things that show in the list.
Well I eventually got the two fairly similar, but hadn’t worked out all display characteristics for the selection list items. So I was testing and picked the first two items in the list for my two magic missile wand test. I hadn’t quite realized I had targeted myself until I didn’t see any missiles visibly flying to targets, but the tell-tale impact splash was centered on my camera.
Dutifully I rolled both missile damages, then watched as my display window went black…I had knocked myself unconscious and dying.
The last month hasn’t been idle time. I’ve been working towards TransientVisualizers (think animation sequences for certain splashy actions) being associated with certain server-side model activities and being transmitted to the client where they can rendered. I’ve added support for “literal” brush keys, in which the key name represents a solid color or a linear gradient (horizontal or vertical) so that I can encode fail-safe animation colors without having to have mapped brushes defined (in Ikosa packages) for the models.
I’ve also added a storage area in the map for holding transient visualizations for the current tick. When the map time changes the transient visualizations are cleared (hence: transient). This storage area is accessed by an operation contract in the visualization service contract. Well enough to have a place to store and retrieve visualizations, but I also added bits to the power definitions and (by extension) the spell definitions for supporting animation types based on targets and animation style. Turns out that not too many spells (in the 0th to 2nd level range) require flashy animations, as some of them are buffs, divinations, “invisible” effects, or create persistent (not transient) objects such as dancing lights.
I did add one new type of animation over my previous set: namely a flying orb that moves a sphere from point to point. I already had a flying “bolt” (ray bolt), but there are some low level orb-spells that are necessary. I bound animations to the spells that needed it, and fixed a few power and spell issues I noticed along the way.
Finally, the past week or so has been fixing some client-side items (and server-issues that led to them) related to icon imagery, which I never implemented in the client (despite being the reason for doing all my flat XAML icons), but now have.
My next bits of effort are in surfacing wand and spell action selection and targeting in the client (they are defined and should be “working” server-side) so that I can test and fix the animations that should be bound to them.
Hooray for ILSpy.
I inadvertently reverted an important file that was at the center of a series of changes I was making to fix a model resource bug. I had compiled and tested it, but when I was committing the files via the Ankh SVN integration I saw one file I only changed to troubleshoot. Naturally I wanted to revert the file (or not commit it), but made the “mistake” of attempting it in the commit box (before I had committed anything). I thought I did it all right, but apparently the checkbox and the revert context menu do weird things (and I didn’t double check in the confirmation dialog).
I didn’t discover my problem until the next day. The only good thing was that I still had the compiled assembly, so after trying to hand uncrank the code back to C# source, I found and downloaded ILSpy. Worked wonderfully, only had to polish a few things back up, and add some comments to make it look like the rest of my codebase style-wise.
I finished off the PanelCellSpace a few weeks ago, and got it pushed through to the service host, proxy client and client UI. One thing I noticed (since I was testing in a large outdoor space) was that the performance was absolutely crappy (client-side…the workshop rendering was mostly OK). I wanted to fix this right away; but knew it would take profiling, though spending $500 around tax time wasn’t a viable alternative. Thus I had to improvise.
Enter good old Debug.WriteLine() statements with timings. I soon narrowed down a major performance problem to calling the full map rendering method 3 times. Basically when anything changed I was redrawing the entire map, locators (game tokens) and overlay graphics (aiming cells and lines). By separating those functions and only calling them when needed, I reduced re-draw time from 4.5 seconds (after making a single 5 foot move) to 1.5 seconds. Pretty good, but I was certain it could go faster.
I toyed with several ideas including caching full frozen Geometry3D models (per thread), and having other mesh collapsing optimizations. I finally settled on an approach of rather than drawing each cell face into a cell Model3DGroup with copious amounts of (frozen) transforms, I’d build aggregate meshes for cell faces using the same material rather than separate models. I had to replace a parameter in my call chains (and retain the old group for those cells I didn’t want to “upgrade” to the new style just yet), and futz around with collecting cell Model3DGroups and the shared MeshGeometry3D, but the end result is about 0.3 seconds from action start on client, through to server processing and updating, back to notification, collection of new map display data (based on senses) and rendering.
Starting to fall into the “code before blog pattern” that I got into last time I tried to run a development blog on the Ikosa Framework. Basically I have been fixing some things that my son and myself noticed during some testing, and I’ve been adding support for manipulating a targetting cell around the view window.
I’m probablly going to find a good home inthe UI for spell casting (and complex action aiming) so I can introduce a sorcerer-classed character to a test map. I’ll probably also add a spontaneous divine caster so I can get a little more magic flavor into the mix.
I’ve put ClickOnce installers for the Ikosa Host and Ikosa Client over on the Guildsmanship (aka, the Ikosa Framework) site. Currently putting together documentation for these framework tools, while biding my time waiting for the glacial pace of the state of Pennsylvania to finalize Turn-Based Realities, LLC.
I’ll probably have to make some clearer organization of what is the Ikosa Framework, what is Guildsmanship, what is Guildsmanship: Battle-Scapes; and what Turn-Based Realities, LLC is.