





Hi all! Im back with a story about how we improved the undo functionality. To give a bit of background, the skirmish portion of our game is implemented so it can be simulated in advance of actually using an ability. Every time the hit tile changes, we make a copy of the relevant game state, and run the whole game logic through it, with some flags set to make the end result usable for other things. The output of that process is a list of actions that change the original state to essentially match the simulated one. The original reason why we did it this way was that we wanted to have a spell like revert time which would play the last sequence of actions in reverse. This obviously never went in because of lack of time and some additional tech issues, but the general infrastructure is still proving to be useful. Since we have a copy of the game state with all the changes an action would do, we can query differences between the original and the cloned state. This is how we implemented exact previews of how much health a unit would lose and whether it would die from the hit, where a unit would get pushed or pulled to, which covers would get destroyed, etc. The only way this can work consistently is if all relevant objects are referenced with an equivalent ID. Since the codebase is in C++, the option of pointers is there, but is not useful because theres no easy way to translate/map pointers to between two copies of an object that are considered equivalent or the same. Thus, we use handles. Pretty much every important thing is mostly referenced to with its handle, which is in practical terms just an index into an array. Each thing would be an element in an array, and if we ever needed to destroy the thing, we would just mark the slot as no longer in use. This means we could reuse slots when, say, status effects expired and a new one got created, it would just be placed into the same slot as an expired one. This was the main issue with the system to prevent full undo functionality. Undoing a sequence of actions where one status effect expired and another one got created in the previous ones slot means information loss. There is no easy way to restore the information about the previous status effect in that slot because the new one overwrote that information. This is why creating and destroying things in those arrays wasnt able to be undone. The change we did was to no longer reuse slots. Each thing that gets created has its own slot which is forever owned by that thing and nothing else. When a status effect expires, its slot is marked as retired, but the information it had is still there, untouched. If we wanted to revert/undo the expiration of that effect, wed just undo the retire operation on that slot and thats it, the thing is back just as it was before. Ofcourse, each action has a set of micro operations that need to happen to fully restore the state back to where it was. A status effect tracks the units its affecting, the units which are considered the affector of that effect, both types of units also track which status effect is affecting them and which effects they caused, the creation and removal of status effects can cause unit attributes to change, etc. Each change to any of these things is a micro operation that has to be fully revertable for the system to work properly. To prevent everything to actually be undoable, abilities will define whether their use can be undone or not. All position changing abilities are currently undoable (Run, Sprint and upgrades, Translocation, and a relic or two). And the whole point of this was to fix Tariq from being unable to undo his Run ability use, because his passive effect is implemented as an aura that has a feedback loop with the status effects created on enemies to increase Tariqs power. And there you have it. A sneak peek of how we do stuff with code! If you want to ask questions or comment on something you read, you can find us on our Discord server. Cheers! MarkoP
[ 2021-11-24 12:01:37 CET ] [ Original post ]
- GameBin_Linux [91.57 M]
- Common_Linux [23.65 M]
The Hand of Merlin is a turn-based rogue-lite RPG in which Arthurian legend clashes with cosmic horror. Recruit a company of up to three mortal heroes and guide them in spirit on a desperate journey from Albion to Jerusalem. Explore a richly-imagined medieval setting on the brink of apocalypse. Trade with merchants, improve your heroes and unearth ancient relics. Search for the lost fragments of your soul, scattered across the multiverse - and save as many worlds as you can.
Enjoy a compelling story inspired by Arthurian legend, the Matter of France, and the history of Al-Andalus - with an unusual twist. Make choices in interactive encounters that change every time you play. Written by Jonas Kyratzes (The Talos Principle, Serious Sam 4) and Verena Kyratzes (The Lands of Dream, Serious Sam 4).
Master the tactics of squad-based and turn-based combat to conquer both human and demonic foes. Your enemies will be tough and ruthless; make use of cover, set up ambushes and coordinated attacks, harness synergies between different Hero classes and skills.
Carve a path across the lands of Albion, Marca Hispanica and Al-Andalus. Will you take a dangerous route, risking life and limb in pursuit of a legendary relic? Or will you choose a safer path? Plan and prepare. Negotiate, barter, fight. Tackle challenges. Suffer losses. Recruit new Heroes. Earn Gold, Supplies and Renown. Be careful: your choices are permanent, as is death. But don't tarry - evil never rests.
Use Renown to level up your Heroes, and choose between a randomized set of new skills or improved attributes. But choose wisely! Select skills with great synergy and balance your party for the road ahead.
As you jump from one parallel dimension to the next, history is reshaped. Different kings rule the land, changing the encounters, characters, and events. No two worlds are ever quite the same, and each journey will be unique. And should your heroes fall, remember: defeat is not the end, only a new beginning.
Seek out towns to improve your arms and armor, or stumble upon hermit artisans in the wild. With every day that passes, the world plunges deeper into darkness, and you will need all the equipment gold can buy.
From a peasant's humble luck charm to the legendary sword wielded by Arthur himself, items imbued with magical power are scattered about the world. Some you will be able to purchase from merchants and collectors, but others will have to be earned through acts of heroism - or displays of wit.
Rain thunder and brimstone upon your foes! Seek out and gather Soulstones to restore your power and unlock new Spells. Even if defeated, your spirit will retain all of your collected arcane knowledge as you jump into the next dimension.
There are as many worlds as there are stars in the sky. In each stands Camelot; in each there is a Grail. But there is only one Merlin, and his eternal burden is to stand against the horror from beyond. Each world that is saved is saved forever; each world that is lost is lost for good.
https://store.steampowered.com/app/600610/The_Hand_of_Merlin/
- OS: Linux SteamOS 3.0 or Ubuntu 18.04 LTS
- OS: Linux SteamOS 3.0 or Ubuntu 18.04 LTS
[ 6013 ]
[ 3582 ]
[ 3975 ]