nkzw-tech / athena-crisis

Athena Crisis is an Advance Wars inspired modern-retro turn-based tactical strategy game. Athena Crisis is open core technology.
https://athenacrisis.com/open-source
Other
1.37k stars 105 forks source link

feat: add undo-stack on a per map basis #22

Open tjamesmac opened 1 month ago

tjamesmac commented 1 month ago

Description

Hoping to resolve #3 Adds the ability to:

Todo

Would appreciate any feedback and whether this has hit the mark! :)

cpojer commented 1 month ago

Here are the replies to your questions from the issue:

The MapObject.id is returning undefined and never returns an actual id. Is this expected? If it is, do you have any suggestions for generating a decent fallback?

If you rebase, now it will be an empty string when you "save" it.

Instead of restoring the previous map with the Restore button, i'm restoring if a previousState is present. When clicking New map I then delete the related localstorage items so a refresh doesn't continually bring back the last map. Does this sound like the right path for the U? Happy to change if I misinterpreted the requirement.

I think that makes the most sense, yes. If you don't hit restore before clicking "new map", we should wipe the undo state.

Also not sure if i'm missing something obvious but the confirmation dialogs for the new/reset map don't seem to work. I've just started calling new map directly

Yes that's fine. The docs page doesn't have those confirmation dialogs but they are in the game.

Lastly, are there tests for the map editor?

There are no tests 🪦 If you write a function (not React) that you want to test, feel free to add a test. Otherwise we are living in a brave world here.

cpojer commented 1 month ago

Hey @tjamesmac, thank you so much for your contributions! I left a few comments, would you mind taking a look?

if the map isn't saved, the undo stack is extended across reloads. Meaning, you can go back to the last refreshed map with ctrl-z.

I think this is ok actually, that's the whole point of replacing the "restore" feature with this one, as long as the id matches.

tjamesmac commented 1 month ago

Hey @cpojer, thanks for the quick review and sorry for the slowish response. Busy weekend!

I've made your suggestions and added a few more fixes for some edge cases. Would appreciate another review!

Also thanks for open sourcing Athena crisis :)

cpojer commented 1 month ago

This is looking really solid! I think there are only two more considerations before it's ready:

Just note, we should probably not immediately update undo every time an effect changes since a user can type into the textarea to update the text a character says and it would probably be slow and not fun to add each character to the undo stack.

tjamesmac commented 1 month ago

Hey thanks, got a bit busier than I expected. Will look at shifting the effects into the stack when I get chance

tjamesmac commented 1 month ago

Hey @cpojer , I have a couple of questions!

When I edit a map, then reload and hit cmd+z, it restores the map with one state less than expected. Ideally it restores it at the same state as before.

How do you feel about the previous state (if present) just being restored straight off a reload instead of hitting restore to get back to the previous state? If that's okay I think I can check when getting the initial map state whether I should restore from:

Ideally they get versioned with the current state of the map as well.

Does this mean move the effects into MapData and store that as an entry in the undostack? Instead of adding an Effect as a separate value in a undoEntry?

cpojer commented 1 month ago

How do you feel about the previous state (if present) just being restored straight off a reload instead of hitting restore to get back to the previous state?

I prefer not to do this. In the game, opening the map editor should start you off with a fresh map. I mostly just want undo to work properly in that empty state so that we can make the "Restore Map" button more prominent in the editor in a follow-up. That way we give control to the user.

Does this mean move the effects into MapData and store that as an entry in the undostack? Instead of adding an Effect as a separate value in a undoEntry?

I think we have to change undoEntry to take [MapData, Effects] instead of just MapData. Effects cannot live on MapData directly.