eternagame / EternaJS

Eterna game/RNA design interface
Other
12 stars 10 forks source link

`Puzzle` in `ConstraintContext` #495

Open everyday847 opened 4 years ago

everyday847 commented 4 years ago

A ConstraintContext optionally takes a Puzzle -- which means constraints relying on that member can't be used in puzzlemaker. MaximumMutationConstraint is a good example.

Would it be possible/desirable to build up a 'stub' Puzzle definition in puzzlemaker (for example, one where the starting sequence is whatever the current sequence state is) to enable such constraints? What's the right path here?

luxaritas commented 4 years ago

Definitely - but I actually wouldn't make it a stub. So first off, we should split out the "eterna specific" things from the actual "rna puzzle" (which would be useable eg in a research context) - so things like NID, point value, etc should be in a separate class/interface (or to some data structure/serialization format that allows for "extensions", ie by vendor-prefixed keys) which is only used in the puzzle solver (and almost certainly not in the core functionalities ie constraints). For the remaining things like starting sequence, this is actually something that indicates a limitation in puzzlemaker: we should be able to set the starting sequence independently from solving the puzzle to allow for submission. Don't forget that we need to support undo/redo for the puzzle definition as well as the solve state in puzzlemaker!

everyday847 commented 4 years ago

Yeah, by 'stub' I don't mean 'intentionally hobbled' so much as 'nonfinal, in contrast to the sort of puzzle you construct from a puzzle json'.

I see what you mean, but that really means UndoBlock gets more distant (or at least specialized) between the two. Or perhaps we just need it to track transformations impossible in PoseEditMode as well.

everyday847 commented 4 years ago

Hm, what's the best abstraction for the "progression specific" puzzle elements? To help brainstorm a name, here's what I can see:

_nid, _name, _missionText, _round, _numSubmissions, _reward, _rscriptOps, _nextPuzzle, _hint, _maxVotes, _alreadySolved

maybe something like WebPuzzle.

Anyway, irony here is that actually the nid is one of the few things mandatory for constructing a puzzle, so the division you're imagining is alas not very natural yet in the current state of affairs. Perhaps unsurprisingly.

luxaritas commented 4 years ago

Yeah, by 'stub' I don't mean 'intentionally hobbled' so much as 'nonfinal, in contrast to the sort of puzzle you construct from a puzzle json'.

Sure, but my argument is that it should be a perfectly valid final puzzle, barring what the Eterna backend adds which should ideally not affect actual puzzle solving functionality

I see what you mean, but that really means UndoBlock gets more distant (or at least specialized) between the two. Or perhaps we just need it to track transformations impossible in PoseEditMode as well.

What about maintaining two undo stacks? So you could separately undo solving steps vs puzzle change steps? Though some puzzle change steps could make some solving steps impossible... We could do some sort of "delta" momento, but that's probably more likely to have bugs. Maybe just store the new [gamestate|puzzledef], whichever changed? IDK. Tracking both is also not terrible.

Hm, what's the best abstraction for the "progression specific" puzzle elements

  • FYI, rscript/tutorial creation should probably be handled in the puzzlemaker.
  • While NID is currently required, that's really just due to the nature of the format returned by the web server. It should be required within the "WebPuzzle"
  • As far as the name... EternaPuzzleConfig?
everyday847 commented 4 years ago

it should be a perfectly valid final puzzle

Yup, totally agree with you there! All "finalization" is just EternaPuzzleConfig (fine name) stuff.

Right now I'm just taking a pass at reading every reference in the code to Puzzle to try to ensure I understand the right thing.

luxaritas commented 4 years ago

Also: EternaPuzzleConfig should only exist within PoseEditMode. None of this should exist within any functionality shared among game modes.

Also also: Hint also falls into the same category as rscript

everyday847 commented 4 years ago

That seems difficult. I mean, unless "only within PoseEditMode" is not quite what you mean -- EternaApp, etc. need to be able to request puzzles.

Wait, unless you mean that the EternaPuzzleConfig is the thing that lacks all the "extra stuff"

luxaritas commented 4 years ago

That seems difficult. I mean, unless "only within PoseEditMode" is not quite what you mean -- EternaApp, etc. need to be able to request puzzles.

Let me rephrase, because I realized there are actually other issues with what I said: EternaPuzzleConfig should not be used in any classes that are (or should be) used in common across all pose edit modes. IE, it shouldn't show up in Pose2D, any Constraints, Folder/FolderManager, etc. Except for maybe the case where it's nullable and providing some extra optional functionality. But like, the point is that you shouldn't ever need to have an EternaPuzzleConfig for PuzzleEditMode to work, which I think you can agree with.

everyday847 commented 4 years ago

OK, that's fair.

Here is an interesting case. PoseEditMode switching to DesignBrowserMode using this.puzzleID (which asks this.puzzle for its nodeID meaning this.puzzle should in fact be "EternaPuzzleConfig-aware") -- that means EternaApp gets either a number or puzzle, in this case a number, asks EternaApp.loadPuzzle for a puzzle, which hits PuzzleManager.getPuzzleByID, which returns a puzzle only if its nodeID matches the passed number. Meaning either:

  1. DesignBrowserMode needs a puzzle-with-a-nodeID
  2. PuzzleManager should maintain a map from puznid to non-nodeID Puzzles
luxaritas commented 4 years ago

For consideration: I don't really see a situation where you could transition from a PuzzleEdit to a DBM. DBM definitely needs other EternaPuzzleConfig fields too - eg, the current round, votes, etc. I imagine a future where DBM is external to EternaJS entirely (written in HTML, etc). This is the same future where the core EternaJS lib doesn't know anything about Eterna at all, and can just load an RNAPuzzle with different puzzle editing tools disabled, mission screens are handled by this same "wrapper code", etc