If your audience is furry and gay, you can consider linking my Bluesky (https://bsky.app/profile/wattson.bsky.social). But if you don't think ppl would want to see how much I repost on there, you can just say Wattson or use my name in the files, depending on what works best for you.
Wattson
Creator of
Recent community posts
Sorry for being slow on the reply. If you still need help with this, I managed to fix this by changing the "none_to_float" function around line 173 to
def none_to_float(param): if param is None: return 0.0 if isinstance(param, position): return param.relative return param
Think that should help make it not crash anymore.
I should be upfront that I am friends with many of the developers, and some of my code is used in the game, though I had little to no direct involvement. So to be fair, I will mention any problems I have, even if nitpicky.
That said, this is still one of the best quality VNs I've played in a while. A full course meal in a very digestible size. There is room to expand, but for a game made in a month, I'm happy with it, leaving me wanting more. The level of polish of what it there more than makes up for any shortcomings.
The story is a fun murder mystery with a cast I would consider large for the limitations. Twelve speaking characters is a lot to flesh out in a 2-3 hour story while weaving in clues and hints. I might critique that it would be nice to get more from some of the characters, but it likely would have made it harder to keep track of all the elements within the limitations. Though the main cast of the living feel well developed enough to carry it, and the number of characters makes it a good popcorn read with friends. The path to the true ending has one complication that I feel could be smoothed out, but the steps to it are not difficult to reach otherwise. The balance of comedy and horror walks a fine line, having dark subject matter kept digestible with a deft attention to the tone. Characters who have done awful things are fun to watch bounce off Maxwell, who keeps a level head through it all.
All of the visuals are fantastic. Each sprite feels unique and has plenty of fun expressions to elevate their lines. Backgrounds are high quality, though the storage room and attic bg are a bit too similar imo. Also feels like maybe one or two more CGs were desired but likely were cut, though I'm glad the CGs that are there leave great impact and were worth prioritizing. The UI is very clear with plenty of style and polish. I'm especially impressed that the textbox manages to make lines bordering on a paragraph feel readable, even though lines that long are rare (which is a good thing).
All of the music is fantastic and perfectly fits the mood. The inclusion of a fully original soundtrack really elevates each scene. The sound design is also deserving of praise, with meaty thuds and every step appropriate to the room. Sorry, I'm not very articulate with sound stuff, but all of it is a cut above even VNs made with more time and budget.
I'm not sure why a game jam would have a voice acting category. The inclusion of sounds for the text appearing though is always fitting, and I will consider it close enough. The UI sounds can be a tad loud by default, but easy enough to turn them down to your preference. None of it was beneath the standard of the rest of the experience.
Cinematography is fantastic as always from Domn. His skill he's wielded upon Crypid Crush is in full effect to make scenes fun and bouncy when appropriate, and spooky and mysterious when needed. I especially enjoy the zoom in on the character introductions, which looks fantastic. The scene transitions are also very fun to see, and I appreciated their style. Only nitpick is some transitions between selecting someone to talk to or a topic and a dissolve into the conversation, where it feels odd the characters shift a small amount, even with the dissolve to smooth between them. Though fixing them would be an effort that is better spent after the jam is concluded.
Outside of the normal ratings, I have some small critiques, though most of them would be better saved for the post-jam version. I've seen one person have an issue with navigating between the rooms. I would recommend a map to select between scenes, even if some rooms are locked, better to just see all options than using the choice screen that is limited. Fixing choice menus to grey out previously selected options will be a nice QoL move. And the handful of typos and times a tooltip clips the UI were never major issues that held back the overall experience.
That all said, the project is a fantastic piece of spooky fun that I think makes for a fun read for the season. I look forward to recommending it every year for a fun, spooky romp. The passion and love put into every piece is on full display, and I'm left only wanting more from these characters and the world. Let's all hope the creators can come together to make more of this exceptional story and world.
I should be upfront that I am friends with many of the developers, and some of my code is used in the game, though I had little to no direct involvement. So to be fair, I will mention any problems I have, even if nitpicky.
That said, this is still one of the best quality VNs I've played in a while. A full course meal in a very digestible size. There is room to expand, but for a game made in a month, I'm happy with it, leaving me wanting more. The level of polish of what it there more than makes up for any shortcomings.
The story is a fun murder mystery with a cast I would consider large for the limitations. Twelve speaking characters is a lot to flesh out in a 2-3 hour story while weaving in clues and hints. I might critique that it would be nice to get more from some of the characters, but it likely would have made it harder to keep track of all the elements within the limitations. Though the main cast of the living feel well developed enough to carry it, and the number of characters makes it a good popcorn read with friends. The path to the true ending has one complication that I feel could be smoothed out, but the steps to it are not difficult to reach otherwise. The balance of comedy and horror walks a fine line, having dark subject matter kept digestible with a deft attention to the tone. Characters who have done awful things are fun to watch bounce off Maxwell, who keeps a level head through it all.
All of the visuals are fantastic. Each sprite feels unique and has plenty of fun expressions to elevate their lines. Backgrounds are high quality, though the storage room and attic bg are a bit too similar imo. Also feels like maybe one or two more CGs were desired but likely were cut, though I'm glad the CGs that are there leave great impact and were worth prioritizing. The UI is very clear with plenty of style and polish. I'm especially impressed that the textbox manages to make lines bordering on a paragraph feel readable, even though lines that long are rare (which is a good thing).
All of the music is fantastic and perfectly fits the mood. The inclusion of a fully original soundtrack really elevates each scene. The sound design is also deserving of praise, with meaty thuds and every step appropriate to the room. Sorry, I'm not very articulate with sound stuff, but all of it is a cut above even VNs made with more time and budget.
I'm not sure why a game jam would have a voice acting category. The inclusion of sounds for the text appearing though is always fitting, and I will consider it close enough. The UI sounds can be a tad loud by default, but easy enough to turn them down to preference. None of it was beneath the standard of the rest of the experience.
Cinematography is fantastic as always from Domn. His skill he's wielded upon Crypid Crush is in full effect to make scenes fun and bouncy when appropriate, and spooky and mysterious when needed. I especially enjoy the zoom in on the character introductions, which looks fantastic. The scene transitions are also very fun to see, and I appreciated their style. Only nitpick is some transitions between selecting someone to talk to or a topic and a dissolve into the conversation, where it feels odd the characters shift a small amount, even with the dissolve to smooth between them. Though fixing them would be an effort that is better spent after the jam is concluded.
Outside of the normal ratings, I have some small critiques, though most of them would be better saved for the post-jam version. I've seen one person have an issue with navigating between the rooms. I would recommend a map to select between scenes, even if some rooms are locked, better to just see all options than using the choice screen that is limited. Fixing choice menus to grey out previously selected options will be a nice QoL move. And the handful of typos and times a tooltip clips the UI were never major issues that held back the overall experience.
That all said, the project is a fantastic piece of spooky fun that I think makes for a fun read for the season. I look forward to recommending it every year for a fun, spooky romp. The passion and love put into every piece is on full display, and I'm left only wanting more from these characters and the world. Let's all hope the creators can come together to make more of this exceptional story and world.
Yeah if you want to do this with individual images, you'll have to do something like.
image eileen happy = At('eileen_happy', sprite_highlight('eileen'))
image eileen sad = At('eileen_sad', sprite_highlight('eileen'))
# Or, if you'd want an ATL example
image eileen happy:
'eileen_happy'
function SpriteFocus('eileen')
It's definitely more cumbersome but I don't have a lot of good ways of working around this. Hope this helps though.
I probably should put out a patch but think if you fix my DispTextStyle code on line 72 to be
self.tags[tag] = value
and update whatever tag you're using by replacing a
char_text = Text(my_style.apply_style(char))
with
if "" in my_style.tags: char_text = Text(my_style.apply_style(char), style=my_style.tags[""]) else: char_text = Text(my_style.apply_style(char))
You should see some improvement. Hope that helps.
I didn't originally add a speed setting to the ScareText admittedly but it wouldn't be hard to add if you wanted. To just slow it down, all you need to do is to change the renpy.redraw(self, 0) in the render function to be something like renpy.redraw(self, 1./30) or something. The '0' tells renpy to redraw this element every frame, so if you have a high frame rate, it'll update very quickly. Putting a fraction there tells it to wait until [fraction] has passed.
You can't really tell it to every 5 frames sadly because, if the frame rate is high, 5 frames might not be a lot anyway. So what you really want is a rate. You can play around with what speed you want but you can try .1 or .05 if you want. Or if you just want division, just do 1./12 for a twelth of a second (I recommend adding the '.' because it tells python to do floating point division instead of integer).
For adding it as a parameter though, you can add that by doing something like.
def scare_tag(tag, argument, contents):
new_list = [ ]
if argument == "":
shake = 5
speed = 1./30
elif '-' in arguemnt:
shake, _, speed = argument.split('-')
shake = int(shake)
speed = float(speed
else:
shake = int(argument)
my_style = DispTextStyle()
for kind,text in contents:
if kind == renpy.TEXT_TEXT:
for char in text:
char_text = Text(my_style.apply_style(char))
char_disp = ScareText(char_text, shake, speed)
new_list.append((renpy.TEXT_DISPLAYABLE, char_disp))
elif kind == renpy.TEXT_TAG:
if text.find("image") != -1:
tag, _, value = text.partition("=")
my_img = renpy.displayable(value)
img_disp = ScareText(my_img, argument)
new_list.append((renpy.TEXT_DISPLAYABLE, img_disp))
elif not my_style.add_tags(text):
new_list.append((kind, text))
else:
new_list.append((kind,text))
return new_list
for the tag and then
class ScareText(renpy.Displayable):
def __init__(self, child, shake=2, speed=1./30, **kwargs):
super(ScareText, self).__init__(**kwargs)
self.child = child
self.shake = shake # The size of the square it will wobble within.
self.speed = speed
# Include more variables if you'd like to have more control over the positioning.
def render(self, width, height, st, at):
# Randomly move the offset of the text's render.
xoff = (random.random()-.5) * float(self.shake)
yoff = (random.random()-.5) * float(self.shake)
child_render = renpy.render(self.child, width, height, st, at)
self.width, self.height = child_render.get_size()
render = renpy.Render(self.width, self.height)
render.subpixel_blit(child_render, (xoff, yoff))
renpy.redraw(self, self.speed)
return render
def visit(self):
return [ self.child ]for the class. I haven't tested that code myself so you might need to fix it if I missed a bug but I think it's good to learn how to debug stuff. Hope this helps and you're able to get it to work how you want it to!
The problem is that you put everything inside the _() function. So you need to move the first ')'
define sa = Character(_('Sasha', callback = name_callback, cb_name = "Sasha"), color="#efe49c")
It should be:
define sa = Character(_('Sasha'), callback = name_callback, cb_name = "Sasha", color="#efe49c")
You are free to modify it but yeah most of them don't put much of a delay on the effects. And the looping is just because they keep updating themselves as renpy calls them. I imagine you're looking to modify the SwapText though and you're free to modify that to how you want it to work. It uses it's swap_to_1 variable to keep track of which character it should be. So probably just need to treat the current timer variable it has to be a delay instead and remove the logic for switching back. Might need to add more code in there too if you want more than just the letter swap. Hopefully that helps though.
I've never had it flat out refuse to work. My best guess would be maybe your sprites are sharing names that are used to look up which to highlight. Having two sprites referring to the same one can often make it act screwy. Could be something else. but without more information about what's going on, that's my best guess.
Yeah, the kinetic text tags are a displayable being shown as part of an overall text displayable, but that text displayable doesn't know to pass it's style information down to the kinetic text tag's text. My solution to this was defining a style with all the properties you want, and then using the {=style} tag (https://www.renpy.org/doc/html/text.html#style-text-tags) INSIDE the kinetic text tag to carry that information in. While going through the text it's given, my text tags will try to keep track of other tags inside it and apply them to their text. So you'd want to do something like
style narr_text_style:
color "#fff"
outlines [(2, "#000000")]
size 1900
font "fonts/DisgustingBehavior-AZrA.ttf"
"{sc=10}{=narr_text_style}{outlines}No! You just don't want me to be happy!{/sc}"Not sure the style tag applies all of that attributes, especially outlines, or if that will necessarily work entirely. Though that's the general way I made it work.
While looking into this though I did learn that renpy now has some of this stuff built in. https://www.renpy.org/doc/html/textshaders.html So if it's not working it might be worth using their jitter instead.
Sorry, I can't say I tested it very extensively in NVL mode. I'll try to make a note to look into it more later. I have some guesses as to what the issue might be. I know Renpy likes to reset the whole textbox in ADV mode whenever it updates, so maybe it does something similar in NVL mode. If true, then the time being given to the displayables would be reset and not a lot I could do about that outside of awkwardly storing timers in globals in a way that'd be really messy. Though given your description, it that might not be the case and could be something else. I'll try to look into it when I have time but been busy lately.
I'll say I'm not entirely sure what you're asking, From the sounds of it, you're asking to have the shake and gradient tags moved to their own files. You are free to remove those sections are put them in their own .rpy file if you like, but I'm not sure how that will help you. If you're wondering how to use them, you just do "{sc}Some text{/sc}" for the scare tag, and the gradient tag is a bit harder, though I believe I provided some examples and reference for it in the comments of gradient_tags.rpy. Hopefully that helps but if you need more help feel free to ask!
No, I've never directly made an effect like that, but with my setup, it wouldn't be hard to make one if you know what you want and have some coding experience. Could maybe make one if you need though, but currently busy with another project so can't promise anything for a bit if you need it right now.
If I had to guess I would presume it's because when the scene starts, the character hasn't been speaking, so the speaking_char is probably either None or someone else. Then when the line starts, the character is then set as the speaking_char, so he lights up to normal. If you want them to start off already focused, you can manually set the speaking char by doing:
$ speaking_char = "guard1"
either before the transition or sometime during it. Which would then have the sprite start off in the talking state.
Hopefully that helps. But if it's some other issue, let me know and I'd be happy to help correct it.
Hi. Sorry for the late reply. I tried replicating the issue on my end, but doing the same setup (or at least what I can suppose from your comment) yielded results that looked correct to me. My best guess for the issue is that something about how you defined the sprites is causing renpy to reset the anim_time value, which would cause the sprite_highlight function to snap to the highlighted value. Which maybe you're confusing for the .2 seconds given .2 is pretty fast. Though I could be wrong. This is just my best guess given the information.
I tested with NVL and that didn't seem to make much of a difference. If you'd want to show me your code so I could test it and see what the issue might be, I'd be happy to take a look when I have time. (My username on discord is wattson if you need to reach out). But yeah I'm not entirely sure what the problem might be beyond my guess. Hope this was helpful and a solution to your issue can be found!
Hi. Sorry for taking a bit to get back to you. But yeah I appreciate you wanting to edit it to be easier for non-programmers to read it. I will admit I did my best when writing the original code to try and make it approachable as I could. If you have ideas on how to make it more approachable, I'd be happy to take feedback and upload a modified version on here with credit to you for the help. But if you're not making significant changes to the functionality and just adding comments, I feel like it'd be best to just have one project up. Sent a friend request on discord so we can chat more about it. Thanks for your feedback.
- Wattson
1. You'll probably need to add the glitch tag to the DispTextStyle class as part of the custom tags. That way it'll try and add it to every letter more or less.
2. Depends on what you want to do with the swap text. You'll probably want to update the SwapText class at least to take a list of texts to do. And then tell it to keep track of which one is being shown and increment it when you want it to go to the next one. But yeah the details from there are up to how you want to do it.
Sure I'll see what I can do about that. The main reason I split them up was originally to make it more modular. So if you didn't need every tag, you could pick and choose which you want, without it becoming a 1000+ line script file to go through. But given how many of my custom tags use the DispTextStyle class to handle other tags, probably makes sense to just lump them into one. So ppl just need to download one file even if they don't use all of them. I've just been pretty busy lately with my actual job and life stuff, so I'll see about when I get around to updating it. Probably when I have enough free time to work on another tool I've been meaning to release for a while.
The text's default position is going to be relative to where it would normally be placed on the screen. I don't know which specific tag is giving you problems, but I will guess it's the ATL tag. Depending on the values you give it, you may just be offsetting it too much and might want to bring them down closer to 0. Hard to know what exactly is the problem without more details, but hope you're able to get it fixed.



