[icon ] blenderdumbass . org [icon scene] Articles

Story Without Cutscenes in Dani's Race

[avatar]  Blender Dumbass

January 28, 2025

👁 52

https://dev.dubvee.org/ : 👁 1
https://blenderdumbass.org/ : 👁 4
https://blenderdumbass.org/search?text=DanisRace&tags=on : 👁 1

#DanisRace #MoriasRace #Game #Gamedev #UPBGE #blender3d #animation #GTAClone #programming #project #Story #Storytelling #Gnu #Linux #Freesoftware #OpenSource

License:
Creative Commons Attribution Share-Alike
Audio Version





There is a petition happening right now for Dani's Race version 2025-01-19 which if you will sign it, will help both the development of the game and will help one very important contributor. So please go there and sign it. ( You must have a fediverse account for it, though ).



Continuing Moria's Race I can't make Dani's Race simply story-less, yet I do not want to take the obvious route and turn the game into a movie either. A lot of games these days forget that they are games and try very hard to be "cinematic". Which means that they are films and not games. And that is not interesting. Why don't you just release it as a movie if you want to make a movie?


[embedded image]


So the challenge for Dani's Race is deliberately not to be a movie. As in the game should not have cuts, nor there ever should be a moment when the player loses control over the character. Yet through all those limitations I want to continue a story I started in an actual movie. Which is kind of complicated.

For example in the first story mission in the game, which you play immediately as you download the game: Dani is in his room alone. Suddenly a phone calls and Paps ( the father character from Moria's Race with a recognizable voice ) is asking Dani ( and by extent you, the player ) to bring a race car from the garage of the house to the racetrack. But he instructs you not to break it. Since Moria will need to use this car later to practice the race.


[embedded image]


Here are some challenges: You should be able to combine the animation of Dani talking to a phone with him walking around and doing any other activity. So that the answering of the phone will not break the flow of the rest of the game; there should be cars which are breakable; a specific car, related to a story should spawn in a specific place for the story to work; there should be Paps and Moria waiting for you in the racetrack; And when you bring the car Moria should take it from you and go practicing with it on the racetrack. So if you stick around you could see her drive the whole racetrack. And if you remember from the movie it is not a simple racetrack; Also characters should speak at their right moment. And even sometimes say different lines based on different things you do. And while speaking they also need to at least open their mouths.


[embedded image]


The way the animation was approached is rather fortunate. UPBGE, the game engine of choice, has an ability to mix multiple animations into one. Overwriting only certain actions. So I can have a base animation ( layer 0 ) be the walking of the character. While on top of that ( layer 1 ) have him put his phone near his head to talk. Where only the hand will overwrite everything. While the rest of the body will use the animation from layer 0.


[embedded image]


Dani has multiple actions. One for the base, one for the phone specifically, and one for emotions and facial expressions. Which I can layer one over the other to make the range of animations that I need for this game. The base animation action might contain multiple base animations at different times. For example from frame 0 to frame 300 it is Dani's idle animation. Basically him standing. Then from 300 to 310 it's his walk cycle. And so on. All of those I later write down into a JSON file, which is later interpreted with this function, so I wont need to setup everything manually each time:

def ApplyAnimation(character, animation, keep=False, **kwargs):

    # Optimization
    cam = bge.logic.getCurrentScene().active_camera
    if character in Reuse.reuse.get(character.name, [])\
       or cam.getDistanceTo(character) > 150:
        return
    
    # Exctracting data request
    rig        = getRig(character)   
    action     = rig.get("Action") 
    startframe = animation[0]
    endframe   = animation[1]

    # Failsafe
    if not action:
        return
    
    # If we are reading animation from the database
    if type(animation) == str and animation in animations.get(character.name, {}):
        
        data       = animations[character.name][animation]
        action     = data.get("Action", action)
        keep       = data.get("Keep", keep)
        startframe = data["Frames"][0]
        endframe   = data["Frames"][1]
        kwargs     = data.get("kwargs", kwargs)

    elif type(animation) == str:
        startframe = 0
        endframe   = 0
        
    # Sometimes we might want to keep the animation at it's
    # last frame when it ends.
    if keep and rig.getActionFrame(kwargs.get("layer", 0)) == endframe:
        startframe = endframe
    
    
    # Executing the animation
    rig.playAction(action, startframe, endframe, **kwargs)

    # To activate the stand animation we want to know if anything is playing
    if kwargs.get("layer", 0) == 0:

        # Recording the animation
        rig["animation"] = animation


So now if I want to have Dani do the answering of the phone motion I can just simply write:

Character.ApplyAnimation(dani, "AnswerPhone")


... which is exactly what I do in Script.py when he answers his phone.

Now if you look into the first scene() function in that file you will see that there are some conditions on the rigging of the phone. It doesn't just immediately ring. I want the player to get somewhat familiar with the controls first. And then when it does ring it gives the player an option of not answering it. Postponing the plot of the game.

Yet since the car is supposedly in the garage of this house and Paps and Moria are waiting for this car on the racetrack, the phone should not ring far away from the house. Or especially should not ring on the racetrack. So that the illusion of the game world happening will not be broken.

if dani.getDistanceTo(house) < 600 and not dani.get("race"):
    
    # If at least 20 seconds have been passed from the start of the game.
    
    if bge.logic.getRealTime() > Story.get("lastring", 20):
        
        Story["ringing"] = RingPhone()
        Story["lastring"] = bge.logic.getRealTime() + 400

As you can see the program is checking that Dani is not father than 600 meters away from the house and is not currently racing, or doing some other side-quest, which I always record into dani"race"
Of course the location of the house before the first mission is marked on the mini-map, so if you do get away from it and start messing around in the city, you will still get reminded that something interesting must be at the house itself.

Now, when you answer the phone this audio-file plays:




As you can hear, the audio starts with 3 seconds of silence. This is needed for the animation of Dani answering the phone to be done before we can hear him say "Yes". Which is then followed by Paps's monologue.

While writing new lines for Paps is not a significantly complex process, because I was the voice actor in Moria's Race that voiced Paps and I can always switch to using Paps's voice. With Dani or Moria this is not that simple. I talked many times about the challenges of finding and then convincing a voice actress to do Moria's Race with me. And expecting her to come back, let alone work in such an unpredictable pace ( after she told me that she would not do that ), is not going to happen. So I am trying to reuse the stuff I got from her for the movie, which is not a lot of stuff, even though I can use takes that didn't make it into the final cut.

Writing new scenes with such a limited palette of phrases is actually sort of interesting in an artistic way. It kind of makes me go through a Lars Von Trier-esk technique of limitations, to distill some interesting stuff. And even though it is very hard, I am kind of enjoying the process. I don't really want to have a voice actor for Moria and Dani for this game.

Anyway. I guess I need to stop blabbering. This article is already getting a bit long. And I need to still proof-read it, record a recording of it... Damn! I forgot to start a recording of how I'm writing it. See? This is what happens when you are tired.

At the moment I'm working on another scene which involves characters that need to navigate themselves through doors and stuff and being able to drive though the whole town without mistakes. This will flex my programming a bit since I need to make sure the game has code for all of it. I guess you can visit my livestreams where I am occasionally streaming how I'm working on this game.

And do not forget to sign the petition. It is really important. It helps the community. And helps the game be released. And there are a lot of reasons for it. So please go to the latest petition page, use your fediverse account and help us get the project rolling. Thank you! ... and ...

Happy Hacking!!!





Subscribe RSS
[icon link] Author
[icon link] Website
Share on Mastodon









[avatar]  elban c:0


Если ты просто сейчас пошёл спать ничего мне не сказав, я буду тебя проклинать

[icon send] Reply
[avatar]  elban c:1


На заставке статьи папус выглядит так будто его штаны настолько ему жмут что весь жир ушел под нижнюю часть тела...

[icon send] Reply
[avatar]  elban c:2


Ты же понимаешь что если ты не зайдешь в звонок в течении десяти минут, тебе будет пиздец?

[icon send] Reply



[icon reviews]Minority Report

  Unread  

[thumbnail]

[avatar]  Blender Dumbass

👁 37 💬 0



I reviewed a lot of films on this website and in almost every review I mention the name of Steven Spielberg. It's not because every movie I review is made by Spielberg. But it seem like every director can be viewed on a scale of Spielbergness. And the higher you go on that scale the better. At the top there is Steven Spielberg himself.


[icon petitions]Release: Dani's Race v2025-01-19

  Unread  

[thumbnail]


230 / 250 Signatures

[avatar]  Blender Dumbass

👁 70 💬 0



Dani's Race version 2025-01-19


#DanisRace #MoriasRace #Game #UPBGE #blender3d #project #petition #release


[icon reviews]Ambulance 2022 is a fucking masterpiece

  Unread  

[thumbnail]

[avatar]  Blender Dumbass

👁 21 💬 0



Critics often think Michael Bay doesn't give a damn about characters, but how can you believe that when everything in the film is shut deliberately to be from a perspective of a character? Michael Bay is Lars Von Trier of action. Lars uses strange chaotic camera work and weird editing choices to elevate the emotion on screen and Michael Bay uses chaotic camera work and weird editing choices to elevate the emotions too. If you take him seriously everything clicks into place. It's just Michael Bay likes it louder.


#Ambulance #Ambulance2022 #MichaelBay #film #review #movies #cinemastodon #EizaGonzales #JakeGyllenhaal


[icon reviews]Speed Racer

  Unread  

[thumbnail]

[avatar]  Blender Dumbass

👁 26 💬 0



This had to be done finally! One of the biggest inspirations for Moria's Race, one of my favorite childhood movies, one of the best action films ever and perhaps one of the most colorful films: Speed Racer by the Wachowskis.


[icon music]The Pentas

  Unread  

[thumbnail]

[avatar]  Blender Dumbass

👁 36 💬 0



Pentas are 5 gong-style round drum-things which are used to play simple melodies. Each one of those is one note in a scale called the Pentatonic scale. If you take the modern western scale with it's 7 notes (Do, Re, Mi, Fa, Sol, La, Si). The pentatonic scale is the best sounding 5 of those (Do, Re, Mi, Sol, La). The easiest way of achieving the pentatonic scale on a piano would be to play only the black keys. Also the pentatonic scale is quite popular with beginner guitarists. It's rather simple on a fret-board and gives a nice sounding solo when improvising. The Pentas - being my second album, was still recorded during my time learning the guitar. So I used a lot of the pentatotic scale in it. Thought quite frankly, knowing about the other two notes (Fa and Si) I added them quite often still.


[icon codeberg] Powered with BDServer [icon analytics] Analytics [icon mastodon] Mastodon [icon peertube] PeerTube [icon element] Matrix
[icon user] Login