-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generalize representation of dependencies between goals #795
Comments
Hmm, I'm not convinced --- that is, I'm not convinced it's worth it to use trees in particular. What about a scenario where you have to complete goal A to unlock goals B and C, and then you can only unlock goal D once you have completed both B and C? Or what about something where you need to complete any two of A, B, or C in order to unlock D? Or where secondary goal B is only available to you if you have already completed a different tutorial scenario? etc.? Switching to trees would be a lot of work and would complicate the code, but there would be lots of potential scenarios we still could not express. Really the only reason to use trees in particular would be that YAML can already represent them. So it would be a lot of added complexity with only a small gain in expressiveness. If we want to generalize the goal system (and I'm very open to that), I think we should jump straight past trees to something much more general. I'm not sure exactly what, but here are some ideas off the top of my head:
|
I like this proposal in general and either Tree/DAG/active system would be an improvement with many fun possibilities. Some issues, that I can think of:
Overall I think the "active system" is the most general and might even be easiest to implement:
@byorgey we can test backward compatibility for the first time in scenarios and keep supporting the good ol' objective list syntax. The new system does not need a new name - it can simply be a JSON/YAML object instead of a list. Guaranteed identifier uniqueness for free. 😁 PS: The active system is still a |
Sounds interesting, but can you elaborate on how this would work? I like the idea of expressing as much of the dependency relationships statically as possible, so that we don't have to execute arbitrary code to, say, visualize the objectives network.
A step beyond the "prerequisites list" implementation of a DAG in the yaml file could be a string that defines a boolean expression of other goals. These expressions would support In fact, with a CNF boolean expression, we could make the
but we could also do more fancy stuff like:
Can you think of any arrangement of objectives that this would be unable to represent? |
Very simply, you start with your starting objective in the The advantage is that adding/removing objectives would be very simple - just add/remove those listed on the finished objective. I now realize this is different from what @byorgey was pitching and would lead to arbitrary (?) graphs on sets of objectives. The implementation in code and in YAML is simple and there are almost no restrictions, but the alternatives may be better. |
Boolean expressions look nice - they have the same power as the active/inactive system but would not require hacks when writing scenarios. Regarding the format, I would either go all the way and use the parser and evaluator you linked or use YAML as much as possible: prerequisite:
- objective1
- or:
- objective2A
- objective2B
- not: objective3 If we process the Aeson Turns out JSON schemas can be recursive[SO] so we do not need to limit ourselves to CNF. 😅 So far I like the "DAG using a list of alternative prerequisites" (@byorgey) and the "boolean expressions using YAML only" (@kostmo, but with Mergify-style |
I like @kostmo 's boolean expression proposal as well. It's strictly more powerful than a simple list of prerequisites, but still relatively simple, and keeps all the prerequisite logic for a scenario in one place (I think @xsebek 's proposal to have each objective enable/disable others might end up being equivalent in power, but it would be hard to understand under what circumstances a given objective would become active, since that information would be distributed around among other objectives). I don't care too much about the specific syntax we use as long as it's easy for scenario authors. Probably Mergify-style I think we should generalize the goal dialog to show all the currently active/available objectives (kind of like a list of "active quests" in an RPG), perhaps with a narrow column on the left side with a list of objectives that you can scroll through, and a larger area on the right side showing the description of the currently selected objective. It makes sense to me that we would then want an optional |
If we were to add a
So we only need to update For my own reference, here's how to get a list of the files:
|
towards #795 At this commit, all unit tests pass and UI behavior remains the same as 'main' branch, including for multi-goal scenarios.
towards #795 At this commit, all unit tests pass and UI behavior remains the same as 'main' branch, including for multi-goal scenarios.
Closes #795    ## Tasks - [x] Vendor a subset of the `boolexpr` package - [x] New display logic for parallel goals - [x] Add a check for whether winning is impossible (due to a "not" prerequisite being achieved) - [x] Add a "Lose" dialog analogous to the "Win" dialog - [x] Validate no dependency cycles in prerequisites specs - [x] Add tests for negative validation result from scenario parsing - [x] Web API to inspect status of incomplete, completed, optional, and prerequisite objectives - [x] Update all of the multi-goal scenarios to use prerequisites ## For follow-up PRs: - [ ] Upload new GHC8-compatible version of `boolexpr` to Hackage (perhaps [take over the package](https://wiki.haskell.org/Taking_over_a_package)?) - [ ] Add prerequisites and its logical operators to JSON schema - [ ] Reverse topological sort of goals before evaluation, with a test that demonstrates necessity - [ ] Automatically skip over the header rows when navigating the Goals list - [ ] Add indicators for optional and hidden goals - [ ] New Challenge for strategizing optional and mutually-exclusive goals
This builds upon #378.
Is your feature request related to a problem? Please describe.
I'd like to be able define "optional" goals (e.g. hidden achievements, or "secondary" or "tertiary" goals) for a scenario, aside from the primary goals.
Describe the solution you'd like
We could use a
Tree
rather than a list to represent the goals. Conveniently, YAML can already represent trees.Goals that must be completed in sequence would be represented as a chain of increasing depth, while goals that are independent of each other shall be siblings in the YAML file. A slight drawback is that for each of the existing scenario files, multi-goal sequences will need to be indented into a "terrace" of children.
Perhaps we would define the following enum to label each goal:
Primary
shall be the "default" goal type when omitted.The scenario would be considered "complete" once all of the
Primary
goals are met. The "Keep playing" option will then be useful to pursue the other goals.The text was updated successfully, but these errors were encountered: