We are still tweaking & tuning the game, trying hard to release soon. We already submitted for IGF, but since they accept updates, we're hoping a new version improves our chances.
Some changes since our last update :
The player's gun always displays an aiming reticle, even when there is not a laser sight on the weapon
The AI will notice if the player has not taken damage for the last two shooting state cycles, and will try to move closer to the player.
The AI realizes when its accuracy is dropping low, and holds fire until the accuracy gets > 30% of their nominal accuracy with the weapon.
The AI will reload if it doesn't have LOS to the player for a while and has < 50% bullets in the clip.
If the reloading will taking a while, then the AI will switch from shooting to cover mode early.
The AI now uses its true muzzle positions to detect shootability to the player, and the player's real muzzle positions for his shootability, reducing times when the AI thought it had cover but was being shot, and where it thought it didn't have a shot, when it actually did.
A bunch of the AI fixes were enabled by the new 'Ephemeral' data structure. Previously, almost all new entity data was added via facets, which are a accessed via a string->variant map attached to each entity. Facets are automatically saved & loaded, and aren't part of the static footprint of the entity class, so don't break saved games or cause long compiles if added directly to Entity.h.
But increasingly, things that were accessed every frame were put in facets, and they didn't need to be tweaked via the facet system, so didn't need to be in there at all, so I made an struct called Ephemeral which holds temporary data that is not saved or loaded with a saved game.
The ephemeral struct is forward declared in entity.h, so only a small fraction of files have to be recompiled when it changes, and since it doesn't save or load, it doesn't break levels or saved games.
It has about 40 members now, most representing things moved from facet->ephemeral, but others just added partly because it's way easier to code directly on a struct rather than through the facet system.
Some examples of things in the ephemeral struct are animation blending coefficients, LOD values, current light occlusion values, whether the AI should reload, the player's tension value that controls the music changes, values for which walk sound to play, water sound fading, the current muzzle locations of each gun in an entity's hand, etc.
An arch change that would have allowed both styles of coding on the same data might be one where there were two structs in an entity, the persistent data and the ephemeral data. Data would be accessed either via the struct directly or via a string->struct offset lookup. The permanent struct would be saved, and the other one not, but it could be reloaded from facets to initialize it at loading time.
So, while I highly recommend a property/facet system, be careful over-using it, and pull common things back into code, which gave me quite a nice speedup.