- Joined
- Feb 5, 2008
- Messages
- 228
Hey, everyone! I wasn't quite sure where to post this, but courtesy of some awesome mods, this thread is now where it belongs! Anyway, I just wanted to share some of what I've learned about game caches in my time with Chasing the Dawn and the ANA system, both of which are highly dependent on using game caches creatively. I will note that some of what I discuss here is different from what I use in my campaign, as I've tried to adapt my system to work with a traditional campaign setup where you can replay missions at any time (which you cannot do in mine). All of what I'm doing can be accomplished with GUI alone.
Please note that I recommend not changing your campaign's name once you've built a dynamic game cache. More likely than not it will make no difference, but I'm superstitious about it. I will test whether the game caches persist between campaigns of different names once I'm finished with this and update it accordingly.
1) Building a Basic Dynamic Game Cache
I'm assuming that, if you're here, you know what a game cache is and why it's useful to a campaign. If not, there is an actual tutorial on this by Bob27 (Game Caches) which can give you a rundown of the basics of building a traditional mission-by-mission game cache. My system is intended to complement the traditional game cache system. There is an alternate build for dynamic game caches that replaces traditional game caching entirely, but right now there is a potential exploit that, in my opinion, renders it less viable. I will explain complementary systems here, as I believe they will make more sense with a traditional campaign setup.
First, either way we're doing it, we need a main game cache file. I typically recommend building a trigger just for game caching and have your victory trigger call it rather than building it directly in. It makes it easier to update later, which trust me, if you are anything like me, you will be doing.
*There is no actual need to restore any of the data from the main game cache in any map but Mission 1 at the moment.
So far all we've done is do a basic campaign game cache, but we've begun setting up for the dynamic cache. Now we're going to get into some functions of the dynamic cache.
2) Game Restoration
The first use of the dynamic game cache is restoring games. If you're like me, it has always bothered you that, if you download an updated version of the campaign you're playing, you have to start all over (that, or cheat). However, the dynamic game cache presents a simple, elegant solution to this problem. All we have to do is go into the first map that is available to the player and set up a quick trigger or two.
First, although the mission has nothing cached of its own yet, we need to restore the main game cache and all of the values related to mission completion. So if we have a four-mission campaign...
Now, we have a choice here. We can a) load the last played map in the campaign, b) load the farthest the player has gotten in the campaign, or c) let the player choose. I'm going to walk through the setup for the third option, as I like giving the player more control if possible, but it should be fairly simple to extrapolate from option (c) how to do the other two. Let's start by building a dialog. I will have it built in one of two ways, depending on whether the player's last played mission matches their farthest point in the campaign. You will need an "and" condition check for each mission in the game but one, as so.
The first button is built using Concatenate Strings, converting the variable LastCompletedMission into a mission number, while the second button is built using Concatenated Strings and a string variable called ButtonBuilder. You can of course create whatever buttons you want. Now we build a response trigger to a button press, again using If/Then/Else functions to dictate responses. Clicking buttons 1 and 2 will restore those respective points in the campaign, while clicking button 3 will effectively wipe the main game cache and force a full restart.
3) Choices, Choices
One of my favorite features in my campaign is the ability to change your army composition. This is a feature that allows the player to make decisions that carry over from mission to mission but can be changed at any time. While I will not be giving a full tutorial in how to recreate the ANA system here, I will, however, do a brief overview of how to create a system that allows you to catalog decisions made by the player and carry them over in a way that is easily changeable from map to map.
For our example, I have decided that, in the Adventures of Buddy the Paladin, you can pick whether you can build Footmen or High Elven Swordsmen from the Barracks, which is decided in some manner in some place that is not a dialog that pops up at the beginning of each mission (because then you would have no need of this system!) So first, in whatever map this decision is made, we need to find a way catalog our decision, so we're going to create an integer called FootmanChoice. Then, in our choosing trigger, we add...
Obviously this part of the system can be used for far more than just unit selection. It can be used to effectively catalog any recurring choice and replicate it across multiple maps. I use it for unit selection, talent selection, and game difficulty in Part I of my campaign.
Of course, you could also use this to catalog mission-specific stuff in the Mission Game Cache, like if you wanted to make a sort of Brood War-style choice where you could destroy one type of tech for the enemy or another and it would restrict their tech in the specified way in the next mission.
4) Conclusion
Well, that's it. That's the basics of complementary dynamic game caching. If you wanted to fully dispose of Mission Game Caches you could use just a Main Game Cache (as I do in my campaign), but it would effectively prevent missions from being replayed unless you build a system of detecting whether the mission is being replayed rather than being played for the first time, which could be done using the MissionXComplete boolean sets we generated for Section 2. However, I will leave that development to you.
I will likely be updating this thread as I think of other uses for dynamic game caching. I'm sure I've already used it in more ways than I have listed and I have simply forgotten because I have a pounding headache right now and can barely focus. This is pretty simple stuff, so I'm honestly not sure if this will help anyone or not, but it felt useful to me to put my knowledge somewhere where people could find it. If nothing else, I would love to see more campaigns use this to make campaigns that can restore previous progress.
Please feel free to comment, ask questions, point out issues, et cetera, et cetera. I will do my best to watch this thread and respond to comments.
Also, make sure you actually fire the game cache trigger in the victory trigger (or alternatively directly integrate it, which I don't recommend).
Please note that I recommend not changing your campaign's name once you've built a dynamic game cache. More likely than not it will make no difference, but I'm superstitious about it. I will test whether the game caches persist between campaigns of different names once I'm finished with this and update it accordingly.
1) Building a Basic Dynamic Game Cache
I'm assuming that, if you're here, you know what a game cache is and why it's useful to a campaign. If not, there is an actual tutorial on this by Bob27 (Game Caches) which can give you a rundown of the basics of building a traditional mission-by-mission game cache. My system is intended to complement the traditional game cache system. There is an alternate build for dynamic game caches that replaces traditional game caching entirely, but right now there is a potential exploit that, in my opinion, renders it less viable. I will explain complementary systems here, as I believe they will make more sense with a traditional campaign setup.
First, either way we're doing it, we need a main game cache file. I typically recommend building a trigger just for game caching and have your victory trigger call it rather than building it directly in. It makes it easier to update later, which trust me, if you are anything like me, you will be doing.
-
Events
- (No need to put anything here - will be called by another trigger)
- Conditions
-
Actions
- Game Cache - Create a game cache from AdventuresOfBuddyThePaladin.w3v
- Set MainGameCache = (Last created game cache)
-
Actions
- Game Cache - Create a game cache from AdventuresOfBuddyThePaladin.w3v
- Set MainGameCache = (Last created game cache)
- Game Cache - Create a game cache from AoBtPMission1.w3v
- Set MissionGameCache = (Last created game cache)
-
Actions
- Game Cache - Store BuddyThePaladin as BuddyThePaladin of Heroes in MissionGameCache
- Game Cache - Store (Other Stuff) as (Other Stuff) of (Reasonably Named Category) in MissionGameCache
- Set LastCompletedMission = 1
- Set Mission1Complete = True
- Game Cache - Store LastCompletedMission as LastCompletedMission of General in MainGameCache
- Game Cache - Store Mission1Complete as Mission1Complete of General in MainGameCache
- Game Cache - Save MissionGameCache
- Game Cache - Save MainGameCache
*There is no actual need to restore any of the data from the main game cache in any map but Mission 1 at the moment.
So far all we've done is do a basic campaign game cache, but we've begun setting up for the dynamic cache. Now we're going to get into some functions of the dynamic cache.
2) Game Restoration
The first use of the dynamic game cache is restoring games. If you're like me, it has always bothered you that, if you download an updated version of the campaign you're playing, you have to start all over (that, or cheat). However, the dynamic game cache presents a simple, elegant solution to this problem. All we have to do is go into the first map that is available to the player and set up a quick trigger or two.
First, although the mission has nothing cached of its own yet, we need to restore the main game cache and all of the values related to mission completion. So if we have a four-mission campaign...
-
Events
- Map Initialization
- Conditions
-
Actions
- Game Cache - Create a game cache from AdventuresOfBuddyThePaladin.w3v
- Set MainGameCache = (Last created game cache)
- Set Mission1Complete = (Load Mission1Complete of General from MainGameCache)
- Set Mission2Complete = (Load Mission2Complete of General from MainGameCache)
- Set Mission3Complete = (Load Mission3Complete of General from MainGameCache)
- Set Mission4Complete = (Load Mission4Complete of General from MainGameCache)
- Set LastCompletedMission = (Load LastCompletedMission of General from MainGameCache)
-
Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- LastCompletedMission Greater than 0
-
Then - Actions
- Trigger - Run RestoreSetup <gen> (ignoring conditions)
-
Else - Actions
- Trigger - Run (whatever trigger you put main map functions in) (ignoring conditions)
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Now, we have a choice here. We can a) load the last played map in the campaign, b) load the farthest the player has gotten in the campaign, or c) let the player choose. I'm going to walk through the setup for the third option, as I like giving the player more control if possible, but it should be fairly simple to extrapolate from option (c) how to do the other two. Let's start by building a dialog. I will have it built in one of two ways, depending on whether the player's last played mission matches their farthest point in the campaign. You will need an "and" condition check for each mission in the game but one, as so.
- Events
- Conditions
-
Actions
- Dialog - Change the title of RestoreDialog to Do you wish to restore your previous progress?
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
Or - Any (Conditions) are true
-
Conditions
- (Mission2Complete Equal to True) and (LastCompletedMission Equal to 1)
- (Mission3Complete Equal to True) and (LastCompletedMission Equal to 2)
- (Mission4Complete Equal to True) and (LastCompletedMission Equal to 3)
-
Conditions
-
Or - Any (Conditions) are true
-
Then - Actions
- Dialog - Create a dialog button for RestoreDialog labelled (Restore Last Played (Mission + (String(LastCompletedMission)) + )))
- Set RestoreDialogButton[1] = (Last created dialog Button)
- If (Mission1Complete Equal to True) then do (Set ButtonBuilder = 1) else do (Do nothing)
- If (Mission2Complete Equal to True) then do (Set ButtonBuilder = 2) else do (Do nothing)
- If (Mission3Complete Equal to True) then do (Set ButtonBuilder = 3) else do (Do nothing)
- If (Mission4Complete Equal to True) then do (Set ButtonBuilder = 4) else do (Do nothing)
- Dialog - Create a dialog button for RestoreDialog labelled (Restore Farthest Point (Mission + (ButtonBuilder + )))
- Set RestoreDialogButton[2] = (Last created dialog Button)
- Dialog - Create a dialog button for RestoreDialog labelled Start New Campaign
- Set RestoreDialogButton[3] = (Last created dialog Button)
-
Else - Actions
- Dialog - Create a dialog button for RestoreDialog labelled (Restore Last Played (Mission + (String(LastCompletedMission)) + )))
- Set RestoreDialogButton[1] = (Last created dialog Button)
- Dialog - Create a dialog button for RestoreDialog labelled Start New Campaign
- Set RestoreDialogButton[3] = (Last created dialog Button)
-
If - Conditions
- Dialog - Show RestoreDialog for Player 1 (Red)
The first button is built using Concatenate Strings, converting the variable LastCompletedMission into a mission number, while the second button is built using Concatenated Strings and a string variable called ButtonBuilder. You can of course create whatever buttons you want. Now we build a response trigger to a button press, again using If/Then/Else functions to dictate responses. Clicking buttons 1 and 2 will restore those respective points in the campaign, while clicking button 3 will effectively wipe the main game cache and force a full restart.
-
Events
- Dialog - A dialog button is clicked for RestoreDialog
- Conditions
-
Actions
- Dialog - Hide RestoreDialog for Player 1 (Red)
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Clicked dialog button) Equal to RestoreDialogButton[1]
-
Then - Actions
- If (LastCompletedMission Greater than or Equal to 1) then do (Show custom campaign button (Mission 2)) else do (Do nothing)
- If (LastCompletedMission Greater than or Equal to 2) then do (Show custom campaign button (Mission 3)) else do (Do nothing)
- If (LastCompletedMission Greater than or Equal to 3) then do (Show custom campaign button (Mission 4)) else do (Do nothing)
- Game - Victory Player 1 (Red) (Skip dialogs, Skip scores)
-
Else - Actions
- Do nothing
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Clicked dialog button) Equal to RestoreDialogButton[2]
-
Then - Actions
- If (Mission1Complete Equal to True) then do (Show custom campaign button (Mission 2)) else do (Do nothing)
- If (Mission2Complete Equal to True) then do (Show custom campaign button (Mission 3)) else do (Do nothing)
- If (Mission3Complete Equal to True) then do (Show custom campaign button (Mission 4)) else do (Do nothing)
- Game - Victory Player 1 (Red) (Skip dialogs, Skip scores)
-
Else - Actions
- Do nothing
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- (Clicked dialog button) Equal to RestoreDialogButton[3]
-
Then - Actions
- Set Mission1Complete = False
- Set Mission2Complete = False
- Set Mission3Complete = False
- Set Mission4Complete = False
- Set LastCompletedMission = 0
- Game Cache - Save Mission1Complete as Mission1Complete of General in MainGameCache
- Game Cache - Save Mission2Complete as Mission2Complete of General in MainGameCache
- Game Cache - Save Mission3Complete as Mission3Complete of General in MainGameCache
- Game Cache - Save Mission4Complete as Mission4Complete of General in MainGameCache
- Game Cache - Save LastCompletedMission as LastCompletedMission of General in MainGameCache
- Game Cache - Save MainGameCache
- Trigger - Run (whatever trigger you put main map functions in) (ignoring conditions)
-
Else - Actions
- Do nothing
-
If - Conditions
3) Choices, Choices
One of my favorite features in my campaign is the ability to change your army composition. This is a feature that allows the player to make decisions that carry over from mission to mission but can be changed at any time. While I will not be giving a full tutorial in how to recreate the ANA system here, I will, however, do a brief overview of how to create a system that allows you to catalog decisions made by the player and carry them over in a way that is easily changeable from map to map.
For our example, I have decided that, in the Adventures of Buddy the Paladin, you can pick whether you can build Footmen or High Elven Swordsmen from the Barracks, which is decided in some manner in some place that is not a dialog that pops up at the beginning of each mission (because then you would have no need of this system!) So first, in whatever map this decision is made, we need to find a way catalog our decision, so we're going to create an integer called FootmanChoice. Then, in our choosing trigger, we add...
-
Actions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
- You picked Footman
-
Then - Actions
- Blah blah blah in-game actions
- Set FootmanChoice = 1
-
Else- Actions
- Blah blah blah other in-game actions
- Set FootmanChoice = 2
-
If - Conditions
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
Actions
- Game Cache - Store FootmanChoice as FootmanChoice of Units in MainGameCache
-
Events
- Map Initialization
- Conditions
-
Actions
- Game Cache - Create a game cache from AdventuresOfBuddyThePaladin.w3v
- Set MainGameCache = (Last created game cache)
- If (FootmanChoice Equal to 1) then do (Make Footman Available for training/construction by Player 1 (Red)) else do (Make Swordsman Available for training/construction by Player 1 (Red))
Obviously this part of the system can be used for far more than just unit selection. It can be used to effectively catalog any recurring choice and replicate it across multiple maps. I use it for unit selection, talent selection, and game difficulty in Part I of my campaign.
Of course, you could also use this to catalog mission-specific stuff in the Mission Game Cache, like if you wanted to make a sort of Brood War-style choice where you could destroy one type of tech for the enemy or another and it would restrict their tech in the specified way in the next mission.
4) Conclusion
Well, that's it. That's the basics of complementary dynamic game caching. If you wanted to fully dispose of Mission Game Caches you could use just a Main Game Cache (as I do in my campaign), but it would effectively prevent missions from being replayed unless you build a system of detecting whether the mission is being replayed rather than being played for the first time, which could be done using the MissionXComplete boolean sets we generated for Section 2. However, I will leave that development to you.
I will likely be updating this thread as I think of other uses for dynamic game caching. I'm sure I've already used it in more ways than I have listed and I have simply forgotten because I have a pounding headache right now and can barely focus. This is pretty simple stuff, so I'm honestly not sure if this will help anyone or not, but it felt useful to me to put my knowledge somewhere where people could find it. If nothing else, I would love to see more campaigns use this to make campaigns that can restore previous progress.
Please feel free to comment, ask questions, point out issues, et cetera, et cetera. I will do my best to watch this thread and respond to comments.
Also, make sure you actually fire the game cache trigger in the victory trigger (or alternatively directly integrate it, which I don't recommend).
Last edited: