Jump to content

Recommended Posts

After having my curiosity peaked and looking into it a bit, I have created a custom template the community can use to create encounters and run them. I have an idea for the use of this template that I think would be great for the community which I will discuss at the end but for now the technical side.

Most people are likely aware of the SpawnPrefabAtMouse command which people often use for testing. There is also the SpawnPrefabAtPoint command which is lesser used but still interesting. To keep it simple, all I have done is create a executable TXT which spawns enemies at preset locations on the Crucible ring (to zone into this map, enable the console, press F11 and type "Crucible" into the search bar, the bottom one is what I tested this on). I have attached 3 TXTs to this post, 1 is called "dummy.txt" which is the template. It spawns 9 dummies in a 3 X 3 grid on the Crucible. What I then did is simply go into the "dummy.txt" and change the creature IDs to whatever I want, close the game and rerun the txt. I attached 2 more TXTs to this post, one is "dragon.txt" the other is "random.txt". "dragon.txt" includes Jaderfelas the Ancient and some other enemies and "random.txt" is just a bunch of stuff I threw it to see if it worked. To modify the TXTs to your desire all you need is the creature IDs, which are harder to find than you might think sadly. This is an incredibly rudementary "mod" if you could call it that but still accomplishes something I have wanted for a while, a custom battle "mode" for deadfire. To run it, paste the TXTs into the following pathway F:\Steam\steamapps\common\Pillars of Eternity II\PillarsOfEternityII_Data\data\batchfiles and just type "exec XXXXXX.txt" into the console with the XXXXX as whatever the name of the txt file is.

There is much that can be experimented on with this including other maps, monster types and placements. The placements I used were just ones that worked but there are tons more, I am just not familiar enough with Unity Engine geometry to understand it beyond lots of boring copy paste testing.

In my testing there were some issues with certain monsters, for instance the Sea Dragon. The Sea Dragon battle is tied to it's lair and as such, spawning it outside of the lair breaks the fight a little bit. Also, some monsters will fight amongst themselves (this occured with the Memory Hoarder and Steelclad Constructs), which while amusing can impede the intended encounter design. 

My idea for this "mode" is for the community to come together and effectively create our own Seeker, Slayer, Survivor. I think it would be a great community event where we all come together and create custom encounters for each other to play through and the best can be voted upon to create a series of encounters we can play through as our very own arena gauntlet. That is just a concept to build off this "mode" which I hope people can enjoy/find use for. 

dragon.txt dummy.txt random.txt

Edited by patronkus
  • Like 7
Link to comment
Share on other sites

First installment of the Custom Encounters is Double Dragon! You'll face Jaderfelas and Neriscyrlas simultaneously (along with some associated minions for each). One is fire immune and the other is weak to fire... you'll need to balance your elemental attacks appropriately to bring both down while also contesting with Jaderfelas' summons and Neriscyrlas spells. Good luck!

DoubleDragon.txt

  • Gasp! 2
Link to comment
Share on other sites

Second installment is the third return of everyones favourite Lich Concelhault! After being slain once more a Bekarna's Observatory part of his essence was thrown to the White Void where he brokered a deal with the Beast of Winter itself, procuring another body and aid of some of the entropy gods chosen. Backed by the fearsome aurochs, and some additional ancient liches for good measure, he comes for the Watchers soul once more!

ConcelhaultReturned.txt

Link to comment
Share on other sites

This is right, creature's name is hard to find. For example, I tried the other time to spawn a frost rathun to steal his unique spell (Freezing Bolt, a PL7 minor version of Missile Salvo mixed up to Ninagauth's shadowflame) but the command LAX03_CRE_Rathun_Frostcaller dont work (from LAX03_CHA_CRE_Rathun_Frostcaller).

In other hand, I tried, again for steal the Animated Weapon PL1 spell form the Luminary Vithrack with this LAX03_CRE_Vithrack_Luminary (from LAX03_CHA_CRE_Vithrack_Luminary) and that worked.

I mean I was able to make the Luminary Vithrack spawn, not to steal the spell ! 

Link to comment
Share on other sites

18 minutes ago, Constentin Lévine said:

This is right, creature's name is hard to find. For example, I tried the other time to spawn a frost rathun to steal his unique spell (Freezing Bolt, a PL7 minor version of Missile Salvo mixed up to Ninagauth's shadowflame) but the command LAX03_CRE_Rathun_Frostcaller dont work (from LAX03_CHA_CRE_Rathun_Frostcaller).

In other hand, I tried, again for steal the Animated Weapon PL1 spell form the Luminary Vithrack with this LAX03_CRE_Vithrack_Luminary (from LAX03_CHA_CRE_Vithrack_Luminary) and that worked.

I mean I was able to make the Luminary Vithrack spawn, not to steal the spell ! 

Yes it is a total pain to find what can actually work through the console. For instance I had hoped to do a Circle of Archmagi fight where you'd face each member of the Circle which appears in the game (Concelhault, Maura, Tayn and Llengrath I believe) but I couldn't find Maura, Tayn or Llengrath IDs to spawn them sadly. 

  • Like 1
Link to comment
Share on other sites

2 hours ago, patronkus said:

but I couldn't find Maura, Tayn or Llengrath IDs to spawn them sadly. 

Hmm, 

Do you have a save when you meet them? or are in the same scene?

If yes, give "findobject "<name>" a try. 

-----

P.S. Also it could be a problem with name variation.

It's kinda weird that spawn ids sometimes differ from CharacterStatsGameData's id. E.g:

  • CHA_CRE_Skeleton_Steelspine_Berserker -> SpawnPrefabAtMouse CRE_Skeleton_Steelspine_Berserker
  • CHA_CRE_Skeletal_Fighter -> SpawnPrefabAtMouse CRE_Skeleton_Fighter

* the second creature ^ is "skeletal" but uses "skeleton" to be spawned..

Link to comment
Share on other sites

5 hours ago, MaxQuest said:

Hmm, 

Do you have a save when you meet them? or are in the same scene?

If yes, give "findobject "<name>" a try. 

-----

P.S. Also it could be a problem with name variation.

It's kinda weird that spawn ids sometimes differ from CharacterStatsGameData's id. E.g:

  • CHA_CRE_Skeleton_Steelspine_Berserker -> SpawnPrefabAtMouse CRE_Skeleton_Steelspine_Berserker
  • CHA_CRE_Skeletal_Fighter -> SpawnPrefabAtMouse CRE_Skeleton_Fighter

* the second creature ^ is "skeletal" but uses "skeleton" to be spawned..

Yes it's totally bizarre how the naming conventions of the game IDs correlate to the actual names of creatures. In any case, with some trial and error I was able to get some more monsters to work, maybe i'll keep a TXT log of all confirmed functional IDs to use for creating custom encounters.

Link to comment
Share on other sites

i'll bet it wouldn't be that hard to generate a mapping of "in game name" => "CRE_xxx" codes for every creature in the game, and then subdivide some maps into easy coordinates.

 

basically, what i'm thinking is: a website (i tend to think in websites since i work on internet stuff), where you select a map, and you get a scaled-down version of that map subdivided into a grid, and you can click spots on that grid and select a creature from a dropdown, and then click a button and generate these .txt files (since it looks like just a series of SpawnPrefabAtPoint)

Edited by thelee
Link to comment
Share on other sites

1 hour ago, thelee said:

did you have like a script for this, or did you have to do a lot of manual lookup and guess-and-check for coordinates?

 

there's some very intriguing possibilities here, especially if it can be hooked into SSS/S4 somehow

No script unfortunately so I resorted to manually checking and guessing. I used the 3 X 3 grid as a basic template but I could have gone further for placements and had them all over the ring, the issue with that for the template "dummy.txt" is it would be hard for someone new to the template to figure out what is going where so I kept it to a small, dense placement population. I did some more exploring for coordinates and could likely get a full grid of placements and in the TXT itself I could comment maybe where they would appear, possibly segmenting the ring into quadrants for ease of understanding for new users. 

In terms of further functionality I don't know how you would get an S4 style format running however you could setup a 5 or 10 battle gauntlet by just importing 5 or 10 txts into your folder and running them consecutively. I think it would be an extremely fun challenge for the community to collaborate on and some interesting encounters could be designed. For instance I had the themed "Double Dragon" and hopefully I will be able to get the Circle of the Archmagi encounter functioning by finding the spawn commands for Tayn, Arkemyr, Maura and Llengrath. I'd be curious to see what other users would come up with.

Link to comment
Share on other sites

1 hour ago, thelee said:

i'll bet it wouldn't be that hard to generate a mapping of "in game name" => "CRE_xxx" codes for every creature in the game, and then subdivide some maps into easy coordinates.

 

basically, what i'm thinking is: a website (i tend to think in websites since i work on internet stuff), where you select a map, and you get a scaled-down version of that map subdivided into a grid, and you can click spots on that grid and select a creature from a dropdown, and then click a button and generate these .txt files (since it looks like just a series of SpawnPrefabAtPoint)

This would be a more advanced version of what I am currently working on. What I considered is taking a screenshot of a fully populated ring and then editing the coordinates of the spawns over top so users can see where their monsters would be placed. The other thing I considered iterating onto this is a type of "randomiser". Basically by using a "Randbetween" function to randomise a number and that number correlates to a spawn ID at each coordinate you could generate random encounters each exec of the txt. You could assign this to every coordinate on the ring, randomising a number between say 0 and 6 where 0 is nothing and 1-6 are preset monsters (say tiger, panther, scourge, lich, menpwrga, rathun) but different at every coordinate.

  • Thanks 1
Link to comment
Share on other sites

4 hours ago, thelee said:

i'll bet it wouldn't be that hard to generate a mapping of "in game name" => "CRE_xxx" codes for every creature in the game, and then subdivide some maps into easy coordinates.

 

basically, what i'm thinking is: a website (i tend to think in websites since i work on internet stuff), where you select a map, and you get a scaled-down version of that map subdivided into a grid, and you can click spots on that grid and select a creature from a dropdown, and then click a button and generate these .txt files (since it looks like just a series of SpawnPrefabAtPoint)

I took the time to plot the following coordinates to determine where everything ends up on the ring. Basically you have a range of coordinates from (x=10-35, y=1, z=10-30) and will appear on the ring in the indicated positions. In general, increasing X value from 10 moves the position to the southwest and increasing Z value moves the position to the southeast. Hopefully the graphic makes it clear (I had to compress it majorly to make it fit into the upload size)

307459031_615852606955437_6061917653308927449_n (1).png

  • Like 2
Link to comment
Share on other sites

I ran a test in the hopes that it might be possible to get something like this to work straight from the pool of memories menu, unfortunately I think there is something hardcoded in the set up of each of the SSS encounters. While the arena maps (as seen in lax1_worldmap.gamedatabundle) share the same data structure as random encounter maps, I don't think they are set up for the "CreatureSpawns" parameter to work. I don't know for sure but at a guess random encounter maps likely have preset locations where enemies can be spawned, which the arena maps are lacking. Trying to use that parameter like any other random encounter just leads to an empty arena and an error message in the output_log.txt file along the lines of "failure to find default creature spawn on map". 

There is no way I can see to spawn prefabs using scripts as far as I can tell, which is a real shame.

Ah well, at the very least it's an alternate way into a blank arena from the pool of memories using a .gamedatabundle:

Spoiler
{
    "GameDataObjects": [
        {
            "$type": "Game.GameData.ArenaEncounterManager, Assembly-CSharp",
            "DebugName": "Arena Encounter Manager",
            "ID": "6307c321-5856-42ca-93c6-e60febffa51c",
            "Components": [
                {
                    "$type": "Game.GameData.ArenaEncounterManagerComponent, Assembly-CSharp",
                    "ArenaEncounterListIDs": [
                        "e773f433-734f-448a-9096-d2ee260528cd",
                        "1ee316f2-99f3-4be5-977c-4277a350edc4",
                        "cf80aae5-b307-48cb-9fd5-19183ba73997",
                        "d7a3b7f1-d100-48e6-bdf7-fa98568782bc",
                        "dcd11cba-6984-4c0e-b450-da954f5443e4",
                        "37ed44fc-b753-465a-b153-f0ab4b1213c3",
                        "41c492ea-8b73-4bd1-933e-d75e37211307",
                        "30dd3186-630f-41d3-ba62-0379371f45d8",
                        "d8aa8059-da51-4697-a12e-bedca2ee25e8",
                        "09a9d626-dca4-464f-a4f6-326433e944bb",
                        "d17189bc-2e90-42a7-a776-4813bb342899",
                        "da3640bf-0c12-408a-b27e-8a1141be19d7",
                        "0dd7d41e-0b65-4175-8f90-02802f3a3c11",
                        "21f92a31-67a7-4144-8013-cc69924d568d",
                        "b007c9c1-cada-48fd-ba72-c4a0859c92b8",
                        "1c9e459f-ac14-4899-b7d5-bf8160b30393",
                        "4209d735-6ca2-423b-8217-dad26985438a",
                        "4fb11769-c99a-440b-b373-8ea8bdef9bfc",
                        "1e43a185-577f-4b2b-b708-87d2328c5a68",
                        "1e850edf-c55d-429e-a6f1-455854e3e136",
                        "a0314a76-3308-477b-b0dd-8333bebc4b46",
                        "bcb3fd8b-e806-4acd-b019-94507a2e8b04",
                        "d5f38d4c-149f-4a68-b97b-799d72e4d11b",
                        "e57f4449-ef2b-46c6-9ca0-3d287ce03211",
                        "f828a55b-8998-4b90-a7a4-e8a088fb6e8a",
                        "6df03858-9e3f-480e-a3aa-0b503bb7bb7b",
                        "8455ed2d-cd96-46c0-82a2-1efade7a4755",
                        "af21331a-b754-4c5f-8046-1b46e243a8b1",
                        "a049d8ab-2768-4177-807b-af469a6896c4",
                        "18d0bb4b-80a9-495c-9979-364fb5a8fb6a",
                        "fe4f12f7-533e-497c-9bf5-4afa9c788ca0"
                    ]
                }
            ]
        },
        {
            "$type": "Game.GameData.WorldMapEncounterGameData, Assembly-CSharp",
            "DebugName": "lax01_arena_test",
            "ID": "fe4f12f7-533e-497c-9bf5-4afa9c788ca0",
            "Components": [
                {
                    "$type": "Game.GameData.WorldMapEncounterComponent, Assembly-CSharp",
                    "PopUpTitle": -1,
                    "PopUpText": -1,
                    "MapIconName": -1,
                    "ScriptedInteraction": {
                        "GuidString": "00000000-0000-0000-0000-000000000000"
                    },
                    "EncounterConversationStartID": -1,
                    "PreEncounterScripts": {
                        "Conditional": {
                            "Operator": 0,
                            "Components": []
                        },
                        "Scripts": []
                    },
                    "ValidityConditions": {
                        "Operator": 0,
                        "Components": []
                    },
                    "BiomeID": "5e19b90d-49e3-48cb-a216-ff5ba02f5bba",
                    "OverrideMapID": "00000000-0000-0000-0000-000000000000",
                    "CreatureSpawns": [],
                    "ShipSpawnID": "00000000-0000-0000-0000-000000000000",
                    "AudioEvent": "",
                    "OnceOnly": "false",
                    "EncounterLevel": 16,
                    "EncounterType": "Moderate",
                    "SailorTalesReward": 0,
                    "IsHostile": "false",
                    "IsCritPath": "false",
                    "ScriptedMusicForSI": "",
                    "CombatEndsWhenAllAreDead": "false"
                },
                {
                    "$type": "Game.GameData.ArenaEncounterComponent, Assembly-CSharp",
                    "DisplayName": 465,
                    "Description": 465,
                    "CategoryID": "8a2b082a-af38-4aaf-b229-a1966de209b8",
                    "WinScripts": {
                        "Conditional": {
                            "Operator": 0,
                            "Components": []
                        },
                        "Scripts": []
                    },
                    "RewardLootListID": "00000000-0000-0000-0000-000000000000"
                }
            ]
        }
    ]
}

 

 

Edited by Kvellen
Link to comment
Share on other sites

8 hours ago, Kvellen said:

I ran a test in the hopes that it might be possible to get something like this to work straight from the pool of memories menu, unfortunately I think there is something hardcoded in the set up of each of the SSS encounters. While the arena maps (as seen in lax1_worldmap.gamedatabundle) share the same data structure as random encounter maps, I don't think they are set up for the "CreatureSpawns" parameter to work. I don't know for sure but at a guess random encounter maps likely have preset locations where enemies can be spawned, which the arena maps are lacking. Trying to use that parameter like any other random encounter just leads to an empty arena and an error message in the output_log.txt file along the lines of "failure to find default creature spawn on map". 

There is no way I can see to spawn prefabs using scripts as far as I can tell, which is a real shame.

Ah well, at the very least it's an alternate way into a blank arena from the pool of memories using a .gamedatabundle:

  Hide contents
{
    "GameDataObjects": [
        {
            "$type": "Game.GameData.ArenaEncounterManager, Assembly-CSharp",
            "DebugName": "Arena Encounter Manager",
            "ID": "6307c321-5856-42ca-93c6-e60febffa51c",
            "Components": [
                {
                    "$type": "Game.GameData.ArenaEncounterManagerComponent, Assembly-CSharp",
                    "ArenaEncounterListIDs": [
                        "e773f433-734f-448a-9096-d2ee260528cd",
                        "1ee316f2-99f3-4be5-977c-4277a350edc4",
                        "cf80aae5-b307-48cb-9fd5-19183ba73997",
                        "d7a3b7f1-d100-48e6-bdf7-fa98568782bc",
                        "dcd11cba-6984-4c0e-b450-da954f5443e4",
                        "37ed44fc-b753-465a-b153-f0ab4b1213c3",
                        "41c492ea-8b73-4bd1-933e-d75e37211307",
                        "30dd3186-630f-41d3-ba62-0379371f45d8",
                        "d8aa8059-da51-4697-a12e-bedca2ee25e8",
                        "09a9d626-dca4-464f-a4f6-326433e944bb",
                        "d17189bc-2e90-42a7-a776-4813bb342899",
                        "da3640bf-0c12-408a-b27e-8a1141be19d7",
                        "0dd7d41e-0b65-4175-8f90-02802f3a3c11",
                        "21f92a31-67a7-4144-8013-cc69924d568d",
                        "b007c9c1-cada-48fd-ba72-c4a0859c92b8",
                        "1c9e459f-ac14-4899-b7d5-bf8160b30393",
                        "4209d735-6ca2-423b-8217-dad26985438a",
                        "4fb11769-c99a-440b-b373-8ea8bdef9bfc",
                        "1e43a185-577f-4b2b-b708-87d2328c5a68",
                        "1e850edf-c55d-429e-a6f1-455854e3e136",
                        "a0314a76-3308-477b-b0dd-8333bebc4b46",
                        "bcb3fd8b-e806-4acd-b019-94507a2e8b04",
                        "d5f38d4c-149f-4a68-b97b-799d72e4d11b",
                        "e57f4449-ef2b-46c6-9ca0-3d287ce03211",
                        "f828a55b-8998-4b90-a7a4-e8a088fb6e8a",
                        "6df03858-9e3f-480e-a3aa-0b503bb7bb7b",
                        "8455ed2d-cd96-46c0-82a2-1efade7a4755",
                        "af21331a-b754-4c5f-8046-1b46e243a8b1",
                        "a049d8ab-2768-4177-807b-af469a6896c4",
                        "18d0bb4b-80a9-495c-9979-364fb5a8fb6a",
                        "fe4f12f7-533e-497c-9bf5-4afa9c788ca0"
                    ]
                }
            ]
        },
        {
            "$type": "Game.GameData.WorldMapEncounterGameData, Assembly-CSharp",
            "DebugName": "lax01_arena_test",
            "ID": "fe4f12f7-533e-497c-9bf5-4afa9c788ca0",
            "Components": [
                {
                    "$type": "Game.GameData.WorldMapEncounterComponent, Assembly-CSharp",
                    "PopUpTitle": -1,
                    "PopUpText": -1,
                    "MapIconName": -1,
                    "ScriptedInteraction": {
                        "GuidString": "00000000-0000-0000-0000-000000000000"
                    },
                    "EncounterConversationStartID": -1,
                    "PreEncounterScripts": {
                        "Conditional": {
                            "Operator": 0,
                            "Components": []
                        },
                        "Scripts": []
                    },
                    "ValidityConditions": {
                        "Operator": 0,
                        "Components": []
                    },
                    "BiomeID": "5e19b90d-49e3-48cb-a216-ff5ba02f5bba",
                    "OverrideMapID": "00000000-0000-0000-0000-000000000000",
                    "CreatureSpawns": [],
                    "ShipSpawnID": "00000000-0000-0000-0000-000000000000",
                    "AudioEvent": "",
                    "OnceOnly": "false",
                    "EncounterLevel": 16,
                    "EncounterType": "Moderate",
                    "SailorTalesReward": 0,
                    "IsHostile": "false",
                    "IsCritPath": "false",
                    "ScriptedMusicForSI": "",
                    "CombatEndsWhenAllAreDead": "false"
                },
                {
                    "$type": "Game.GameData.ArenaEncounterComponent, Assembly-CSharp",
                    "DisplayName": 465,
                    "Description": 465,
                    "CategoryID": "8a2b082a-af38-4aaf-b229-a1966de209b8",
                    "WinScripts": {
                        "Conditional": {
                            "Operator": 0,
                            "Components": []
                        },
                        "Scripts": []
                    },
                    "RewardLootListID": "00000000-0000-0000-0000-000000000000"
                }
            ]
        }
    ]
}

 

 

Damn, that is a shame. It definitely would feel better if these could be accessed from the pool of memories, you could also possibly attach a reward structure after each battle so you could do a 1-20 proggression with it. You can achieve a similar effect through the console but it definitely is not as user friendly or intuitive.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...