Two weeks since the last update, and things have been going a bit slowly. Headachey and nauseous today, which is certainly not helping.
There have been a number of code-improvements that simplify authoring, especially when casting characters into scenes, and similar meta-programming tasks. That’s all to the good.
The writing has been a bit slower, and I think it is because I got hung up on a particular scene.
Now, there’s already a big reveal/twist at the end of what currently constitutes the demo content. It’s integral to many of the characters’ stories, and it works pretty well. There’s a second reveal/twist on the following day, and that’s where things jammed up a bit.
I wrote out the scene, looked it over, and I just wasn’t happy with it. It certainly works – and I was okay with it on that level – but I was uncomfortable with the emotional strength and qualities represented in that scene. Too strong and too harsh for the rest of the narrative, as it currently stands.
(Trying to avoid spoilers here makes it feel like I’m vaguebooking)
I had to sit on it for a bit and think about it. In the end, I decided that leaving it the way it was – and subsequently dealing with all of the consequences – would needlessly undermine a strong character, and it would require a slew of trigger-warnings.
I decided to revisit it and found ways to tone things down. I think the scene (and its ramifications) are considerably more acceptable and fitting now, but for most of two weeks, I really couldn’t think of too much else, and that led to me getting very little of the narrative actually done.
Compilation and Parsing
Lots of cleanup work and improvements here, including the aforementioned meta-programming shortcuts. I’ve replaced more tokens with shortcodes and found ways to eliminate some redundant separators from the compiled story-file, which improves loading speed, as well as cutting down the size of the compiled story (both on-disk, and in-memory).
On my development box, loading the story in its current form takes on the order of 614ms. It’s fast. If it gets much faster, I’m going to have to cut out visual progress-indicators.
If they flash by too fast, users will feel like they’re missing something, and they’ll be almost too fast to see. In fact, cutting them out would probably shave another 90-100ms off of the initial load time. For the moment, I’ll leave them be.
Code
It may or may not come as a surprise to you that text-processing comprises most of the actual work, both during compilation and runtime. Most of the projects I’ve ever worked on involved a significant amount of text-processing. There’s stuff you do over and over.
Clearing whitespace and control characters from both ends of a string, for example:
void chomp(std::wstring &s) { while (s.length() > 0 && s[0] <=L' ') s.erase(s.begin()); while (s.length() > 0 && s[s.length() - 1] <= L' ') s.pop_back(); }
Or splitting a string into tokens:
std::vector<std::wstring> tokenise(const std::wstring &source, const wchar_t delim) { std::vector<std::wstring> result; if (source.length()==0) return result; std::basic_stringstream<wchar_t> source_stream(source); std::wstring tmp; while (std::getline(source_stream, tmp, delim)) result.push_back(tmp); if (source[source.length() - 1] == delim) result.push_back(utils::empty_string); return result; }
Or just cutting a string at the first separator, and returning the segments to the left and right:
std::pair<std::wstring, std::wstring> quick_split(const std::wstring& s, wchar_t delim) { auto i = s.find_first_of(delim); if (i == std::string::npos) return std::make_pair(s, L""); // If there's no delimiter, just return the whole string as the first part return std::make_pair(s.substr(0, i), s.substr(i + 1, s.length() - 1)); }
As algorithms go, these are pretty efficient. Doubtless they could be made even more efficient, but they’re good enough even for the ridiculous amount of work that I throw at them.
Between quick_split() and tokenise(), you can get a surprising amount of sophisticated parsing done. Maybe these can work for you, too.
Now that I’ve gotten myself through the narrative blockage wrought by that one scene, I’m expecting to make a bit more progress. Only time will tell, though.
Thankfully, I’ve no actual deadlines, and can just plug away at this in my own time.