Semantic Vector Search
Motivation
Suppose you’re making a visual novel with lots of images. In most VNs, each scene—say, groping in a hotel room—has a single image you assign to show. So you name your files something like:
hotel_groping.webp
And build scenes like this:
location: 'hotel'
activity: 'groping'
img: 'hotel_groping.webp'
You do this for every event—hotel_handjob, hotel_oral, home_tentacles, dream-world_sleep, and so on. You build an arsenal of lewd images in your assets folder.
But here’s the subtle problem:
If you want to test scenes before the final art is done, you need placeholders for everything. You create hundreds of placeholder files, which get replaced later.
Later, you expand: now each scene can show three images. You update all your scripts and rename all your files:
location: 'hotel'
activity: 'groping'
img: ['hotel_groping_01.webp', 'hotel_groping_02.webp', 'hotel_groping_03.webp']
Then you realize some images don’t fit—wrong hair color, odd angles, whatever—so you delete a few. But now you have to manually update every script that used them, or the game breaks.
Multiply by a thousand images, and you’re spending more time wiring assets than creating content.
AI art generation can’t save you if you’re still hand-wiring every scene.
The Solution: Use Vectors
Instead, you can name your generated image files like this:
hotel_groping_0.1301331480579081.webp
- First part: location
- Second part: activity
- Third part: intensity (a number from 0 [calm] to 1 [wild])
A parser script turns each file into an entry like this:
name: 'hotel_groping_0.1301331480579081.webp'
vec: [1, 0, 0.026]
- 1 = hotel room (location)
- 0 = groping (activity)
- 0.026 = intensity (normalized so every image gets a fair chance to be used)
Now imagine every image is a point in a 3D space:
- Same location? Same row.
- Same activity? Same column.
- Same intensity? Same height.
After parsing, your asset table looks like:
{"name": "hotel_groping_0.1301...", "vec": [1, 0, 0.026]},
{"name": "hotel_groping_0.3127...", "vec": [1, 0, 0.289]},
{"name": "hotel_handjob_0.3659...", "vec": [1, 1, 0.214]},
// ...etc
Now your assets are mapped in a vector space—and computers are very good at finding what’s “closest” in a sea of numbers.
Querying: Let the Computer Choose
When the game needs an image, it doesn’t look for a filename—it describes the kind of image it wants:
location: 'hotel'
activity: 'handjob'
intensity: 0.4
The engine turns this into a vector:
[1, 1, 0.4]
It then finds the nearest neighbor in the asset table—like asking for the closest subway station to your destination. For example, the closest match might be [1, 1, 0.214], returning:
hotel_handjob_0.36592505330525615.webp
That’s the image you see in the game.
Why This Solves Everything (Almost)
One word: scalability.
- Your game logic doesn’t care how many images you have; it always gets the best available match.
- Adding images is trivial. Just drop them in the folder—they’re immediately usable.
- No more placeholder images: the system finds the best candidate, or falls back automatically if a perfect match doesn’t exist.
- No more manual updates after deleting or adding files. No more “missing asset” bugs.
For the Curious: Actual Code
import { abilities, locations } from './data.js';
import { table } from './table.js';
const loc_labels = {}, act_labels = {};
locations.forEach((e, i) => loc_labels[e.label] = i);
abilities.forEach((e, i) => act_labels[e.label] = i);
const w = [16, 1, 1]; // weights: prioritize location most
const sqdist = (v1, v2) => v1.map((v, i) => ((v - v2[i]) * w[i]) ** 2).reduce((a, b) => a + b);
const nearest = vec =>
table.reduce((best, e) =>
sqdist(e.vec, vec) < sqdist(best.vec, vec) ? e : best,
table[0]
);
const qer2vec = (loc, act, intensity) => [loc_labels[loc] ?? -1, act_labels[act] ?? -1, intensity];
export const query = (loc, act, intensity=.5) => nearest(qer2vec(loc, act, intensity)).name;
Why Vectors?
- You always get a fallback: There’s always a closest match.
- No perfect match needed: The system is flexible, robust, and automatic.
- Works at any scale: 10 images or 10,000—no new code needed.
In short:
Vectors turn asset management from a headache into a breeze. The game always shows the most appropriate image for any scene, without ever needing you to play librarian.
Totally Accurate Succubus Simulator
TASS
Status | Released |
Author | Ex Blackhole |
Genre | Visual Novel |
Tags | Adult, Anime, Eroge, Erotic, Female Protagonist, Indie |
Languages | English, Japanese, Chinese (Simplified), Chinese (Traditional) |
Accessibility | High-contrast |
Leave a comment
Log in with itch.io to leave a comment.