Monstergirl GameDev Corner 01
It looks like we have several anons interested in making games now, at least
>>13407 here and
>>16326 and
>>16303 in /mggt/, so I figured I'd offer some help. It looks like most people are coming to code from an art background so I'll start with some basics.
Intro: A Framing Problem
Let's assume both you and your fellow anons are desperate for OC, because WEG-wise
>>5055 is still accurate. You snap and put out the simplest demo possible, a waifu-picker with 4 girls. Sucks for you though, even that isn't zero effort, because it will either fill a PC screen and look tiny on phones, or will go one-column and have tons of unused space on a PC. The 2-column compromise is just that, a compromise.
So even with something that can barely be called a game, we can't escape coding. Luckily, the code here isn't hard. We want to:
>Set a minimum width for the choice of girl, so it looks good on-screen
>Choose a value that works on PC and phone
This can be done as pure HTML + CSS without more complex "proper" code:
[code]
<style>
.choiceList {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}
</style>
<div class="choiceList">
<div class="choice">contents here</div>
<div class="choice">(that means your waifu!)</div>
<div class="choice">can include pics, text, and triggers to let you select 1 of the 4 girls</div>
<div class="choice">yeah, ipsem lorem motherfucker!</div>
</div>
[/code]
The first line in
style say to enable a grid. The second is where the magic happens. To break it down
>repeat(auto-fill, = do it until you fill the space
>minmax(20rem, 1fr) = but set a minimum width of 20 REM units (around 30 letters) per choice, and use a maximum "1.0 fractional", which means fill the screen with the one thing but take out all the little stuff like margins first.
You can see the result in our second pic. I also increased the font size with a media query on aspect ratio since a phone is only a couple inches wide, and the rem unit is relative to the base font size, giving a wider view as a result. You can look that up, or I'll provide the full code once I have this thing release-worthy as a quick fun project.
Second Concept:Objects
You may object, 'I don't want to do some crappy waifu clicker, I want my own Monster Girl Quest Paradox!' Fine, so let's talk about how to think of serious code. At base, code is about defining a
world of rules. Everything you put in it has to be defined. Some of this can be automated, like if you have a 3D model, Unity or Unreal can import & render the polygons. But a lot is still up to you. Start with a simple question: what makes the monstergirl like you more? Maybe something like:
>You give her gifts she likes
>You keep her in the party, even at night...
>...and when that leads to its inevitable conclusion, your hero is good at sex!
Each of these needs to be precisely defined and tracked. Maybe "good at sex" means a numeric sex skill from 1 to 100, and above 60 is "good". But maybe it means a rhythm minigame ala DDR, and you save the final score.
You can't fob this off, not even if you had a perfect AI, because this is what your game is.
So now you're thinking of two big things,
<What do you do, the actual gameplay?
<What numbers do you need to track this?
If you have a big game like Paradox with a lot of girls, it leads to a third
<How do you organize this so it's not a confusing mess that would horrify even YandereDev?
Luckily, this has been answered by the big brains behind Unix: objects! The idea is that each code object corresponds to a thing in the game, exactly like you're used to in an RPG. So a Party object has 4 Characters, and a Character has level, XP, HP, MP, attack, defense, and so on. This is
data, but an object also has things it can
do, like attack or call on Sylph for a barrier, these being its
functions or
behaviors.
Once you're thinking of things this way, the question is how much can be in a
generic object vs. one specific to a character. I've attached an example of how this works in Mario, with the categories of Enemy and Ground Enemy reducing your code from over 100 rules, mostly repeats, to a mere 33.
Our First Detailed Object: Bounding Boxes
You could spend days looking up shit on object oriented programming, but I think it's more useful to look at how a very basic one works at the level of code you'd actually write. How do you tell if Mario's jumped on an enemy, or if Luka's walking into a wall in MGQ:P? The simple answer is a bounding box, literally a square around the character. If it overlaps with another character, you check the rule for that interaction to see what happens. For a platformer, there may be multiple boxes per character. In the example here, our very out-of-place Goomba has two hit locations, a green zone where you can smush it, and a red zone that will hurt Mario. But looking at the rest of the pic, we see a more interesting problem: how does our hero fit through the door to meet his beloved Anubis? The door is just a simple box, and really only the bottom counts. But our hero is a little more interesting, since he wants different boxes and rules for different purposes.
>The minimum draw box, 16x30, is what the computer would need to render, but it's not great since a run animation or combined sprite hugging the Anubis would be bigger. So for draw calls, I define a convenient 24x32 "EZ-box", which I've determined is big enough for all frames of the hero's common animations. But that extra space would keep him from walking through a 1-tile wide door, and even the minbox feels janky for stuff like getting hit, where the gameplay feels better if a shot grazing his hair counts a near-miss instead of a hit. Thus we get the hitbox shown, a mere 12x24 pixels. A shot or collision counts when it overlaps any part of this hitbox. But that looks wrong if you're trying to walk in the door. Your head touches the dark part and you warp into a room, and you mysteriously can't stand right in front of a treasure chest. For that we need one more box, a wallbox, roughly the area covered by the feet in all frames of the run animation, a mere 4 pixels tall. When that bumps into a wall or chest we get pushed back, and if it touches a door, we warp.
This attention to realistic simulation is even more important for 3D games. Look up a video of the hitboxes in Dark Souls or Elden Ring. You'll first see that bosses have a
ton of them, and they change for every attack. Being in 3D, they're actually more like cubes, or in some cases arbitrary polygons with no indentations called a "convex hull", which still is easier to calculate hits with than an arbitrary shape.
In 2D, the math is simple enough to share here. Assume that (x0, y0) is the upper-left corner of the BBox and (xf, yf) is the lower right (in Cartesian quadrants this is Quadrant IV, chosen over Q1 in computer graphics because the screen draws down from the top). Assuming 2 objects, A and B, we only need to test once, since if A is inside B, B is also inside A. The logic here is most efficient by negation
[code]
// stuff after these two slashes is a comment, the computer ignores it but it helps YOU understand
return not (
a.x0 > b.xf or // A is completely to the right
a.xf < b.x0 or // A is completely to the left
a.y0 > b.yf or // A is completely below
a.yf < b.y0) // A is completely above
[/code]
What do you think? If you have questions or requests for other topics I'll do what I can. Alternately, if another anon wants to do a demo on something like model rigging that would be a cool followup. And if any of you anons thinking of making something want to try, now's a good time!