yairm210 / Unciv

Open-source Android/Desktop remake of Civ V
Mozilla Public License 2.0
8.46k stars 1.57k forks source link

An insignificant startup screen error. #9886

Closed AutumnPizazz closed 12 months ago

AutumnPizazz commented 1 year ago

As shown in the screenshot below. When opening Unciv on Windows, a white border appears as shown below. This error only occurs in version 4.7.12. image

yairm210 commented 1 year ago

Does this always happen? Does it stay this way forever? If not then how long does it stay? What happens if you resize

AutumnPizazz commented 1 year ago

Yes, this situation has been occurring regardless of how I adjust the window size. However, it hardly affects the actual usage, as the normal game interface appears after this brief screen (in the previous versions, there was a black screen without the white border).

yairm210 commented 1 year ago

Hm, this might be a result of updating the JDK used for Windows 🤔

AutumnPizazz commented 1 year ago

I agree, because this time the update cannot be directly extracted by overwriting the zip file to the original folder as before, but the folder must be set separately and then the configuration files can be overwritten to open properly.

yairm210 commented 1 year ago

It should still work by overwriting the zip file though? I mean the zip itself should be JDK-agnostic IIRC

AutumnPizazz commented 1 year ago

So this will become a new 'insignificant error', right? QAQ

yairm210 commented 1 year ago

I found that you can set the initial color of the screen, maybe that will help

SomeTroglodyte commented 1 year ago

cannot be directly extracted by overwriting

If you do that you will extract file by file and the extractor will decide file by file to overwrite (or not). Files already present that aren't present in the zip - they just stay. So you'll be mixing a new Java with obsolete files from an old Java where it doesn't need any file of that name.... As Cespenar says "Could get messy". Just so you understand why. Haven't got an idea what we could do about it, there's no "Delete before extracting" instruction in the ZIP standard one could bake into a zip. After all, it's just an archive format, not an installer format.

folder must be set separately and then the configuration files can be overwritten

Or just delete the jre subfolder before extracting, one or two clicks less.

SomeTroglodyte commented 1 year ago

normal game interface appears after this brief screen (in the previous versions, there was a black screen without the white border).

Does that mean you never see the intended "loading splash screen" with the unciv banner, where we had the rotating smiley before?

AutumnPizazz commented 1 year ago

Does that mean you never see the intended "loading splash screen" with the unciv banner, where we had the rotating smiley before?

Wow, I never knew about this!

SomeTroglodyte commented 1 year ago

OK, next question: Do you see that banner on Options-About: image

... or the screenshot on Civilopedia-Tuts-World Screen:? image

SomeTroglodyte commented 1 year ago

Coders: Unconfirmed suspicions - that white wedge is inside the App window, sized close to how big the banner splash should be. So, it might be that thing not displaying correctly. Running the zip myself on W10 works fine. Still, might be the rare resource from ExtraImages, or the ImageWithCustomSize widget, or...

private class GameStartScreen : BaseScreen() {
    init {
        val logoImage = ImageGetter.getExternalImage("banner.png")  // ImageWithCustomSize!
        logoImage.center(stage)
        logoImage.setOrigin(Align.center)  // redundant since we no longer rotate
        logoImage.color = Color.WHITE.cpy().apply { a = 0f }  // setColor copies and any Actor owns its Color instance, so logoImage.color.a = 0f would be cleaner
        logoImage.addAction(Actions.alpha(1f, 0.3f))  // Might be better a line down to ensure the first act() works on the same situation as the rest, and alpha(1) is fadeIn
        stage.addActor(logoImage)
    }
}

...nothing really wrong with it...

AutumnPizazz commented 1 year ago

OK, next question: Do you see that banner on Options-About:

Yeah, I could see all of them. image image

Well, the startup video is like this. https://github.com/yairm210/Unciv/assets/114050365/00bc66a3-12c3-47ac-8593-9504ee90d603 @SomeTroglodyte

SomeTroglodyte commented 1 year ago

Still an interesting curiosity, but I see no "leverage" to get to understand it. That video - the banner should fade in, and that white wedge doesn't, or maybe it's just too fast. :shrug: - anybody an idea how to repro under a debugger or how to log enough info to get a lead?

yairm210 commented 1 year ago

So is this still happening to you with the recent change?

AutumnPizazz commented 1 year ago

It was never gone. (Until 4.7.13) @yairm210

SomeTroglodyte commented 1 year ago

Surprise: I can repro. The rectangle size is the App window size it's supposed to be restoring to, but at that point the window is maximized, and stays so. The banner-splash comes a bit later and is quickly gone, quicker than that rectangle. I've got "windowState":{"width":2048,"height":1112}, in settings and two 2560x1440 monitors on this box...

Again or still something wrong with the desktop window size / restore code. Maybe I should dig out, merge and try this old code - pretty sure that did 'maximized' correctly, besides remembering which screen of a multimonitor rig unciv was on last time....

SomeTroglodyte commented 1 year ago

Got it: GraphicsEnvironment.getLocalGraphicsEnvironment().maximumWindowBounds is badly wrong on certain monitor setups. Here I got 2 screens 2560x1440 each, secondary to the left of primary. maximumWindowBounds should be {x: -2560, y: 0, width: 5120, height: 1360} or close, but is {x: 0, y: 0, width: 2048, height: 1112}: completely off the rocker.

What happens next is: Gdx.Game gets created with the saved size, calls DesktopScreenMode.activate, which sees the saved dimensions equal the maximumWindowBounds dimensions, and decides to maximize. But startup is still busy, so the empty window decoration for the original saved size stays visible until the render loop starts properly. Or so.

AutumnPizazz commented 1 year ago

Got it: GraphicsEnvironment.getLocalGraphicsEnvironment().maximumWindowBounds is badly wrong on certain monitor setups. Here I got 2 screens 2560x1440 each, secondary to the left of primary. maximumWindowBounds should be {x: -2560, y: 0, width: 5120, height: 1360} or close, but is {x: 0, y: 0, width: 2048, height: 1112}: completely off the rocker.

What happens next is: Gdx.Game gets created with the saved size, calls DesktopScreenMode.activate, which sees the saved dimensions equal the maximumWindowBounds dimensions, and decides to maximize. But startup is still busy, so the empty window decoration for the original saved size stays visible until the render loop starts properly. Or so.

I could say nothing but how cool you are. (Admiring) OwO

SomeTroglodyte commented 1 year ago

The JavaDoc says: Returns the maximum bounds for centered Windows. These bounds account for objects in the native windowing system such as task bars and menu bars. The returned bounds will reside on a single display with one exception: on multi-screen systems where Windows should be centered across all displays, this method returns the bounds of the entire display area. - aha, the results blatantly contradict that.

@AutumnPizazz - can you confirm my suspicions? Can you look at GameSettings.json and report the windowState dimensions in there, plus the Monitor setup (number, resolutions, arrangement)?

AutumnPizazz commented 1 year ago

Yeah, I update it as 4.8.2. However, this white border still never go away. There's the GameSettings.json { "mapPanningSpeed": 19, "showWorkedTiles": true, "showTileYields": true, "showUnitMovements": true, "autoUnitCycle": false, "language": "Simplified_Chinese", "screenSize": "Huge", "tutorialsShown": [ "Introduction", "SlowStart" ], "tutorialTasksCompleted": [ "See your stats breakdown", "Found city", "Enter city screen", "Open the options table", "Create a trade route", "Conquer a city", "Pick construction", "Move an air unit", "Move unit", "Pick technology", "Meet another civilization", "Reassign worked tiles", "Pass a turn", "Construct an improvement" ], "soundEffectsVolume": 0.45000002, "citySoundsVolume": 0, "musicVolume": 0, "pauseBetweenTracks": 0, "tileSet": "Civ6 Strategic Perspectives", "unitSet": null, "showTutorials": false, "autoAssignCityProduction": false, "minimapSize": 8, "unitIconOpacity": 0.8, "windowState": { "width": 3456, "height": 2001 }, "visualMods": [ "The Undead", "Civ V - Vanilla", "RekMOD", "Latin-American_Civs-master", "DeCiv Redux", "philosophy mod", "Barbarian xp farm", "APmodofUnciv", "Latin American_Civs", "??????", "Latin American", "Civ V - Gods & Kings", "5Hex Tileset", "Leader Mission 2 Rising Power", "the Coexistence in harmony" ], "notificationsLogMaxTurns": 15, "showAutosaves": true, "multiplayer": { "userId": "7019070e-c113-4ad7-936f-cf577595559c", "passwords": { "class": "java.util.LinkedHashMap", "http://bj.unciv.cn": "741852963" }, "server": "http://bj.unciv.cn", "friendList": [ { "name": "MingTian", "playerID": "e73fb0a3-3304-4e5f-a580-9b4afbac4963" }, { "name": "AoSiMan", "playerID": "d10f91a6-01c5-44ba-9b6d-0913980a109d" }, { "name": "DaiWangShen", "playerID": "5422dad8-ddc9-4323-8761-6c020eb5acd6" }, { "name": "YunMengXi", "playerID": "696a0a0a-67b5-4ff0-9ff5-909e12b04ae1" }, { "name": "TanSuoZhe", "playerID": "a517c29d-d03f-4ae5-bd56-387fbb3a0c55" }, { "name": "LengYu", "playerID": "376b0318-fce3-4c94-a59d-4259cc6d04a6" }, { "name": "LangCi", "playerID": "6d8937b0-166b-49d4-887e-2cb077836e87" }, { "name": "ShaoXiao", "playerID": "8c23a8ad-20c7-4e09-90ca-07ba240576db" }, { "name": "E", "playerID": "e2c45378-676e-4278-a3d2-96e299d4ffd6" } ], "currentGameRefreshDelay": "PT3S", "allGameRefreshDelay": "PT2M", "currentGameTurnNotificationSound": { "fileName": "notification1" }, "otherGameTurnNotificationSound": { "fileName": "notification2" } }, "lastOverviewPage": "Religion", "lastGameSetup": { "gameParameters": { "difficulty": "Difficulty_Online", "speed": "Speed_Online", "players": [ { "chosenCiv": "Nation_Mali", "playerType": "Human" }, { "playerType": "Human" }, { "chosenCiv": "Nation_Rome", "playerType": "Human" } ], "numberOfCityStates": 0, "noCityRazing": true, "victoryTypes": [ "Victory type_Science", "Victory type_Culture", "Victory type_Conquest", "Victory type_Diplomacy", "Victory type_Economic", "Victory type_Score", "Pattern_Permit to build World Wonder", "Pattern_Camorrist", "Pattern_Viceroy", "Victory type_Religion", "Pattern_Landlords" ], "startingEra": "Era_Ancient", "isOnlineMultiplayer": true, "multiplayerServerUrl": "http://bj.unciv.cn", "baseRuleset": "the Coexistence in harmony", "maxTurns": 300 }, "mapParameters": { "type": "Perlin", "shape": "Rectangular", "mapSize": { "radius": 32, "width": 80, "height": 40, "name": "Custom" }, "mapResources": "Strategic Balance", "noRuins": true, "noNaturalWonders": true, "worldWrap": true, "baseRuleset": "the Coexistence in harmony", "createdWithVersion": "4.8.2 (Build 910)", "seed": 1693995731680, "elevationExponent": 0.6, "waterThreshold": -0.1 } }, "enableEasterEggs": false, "maxWorldZoomOut": 6, "notificationScroll": "Visible", "version": 1 }

SomeTroglodyte commented 1 year ago

I only wanted the "windowState": { "width": 3456, "height": 2001 } part... Oh my, that's big. But doesn't tell me anything without the other info I asked for. What does Windows think the available surface is? Is that one 4k monitor, or maybe two, or even differently-sized ones? High-DPI setting?

AutumnPizazz commented 1 year ago

I've been using my Xiaomi laptop all day. I won't be able to turn it on again until tomorrow evening (after 16h from now) to confirm the resolution. My impression is that my computer screen resolution is 1080P, not 4K

SomeTroglodyte commented 1 year ago

I'm pretty convinced my diag is right. I'm curious because I don't understand by that library function "lies" and when, and it is very likely a different degree of wrong on different setups. I suspect the windows font-scaling setting (I called it the High-DPI setting up there), but then why does (in my case) the wrong answer not have the exact same aspect ratio as what I believe the right answer to be, even if one limits that to one monitor? Should be 1120 instead of 1112....

Summary: Not that important. Don't stress over it.

I don't have code ready, as I started out debugging this on top of a recreated old branch, my "BetterWindowPersist", redone - because it has lots of digging into the underlying Lwjgl3 and GLFW backends and does the maximize think differently - saved instead of guessed. Only then I reached the diagnosis it's a wrong system info triggering the "I want maximized" guess. Now I have to iron out the kinks, after all, that old code was from way before vegeta1k95's ScreenMode stuff including the borderless setting, and from before the platform specific helpers got a completely different interfacing.

But in the unlikely event the result gets merged - woohoo Unciv remembers where it was, including which screen! I've dragged it over to the left one soooo often.... And I don't want to have Studio on the left instead.

AutumnPizazz commented 1 year ago

Well, my screen is this. image

SomeTroglodyte commented 1 year ago

Close to 4k but not quite? Such devices exist? (can't even read the name, oc copypaste it into a translator) No matter. The 225% scaling might be what trips the libraries. Would also explain why your rectangle is so much smaller than mine.

Anyway, my experiments aren't going well. What I try to do trips looooots of library shortcomings and outright bugs, and bypassing those gets ugly. And while I could likely fix that rectangle glitch in current master with a few lines, it's much harder in my branch - because that is able to save and restore maximized state and unmaximized size both...

SomeTroglodyte commented 1 year ago

Current state of investigation:

The Java AWT API delivers all (most) dimensions scaled by this setting: image ... while Gdx through GLFW will work with true pixels. That's the root cause here.

That AWT quirk is undocumented, at least not in the lib's Javadoc.

There's no 100% fix as the scaling is applied to insets, too, and it rounds after scaling - meaning projecting back to true pixels will be off by one on certain setups.

Best of all: One can demonstrate that AWT will report display geometry inconsistently within one single call: GraphicsConfiguration.getBounds() will report x/y in true pixels and width/height scaled by that setting. So far I have observed that only on Windows, haven't got a *ix box with multimonitor and a HiDPI scaling setting to test.

SomeTroglodyte commented 1 year ago

Might perhaps be remotely related to this bug in java's bugtracker

AutumnPizazz commented 12 months ago

https://github.com/yairm210/Unciv/assets/114050365/e5341d28-0e94-47e8-aca4-1284632635b9

It's so excited that the last-far start-screen error in my PC can be solved.