A Kiss for the Petals: The New Generation! Programmer’s Corner

Today, we have a programmer’s corner from Craig Donson!

Greetings. This is Craig Donson, and I hope you enjoyed the demo for A Kiss For The Petals – The New Generation!

Before I continue, I would like to once again thank the audience of MangaGamer’s Otakon 2016 panel, where I had the privilege to personally introduce The New Generation in its formal announcement. I actually learned that I would be speaking when I met with MangaGamer personnel on the show floor the day before. I spoke as a panelist for the first time since 2013 with less than 24 hours to prepare my remarks, and the attendees were very gracious for my portion and the questions and answers that closed the panel. I look forward to the next opportunity to share A Kiss For The Petals face-to-face with a convention audience.

image1

As you’ve surely noticed, there are some changes in this title compared to Remembering How We Met and the screenshots I’ve been posting on Twitter for the last few months, not least of which is the HD resolution. This was made possible by a combination of factors that I will recount in the latter half of this post. First, I will discuss the underlying enhancements compared to my 2015 debut as a MangaGamer programmer.

Background

To summarize my previous Programmer’s Corner, most visual novels in this series use an engine probably known as MScripter, a dated engine with many bugs unsuitable for English releases. Even today, I still know very little about MScripter. I cannot find any public information about its authors, its age, or even its actual name. One year before we came to MangaGamer, my co-programmer Procyon and I started a project to port the visual novels to Ren’Py, a popular open-source engine that supports all major computer platforms, and we were employed to complete our work.

image2

We were provided only source code for the main novel portion with no documentation or an SDK. The engine uses Assembly language, but the vast majority of the source code uses a large number of macros for which we have no definitions. With much of the engine’s workings obscured, reimplementing any of the code directly was not an option. Though these titles are relatively simple in presentation, the lack of documentation makes porting several aspects challenging—see the section on eyecatches at the end of my previous post for a particularly extreme example.

The process of porting the engine involved running the retail build and writing Ren’Py code to imitate the behavior. Procyon wrote a set of Bash scripts to convert the original novel code into Ren’Py script based on our findings, and I wrote all other parts of the program alone. Our work on The New Generation was largely an expansion of our port of Remembering How We Met. We spent much of the year improving and optimizing our code, updating the Bash script to match changes in the MScripter code since Remembering How We Met, and adding engine features not used previously: three on-screen characters and multiple routes. The latter was a simple matter of adding branch menus, label jumps, and flags that lead toward or away from the “bad endings” to match the original source code, but showing three characters introduces a new issue when character graphics can overlap.

Three’s a Crowd

MScripter uses macros named “CHAR1”, “CHAR2”, and “CHAR3” that draw up to three images at once at fixed positions. These macros are called for every image change, even when some of the images would be the same. Dialogue is handled with individual macros for every character: “TEXT00” for Hazuki, “TEXT01” for Manami, etc. These macros write text to the screen, play a voice file, and place any images associated with the character in front. A separate macro is used for narration and secondary characters without any images.

In Ren’Py, all of these are done one step per line. Images are called one at a time and are drawn from back to front in the order they are called in the script. Text and voice playback are done with separate commands. Character images are organized with tags, such that an image with a given tag (such as “hazuki” or “aya”) can be replaced by calling another with the same tag, retaining the previous image’s properties (such as their location on the screen) unless they are explicitly redefined. The issue is that image priority per tag is also retained.

For example, this block of MScripter code (comments inserted by me):

# CHAR3 = Place three character images on screen.
CHAR3    "tha02s","tay03s","tai02s"

# TEXT02 = Aya dialogue
TEXT02    "AYA_0160","「……葉月? 何、笑ってるの?」"
# TEXT00 = Hazuki dialogue
TEXT00   "HADUKI0369","「べっつにぃ?」"

Was converted into this Ren’Py code and produces the following screenshots:

# l3 and r3 are manually defined positions for three characters.
show hazuki tha02s at l3
show aya tay03s at center
show ai tai02s at r3

voice "AYA___0160"
aya "Hazuki...?  What're you smiling at?"

voice "HADUKI0369"
hazuki "Noooothing..."

image3

image4

It is subtle, but Hazuki’s sprite on the left remains behind Aya’s during her line, which is not the correct behavior. The image priority must be changed manually in Ren’Py, and our Bash script naively called three images from left to right per the original code without changing priorities. It did not account for the macros changing image priorities as this was not an issue with two characters, resulting in some cases where a character on the left or in the center appears to speak from behind other characters to the right. It is possible that character images are defined internally in a different source file we were not given access to, and the TEXT macros access this list to redraw any matching images on front.

In order to solve this problem with the Bash script, we repeat the image statements before every line of dialogue in scenes with three characters where the speaker changes, even when they would call the same images, so the Bash script can change image properties as necessary. We did this by adding the “behind” property to adjacent characters who were not speaking.

show hazuki tha02s behind aya
show aya tay03s
show ai tai02s behind aya

voice "AYA___0160"
aya "Hazuki...? What're you smiling at?"
show hazuki tha02s
show aya tay03s behind hazuki
show ai tai02s

voice "HADUKI0369"
hazuki "Noooothing..."

image5

This method guarantees the image priorities are correct at the cost of duplicate show statements. The Bash script is unable to read ahead for voice commands and safely remove redundant lines. Regardless, this keeps the code easy to read without any visible performance impact. Another approach I considered was to write a custom Python function equivalent to the MScripter CHAR macros with added arguments to manually select images to move to the back, but at the time this issue was discovered, we opted to keep the implementation simplistic for this project.

These screenshots show only a minor example, and indeed, it may be difficult to appreciate such a minor presentational fix, but even greater overlaps would present in other titles. As with Remembering How We Met, whether we can apply this on other titles will depend on your support…

New Features for The New Generation

I began working with MangaGamer in 2015, and since then, I familiarized myself with their catalog more quickly than I would have otherwise. In the pursuit of improving the experience for the fans, I took the liberty of adding more new features inspired by other titles published by MangaGamer, all to celebrate the freedom from the limitations of MScripter.

A Kiss For The Petals is perhaps best known for its yuri sexual content, and as the first title in the series with erotic scenes to be published by MangaGamer, Western fans should be able to enjoy them to their fullest. I took inspiration from the most unlikely of sources, Clockup, and added a “Climax Timer” that, in technical terms, visually counts down a specific CG change and voiced line. In casual terms, it aids in timing your own actions to those of the girls.

image6

Two timer styles are available: a numerical counter and a graphical counter as a line of dots. It can optionally be configured not to appear until 5, 10, or 25 lines before the climax. The timer is displayed in yellow for the final position in a love scene to help prevent the reader from acting too early. As a side note, the Climax Timer is not enabled by default, so you can decide for yourself if it is necessary or appropriate.

You may recall from my previous Programmer’s Corner that I added the ability to hide and show the text box. You may also recall a certain line from that post: “This is intended to maximize the view of the CGs, and I predict this function will get more use in later releases, should we have the opportunity to produce them.”

image7

For The New Generation, I enhanced this feature with full control over the opacity, rather than a toggle. The text outline that appears in Remembering How We Met when the text box is disabled is now optional. You can change between the normal shadow and the thick outline at any time to adjust readability as you see fit.

Related to the above, when a CG is shown, the text is paused until the user clicks, similar to Liarsoft titles. This feature is optional, and there are also options to automatically resume the text after a short delay when the auto-advance switch is enabled.

As with Remembering How We Met, an issue I encountered in porting The New Generation resulted in a new Ren’Py feature for other developers. The voice files given to us had very little trailing silence. This caused some lines to play too quickly one after another when the text is being automatically advanced, which I felt made for poor flow in dramatic scenes. After a request for an adjustable delay for voiced lines, Ren’Py 6.99.11 added the “config.afm_voice_delay” variable. Small adjustments to this variable can create vast improvements in many scenes, which is preferable to re-encoding thousands of files with an added silence. (For the record, the value used in The New Generation is 0.21.) Once again, I’d like to thank PyTom for his assistance.

Finally, I added a few minor features for convenience:

  • In the original version, the secondary routes are only available after completing the main route, and the reader is required to advance the story to the end of the common route to choose another. In our version, starting a new game after finishing the main route allows you to choose a new route immediately.
  • Previously selected choices in branches are dimmed.
  • Translated lyrics are available for the opening and ending themes in the Extra menu, also inspired by a certain Liarsoft visual novel.

Starting Over

I strive to create a product that presents A Kiss For The Petals as best as possible and improve upon the original work wherever it is reasonable. (I even created the English logo myself, to ensure it can be used in the opening video.) This is only possible with the help of other dedicated individuals who carry on the tasks I cannot handle myself. Yet, I take this task with such devotion that one small fix I made in an earlier product compelled me to redo nearly all of my work on The New Generation after we had completed it. The remainder of this post will be a story about how under the right circumstances, tinkering with a long-completed project can have much greater consequences on another.

image8

Earlier this year, a relative bought an iMac with a 21.5” Retina 4K display. Last month, I decided to test Remembering How We Met on it out of curiosity and discovered a serious flaw: the heart character, a small graphic used frequently in the text, scales very poorly at high resolutions. Japanese character sets lack a native heart character, so Japanese visual novels often use graphics for extra characters like the heart and embed them in the text. MScripter uses a simple control code, 100, to represent the graphic containing the heart. For Ren’Py, I copied this graphic, edited it to match the height of our font, and inserted it with the {image} text tag.

image9

For legibility, Ren’Py automatically increases its window size when used with high-DPI displays such as Retina since version 6.99.6, the version used by the initial release of Remembering How We Met. Text is rendered sharply at any resolution, but graphics are upscaled. At the time of the initial release, I did not have access to such a display, so I did not anticipate that uneven scaling would be an issue. With the increasing prevalence of above-HD displays, such a highly visible blemish is not acceptable. Though we never received any bug reports on it, I took it upon myself to correct this by creating a new heart from scratch as a font glyph by tracing the 24 x 24 px image and inserting it with a font editor.

image10

image11

The fruit of nearly an hour of tracing and testing was released as an update on 20 October 2016 as a “critical fix.” I originally planned on deferring it until Ren’Py 6.99.12, which would deliver a permanent fix for issues with macOS, but I came to a realization that left me unsatisfied: The target resolution for A Kiss For The Petals, and presumably other MScripter visual novels, is 800 x 600—one-twentieth of the iMac’s 4096 x 2304 native resolution. It may have been common when the series started in 2006, but this is true even for the most recent releases. I do not have data on how many users played Remembering How We Met at a resolution greater than its native 800 x 600 or how many of them used Retina displays, but the fact remains that MScripter, to my knowledge, supports only that single resolution.

When we began work on The New Generation, I was given access to the Photoshop source files for all of the artwork so that I could produce uncensored CGs optimized for our project. (This was not the case with Remembering How We Met, where only optimization was necessary.) The artwork is created at a resolution of 1600 x 1200 and downsampled to half that size for the final product. I did the same for our version early in development. However, after replacing the heart character, I got the idea to bypass the downsampling of the artwork and present it at its original size. While there is justification for producing the artwork at a 4:3 aspect ratio, I saw no reason to keep the artwork at a mere 800 x 600 resolution when I had superior copies at my disposal. I asked for consent to increase the resolution to that of the source artwork, and some time later, I received approval from St. Michael Girls’ School. The New Generation would now be a rare HD-remastered yuri visual novel.

image12

(Click to enlarge)

To support the increased resolution, my task would be to reprocess all of the artwork from the source files, rewrite nearly all of my user interface code (imported from Remembering How We Met but now out of date), produce new menu graphics for the rewritten code, and optimize the new images. This would be a very time-consuming and tedious, yet doable, process with undeniable benefit.

However, it was greatly complicated by the timeframe of the approval. I made the request before beta testing on our first version had started, and I got the word of the decision well after it had ended. Development had already wrapped up and the release date finalized. We had produced a complete version of The New Generation in 800 x 600 ready for release, but my ambition rendered it moot.

Nearly 600 image files and 1,000 lines of code had to be recreated in a very limited amount of time, and I would have to do it alone. It also necessitated a second round of beta testing, which returned more fixes needed, all under severe time restrictions with no prospect of a delay. The optimization for the image data alone took over 24 consecutive hours of CPU activity. The amount of work was great enough that my performance at my day job suffered for a time. I imposed a dangerous amount of extra work upon myself due to a single tiny graphic in a visual novel released last year.

image13

Anzu Hana once called me a maniac, so this image is rather apropos.

If my relative had bought the iMac earlier in the year, perhaps I could have avoided this incredible level of stress.

But again, what motivated me is how the fans would accept this modernization. I strongly believe the enhanced presentation will be worth the effort. Indeed, I had been posting 800 x 600 screenshots on Twitter and Tumblr in the months leading up to release and I cannot help but to look back on them with pity. For the majority of users, the artwork will be downscaled slightly on 1080p displays, resulting in a sharper picture. Those with 1440p or larger displays will certainly appreciate the lesser upscaling necessary to fill the screen. It is my hope that the fans will make the most of this upgrade.

Conclusion

When Procyon and I started on the Ren’Py port two years ago, we did it with the intention of bringing A Kiss For The Petals to fans worldwide in a future-facing engine. As much as we loved the content, it was restrained by an archaic, mysterious engine that frustrated efforts in sharing it with the West. By the end of this year, we have succeeded in taking A Kiss For The Petals to the future in more ways than even we expected with only the second English release. St. Michael Girls’ School is committed to making A Kiss For The Petals a success in the West, as evidenced by their support of this HD remaster. With your support, we will hopefully have the honor of producing many more. In closing, I leave you with the theme of A Kiss For The Petals:

image14

Welcome to The New Generation!

Bookmark the permalink.

9 Comments

  1. Hoping we manage to get the entire series. (Although unless you bundle them I’d feel a bit uncertain about paying too much for the old short ones)

  2. It’s always great to read about your work on these!

    And as blogmorph above, I too do hope we could one day enjoy official releases of the whole series. And it would certainly be great to see this one as a proper hard copy as well.

    • Ah, another thing, though – if I hadn’t randomly stumbled on the information about the updated heart character on the game’s Steam page, I would completely have missed the news and the update. Apparently this was never mentioned here on the blog before this post.

  3. Otsukaresama, Mr. Donson. I don’t normally buy English translated eroge but reading about your efforts made me want to buy New Generation to check out the improvements you’ve made. I’ve played eroge with 1080p art and it really improves one’s enjoyment of the game so I hope your efforts are considerably rewarded.

  4. I love when people spend extra time on the little things. Since that’s how you can tell the difference between a good product and a great product.

    Although I also appreciate it when people talk about game code.

  5. Thanks for your hard work, I will do my part and buy every Sono hana game.
    I hope in future games you can add the “feature” sometimes called “hardware fullscreen”, so the users don’t have to manually change their desktop res to avoid the blurry upscaled images.

  6. You could add an Android version if you port it to Ren’Py.

    • By it and you will see this:
      “Download #1 is the Windows release. Download #2 is the Mac release. Download #3 is the Linux release.”

  7. Thank you very much for all of your work on this. I’ve purchased both Kiss for the Petals games and I’ll purchase any future ones as well. I hope you get a chance to release more through MangaGamer. The new features I am most excited about are the higher resolution art, the translated lyrics, and the easier access to the secondary routes.

Leave a Reply