Handling Variables In Ren’Py

I’m currently working on a Ren’Py game with a couple of other people and we’re not quite ready to post about it publicly yet, but I wanted to share some notes on handling variables between states and sessions as its caught me up a little bit!

Supporting Rollback and Save States

I’ve got a couple of classes that handle things like information about the main character and your current relationship with romancable characters. I was setting these up in the init, but it turns out that init variables do not participate in save states or rollback as they are often used for things like the ui.

The solution is to do variable initialisation in a callable label and then run this at start and load time. The hasattr function is used to check if the variable exists, with renpy.store containing every declared variable in the project.

label _init_variables:
    python:
         if not hasattr(renpy.store, 'mc') : mc = MainCharacter()
    return

The call in new context function creates a new context where rollback is disabled and save/load still happens in the top level context.

label start:
    $ renpy.call_in_new_context("_init_variables")

label after_load:
    $ renpy.call_in_new_context("_init_variables")
    return

Persistent Data

We wanted to have a list of achievements and ending so the player knows how many endings they’ve found. While ren’py does have a built in achievements system, this seems mostly for passing backend data to services like stream.

Instead, I used persistent variables. Adding ‘persistent.’ to a variable name saves it in persistent data, which remains the same between sessions.

$if persistent.achievements_list is None:persistent.achievements_list = []

I can then just add to this list when a player gets an achievement.

$ persistent.achievements_list.append("Started The Game")

Capture

Forcing Updates During Runtime

Variables are only checked when changed within the correct scope, which means that a class taking in a variable will only get the value at the point the class instance is created.
This feels hacky, but the accepted solution by the community seems to be to put all the variables that need to be constantly passed around into a screen, as it is forced to updated every frame.

 show screen update_vars()
screen update_vars():
    $ naal.good_value = naal.good_value
    $ naal.other_value = naal.other_value
    $ naal.bad_value = naal.bad_value
    $ sal.good_value = sal.good_value
    $ sal.other_value = sal.other_value
    $ sal.bad_value = sal.bad_value

Floating World Shader Part 5 – Ocean Material

This is the last part of the breakdown of my shaders based on work by Owakita. This will probably be the biggest one of all as we tackle the gersner wave ocean material.

I’ve written a number of posts breaking this down, and these can be found here:

Part 1 – Initial Plans
Part 2 – Sky Material
Part 3 – Post Processing Material
Part 4 – Gradient Fresnel Material

Gersner Wave Function

The gersner wave function was made based on this video from the Dreams team. Its a fantastic watch, so I’m just going to pop this here in lieu of going through the graph.

The main change that I had to do to get this into unreal was to replace the loop with repeating the wave function over and over, which causes node spaghetti and makes the system far less flexible.

0e39026e32a4895225f348cebd4f1564

blog15

The bitshifting for the psudo random number had to be done in a custom hlsl node, as there is no other way to convert to int and to bitshift.

blog16

I also did the final calculation in a custom node, as it was simpler to read than trying to drag the pins from each variable in. Honestly, its still a mess. I was really missing just writing hlsl at this stage.

blog17

Normals and Light Stylisation

I had some issues with normals appearing incorrect, which was eventually was down to some dodgy order of operations and some calculations being done in meters when they should have been in centimeters. Caught out by a couple things when trying to move between code and nodes.

ezgif-2-858790595a9f

I rounded the normal in order to give a hard edged, toon look to the shader.

9b478778c7b354907dabc39204061d26

Texturing

blog19

To create the smooth line pattern seen in the concept, I created a tiling texture in photoshop with outline on R and color variation on G.

I used the same smoothstep trick as with the gradient to have a color assigned to black, white and midgrey.

blog22

12ca3f35f65b888b285a05037ed23262

To add the outline, I took the black outline on the R channel of the texture and added the outline color to it. I then multiplied this with the lerped color.

blog24

Foam

In order to make the foam appear on top of the waves, I got the dot product of the surface normal and a vector parameter. This vector was used to control the angle of the foam. This was them multiplied with a noise texture to provide the breakup effect and rounded to keep the toon feel.

blog27

blog26

The outline on the foam was created by taking the above and creating an inverted version of it, with a slightly smaller wave. This multiplied by the original created an outline. This then hooked into the texture outline to receive the same color.

blog29

466716526a04d45f0c8e1df1d9eed190

blog28

All together, we get a nice breakup wave effect.

ezgif-2-282099dc540d

Final Shader

Combine all of this and you get the ocean shader from the original gif!

okiawaGif

Floating World Shader Part 4 – Gradient Fresnel Material

Here’s part four of the breakdown of my shaders based on work by Owakita. This is going to cover the gradient material found on the meshes in the scene.

I’ve written a number of posts breaking this down, and these can be found here:

Part 1 – Initial Plans
Part 2 – Sky Material
Part 3 – Post Processing Material
Part 5 – Ocean Material

Object Space Gradient

I wanted the gradient to run vertically across the object, unaffected by the position of the object in world. I didn’t want to adjust my UV map in order to accommodate this, so decided to do my gradient in object space Z. (Unreal is Z up)

blog12

I used the ObjectLocalBounds node to get the top and bottom of the object bounds in Z (though I did include a mask parameter so the gradient could be used in other directions), then used a smoothstep to produce a 0 – 1 value between the two.

Three Part Gradient

The reference image actually has three colors in its gradient, and I wanted to get as close as possible. To do this, I had to lerp twice, breaking the initial 0 – 1 coming from my object bounds into two parts.

To do this, I smoothstepped between 0 and 0.5, to map the bottom half of the value range to 0 – 1, then smoothstepped between 0.5 and 1 to do the same to the top half. I then used the first value to lerp between two colors, and the second to lerp between the previous lerp and the third color.

blog11

Fresnel

The fresnel effect is very simple, literally just using the fresnel node to lerp between an edge color and the main gradient. This was used to provide the edge highlighting seen in the reference.

1

For context, the fresnel node does a dot product between the input normal (in this case either a normal map converted to world space or the the world space normal of the pixel) and the camera position to determine whether the surface is facing the camera. Facing returns 0, facing away returns 1, so we can use this to assign a color to faces at grazing angles.

blog13

Rock Variation

The rocks also use this shader, but forego the gradient and have a normal map input to the fresnel, as well as a very high fresnel amount, giving a shadowed, two tone look.

blog14

 

 

Floating World Shader Part 3 – Post Processing

Today I’m continuing the breakdown of my shaders based on work by Owakita. Here’s part three!

I’ve written a number of posts breaking this down, and these can be found here:

Part 1 – Initial Plans
Part 2 – Sky Material
Part 4 – Gradient Fresnel Material
Part 5 – Ocean Material

Post Process Material

The aim of the post process was to create an outline around the objects, provide a grainy look and tint the screen color.

okiawaGif

Different Approaches

There were two approaches I considered for this. One was the kernel based edge detection I used on a project a couple years back, and another was the simpler sampling depth offset technique found in the UE4 stylised rendering example.

Ultimately I went for Epic’s approach, as while it may have been slightly more expensive for the amount of times it sampled depth, it was far simpler to setup and read later down the line. For this project I was really focused on the aesthetic over performance or tech, but I do still like to consider these things.

Determining Line Width

I started off by creating a single line on one side, by by getting the screen uv and offsetting it. I then multiplied this by screen texel size so the offset appears to be the same width, regardless of screen resolution.

width
Node graph for offset UV. 

Subtracting one channel of this value from the scene depth will give a single line edge, but we want an edge on all sides!

blog5
Scene with an outline on a single side.

Creating An Outline On All Sides

I then split this offset into its U and V parts and multiply each by minus one, leaving us with four sets of offset UVs, as seen in the image below. These are then used to sample scene depth, which creates four different samples of the depth, all with a slight offset in one direction.

explaination
Diagram showing how depth sampled with offset UV’s combine to create an outline.

Subtracting these from the initial scene depth then adding them together leaves us with a nice combined outline!

Sample Depths
Node graph for combing offset UV samples.
blog6
The scene with an exaggerated outline.

Depth Based Line and Wireframe Fix

With this approach, we start to get the internal wireframe being outlined at distance. As a fix, we take the scene depth, divide it, then take one minus this (as UE4’s depth is flipped) then clamp it. This is the multiplied with the outline. This lowers the outline amount for these faces.

blog9

Capture

I later added something very similar to the initial outline calculation, where this was multiplied with the result of the texel size multiplier. What this did was take the depth and as the object gets further away, reduces the size of the line. This allowed me to not lose detail at distance and stopped blobby looking outlines.

blog8

Putting It All Together

One this outline is created, it is used as the alpha to lerp between the line color and the scene color. Here I’ve multiplied the scene color with a texture and color to add a bit of grain and color tinting.

color
Node graph for the combined result.

Final Result

result
Sphere showing the final result of the material.
options
Exposed parameters for the material.
blog7
Final result in the scene. 

Floating World Shader Part 2 – Sky Material

As talked about in my last post, I’ve been working on some shaders based on work by Owakita. Here’s part two of the breakdown!

I’ve written a number of posts breaking this down, and these can be found here:

Part 1 – Initial Plans
Part 3 – Post Processing Material
Part 4 – Gradient Fresnel Material
Part 5 – Ocean Material

Sky Material

9a1e8e847636d86ea7737b20299d1077

The sky material for this project was pretty simple, as I made a copy of the base sky material found in the construction script of BP_Sky_Sphere, and replaced that reference with the copy.

blog1
BP_Sky_Sphere Construction Script

Inside of that copy, I replaced the scrolling clouds texture with my moon, and the stars with my stars. I also added an additional cloud speed parameter so that I could control the speed of the stars and moon separately, for a nice parallax effect.

blog2
Texture samples that need changed in M_Sky.

The most challenging part here was creating the moon texture. As it has such a large area to cover and is projected over a sphere, I had to get the moon shape in the correct area of the texture and bend it appropriately so that it looked correct on the sky sphere mesh. I got there after a lot of trial, error and free transform!

blog3
The star and moon textures I created. 

For the colors, I left the material as is but overrode the light based colouring in the details menu. I then tweaked zenith and horizon color until I got close to the reference image.

blog4
Tickbox for turning off sun position based color and color controls.

That’s all there was to it for the skybox! Next post will look at the post processing effect.

Floating World Shader Part 1 – Initial Plans

Over the bank holiday I worked on a number of shaders in UE4 based on work by Owakita. I love her dreamy, pastel aesthetic and wanted to try it for myself.

I’ve written a number of posts breaking this down, and these can be found here:

Part 2 – Sky Material
Part 3 – Post Processing Material
Part 4 – Gradient Fresnel Material
Part 5 – Ocean Material

okiawaGif
The finished product!
comparison
Comparison between Owakita’s original work and my recreation of it.

Reference Breakdown

Initially looking at the work, I broke my project down into a post process, gradient and gersner ocean material. In future blog posts I’ll be covering how I did each of these stages!

Untitled-1

At this point I listed some features I thought each shader should have, but this did change a fair bit over the course of development.

Nanoreno Week 4 – Finished!

I’ve officially completed NaNoRenO2020! Its a really good feeling since I’m pretty terrible at finishing game projects normally!

You can play the game at https://amesyflo.itch.io/dream-dilemma.

Proofreading

Most of this last week was dedicated to proofreading. This should have been the easiest part of the project really, but having my full dialog script inside of my game code made it quite tough. Spellcheck picked up on a lot of things it shouldn’t and it wasn’t super easy to write in flow when there’s game code dotted about.

It made me think about writing a tool to parse dialog from a text document/spreadsheet  into .rpy files. At the very least I think next project I want to think about a file structure that allows me to keep game code and dialog separate.

Overall Experience

Overall this game jam was a great experience – I finally finished a game! Its led me to have a bunch more VN ideas, so expect to see more of that in the future. First though…I have a shader I want to write…

 

 

NaNoReno Weeks 2 and 3

I’ve now finished the first draft of the game (which now has a name!), including all art, sound and UI and am now in the process of proofreading and redrafting the script, fixing bugs and if I have time polishing art and audio.

ETuHd7zWsAos1UI

Progress and Cutting Features

In order to get here I significantly cut what I wanted to do with the second act.

Originally, it was going to have a deductive reasoning section where you figured out the riddle in multiple stages, alongside an emotional conversation about the origin and nature of the dreams to potentially open up the second ending. I cut the deductive reasoning section as it involved the most design work and potentially more artwork and kept the emotional section.

While detective kind of puzzles are totally my jam, it seemed the most logical thing to cut as it only fed into a potential death ending. If I somehow have more time at the end of the jam I might resurrect it.

lake

Time

I did most of the last two week work on the Saturdays, as we’ve been really busy with the house. The situation right now has meant we had to try and get everything up and running in our new house as fast as possible, since we’re stuck here. The general anxiety surrounding corona has really not helped my productivity.

This did help me figure out that when all assets have been sourced it takes me about an hour to write a single scene. With each act having around five scenes, it means I’m not too bad for time if I can find a a free weekend afternoon or manage an hour before work each weekday.

lake2

Asset Naming Conventions

One thing I noticed that would help speed up/clarify the writing process is better naming conventions for character sprites. I used descriptive names in a common format like I would at work, but I realised that what I needed was not a description of the character and their expression, but for the name to be the exact emotion the character is displaying, so I can easily drop it in while writing. “Elieen_Sad” is actually much more useful than “Character_Elieen_1024_NormalEyes_PoutMouth”. The second name is a bit of an exaggeration, but its not far off names in most places I’ve worked, where we have so many assets that we need to be that precise.

I seem to be throwing all conventions out the window with this project!

lake3

Character Sprites

On the topic of sprites and expressions, i seem to have settled on an expression change every two lines being about the correct amount for making things feel alive, while not being too distracting.

shrine1

UI Changes

While I’ve not done anything major with the UI, I thought it was worth noting some of the lines to change for text, as most of the documentation is outdated and styles are split between options, gui and screens .rpy, making them not always easy to find.

Main Menu

Main Menu Overlay Image = line 392 in Screens.rpy

Main Menu Background Image = line 88 in gui.rpy

Main Menu Font Color = line 29 in gui.rpy

Main Menu Hover Color = line 36 in guy,rpy

Main Menu Music = line 63 in options.rpy

Choices and Dialog

Choice Menu Text Color = line 212 in gui.rpy

Dialog Text Color = line 51 in gui.rpy

 

 

NaNoReno Week 1

I’m taking part in NaNoReno, a visual novel game jam running through March, inspired by national novel writing month. The aim is to make a complete vn in a month.

The game I’m working on is, for now, called ‘Dream Boy’. A rumour is going around town that many people are having the same dream – one where you have to answer a riddle which will reveal the location where you’ll meet your soulmate. Unfortunately, our protagonist finds that these dream riddles are far more sinister, and must solve them, or face a devastating future.

Image
Art by Konett and RuneRacoon

I wanted to talk a bit about my production methodology for this project – this is, basically none at all – as I’ve been incredibly motivated and got far further with this in a week than I have with other full game projects in much longer time frames.

‘Pantsing’ aka ‘I Am Banned From Trello ‘

I’ve approached this project very different to others, in that I’ve effectively planned nothing. I am by nature a planner and am always thinking about two steps ahead of where I’m at, which is great for my day job as a tech artist, but isn’t helpful for doing small solo projects.

Seeing how much needs to be done is completely paralysing and demoralising. For this project, instead of focusing on what needs done, I’m focusing on the deadline, and getting what I can done before then.

I did a tiny half an hour of planning on day one, where I decided on the general theme and scope. Here I decided that the game would be about riddles in dreams and that my minimum working hours for the month was 16, so I had to stick to something small, with no mechanics that aren’t built into ren’py and that doesn’t require any new art or sound – it all had to be bought or downloaded.

Image
Art by Konett and RuneRacoon

So far I’ve worked completely linearly, where I normally jump about and work on whatever I feel like that day. This has kept me motivated, as there’s parts I want to get to, but also got rid of time spent deciding what to work on, and doesn’t leave anything half-done, which is another demotivator.

I’m also avoiding writing down any random ideas I have for sections I’m not currently working on. If its a good idea, it will come back to me. This is very against my nature but working so far!

Once I’d naturally hit my first branching choice, I did a very small diagram for the story branching. It was incredibly simple, and added deaths and two different true endings. Using death as an ending kept scope small, and the different true endings, while based on a variable that is changed based on main branch choices, doesn’t branch itself until very near the end. I don’t intend to do any further planning.

Using Premade Assets

Art is one of the most time consuming and contentious part of development. Because my background is art based, I tend to be a lot more precious over this part of the game which slows my pace.

I also hate seeing placeholder art, because I get frustrated at it not looking good. Having full art in has made me excited to see my game everyday, which is so great!

To make this simple, I chose three artists with a wide library of assets for sale or download, and every time I need something I grab it from one of them. The second I see something I like, I just grab it, and don’t look through everything and deliberate. Usually I’d be totally against this, but treating this as a prototype and not being worried about getting things totally right has really sped things along.

I’ve done the same thing with audio, finding one site that has collections of music and using the first thing I find on there that fits.

I’ve made some edits to art and audio, but nothing that takes more than an hour.

Image
Edited art by Konett and RuneRacoon

No Complex Code

As mentioned in planning, I’m not using any gameplay that doesn’t come built into ren’py, so don’t need to allocate time for code. On previous projects I’ve tried copying and altering systems from games I like, which while very interesting, tends to push the scope of the project closer to those games, which I obviously can’t do alone.

Not adding functionality also means less debugging, so I can focus on just getting the game done.

Simple Puzzles

I’ve also not spent too long on my puzzle design. They’re very simple, and could be worked out without any assistance from the game. This is probably something I’d completely re-do if taking the game beyond the jam, as if the puzzles aren’t fun I don’t have a game.

Image
Art by Konett and RuneRacoon

Do Something Every Day

Another of the major motivators here is that I’ve worked on it everyday. I’ve been getting up a little earlier and getting in around an hour’s work each morning, so even if things get unexpectedly busy in the evening I’ve still made progress.

The do something everyday rule is often talked about, but can be hard with projects where you have tools or levels that take a long time to load up. Thankfully, the time to start on ren’py is very low, just fire up atom and go. There’s no loading time for testing the game either, which is one of my pet hates!

Useful Blender Things

I’m between 3DS Max licenses at the moment, so it seemed a good opportunity to try and learn blender! This has been so frustrating, but hopefully worth it to learn what is becoming more and more of an industry standard.

This is just a dump of some of the shortcuts and tools I’ve used so far so I can come back to it! Will probably just add to this post as I go.

Shortcuts

Ctrl-B – Bevel

Ctrl-R – Edge Loop

S-X/Y/Z – Scale in x, y, or z axis

R-X/Y/Z – Rotate in x, y, or z axis

Tab – Go between edit and object modes

A – Select All

Shift-A – Creation Menu

Object Mode – Ctrl A – Rotation and Scale – Freezes all transform data

Tools

Modifier Menu – Mirror

Edit Mode – Mesh – Normals – Flip

Edit Mode – Mesh – Normals – Recalculate Outside

Edit Mode – Mesh – Normals – Average – Custom Normal (Good quick smoothing results)

Gotchas

Negative scale will flip normals randomly, freeze scale then recalculate outside.