pub struct State {
pub version: String,
pub username: String,
pub workspace: PathBuf,
pub current_level: String,
pub start_time: NaiveDateTime,
pub levels_complete: IndexMap<String, LevelCompletion>,
pub level_attempts: IndexMap<String, u32>,
pub level_hints_used: IndexMap<String, u32>,
pub level_started_at: IndexMap<String, NaiveDateTime>,
pub completed_at: Option<NaiveDateTime>,
}Expand description
Everything the game remembers about one player: the contents of state.json.
The fields are written in declaration order, which is the order pydantic uses. The four per-level maps are keyed by level ID and keep insertion order.
§Level ID migration
Versions 1.0 and 2.0 numbered the sections differently. When such a file is loaded,
the IDs in current_level and in the keys of the four per-level maps are remapped
(2.7 and 2.8 swap, 6.7 and 6.8 swap, then section 7 becomes 8, 8 becomes 9, 9
becomes 10 and 10 becomes 7), so every level keeps its content and its credit.
The migration, the version check and the Czech error messages belong to
StateStore::load; deserializing a State directly bypasses them.
Fields§
§version: StringSchema version. CURRENT_STATE_VERSION once loaded or created.
username: StringName of the player; also names the default workspace.
workspace: PathBufDirectory in which the level fixtures are built.
current_level: StringID of the level the player is on, for example "1.12".
start_time: NaiveDateTimeWhen the game was started.
levels_complete: IndexMap<String, LevelCompletion>Finished levels, in the order they were finished.
level_attempts: IndexMap<String, u32>Failed submissions per level.
level_hints_used: IndexMap<String, u32>Number of revealed hints per level.
level_started_at: IndexMap<String, NaiveDateTime>When the player first saw each level.
completed_at: Option<NaiveDateTime>When the player finished the last level; None while the game is still running.
Implementations§
Source§impl State
impl State
Sourcepub fn new(
username: impl Into<String>,
workspace: impl AsRef<Path>,
now: NaiveDateTime,
) -> Self
pub fn new( username: impl Into<String>, workspace: impl AsRef<Path>, now: NaiveDateTime, ) -> Self
A fresh game on the introduction 0.0 (Python’s StateManager.create).
workspace is normalized like a Python Path. The timer of the first level starts
at now.
Sourcepub fn record_attempt(&mut self, id: &str)
pub fn record_attempt(&mut self, id: &str)
Counts one failed submission on level id. Successful ones are never recorded here.
Sourcepub fn ensure_level_started(&mut self, id: &str, now: NaiveDateTime) -> bool
pub fn ensure_level_started(&mut self, id: &str, now: NaiveDateTime) -> bool
Starts the timer of level id at now, unless it is already running.
Returns whether the timer was started, that is, whether the state changed and needs saving.
Sourcepub fn record_completion(
&mut self,
id: &str,
now: NaiveDateTime,
) -> LevelCompletion
pub fn record_completion( &mut self, id: &str, now: NaiveDateTime, ) -> LevelCompletion
Records level id as finished at now and returns the new record.
The time is the number of whole seconds since the level was started, never negative and 0 when the start was never recorded. Hints and attempts are copied from the per-level counters.
Sourcepub fn hint_status(&self, id: &str, total_hints: usize) -> usize
pub fn hint_status(&self, id: &str, total_hints: usize) -> usize
How many of the level’s total_hints hints the player has seen already.
Sourcepub fn reveal_next_hint(
&mut self,
id: &str,
total_hints: usize,
) -> Option<usize>
pub fn reveal_next_hint( &mut self, id: &str, total_hints: usize, ) -> Option<usize>
Reveals the next hint of level id.
Returns the index of the newly revealed hint, or None when all total_hints hints
have been revealed already (the state is then left unchanged).
Sourcepub fn is_finished(&self) -> bool
pub fn is_finished(&self) -> bool
Whether the player has finished the whole game.
Sourcepub fn reset_level_progress(&mut self, id: &str, now: NaiveDateTime)
pub fn reset_level_progress(&mut self, id: &str, now: NaiveDateTime)
Forgets everything recorded for level id and starts its timer anew at now.
Also clears completed_at, so a finished game becomes playable again. Meant for
dev jump, which must be able to replay any level from scratch. Other levels keep
their entries and their order.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for State
impl<'de> Deserialize<'de> for State
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for State
impl StructuralPartialEq for State
Auto Trait Implementations§
impl Freeze for State
impl RefUnwindSafe for State
impl Send for State
impl Sync for State
impl Unpin for State
impl UnsafeUnpin for State
impl UnwindSafe for State
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.