unet – Unity mirror networking – game laggy for everyone after second client joins

I would like to ask a question about networking (mirror) in unity. I’ve already programed almost a whole game, but I got stuck on unexpected issue. Everything works great (even multiplayer) unless there are more than two players present. At this point the game starts being extremely laggy for everyone. I thought that it was happening due to my poor code optimalisation so I tried to disable all of these “features”. It made absolutely no difference. I tracked down the problem until I disabled almost everything but the core functionality (movement). I’m using Opsive Ultimate character controller (https://assetstore.unity.com/packages/tools/game-toolkits/ufps-ultimate-fps-106748) for movement so finding some “problems” in there is almost impossible! I would love to share the code with you, but since I disabled practically all of it, it does not make much sense at this point. Does anyone have similar experience with mirror networking asset?? (PS my game has quite a big map so I set quality to the lowest possible, which resulted in no success either)

Thanks everyone!

Papouc

unity – Creating a Full Stadium of People, Ready as a Game Asset (ie. not too CPU intensive)

In answer to one of your comments:

I actually have the same question, but regarding the seats in the stadium. Would it be better to make them in maya (all of them) or is it better to import just one chair mesh to Unity and place them procedurally?

There is extra performance overhead for multiple GameObjects; for example, it’s faster to render one mesh containing 100 chairs than to render a single chair mesh 100 times. You can reduce overhead by doing manual instanced rendering using Graphics.DrawMeshInstanced() but that is done with code and can be an extra headache to set up. I’d suggest grouping multiple chairs into one mesh.

However, you should not put all of the chairs in the entire arena into a single mesh, as this prevents frustum culling from working. Frustum culling refers to skipping render of objects that are not inside the camera’s boundaries. If all of the chairs are in a single mesh that wraps all the way around the arena, that means that at least some of the chairs will be visible to the camera no matter what direction the camera is pointed, preventing frustum culling. I once worked on a racing game for mobile where the artist had made the barrier around the entire track as a single 200k poly mesh. This ended up causing major performance issues because the engine could never cull any part of the barrier, so we eventually had to break the barrier into segments.

I would suggest grouping chairs into sections, and making each section a single mesh. This way you have less overhead than if each chair was its own object, but frustum culling will still work for sections of chairs that are not in front of the camera.

EDIT: As DMGregory noted in a comment, in the likely event that the chairs are completely stationary, you can also use static batching to have Unity automatically combine multiple instances of a mesh into a single mesh. So for example, if you imported a mesh containing 1 chair and added 500 copies of that chair to the scene, using static batching you could let Unity combine multiple chairs into a single mesh. I do not know offhand how this would work with frustum culling.

design – Best back-end architecture for a card game?

For learning, am looking to make a simple card card back-end server. Want to support the following:

  • Runs on a single box (like $20/month Linode). No need to worry about LBs.
  • At most 10,000 concurrent users
  • Uses real sockets/web sockets, not long polling/Comet
  • Deployments can cause brief outages, but games should not be lost
  • Game is turn-based and for fun, so no worries about lag or cheating.
  1. There are so many languages to pick. I’ve looked into:
  • Python with gevent or curio (coroutine-based)
  • Node (single-thread)
  • Java (thread per connection)
  • Kotlin (coroutines)
  • Go (goroutines)

How does one go about picking one?

  1. What things should one consider when picking a thread per connection vs. green threads / coroutines? Or using an event loop like libuv?

  2. And how to handle deployments in a stateful system? For example, let’s say we have this on a server:

player.tell("Pick a card");
val cardChosen = player.choose("Yellow 8", "Green 5", ...); // block on player input
if (isValid(cardChosen)) { ... } 

If the service needs to do a deployment and we are blocked on player input, how to ensure the state is the same when the services comes back up? Should all game state be persisted to disk or DB or Redis?

Thanks for any advice.

python – Hangman Game Efficiency

To put it simply, I’m making a hangman game and it works as it is, it correctly outputs what I want it to, and I have no problem with submitting it now. I only wish to make it more efficient, and I doubt it’s at max efficiency as it is. So here it is.

"""
This code runs a hangman game for the user.
"""
# This function gets the user's guess for the letter and determines if its correct
def get_guess():
    global user_guess
    while True:
        user_guess = input("Guess a letter: ")
        if user_guess.isnumeric():
            print("That is not a letter!")
        elif len(user_guess) > 1:
            print("You can only enter one letter!")
            continue
        elif user_guess.islower() == False:
            print("Remember to enter a lowercase letter, but I'll swap it for you this time :)")
            return user_guess.lower()
        else:
            return user_guess

# This function updates the dashes that the code outputs, this function displays the progress
# of the user's guess for the secret word
def update_dashes(secret_word, dashes, user_guess):
    for i in range(len(secret_word)):
        if secret_word(i) == user_guess:
            dashes  = dashes(:i) + user_guess + dashes(i + 1:)
            return dashes

# This imports the random function
import random
# This list defines what words the random.choice method can select from for hangman 
words = ("jazz", "hello", "bird", "birds", "peanut", "butter", "cake", "hallway")
# This secret_word defines a random word from the list for the user to guess
secret_word = random.choice(words)
# This variable defines the progress meter of dashes based on the length of the random word
dashes = "-" * len(secret_word)
# This variable defines the number of tries the user starts with and has left
tries = 10
# This while statement updates the user's progress for guessing the word
while tries > 0 and dashes != secret_word:
    print(dashes)
    guess = get_guess()
    dashes = update_dashes(secret_word, dashes, user_guess)
    if guess in secret_word:
        print("That letter is in the secret word!")
    else:
        print("That letter is not in the secret word.")
        tries = tries - 1
         print("You have " + str(tries) + " tries left.")
    
# This if statement determines if the user has won or lost based on their tries or if the 
# progress meter is full
if tries == 0:
    print("You ran out of guesses, the word was " + secret_word + ".")
    print("--------------------------YOU LOSE----------------------------")
elif dashes == secret_word:
    print(dashes)
    print("You guessed correctly, the word was " + secret_word + "!")
    print("--------------------------YOU WIN!----------------------------")

game design – How many choices for attacks should a player be given?

The core idea I teach my students is that choices in a game should be contingent and situational.

That is, there should be situations in which you would choose one option and situations in which you would choose another. This leverages the player’s skill, judgement, and intuition in discerning which of these situations they’re in.

You give an example of this with head vs body shots.

  • “My hit chances are low, I’d better aim conservatively to minimize the risk of missing” –> aim for body

  • “My hit chances are high, I’m not at much risk of missing and can prioritize damage” –> aim for head

Here, the exact threshold between “low” and “high” hit chance, or how much risk of missing the player is willing to take, are subjective and situational. Different players will come to different conclusions in different situations, depending on their aggression or risk tolerance or details of the scenario.

Maybe the enemy is on its last legs and so damage isn’t so important as just landing a hit to end the fight. Maybe you’re on your last legs and if you don’t get a headshot now it’s over, so it’s an all-or-nothing gamble. Maybe you’re concerned about running out of ammo, maybe you’re more concerned about draining your healing item supply. Each of these different elements add layers to the decision, and opportunities for players to choose to prioritize one or another.

Together, these considerations keep the player’s mind and subjectivity engaged in the decision, so it doesn’t just collapse to a calculation.

So, if you’re adding additional choices, the question to ask yourself is “in what situations should a player choose this over the options I already have?” and “in what situations should a player choose another option over this one?” If you have strong answers to both questions, that’s a sign the choice will create interesting decisions for your player. Particularly if sorting between those situations demands considering lots of factors (like my health, its health, engagement distance, amount of ammo, healing item supply, distance from a safe location, chance of backup, etc…) that can test their observation, quick thinking, tactical judgement, and intuition.

If there’s only a few situations to choose one thing or its alternatives, or those situations are obvious (lacking the subjective assessment of high/low and risk of the example above), then it’s likely to collapse to a calculation instead of challenging your players.

There’s a good Extra Credits video on this topic too. 😊

architecture – Can you show rng code running in real time in a game?

First off, I know almost nothing about game development/rng but I will learn. So apologizes for sounding uninformed.

I want to make a sandbox ios game with several activities to do within, one of which is poker, but I want the poker to be infallibly transparent unlike online poker. They wouldn’t dare.

So I want to show the rng code to be viewable by players as the hand plays out, so players will know its legit, and can verify after the hand etc if they have concerns, is this possible, can you “show” rng?

Made a monster array for a text based game with a class constructor C++

I created a class in a separate .h and .cpp file with the idea of having an array of 3 monsters with each monster having different stats( name; health; damage). The problem is that the constructor should change the properties but when I try to call them in the main file only the 3rd monster’s properties are changed.

main.cpp

#include <string>
#include <iostream>
#include <Windows.h>
#include <stdio.h>
using namespace std;



#include "Player.h"
#include "Monsters.h"
#include "MonsterCluster.h"
int main()
{

    Player player;
    Monsters monster;
    MonsterCluster enemies;

    enemies = MonsterCluster(0, "Goblin", 20, 5);
    enemies = MonsterCluster(1, "Wraith", 50, 10);
    enemies = MonsterCluster(2, "Legionare", 80, rand() % 60+20);

    cout << enemies.monsterList(2).name << endl;
}

MonsterCluster.h

#pragma once
#include "Monsters.h"

class MonsterCluster :
    public Monsters
{
public:
    Monsters monsterList(3);



    MonsterCluster();
    MonsterCluster(int _monsterIndex, string _name, int _health, int _damage);
   
    
}

MonsterCluster.cpp

MonsterCluster::MonsterCluster()
{
    /*name = "";
    health = 2;
    damage = 3;*/
}

MonsterCluster::MonsterCluster(int _monsterIndex, string _name, int _health, int _damage)
{
    monsterList(_monsterIndex).name = _name;
    monsterList(_monsterIndex).health = _health;
    monsterList(_monsterIndex).damage = _damage;
}

Where should I handle player movements in a Java Game?

I had an old pure Java 2D top-down game that I’m trying to reformat a bit. Before, I had a bit of a messy game loop that didn’t use delta timing for any movements or animations. Now, I’m trying to implement this delta timing.

I implemented delta timing into the game loop with two framerates (60FPS and 30FPS) to test it, but I noticed that the movement created with the 30FPS was half of what was obtained using the 60FPS.

When I moved the player, I did something like:

posX += Game.deltaTime * SPEED;

and this didn’t work well because the delta time was the same for both the 30FPS and 60FPS.

So, I did some calculations… I run into some problems if I use change the player’s position from the update() method, because it runs at a constant 60UPS.

Here are my calculations


int deltaXPerSecond = Game.deltaTime() * SPEED * 60;

// To get the delta X over a second, I multiplied deltaX by 60 (UPS)
// with 30FPS, it was 9.9, with 200FPS it was 1.5

// Game Loop

private static final double UPDATES_PER_SECOND = 1.0 / 60.0;

@Override
        public void run() {
            
            /*
             * Note: This game loop uses Majoolwip's game loop.
             * https://www.youtube.com/watch?v=4iPEjFUZNsw&list=PL7dwpoQd3a8j6C9p5LqHzYFSkii6iWPZF
             */
            
            double firstTime = 0;
            // converts to seconds because System.nanoTime is extremely accurate.
            double lastTime = System.nanoTime() / 1000000000.0;
            double passedTime = 0;
            double unprocessedTime = 0;
            
            double frameTime = 0;
            int frames = 0;
            int fps = 0;
            
            boolean render = false;
            
            // Continuously repeats this loop until the game is stopped.
            while (running) {
                render = false;
                firstTime = System.nanoTime() / 1000000000.0; // converts to seconds.
                
                // Gets how many milliseconds have passed between now and the last time.
                passedTime = firstTime - lastTime;
                deltaTime = (float) passedTime;
                lastTime = firstTime; 
                unprocessedTime += passedTime;
                frameTime += passedTime;
                
                while (unprocessedTime >= UPDATES_PER_SECOND) {
                    unprocessedTime -= UPDATES_PER_SECOND;
                    // Sets render to true. This makes the game render only when it updates
                    render = true;
                    
                    // Updates the game
                    if (frameTime >= 1.0) {
                        frameTime = 0;
                        fps = frames;
                        frames = 0;
                        System.out.println("FPS: " + fps);
                    }
                    update();
                }
                
                if (render) {
                    frames++;
                    render();
                }
                else {
                    
                    /*
                     * If the game doesn't need to render or update,
                     * the GameLoop thread sleeps for 1 millisecond,
                     * causing a decrease in CPU usage.
                     */
                    
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                
            }
        }

What am I doing wrong? Shouldn’t these numbers be approximately the same regardless of the frame rate? Do I need to change the game loop? Please let me know what I am missing.

beginner – My Blackjack Game in Python

I am a beginner programmer ( just recently picked it up ). I just completed my first ever project, that is creating a Blackjack game in Python. I would like to know your opinions about it and how it can be improved! Thanks in advance. This code is original and I made it myself without any external assistance.

import random
import os
import time

def clear():
    os.system('cls' if os.name == 'nt' else 'clear')

def addPlayerCard(playerCards, cards):
    playerCards.append(random.choice(cards))

def addDealerCard(dealerCards, cards):
    dealerCards.append(random.choice(cards))

def addSum(hand):
    totalsum = 0
    hand2 = ()
    for card in hand:
        if(card == 'A'):
            hand2.append(card)
            hand2.remove(card)
        else:
            hand2.append(card)

    for cards in hand2:
        if(cards == 'A'):
            hand2.append('A')
            hand2.remove('A')
        if(cards == 'J' or cards == 'K' or cards == 'Q'):
            totalsum += 10
        elif(cards == 'A'):
            if(totalsum + 11 <= 21):
                totalsum += 11
            else:
                totalsum += 1
        else:
            totalsum += cards
    return totalsum 

def showDealerHand(dealerCards):
    print("Dealer's hand: (X,", str(dealerCards(1)) + ")")

def showPlayerHand(playerCards):
    print("Player's hand: (" + str(playerCards(0)) + ", " + str(playerCards(1)) + ")")

def checkBlackjack(cards):
    flag1 = 0
    flag2 = 0
    if(cards(0) == 'A' or cards(1) == 'A'):
        flag1 += 1
        if(cards(0) == 'J' or cards(1) == 'J' or cards(0) == 'K' or cards(1) == 'K' or cards(0) == 'Q' or cards(1) == 'Q'):
            flag2 += 1
    if(flag1 + flag2 == 2):
        return True
    else:
        return False

def handCount(hand):
    handCount = len(hand)
    return handCount

def hitOrStand(playerCards, dealerCards, cards, fiveHandRule):
    i = 0
    while(i != 2):
        hitstand = str(input("nDo you want to hit or stand?n")).lower()
        if(hitstand(0) == "h"):
            addPlayerCard(playerCards, cards)
            flag1 = addSum(playerCards)
            flag2 = handCount(playerCards)
            clear()
            print("Dealer's hand: (X,", str(dealerCards(1)) + ")")
            print("Player's hand: " + str(playerCards))

            if(flag1 > 21):
                print("nYOU BUSTED!")
                time.sleep(2)
                return True
            elif(flag2 >= 5 and flag1 <= 21):
                fiveHandRule.append("PASS")
                return True
        if(hitstand(0) == "s"):
            return True

def dealerCheck(dealerSum, dealerCards, cards, playerCards):
    if(dealerSum <= 16):
        print("Dealer's hand: " + str(dealerCards))
        print("Player's hand: " + str(playerCards) + "n")
        print("_________________________________________________n")
        print("The Dealer's Cards' Total Sum do not exceed 16.")
        print("The Dealer Hits!")
        addDealerCard(dealerCards, cards)
        dealerSum = addSum(dealerCards)
        time.sleep(2)
        return dealerSum

def blackjackCard(playerCards, dealerCards):
    print("You Got a Blackjack!n")
    time.sleep(1)

    print("Revealing Dealer's Hand...")
    time.sleep(1)
    print("Dealer's hand: " + str(dealerCards))
    print("Player's hand: " + str(playerCards) + "n")

    if(checkBlackjack(dealerCards)):
        print("The Dealer Also Has a Blackjack!n")
        return 8
    else:
        print("The Dealer Does Not Have a Blackjack.n")
        return 9

def winLose(pSum, dSum, pHandCount):
    if(pSum > dSum and pSum <= 21):
        return 1
    elif(dSum > pSum and dSum <= 21):
        return 2
    elif(pHandCount >= 5 and pSum <= 21):
        return 3
    elif(dSum == pSum and pSum <= 21 and dSum <= 21):
        return 4
    elif(pSum > 21 and dSum <= 21):
        return 5
    elif(dSum > 21 and pSum <= 21):
        return 6
    elif(pSum > 21 and dSum > 21):
        return 7

def gameEnd(result):
    if(result == 1):
        print("nCongratulations, You Won! Your Cards' Total Sum Is Higher Than The Dealer's.")
        return 1
    elif(result == 2):
        print("nYou Lost! The Dealer's Cards' Total Sum Is Higher Than Your's.")
        return 2
    elif(result == 3):
        print("nCongratulations, You Won! You Have a 5 Card Hand Without Busting, Winning by 5-Card Charlie.")
        return 1
    elif(result == 4):
        print("nIt's a Push! Your Cards' Total Sum Is The Same As The Dealer's!")
        return 3
    elif(result == 5):
        print("nYou Lost! You Busted but The Dealer Did Not. The Total Sum of Your Cards Exceeded 21.")
        return 2
    elif(result == 6):
        print("nCongratulations, You Won! The Dealer Busted but You Did Not. The Total Sum of The Dealer's Cards Exceeded 21.")
        return 1
    elif(result == 7):
        print("nIt's a Push! Both Parties Busted. Both Parties' Total Sum of Their Respective Cards Exceeded 21.")
        return 3
    elif(result == 8):
        print("nIt's a Push! Both Parties Have a Blackjack!")
        return 3
    elif(result == 9):
        print("nCongratulations, You Won! You Have a Blackjack but The Dealer Does Not!")
        return 1

def gameEnd2(result):
    if(result == 1 or result == 3 or result == 6 or result == 9):
        return 1
    if(result == 2 or result == 5):
        return 2
    if(result == 4 or result == 7 or result == 8):
        return 3
    
def Blackjack():
    clear()
    cards = ('A','J','K','Q', 2, 3, 4, 5, 6, 7, 8, 9, 10)
    dealerCards = ()
    playerCards = ()

    addPlayerCard(playerCards, cards)
    addPlayerCard(playerCards, cards)
    addDealerCard(dealerCards, cards)
    addDealerCard(dealerCards, cards)
    showDealerHand(dealerCards)
    showPlayerHand(playerCards)
    checkBlackjack(playerCards)
    checkBlackjack(dealerCards)

    blackjack = False
    if(checkBlackjack(playerCards)):
        blackjack = True
        blackjackCard(playerCards, dealerCards)

    fiveHandRule = ()
    if(blackjack == False):
        while(hitOrStand(playerCards, dealerCards, cards, fiveHandRule) != True):
            hitOrStand(playerCards, dealerCards, cards, fiveHandRule)

        if(len(fiveHandRule) <= 0):
            clear()
            print("Revealing Dealer's Hand...")
            time.sleep(1)
            dSum = addSum(dealerCards)
            if(dSum <= 16):
                while(dSum <= 16):
                    dealerCheck(dSum, dealerCards, cards, playerCards)
                    dSum = addSum(dealerCards)
            
            if(dSum > 16):
                print("Dealer's hand: " + str(dealerCards))
                print("Player's hand: " + str(playerCards))
            if(dSum > 21):
                print("nTHE DEALER BUSTED!")
                time.sleep(2)

            pSum = addSum(playerCards)
            dSum = addSum(dealerCards)
            pHandCount = handCount(playerCards)

            winLose(pSum, dSum, pHandCount)

            result = winLose(pSum, dSum, pHandCount)

            gameEnd(result)
        else:
            print("Five-Hand Charlie!")
            time.sleep(2)
            result = 3
            gameEnd(result)
    else:
        result = blackjackCard(playerCards, dealerCards)
        gameEnd(result)

    input("Input any key to continue.n")
    return result

def endgame(result, gamelog):
    clear()
    print("The Match Has Been Concluded.")
    flag = gameEnd2(result)
    if(flag == 1):
        print("Result: WIN")
        gamelog.append('W')
    elif(flag == 2):
        print("Result: LOSS")
        gamelog.append('L')
    elif(flag == 3):
        print("Result: TIE")
        gamelog.append('T')
    input("Input any key to continue.n")
    clear()

def lobby(gamelog):
    totalgames = len(gamelog)
    totalwins = 0
    totallosses = 0
    totalties = 0
    for game in gamelog:
        if(game == 'W'):
            totalwins += 1
        elif(game == 'L'):
            totallosses += 1
        elif(game == 'T'):
            totalties += 1
    winrate = (2 * totalwins + totalties) / (2 * totalgames) * 100
    winrate = round(winrate, 2)
    
    print("Your Stats")
    print("_________________________________________________n")
    print("TOTAL GAMES: " + str(totalgames))
    print("WINS: " + str(totalwins))
    print("LOSSES: " + str(totallosses))
    print("TIES/PUSHES: " + str(totalties) + "n")
    print("YOUR WINRATE: " + str(winrate) + "%")
    print("_________________________________________________n")

gamelog = ()
print("Welcome to Darrance's Blackjack. Have fun!")
time.sleep(2)

def main():
    result = Blackjack()
    endgame(result, gamelog)
    lobby(gamelog)
    option = input("Would you like to play again? (Y/N)n").lower()
    if(option(0) == 'y'):
        main()
    elif(option(0) == 'n'):
        clear()
        print("Thank you for playing Darrance's Blackjack!")
        input("Input any key to exit program.")
        clear()

main()