Precache, Fixing and avoiding issues

edited February 2015 in Tutorials

When spawning units through KV and Lua, you might have to deal with the precache-dilemma. This also applies to particles and sounds. I talked about it briefly in the precache section of the datadriven breakdown but here I have an straightforward example to help understand the matter.

So, if you see an unselectable orange ERROR as the model of a unit, then you have a precache model issue:

http://puu.sh/fBzOp/5c7afff665.jpg

Missing particles are indicated by red crosses:

How to fix and avoid this crap?

First, the datadriven "SpawnUnit" Action will always precache the "UnitName" custom unit and whatever cosmetics you have attached to it. For example in this Avatar of Vengeance ability, I'll be spawning a Spectre with some hats:

"SpawnUnit"
{
    "UnitName"  "npc_avatar_of_vengeance"
    "UnitCount" "1"
    "SpawnRadius"   "100"
    "Duration"  "%duration"
    "Target"        "CASTER"
    "OnSpawn"
    {
    "FireSound"
    {
        "EffectName" "Hero_Spectre.Haunt"
        "Target"     "CASTER"
    }
    }
}

Now there will be many many times that SpawnUnit doesn't cut it, and you need to spawn units in lua, using the CreateUnitByName function.

If I went ahead and just spawned my unit in lua (simplified example of this script):

function SpiritOfVengeanceSpawn( event )
    local caster = event.caster
    local unit_name = "npc_spirit_of_vengeance"
    local origin = caster:GetAbsOrigin()
    local spirit = CreateUnitByName(unit_name, origin, true, caster, caster, caster:GetTeamNumber())
end

Without any previous precache I'll get something like the ERROR model like before, or if this isn't the first I run the tools (because after the 1st run it attempts to store some models to keep on the cache), something like this:

http://puu.sh/fBwmn/0659d05a11.jpg

So yeah, that's bad, here's how to fix it:

Always add a datadriven precache block with all models, sounds and particles that your ability would use

In this case, I precache all the models and the ambient particles I'm using, inside the main datadriven ability.

"precache"
{
    "soundfile" "soundevents/game_sounds_heroes/game_sounds_spectre.vsndevts"
    "model"     "models/heroes/vengeful/vengeful.vmdl"
    "model"     "models/items/vengeful/vengeful_immortal_weapon/vengeful_immortal_weapon.vmdl"
    "model"     "models/items/vengefulspirit/fallenprincess_shoulders/fallenprincess_shoulders.vmdl"
    "model"     "models/items/vengefulspirit/fallenprincess_legs/fallenprincess_legs.vmdl"
    "model"     "models/items/vengefulspirit/fallenprincess_head/fallenprincess_head.vmdl"
    "particle"      "particles/units/heroes/hero_vengeful/vengeful_ambient.vpcf"
    "particle"      "particles/econ/items/vengeful/vengeful_wing_fallenprincess/venge_wingsoffallenprincess_ambient.vpcf"
}

Now all the models will load properly.

http://puu.sh/fBx1X/8f04e3cd86.jpg

Final note, some cosmetics you might want to use have their own particles and its hard to know their names. In the first gif (the one with the red crosses) I was missing the wing particle effect for fallenprincess_shoulders. If this is the case, you can also find the particles used by the cosmetic in its item_game.txt definition:

http://puu.sh/fBxWT/83cceac063.png


Now after adding that particle (which I just looked up on the Asset Browser and copied the path to the .vpcf), everything is displaying properly:


The concept of Modding Community doesn't go well together with Competitive Business
My Project Page || My GitHub Profile ||

Comments

  • edited February 2015 Posts: 1,670

    There's many other quirks with precache, which I frequently explain to anyone having problems with it on IRC, but I want to write it all down here as I get with good examples and simple fixes.

    Leave any problem related to the topic in here and I'll edit the post to expand it after we resolve it :smile:

    The concept of Modding Community doesn't go well together with Competitive Business
    My Project Page || My GitHub Profile ||

  • edited November 2015 Posts: 1,670

    Important note or "why is my datadriven precache block not working?

    When you add a datadriven precache block, it's not always going to be read by the game. The way it is at the moment, it's just there to act as a list of resources that will be preloaded only if you tell the game to do it

    This "telling the game to run the precache block" is done in various ways:

    1. Picking a hero will read all the precache lines associated with it, mostly the needed models and every particle and sound defined in its abilities
    2. Dragging a datadriven unit to the Hammer map should also read the hero/abilities precache block when the addon is loading
    3. Lua Precache(context) lets us load specific resources with PrecacheResource or ByName for Items and Units.


    If you need to load any item/ability resources (remember items are technically just abilities that take an inventory slot) just PrecacheItemByNameSync("item_name", context) or PrecacheUnitByNameSync("unit_name", context) of the unit which contains all the abilities you want to precache, in addon_game_mode.lua

    If you have an ability which is taught on the hero through Lua or abilities on non-hero units that are spawned through various ways, you will need to do Lua precache, or at least, copy all the associated lines of the precache blocks to some ability on the hero (which I don't recommend because it can get quite messy)

    Doing a PrecacheUnitByNameSync will load 1. The unit's model 2. Attached wearables 3. Particle effect attack 4. Each abilities precache {} block

    Nothing else, nothing more. Just keep in mind, if it's Sync, it does it for every player, and game wont start until its loaded. Going too ham with Syncs can make your game take 1~2 or even 3 minutes, at the point nobody loads

    The concept of Modding Community doesn't go well together with Competitive Business
    My Project Page || My GitHub Profile ||

  • edited April 2015 Posts: 45

    we could easily use these code for quick precache in lua.

    function PrecacheEveryThingFromKV( context )
        local kv_files = {  "scripts/npc/npc_units_custom.txt",
                                "scripts/npc/npc_abilities_custom.txt",
                                "scripts/npc/npc_heroes_custom.txt",
                                "scripts/npc/npc_abilities_override.txt",
                                "npc_items_custom.txt"
                              }
        for _, kv in pairs(kv_files) do
            local kvs = LoadKeyValues(kv)
            if kvs then
                print("BEGIN TO PRECACHE RESOURCE FROM: ", kv)
                PrecacheEverythingFromTable( context, kvs)
            end
        end
    end
    
    function PrecacheEverythingFromTable( context, kvtable)
        for key, value in pairs(kvtable) do
            if type(value) == "table" then
                PrecacheEverythingFromTable( context, value )
            else
                if string.find(value, "vpcf") then
                    PrecacheResource( "particle",  value, context)
                    print("PRECACHE PARTICLE RESOURCE", value)
                end
                if string.find(value, "vmdl") then  
                    PrecacheResource( "model",  value, context)
                    print("PRECACHE MODEL RESOURCE", value)
                end
                if string.find(value, "vsndevts") then
                    PrecacheResource( "soundfile",  value, context)
                    print("PRECACHE SOUND RESOURCE", value)
                end
            end
        end
    end
    

    and call this in precache function PrecacheEveryThingFromKV( context )

    but this does not work to attachwearables

    (**Edit by Noya - added ~~~ for syntax*)

  • edited April 2015 Posts: 96

    Using precache everything will cause massive loading time which can cause dropout during loading screen.

  • edited April 2015 Posts: 1,670

    I agree with kritth, precache everything is totally not recommended, using that code is anything but quick.

    The concept of Modding Community doesn't go well together with Competitive Business
    My Project Page || My GitHub Profile ||

  • Posts: 45

    ok... is that the only problem? will precache everything make the game laggy during the game progress?

  • edited April 2015 Posts: 1,670

    Only before loading, as every client will have to load a lot of stuff before connecting. Once it's loaded I don't think it should have an impact in-game.

    The concept of Modding Community doesn't go well together with Competitive Business
    My Project Page || My GitHub Profile ||