#Build only works on developer's devices, severely bugged on client PC

1 messages · Page 1 of 1 (latest)

tawny crane
#

I'm working with some folks who need a game for their thesis.
I wasn't originally the dev, they hired someone else initially and wanted some extra changes and the other guy was hard to talk to apparently.

Anyway. two buttons, basically just yes and no are supposed to work like in the first two videos.

(The second video has the top and bottom cut off because it's made specifically for the resolution of their device. Needed the image sizes to be exact for vision testing)

But when they try to run it, the next two happens

#

Build only works on developer's device, severely bugged on other

#

Build only works on developer's device, severely bugged on other PCs

tawny crane
#

Build only works on developer's devices, severely bugged on client PC

#

Their PC is a Surface pro 6
just tested it on my sister's old surface pro 6 and it worked completely as expected 😭

silver torrent
#

You'll have to show the code

tawny crane
#

snippets or the .cs file?
either way I'm gonna do a walkthrough of how it runs
I'm having to work with some dude's left over vibe code unless I want to start over

#

levelSet being a container for an array of these scriptableobjects

#

At scene start StartLevel is called to start at the very first level in the LevelSet

void StartLevel(int index)
{
    _gameOver = false;
    _currentLevelIndex = Mathf.Clamp(index, 0, levelSet.levels.Length - 1);
    _currentRound = 0;
    _levelCorrectCount = 0;     // reset per-level correct counter
    _attemptsUsed = 0;
    _score = 0;                 // remove this line if you want cumulative score across levels

    // reset current level session counters
    _sessionLevelScores[_currentLevelIndex] = 0;
    _sessionLevelWrongs[_currentLevelIndex] = 0;

    UpdateHeader();
    BuildStarIndicators();
    NextRound();
}

2 of the methods called set the UI stuff to match the levelset.
BuildStarIndicators() supposed to put the stars on the screen which you can see the client's video doesn't have

    void BuildStarIndicators()
    {
        if (!starContainer || !starPrefab) return;

        foreach (Transform child in starContainer)
            Destroy(child.gameObject);
        _starImages.Clear();

        var lvl = levelSet.levels[_currentLevelIndex];
        for (int i = 0; i < lvl.rounds; i++)
        {
            var star = Instantiate(starPrefab, starContainer);
            star.sprite = emptyStarSprite;
            _starImages.Add(star);
        }
    }

NextRound() destroys any image on screen because before I was on the project had an array of images instead of just one

    void NextRound()
    {
        var lvl = levelSet.levels[_currentLevelIndex];

        foreach (var b in _spawned) if (b) Destroy(b.gameObject);
        _spawned.Clear();

        _currentRound++;
        _attemptsUsed = 0;

        if (roundText) roundText.text = $"Round: {_currentRound}/{lvl.rounds}";

        int px = lvl.GetPixelSize(config.devicePPI);
        SpawnShapes(lvl, px);

        ResetTimer();
    }

SpawnShapes is where the meat is and is the only method I touched. It's what spawns the icon in the center

#
    {
        if (!playArea)
        {
            Debug.LogError("Assign playArea.");
            return;
        }

        // Decide target shape (can change per attempt if randomizeTargetShape = true)
        _currentTarget = lvl.fixedTargetShape;
        if (lvl.randomizeTargetShape && lvl.allowedShapes != null && lvl.allowedShapes.Length > 0)
            _currentTarget = lvl.allowedShapes[Random.Range(0, lvl.allowedShapes.Length)];


        // === spacing & centering ===
        float spacing = (config.spacingMode == SpacingMode.Pixels)
            ? config.shapeSpacingPx
            : px * config.shapeSpacingFactor;

        float totalWidth = 0;

        var area = playArea.rect;

        float startX = 0;
        float yCenter = 0f;

        playArea.pivot = new Vector2(0.5f, 0.5f);

        // spawn the snellen or whatever it's called

        var obj = Instantiate(new GameObject(), playArea);
        _spawned.Add(obj);
        var rt = obj.AddComponent<RectTransform>();
        rt.anchorMin = new Vector2(0.5f, 0.5f);
        rt.anchorMax = new Vector2(0.5f, 0.5f);
        rt.pivot = new Vector2(0.5f, 0.5f);
        rt.sizeDelta = new Vector2(px, px);

        float x = startX + 0 * (px + spacing);
        rt.anchoredPosition = new Vector2(x, yCenter);

        var img = obj.AddComponent<Image>();
        img.sprite = GetSprite(_currentTarget);

    }```
#

It used to also set the images as buttons but since the clients pivoted from that now it just spawns an image in a specific size

#

For posterity or whatever this is what it looked like before I touched it

#

The yes or no button are attached to this method that just checks if you clicked yes or no.

Used to be attached to the vision test icons when it was supposed to spawn a bunch of them

public void OnShapeClicked(bool correct)
{
    if (_gameOver) return;

    //   if (hideReferenceAfterClick && choiceBoards)
    //       choiceBoards.enabled = false;

    // Demotion rule: Level 1 (index 1), Round 1, Attempt 1, wrong => jump to Level 0
    if (!correct
        && _currentLevelIndex == 1
        && _currentRound == 1
        && _attemptsUsed == 0)
    {
        CancelInvoke(nameof(AutoFailRound));
        Debug.Log(":arrow_lower_right: Demoted from Level 1 to Level 0 (first attempt wrong on first round).");
        StartLevel(0);
        return;
    }

    if (correct)
    {
        FinishCurrentQuestion(correct: true);
    }
    else
    {
        _attemptsUsed++;
        if (_attemptsUsed < Mathf.Max(1, maxAttemptsPerQuestion))
        {
            RespawnCurrentRound();
        }
        else
        {
            FinishCurrentQuestion(correct: false);
        }
    }
}

the rest of the methods just do computation stuff for the score and put you in the next round if you're good enough

#

I basically modified what used to be this into a yes or no if that helps with context

#

which meant I mostly removed stuff

#

oh and I put this in Update()

    void Update() {
        lastpress = keypress;
        keypress = (int)Input.GetAxis("YesOrNo");

        if (keypress == 0 && lastpress != 0) {
            if (lastpress < 0)
            {
                OnShapeClicked(false);
            }
            else OnShapeClicked(true);
        }
        
    }

because they asked to be able to press 1 for yes and 2 for no
I forget if there was a "input released" event in unity since I've been running godot so I did it like this

tawny crane
#

they just opened the build I compiled as "development build" I sent and suddenly it's fine

#

this is killing me