I am in the process of implementing a speed lines shader to the stk-codebase. With this post I'm hoping to discuss the possibility of adding it to the game.
Intro
Speed lines (aka wind streaks) (see the videos below for more info) are quite a common feature in kart racing games, as the name suggests they come on screen when the player experiences a speed boost of some sorts, usually through an upgrade. I personally noticed them first in Mario Kart, but I've since gone and checked a few other kart racers (Sonic, Crash Team Racing etc.) and they all feature them in some capacity. The main purpose is to provide an extra sense of speed to the player, by mimicking wind rushing past at high speeds.
Shader
I initially started writing the effect purely in GLSL, but pivoted to using Godot's visual shader graph for quicker iteration. Before delving into more specifics here's what it looks like in isolation: https://youtu.be/_1LBMsESjSQ
(or see next post for embedded view)
There are quite a few tweakable parameters for the shader. Ranging from:
Density of particles
Softness of the particles
Amount of wisps (i.e. how many subdivisions of the UV space to sample the noise texture from)
Wind speed (very useful as we can tie the intensity of the boost to this)
Radial stretch (how blobly should the wisps be, effectively stretches the uv.x coordinate)
Radial mask size (how much of the screen should be ensure is always free of the effect - for gameplay purposes)
etc.
At the moment I have implemented a primary control to the shader (value ranging from 0-1 as a scalar float) BoostIntensity. That value is driving:
the wind speed
size of the radial mask (make the mask a bit tighter at higher intensities to really bring home the sense of speed)
color saturation (make the effect pop more at higher intensities, makes the wind feel more intense)
While I still need to profile on some weaker hardware, the shader should be really cheap to run on most hardware. On my machine it was close to 30us (7900xt). The effect works with sampling a noise texture at 2 samples per pixel, which is really modest in my experience.
Preview
Hooking up the shader and it's driving value -> BoostIntensity. We get something like the following:
(note the effect does look somewhat choppy due to the video quality, but is smooth during actual gameplay)
Implementation I am still trialing the proper CPU side implementation, mainly on the 'how exactly' the effect should come in, how strong and how long should it last etc.
I've been experimenting with a few different options for the question 'how exactly'. Ranging from:
Should it come in mainly based on current velocity ratio with maximum velocity?
Should it be on impulse/activation of a SpeedIncrease?
I believe at the moment I'm going with a bit of a hybrid solution of the both, this looks roughly like the following:
Use the trigger of any SpeedIncrease modifier as the impulse
(as long as there's no active SpeedDecrease or Attachment like the anchor/parachute etc.).
Then shortly driving up the value and overshooting slightly to a target value.
(make the impulse of the effect a tad stronger than it's sustained intensity).
Then settle down the intensity value and base it on the ratio between the current speed and the maximum speed.
The last step here effectively helps tie the effect to match with the current speed regardless of difficulty setting.
Then I use the already pre-existing unique duration(s) of the SpeedIncrease to keep the effect active.
Once the SpeedIncrease runs out we linearly interpolate back down to 0 to gently ease out.
There are also some provisions for correctly latching whether we've crashed into something, drastically lost speed or got hit with a SpeedDecrease to then directly ease down to 0 (rather than waiting for the effect to run out naturally).
I am still needing to properly clean up and dial in the logic, but I personally think it's getting closer to the final solution. A couple of notes from my side:
The effect does still ramp up to 1.0f quite fast at the moment, dialing this down is something I'm working on, it should only really be at 1.0f if we've stacked 2-3 speed increases and going fast (i.e. coming out of red skid + zipper + nitro should be 1).
Once we crash the effect can come down just a tad faster in my book, at the moment it uses the same linear ease down to 0 as when the effect normally runs out.
Certain SpeedIncrease items we can maybe experiment with not having it contribute to the intensity (i.e. turn it off for skids etc.?)
Closing Remarks
If this feature/effect looks of interest to you and would be a good fit for the game, let me know and I can clean up my code and start the PR. From there we can discuss further and iterate on feedback/suggestions.
PS: I did only notice at the posting of this post that there might be a related thread to another implementation of speed lines, my apologies there, but I do think we can work out a way to combine our efforts. https://forum.supertuxkart.net/thread-200.html
Are there modifications for the client itself? So the user interface and such, besides just custom karts, sounds and tracks.
As an example, there seem to be a bunch of UI elements that I couldn't find in the settings in the attached image (it's from this video: https://www.youtube.com/watch?v=czyonmAYYjo).
I wanna make some concepts for a polished Race UI for Mobile, but I want to know if exists somewhere that I can download the .svg files (that is easier to edit) of cartoon theme (the classic is very outdated, so I'll recommend a redesign of the buttons for this theme, based in the new UI of STK Evolution).
(Don't worry, I'm not going to complain about anything)
I'm making a fork of STK based on version 0.8.1. I don't know how to program, and I don't know how to compile that old code to make my fork. I've tried different methods, like asking the AI (don't criticize me, I'm innocent) or trying to do it myself (I have technical skills but not programming), but none of them have worked. It gets stuck in an extra phase; it shows the terminal but says:
"Irrlicht Engine version 1.8.0
Professional (Build 26200)
[debug] main: Error messages and other text output will be logged to C:\Users\(I'm not going to show you the account name)\AppData\Roaming/supertuxkart//stdout.log."
And there's nothing special in the log. I'm using msys mingw64.
I noticed that under Options -> Interface, there's a toggle disabled by default to "Show other karts' held powerups." I feel that if such a feature is present, it should be enabled by default. Being able to see if another player is holding a cupcake or switcher, for example, can be a game changer, especially in a battle. But, any player who hasn't opened the interface settings probably isn't aware of this feature, so the game is unfair by default when playing against someone who has it enabled. Furthermore, not knowing what powerups another player is holding makes the game less predictable and more fun. Could this feature either be removed or turned on by default?
I'd love to have the blend file for the Las Dunas Stadium track (not the arena). Does anyone know Tux Brothers (the authors) or GeekPenguinBR (the submitter)? I'd like to ask them for the blend!
Issue #5197 mentions adding the ability to pause, seek, move back and forth by individual frames and change
the speed of playback when watching replays. To this, Alayan responded "Pause, rewind and speed change are
all things I would like to have as well. This won't be in 1.5 and maybe not in 2.0, but it's definitely on the roadmap."
I have built the engine side of this and in accordance with the "Communicating with the team" section of the contributing code guidelines I am making a forum post about it.
I have implemented this by means of a ReplayControl class that owns the replay clock. It can pause (setPlaying), move
the head of the playback to a desired time (seek) and change the rate of playback (setRate). The ability to move back and
forth by individual frames naturally falls out of this; you would just seek by a frame-sized delta (or move to an adjacent time
via m_all_times, both can work). This functionality is currently enabled via a --replay-control flag and without it it is inert.
This doesn't change the normal race clock: everything outside of watch replay mode remains untouched.
I have deliberately NOT added the UI. I've built the mechanism, however as it stands there is no user interface that allows
the user to control it. This is on purpose and has been done for two main reasons.
1. Building UI blind without knowing if it is wanted or how the structure should be set out puts my time and effort at risk of being wasted.
2. Where the UI lives, how it looks, where the buttons are, etc. are design decisions that are not my call to make.
This feature has a dependency on the fix outlined in pull request #5837 - without it, seeking backwards would cause the ghost
to freeze in place, which is far from ideal.
(Note to reviewer: the three "removed" lines in world_status.cpp are still there, they're just indented one level deeper and so
GitHub shows them as red. None of the original behaviour has been changed or deleted. You can see that exact same code in
lines 479-481.)
To wrap this up, I'd like to ask a few questions:
Is this something you'd want in the main game?
Should I build the UI or is that something you would be doing?
Is driving the world clock the correct approach?
Where should this live? It currently lives in src/replay: does it belong somewhere else?
Whose job should it be to handle frame-stepping - ReplayControl's or the UI's?
Those are the main questions I'd like answers for however if you have any other questions or concerns I'd be happy to answer them.
Hello everyone,
We are excited to announce the 20th edition of the Unofficial SuperTuxKart Soccer Tournament series, which is the September 2026 Soccer Tournament!
You sign up individually, organizers create teams of three or four players and schedule your matches. We’re still playing three games with a 10 minutes time limit on three different arenas. However, this time Red Team chooses the first arena, Blue Team chooses the second arena, and the third arena is chosen randomly among all available arenas. We also require at least ten add-on arenas this time.