Home Creators Posts Import Register Favorites Logout

Content

Hello friends! We are currently on v0.7.1g after some bugfixes following last week's update. Barring anything unexpected, that's probably it until the October update.

But now it is time... to discuss the next major update.

So there's no confusion, especially for new supporters, when I say "major update" I mean a roadmap update which will take some time to complete. We'll see several smaller monthly updates before the update we're discussing today will be delivered.

Last week, I picked five possibilities from the roadmap and laid them out in a poll, and they've now had almost a week to percolate. Adding votes from both platforms together, we have:

Consequences with 92 votes...Crime and punishment with 163 votes...Pregnancy with 260 votes...Year advancement with 265 votes...And finally... background NPC simulation with 275 votes.

I classify these into basically two categories: crime and punishment and consequences (in fact, these have so much overlap they will likely end up combined into one update someday), and simulation stuff, in that the latter three options all involve major life events that happen over time. With that framing, these results make it pretty clear that most of you would like to see the game's simulation extended, with an emphasis on enhancing the handling of NPCs.

What this means is I'll build a framework for simulating events and changes over time, whether they involve an NPC or PC or both, and thereby lay some groundwork for the top three items. As close as it is, though, some item has to win, and background NPC simulation has the most votes, so that will be the top priority. I'm planning to make at least some progress on the other top three items, though whether they'll actually get done in this update remains to be seen — as always, it's a balance between doing everything I'd like to do and delivering the update in reasonable amount of time.

I've spent this week planning, tinkering, and starting to write some baseline code. One thing I'll need to tackle in this update is also a common request when it comes to enhancing the simulation aspect: NPC-to-NPC relationships. This is a bit complicated, especially for a browser game!

Programmer talk

Our first concern is a very practical one: there's save size to consider. Local storage for a browser game is generally limited to 5-10mb, which isn't very much! With IndexedDB, those limits aren't so much of a worry, but not every device can use IndexedDB, so we have to accommodate that.

If you have any experience with databases, you know what a primary key is: a unique identifier attached to a set of data. Many of the game's data structures have a similar setup, including our NPC info: their primary key is the NPC's name. Now, storing strings like names is expensive. It'd be cheaper to use a unique integer as the identifier, but we didn't do that.

Why not? Well, when we're storing 600-2000 NPCs, whether we use strings or integers doesn't actually make so much of a difference, not enough that I wanted to sacrifice readability. That calculus changes when we're talking about potentially storing how every NPC relates to every other NPC — the savings of integer vs. string is more significant when multiplied by 4 million.

So, if we want to use integers, step one is a lookup table. We want to be able to relate a name string to a unique integer identifier and vice versa. The lookup table itself will add to save size, but we'll make that up in later savings. We'll also have a little lookup table for types of relationships so we can use integers to identify those too.

Further, we'll define relationships as two-way. If NPC A is friends with NPC B, then NPC B is also friends with NPC A. But we don't need to store it this way. We can just store how NPC A relates to NPC B, or how NPC B relates to NPC A, but not both. Then whenever we're looking up how two NPCs relate to each other, we'll check NPC A first, and if they don't record that information, we'll check NPC B for it. This immediately halves our data storage needs.

Using these methods, we can look at our worst case: ~2000 NPCs who each have a defined relationship to every other NPC. This results in a save file around 2,000kb... a 10x increase! This is technically within our limits, and saves would generally be smaller than our worst case, but even so, it'd be much better to cut this down some more.

So, let's employ a couple more tricks:

Relevance: There are a lot of NPCs that the player doesn't care that much about or hasn't even met yet, so we don't need to simulate them all the time — at least not in such a way that they record information that contributes to save size. After all, if you've just met an NPC, there isn't really any perceivable difference whether they've been friends with another NPC since the beginning of the game or whether the simulation made them friends yesterday. Which brings us to...

Procedural generation: We can decide algorithmically whether it makes sense for two NPCs to be friends or rivals, and rather than storing this in the save file, we can just process this algorithm and get the result whenever it's relevant. Then, storing a relationship in the save data is only necessary when it would override what the algorithm would determine.

Using these tricks, save size will be quite a lot smaller than our worst case. It will tend to gradually increase throughout a game, and we may need to do more to address it, but unless the player favorites literally every NPC in the game, we should avoid the worst.

What it will actually look like

A background simulation is neat and all, but it isn't of any use unless some aspects of it also end up in the foreground! So, how will we do this?

My current idea is that simulated events will be baked once per day and then roughly scheduled to happen sometime in the following day. (This is basically how relationship changes work already). Rather than being scheduled for a specific time, we can say they're queued for one of the day's time periods: morning, afternoon, evening, or night.

If the player is in the right place at the right time for a queued simulation event, they can witness something that represents the change taking place. For example, if two people you know are destined to become rivals, maybe you witness the argument in the park that sets this off.

If the player doesn't witness a fitting event in this time slot, or if it's something that wouldn't make much sense to be witnessed in the first place, then we need another way to surface it. The logical choice here would be... Elkbook! This update is a good time for Elkbook to get a bit of a facelift and a lot of extending to give you a good idea of what's happening around campus and around town.

Things I intend to simulate include relationship changes (as we've already discussed), inclination changes (particularly as encouraged by the player), skill changes, adding and removing NPCs (this will help us with year advancement), and various other important life changes that involve timed events or situations that progress (which also helps us with year advancement as well as pregnancy). As with everything in the game, our goal is to use these things to drive the player toward erotic scenes, and to give those scenes more context. And it'll also improve the game as a life sim.

Anyway, that was a long one! Sorry if it was overly rambling. Like I said, I'm in the planning and tinkering stages and still figuring out how all this stuff will actually work, and I've also made a start on the baseline simulation code. Next week, my goal is to make some simulated events actually work along with surfacing them in both witnessed events and Elkbook updates.

But until then... I hope you have a good weekend, and thanks so much for your support! Your help really does mean a lot, and it makes this project possible. Until next time!

Files

Comments

luna:3

So cool

Ragnar

I honestly can't wait for this update! I think this is something the game desperately needs at this point and I'm very happy it won. I'm very excited how it will turn out in the end!

MisoSquared

Lol, I would have chosen consequences or background NPC simulation if I realized there was a vote. I'm happy NPC simulation got it cause that seems like the thing that'd be hardest to change as the game developed. Thank you for the technical side too! I'm in my third year equivalency for a cyber security degree so stuff like that is cool to see you talk about, even if most people probably don't care It would be cool to store a heat map of the player's preferred locations (like on some playthroughs I never visit the art building or the isolated dorm building) and then have events weighted to more likely occur in those places

lena

this sounds promising and will definitely contribute to making the game feel more fleshed out even at this stage, good luck and good job as always :)

Reimus

I'm not sure of the specifics behind how IndexedDB works but I'd imagine if the name of a character causes issue with the DB size AND you are using the name as a foreign key, you might want to change how the DB works/table schema. Just to be clear, I'm a bit rusty on the specifics and am not familiar how IndexedDB works so maybe it's doing what I suggest under the hood or you already are and didn't mention it. If you change the foreign key to an ID number you'll considerably reduce the amount of memory you need to store. Going from something like: `CREATE TABLE Characters (full_name varchar(32), ..., PRIMARY_KEY (full_name);` You need to allocate 32 bytes per character which should be 64kb or 256kb depending on what character encoding is being used. Now if you are using the full_name as a foreign key your relationship table might look something like: `CREATE TABLE Relationships (character1 VARCHAR(32), character2 VARCHAR(32), FOREIGN KEY character1 REFERENCES Characters(full_name), FOREGIN KEY character2 REFERENCES Characters(full_name))` Now for every relationship you need 64/256 bytes per relationship (depending on encoding) and since you could have 2000x2000 relationships, that'll fill the memory quickly. (lunch is ready so Imma cut this short and can do more detail if you'd like later, just lmk. You can also ping me in the discord) Adding an id and setting it as the foregin key will take up just 4 bytes to each character but then the Relationships table uses that ID instead of the full_name so you go from 64/256 bytes per relationship down to just 8 since it'd only be an integer you'd need to track. For reability you might want to create a function that can get names by id, but for the most part outside of the relationships or any large table that needs to reference the character table, you could still use the full_name I think

forestlikesplants

i always like reading the bits on the process you take to plan out your coding, so interesting!! excited for more to come

Cyryos

It's going to be a huge update fir the game, amazing. Elkbook and the streaming sites have been a nice touch, glad to see them getting expanded. It would be great if you could use your daily post to comment on the post of the day. That could help shift the influence/skills of your followers.

Tommi

Literally just subscribed since I had played for a few hours and enjoyed it. This post is so impressive with how you’re communicating the development process.

Egypt

I'm sooo happy BG NPC simulation is in the lead. I love playing God when it comes to NPCs. I know it will be a close race with pregnancy. With that being said, I really hope, when released, it comes with a cheat box for ending relationships, pairing specific students up...maybe even editing Likes/Dislikes/personality!

jR1_Esk

I'm excited for the NPC sim but man I can't believe how close the poll was. Only beating out preg by 15 votes is pretty insane to me.

William Urquhart

Sounds great! I gotta admire you tackling it! As for save game size... I am sure you have considered it, but still feel obligated to mention it (as you remember, I am a bit OCD that way): Have you thought about saving different (but linked) files for each 'save game'? Say one for the MC and one for the NPCs? If it is a code limitation, you could 'cheat' a bit and have NPC data saved at 'significant' events occurring while MC data is saved as it is now or something similar. just a thought

courseoftemptation

It could be done, but the limit is less about a single file's size and more about the size of all of them combined, so separate files don't help that much, unfortunately.

courseoftemptation

I'm definitely going to tinker with it some more. I talked with a friend who maintains a large database at her job and that gave me some ideas.

Zqui

Dwarf fortress starts to slow down pretty bad after a certain number of dwarves. Are you seeing any issues coming up with this kind of O(n!) analysis yet?

courseoftemptation

Definitely something I'm concerned about, but the worst case scenario outlined here really is the worst case, and I don't intend to have anywhere near that dense a matrix in practice. It helps too that the game isn't adding new NPCs — besides a few being added when year advancement is in, it'll be a pretty static number.

ѕℓєєρу кιиg

Dang I was really excited for year advancement or pregnancy but at least this will make those other two future expansions more fleshed out and interesting. Good luck this one sounds pretty tricky and tedious but can't wait to see it come to life!