yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
project_plan.h
Go to the documentation of this file.
1#ifndef YAZE_CORE_PROJECT_PLAN_H_
2#define YAZE_CORE_PROJECT_PLAN_H_
3
4#include <string>
5#include <string_view>
6#include <vector>
7
8#include "absl/status/status.h"
9#include "absl/status/statusor.h"
10#include "nlohmann/json.hpp"
11
12namespace yaze::project {
13struct YazeProject;
14}
15
16namespace yaze::core {
17
18// A project plan: goals, milestones, the intended play route, open design
19// decisions and reference documents for a hack. Stored as a JSON sidecar
20// (schema "yaze.plan/1") named by the `.yaze` file's [planning] section; see
21// docs/public/usage/planning.md. Game-independent: nothing here reads a ROM.
22//
23// Every object keeps the keys this build does not model in `extra`, and the
24// top level keeps unknown sections (for example "overworld" or "concepts"), so
25// a plan written by a newer build or another tool survives a save.
26
27using PlanJson = nlohmann::ordered_json;
28
29inline constexpr std::string_view kProjectPlanSchema = "yaze.plan/1";
30
31// A link from plan data to something the editor can show. Written as
32// "<kind>:<id>", for example "room:0x0C", "map:0x4B", "area:D1", "step:D4",
33// "item:flippers", "decision:power-approach", "marker:abyss:m3".
34struct PlanTarget {
35 std::string kind;
36 std::string id;
37
38 static PlanTarget Parse(std::string_view text);
39 // Room or overworld map number for "room:" / "map:" targets, else -1.
40 int NumericId() const;
41};
42
43struct PlanGoal {
44 std::string title;
45 std::string detail;
46 std::string due; // YYYY-MM-DD, optional
47 PlanJson extra = PlanJson::object();
48};
49
51 std::string id;
52 std::string title;
53 std::string start; // YYYY-MM-DD, optional
54 std::string end; // YYYY-MM-DD, optional
55 std::string status; // planned | active | done
56 std::string detail;
57 PlanJson extra = PlanJson::object();
58};
59
61 std::string id;
62 std::string code; // short label such as "D4", optional
63 std::string title;
64 std::string note;
65 std::string group; // chapter or act heading, optional
66 std::string kind; // story | errand | dungeon | shrine | optional | boss
67 std::vector<std::string> targets;
68 PlanJson extra = PlanJson::object();
69};
70
71struct PlanNeed {
72 std::string step;
73 std::string what;
74 PlanJson extra = PlanJson::object();
75};
76
78 std::string id;
79 std::string name;
80 std::string step; // route step where the player gets it
81 std::string category; // gear | mask | song | quest | ...
82 bool required = false;
83 std::string status; // implemented | prototype | decided | proposed | open
84 std::string where;
85 std::string note;
86 std::vector<PlanNeed> needs; // later steps that require it
87 PlanJson extra = PlanJson::object();
88};
89
91 std::string id;
92 std::string title;
93 std::string status; // open | decided | dropped
94 int priority = 0; // 1 = most urgent; 0 = unranked
95 std::string recommendation;
96 std::string answer;
97 std::vector<std::string> targets;
98 std::vector<std::string> refs; // file paths or URLs
99 PlanJson extra = PlanJson::object();
100};
101
103 std::string label;
104 std::string path; // file path or URL
105 std::string author;
106 std::string date;
107 PlanJson extra = PlanJson::object();
108};
109
111 public:
112 static ProjectPlan CreateEmpty(std::string title);
113 static absl::StatusOr<ProjectPlan> Parse(std::string_view text);
114 static absl::StatusOr<ProjectPlan> LoadFromFile(
115 const std::string& path, std::string* source = nullptr);
116 // Creates a new sidecar and its project link. Native publication uses one
117 // rollback-protected set; browser projects retain their IndexedDB writer.
118 // An existing destination is never replaced, even when it cannot be parsed.
119 static absl::Status CreateAndLink(project::YazeProject* project,
120 const std::string& path);
121
122 std::string Serialize() const;
123 // Exclusively creates a new file. Existing destinations are never replaced.
124 absl::Status SaveToFile(const std::string& path) const;
125 // Publishes only if the file still contains the exact loaded source bytes.
126 absl::Status SaveToFile(const std::string& path,
127 const std::string& expected_source) const;
128 // Publishes `text`, which must parse as a valid plan, under the same lock
129 // and exact-bytes check as SaveToFile.
130 static absl::Status PublishSource(const std::string& path,
131 const std::string& expected_source,
132 const std::string& text);
133
134 absl::Status ValidateIds() const;
135 std::string NewMilestoneId() const;
136 std::string NewStepId() const;
137 std::string NewItemId() const;
138 std::string NewDecisionId() const;
139 // A failed rename leaves IDs and all references untouched.
140 absl::Status RenameStep(std::string_view id, std::string new_id);
141 absl::Status RenameItem(std::string_view id, std::string new_id);
142
143 // Index into route_steps, or -1.
144 int FindStep(std::string_view id) const;
145 std::vector<const PlanRouteItem*> ItemsAtStep(std::string_view step) const;
146 // Decisions with status "open", most urgent first (unranked last).
147 std::vector<const PlanDecision*> OpenDecisions() const;
148 // The milestone marked "active", else the first one whose dates contain
149 // `today` (YYYY-MM-DD), else nullptr.
150 const PlanMilestone* CurrentMilestone(std::string_view today) const;
151
152 std::string title;
153 std::string about;
155 std::vector<PlanMilestone> milestones;
156 std::vector<PlanRouteStep> route_steps;
157 std::vector<PlanRouteItem> route_items;
158 PlanJson route_extra = PlanJson::object();
159 std::vector<PlanDecision> decisions;
160 std::vector<PlanReference> references;
161 PlanJson extra = PlanJson::object();
162};
163
164} // namespace yaze::core
165
166#endif // YAZE_CORE_PROJECT_PLAN_H_
std::string Serialize() const
absl::Status SaveToFile(const std::string &path) const
static ProjectPlan CreateEmpty(std::string title)
std::string NewMilestoneId() const
static absl::StatusOr< ProjectPlan > Parse(std::string_view text)
static absl::Status CreateAndLink(project::YazeProject *project, const std::string &path)
std::vector< PlanReference > references
std::vector< const PlanRouteItem * > ItemsAtStep(std::string_view step) const
std::string NewStepId() const
const PlanMilestone * CurrentMilestone(std::string_view today) const
absl::Status ValidateIds() const
std::string NewDecisionId() const
std::vector< const PlanDecision * > OpenDecisions() const
std::vector< PlanMilestone > milestones
static absl::Status PublishSource(const std::string &path, const std::string &expected_source, const std::string &text)
std::string NewItemId() const
absl::Status RenameItem(std::string_view id, std::string new_id)
static absl::StatusOr< ProjectPlan > LoadFromFile(const std::string &path, std::string *source=nullptr)
std::vector< PlanRouteItem > route_items
int FindStep(std::string_view id) const
std::vector< PlanRouteStep > route_steps
std::vector< PlanDecision > decisions
absl::Status RenameStep(std::string_view id, std::string new_id)
constexpr std::string_view kProjectPlanSchema
nlohmann::ordered_json PlanJson
std::vector< std::string > targets
std::vector< std::string > refs
std::vector< PlanNeed > needs
std::vector< std::string > targets
static PlanTarget Parse(std::string_view text)
Modern project structure with comprehensive settings consolidation.
Definition project.h:290