School Days 2 - First Devlog


This Devlog may contain spoilers!

If you haven't played the game yet, check it out here: https://julink.itch.io/school-days-2


Introduction

Hello and welcome to this first (probably last lolšŸ˜¬) devlog for School Days 2! In this devlog I'll mostly talk about how I managed to make the pseudo-3D effect seen in game, and I'll talk a little bit about the fog shader. You can also find a link to the github repo at the end. Enjoy!


The 2.5D / Pseudo-3D effect

- 3D Walls

A lot of people are wondering how I managed to make this effect. If you don't know what I'm talking about, check out this clip:


Here you can see various elements of the room are represented with perspective: the wall, the tables and chairs. In this clip, it is more visible with the walls: you can see the down-facing side of a wall if you are below it, and not the up-facing side, and vice-versa if you are above it.

This effect was inspired by Miziziziz, as seen in this video. The effect makes use of Godot CanvasLayer, as explained in this article.

Basically, a CanvasLayer has a scale property, initialized at 1. The bigger it is, the higher an object will appear on the "z-axis" (which doesn't technically exist since we are in the 2D engine, the object will appear bigger and closer to the camera). In Miziziziz video, we can clearly see that he used 4 layers for the walls (each colored from white to grey).

While this is a cool art-style, I wanted mine to really feel 3D. That's why I used 20 layers for the walls. Each layer is separated by 0.01 unit on the scale value (ranging from 1.00 to 1.19). It may be overkill, and decrease performance (which we'll talk about a bit later), but I think the result speaks for itself.

For a practical reasons, I made myself a little system to help me build walls more easily. A layer of wall is composed of a TileMap, on which I drew the tiles. Obviously I didn't want to make 20 times the same tilemaps on 20 different CanvasLayers, so I made it so that when the game launches, the 20 layers are automatically created by duplicating the base TileMap. The base tile is just a white square, so I'm also able to chose the colors of the wall. That's how I made the walls have different colors (see clip above: from floor to ceiling: yellow-ish, then brown, then beige).

- 3D objects

I used the same system for objects such as the chairs and tables you can see on the clip above. For instance, here is how a chair is made.

First, I draw a sprite (see below, 200% scaled-up) which represent each layer of the object (from top to bottom on the sprite-> from floor to ceiling in game).

 This sprite represents 7 layers. In Godot, I can drag the sprite, set the number of layers, and set the distance between them (with the scale propery of the CanvasLayer, see image below: on the left, the distance between each layer is 0.05, and 0.01 on the right).

That's basically it. If you want to see more details, here the github repo (āš ļøBe careful it's a jam game it's pretty fragileāš ļø): https://github.com/Jul1nk/School-Days-2

- Performances, performances...

Right now, each object has its own CanvasLayers. With dozens of objects per scene, the CanvasLayers count quickly go above hundreds, which causes performance loss. I didn't have time to optimize this system for the jam version, but I'll sure go deeper for the full release (which should appear in a few weeks). I could maybe merge together every CanvasLayer which have the same scale factor, so I'll only have 20 or so CanvasLayers. However, this could prevent something interesting. You could, for example, want to apply a certain effect only on some objects. For instance, you could make the wall moves (like an hallucination or something). But if you merge the layers together, every object will then be affected by this effect. So that's why I'm not totally sure how I'll tackle this problem. Maybe I could make "families" of layers (walls / objects, etc) but still merge the layers inside of these families. Even with that, I don't know for sure if the performance will boost after that, as I didn't have time to test it out. We'll see.


The fog shader

I just wanted to talk a little bit about the fog shader. All it does is taking a seamless noise texture, moving it, and scanning for every pixel on the screen. If a pixel is really close to being black, it replaces it with the noise texture. I really like how it turned yout, especially on the wooden floor, since some pixels are darker, they are affected by the shader and I really like this effect.


The end

Thank you for reading this devlog. If you did, wow, you're an amazing person! I hope it interested you and I hope I was clear. School Days 2 will hopefully be getting a "full-release" in a few weeks (for free). I love this project so much, it has to be my favorite game I've ever made (including personal projects: maybe not the longest, the coolest or whatever, but I really like this art-style and I think it has a lot of potential).

If you have time, please leave a review or a comment to the game, I would love that!

Here's the link to the github again if you're interested: https://github.com/Jul1nk/School-Days-2

Files

School Days 2 Jam Version.zip 62 MB
63 days ago

Get School Days 2

Comments

Log in with itch.io to leave a comment.

Very nice writeup.

For lightning, did you use Light2D nodes and just the flashlight to apply to all the canvas layers? Also, do you have any ideas for shadow casting, like with the desks or objects that arenā€™t world bound? I actually didnā€™t notice their absences until I thought to look for it when thinking about how you did you light.

Hi thank you so much for reading through!

The player has 2 Light2D nodes: one for ambiant (the big circle) and the flashlight. Both have a texture I made and I believe Light2D nodes automatically affect everything in the scene (there is an occlusion mask, pretty much like there is a physics collision mask, but I only used the first bit for everything, so everything in the scene is affected).

For shadows, Tilemap (the walls) have an automatic system to attribute an occlusion. I also added the possibility for objects to have a shadow (in which case the occluder goes on top of the object). I only used it on doors for the moment though. Maybe I could have an occluder on the floor for objects like tables or chairs which shouldn't  fully block the player's view (unlike doors). However I think this shadow should be a little bit transparent (like the shadows I already drew for some objects (see the chair sprite)). I don't know if this is possible though, I'll have to check it out. Also a lot of people think that the bookshelves should cast a shadow, and I totally  agree with that. But the system I currently have put the occluder directly on top of the object, so you wouldn't see the books if I did that.

So yeah I'll definitely work on this system in the future. Hope that helps!