Nuklear icon indicating copy to clipboard operation
Nuklear copied to clipboard

Consecutive properties mess up text alignment within

Open StrikerTheHedgefox opened this issue 2 months ago • 15 comments

Also referenced here: https://github.com/RobLoach/nuklear_console/issues/124

It appears consecutive properties mess up the text alignment of following properties, incrementally

image

StrikerTheHedgefox avatar Sep 30 '25 18:09 StrikerTheHedgefox

Would you mind sharing any code snippet that causes this issue? Preferably, any minimal reproducible example.

I've been looking at the code related to widget alignment recently. Maybe, I will be able to do something about this issue.

EDIT: I guess, this happens when using nk_property() or some of the code from: https://github.com/RobLoach/nuklear_console/blob/c4180cf143777a847d8f8f4f7489069ef0f367f8/nuklear_console_property.h

sleeptightAnsiC avatar Oct 08 '25 17:10 sleeptightAnsiC

You would be correct, anything using an nk_property or nuklear_console_property.

My code currently is as simple as:

nk_console_property_int(controlsMenu, "X/Y Deadzone", 0, &joyXYDeadzone, 16384, 64, 8);
nk_console_property_int(controlsMenu, "Rudder Deadzone", 0, &joyRudderDeadzone, 16384, 64, 8);
nk_console_property_int(controlsMenu, "Throttle Deadzone", 0, &joyThrottleDeadzone, 16384, 64, 8);

StrikerTheHedgefox avatar Oct 30 '25 21:10 StrikerTheHedgefox

[just leaving a note for myself] https://github.com/RobLoach/nuklear_console/blob/c4180cf143777a847d8f8f4f7489069ef0f367f8/nuklear_console_property.h#L236-L263

sleeptightAnsiC avatar Oct 30 '25 22:10 sleeptightAnsiC

Image

Here's a screenshot of the entire menu, as it may give a hint at what UI elements might be causing it. Because for some odd reason, the issue doesn't appear in some menus. Got some comboboxes, checkboxes, etc.

StrikerTheHedgefox avatar Oct 31 '25 17:10 StrikerTheHedgefox

Hello, @StrikerTheHedgefox! Thank you for reporting the issue.

Unfortunately, I wasn't able to reproduce the behavior shown in your screenshot within a reasonable amount of time. I tried various combinations of backends (GLFW, SDL2), fonts, DPI/scaling settings, and window sizes, but none of them resulted in the issue you described. Still, this bug remains interesting and worth investigating.
So, it would be helpful if you could provide some additional information, including:

  1. Operating System.
  2. Monitor scaling / DPI settings (e.g., 100%, 125%, 150%).
  3. Backend used (SDL2, GLFW, custom, etc.).
  4. Font used (name + size) and window size.
  5. Does resizing the window (making it narrower) make the problem appear or worsen?
  6. Are you using a custom Nuklear theme, or default style? If custom, could you share ctx->style modifications (especially padding / spacing values)?

Thanks in advance. Once we can reproduce it reliably, we can move on to implementing a proper fix.

Code snippet

A small code snippet that works well and it does not reproduce the discussed behavior(At least in my environment).

Source code
//Use nuklear_console_demo.c for building
nk_console* nuklear_console_demo_init(struct nk_context* ctx, void* user_data, struct nk_image image) {
    struct nk_style* s = &ctx->style;

    con = nk_console_init(ctx);
    nk_gamepad_init(&gamepads, ctx, user_data);
    nk_console_set_gamepads(con, &gamepads);

    static nk_bool bools[8];
    static int ints[16];

    ints[4] = 4096;
    ints[5] = 1024;
    ints[6] = 24;

    set_style(ctx, THEME_DRACULA);

    nk_console_button(con, "Configure Binds");
    nk_console_checkbox(con, "Controllers Enable", &bools[0]);
    nk_console_checkbox(con, "Turn Axis smoothing", &bools[1]);
    nk_console_checkbox(con, "Auto-leveling", &bools[2]);
    nk_console_combobox(con, "Throttle Type", "Analog (Incremental),Invert,Dual Range", ',', &ints[0]);
    nk_console_combobox(con, "Rudder Axis", "Right Stick X,Left Stick X,Pedals,None", ',', &ints[1]);
    nk_console_combobox(con, "Throttle Axis", "Left Stick Y,Right Stick Y,Trigger Combine,None", ',', &ints[2]);
    nk_console_combobox(con, "Map Zoom Axis", "D-Pad Up/Down,Right Stick Y,Left Stick Y,None", ',', &ints[3]);
    nk_console_property_int(con, "X/Y Deadzone", 0, &ints[4], 16384, 64, 8);
    nk_console_property_int(con, "Rudder Deadzone", 0, &ints[5], 16384, 64, 8);
    nk_console_property_int(con, "Throttle Deadzone Sensitivity Adjustment Calibration", 0, &ints[6], 16384, 64, 8);
    nk_console_combobox(con, "Left Trigger Action", "Brake,Zoom,Throttle Down,None", ',', &ints[7]);
    nk_console_combobox(con, "Right Trigger Action", "Accelerate,Zoom,Throttle Up,None", ',', &ints[8]);
    nk_console_button_onclick(con, "Back", nk_console_button_back);
    return con;
}

PavelSharp avatar Nov 02 '25 22:11 PavelSharp

Windows 11, SDL2. Fonts are custom, but issue occurs no matter which font I use. DPI is 100%. Theme is mostly vanilla, no changes to sizes, just colors.

You menu seems identical to mine:

configureBinds = nk_console_button_onclick(controlsMenu, "Configure Binds", UIFunc_OnConfigureBinds);
activeController = nk_console_combobox(controlsMenu, "Active Controller", joystickMenuList, ';', &joystickIndex);
nk_console_add_event(activeController, NK_CONSOLE_EVENT_CHANGED, UIFunc_OnActiveControllerChanged);
nk_console_checkbox(controlsMenu, "Controllers Enabled", &joystickActive);
nk_console_checkbox(controlsMenu, "Turn Axis Smoothing", &joyAxisSmooth);
nk_console_checkbox(controlsMenu, "Auto-leveling", &autoLevel);
nk_console_combobox(controlsMenu, "Throttle Type", "Buttons;Analog;Analog (Incremental)", ';', &joyThrottleType);
nk_console_combobox(controlsMenu, "Rudder Axis", axisMenuList, ';', &rudderAxis);
nk_console_combobox(controlsMenu, "Throttle Axis", axisMenuList, ';', &throttleAxis);
nk_console_combobox(controlsMenu, "Map Zoom Axis", axisMenuList, ';', &mapZoomAxis);
nk_console_property_int(controlsMenu, "X/Y Deadzone", 0, &joyXYDeadzone, 16384, 64, 8);
nk_console_property_int(controlsMenu, "Rudder Deadzone", 0, &joyRudderDeadzone, 16384, 64, 8);
nk_console_property_int(controlsMenu, "Throttle Deadzone", 0, &joyThrottleDeadzone, 16384, 64, 8);
nk_console_combobox(controlsMenu, "Left Trigger Action", actionMenuList, ';', &joyLeftTriggerAction);
nk_console_combobox(controlsMenu, "Right Trigger Action", actionMenuList, ';', &joyRightTriggerAction);

nk_console_button_onclick(controlsMenu, "Back", nk_console_button_back);

bindKey = nk_console_label(controlsMenu, "Bind Key");
bindKey->alignment = NK_TEXT_CENTERED;
bindKey->selectable = nk_false;
bindKey->disabled = nk_true;
bindKey->visible = nk_false;

Not sure why this bug only happens on this menu, and no others.

StrikerTheHedgefox avatar Nov 02 '25 22:11 StrikerTheHedgefox

Fonts are custom

@StrikerTheHedgefox I apologize if this sounds intrusive, but could you share the exact font name or a link to download it?
Alternatively, does the issue also occur when using any common system fonts such as Arial or Times New Roman?

PavelSharp avatar Nov 02 '25 22:11 PavelSharp

If it helps, my window width is 525px wide, 562px tall. I dunno if the size will have an effect or not.

I can't really share much since the font implementation is entirely custom, but in that image I was using Chicago FLF, converted to my engine's font system. (Baked into an atlas, etc)

static float UI_GetMessageWidth(nk_handle handle, float height, const char *text, int len)
{
	TFURY_UNREFERENCED_PARAMETER(height);

	tfury_uifont_info *fontInfo = handle.ptr;

	float width = TXT_GetMessageWidthIdx((char*)text, fontInfo->fontIndex, fontInfo->scale, len);

	return width;
}

static void UI_GetGlyph(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
{
	TFURY_UNREFERENCED_PARAMETER(next_codepoint);
	TFURY_UNREFERENCED_PARAMETER(font_height);

	tfury_uifont_info *fontInfo = handle.ptr;

	SGlyph scaled = TXT_GetGlyphScaled((char)codepoint, fontInfo->fontIndex, fontInfo->scale);

	codepoint -= FIRST_CHAR;
	if (codepoint < 0)
	{
		glyph->width = 0.0f;
		glyph->height = 0.0f;
		glyph->offset.x = 0.0f;
		glyph->offset.y = 0.0f;
		glyph->xadvance = 0.0f;
		glyph->uv[0].x = 0.0f;
		glyph->uv[0].y = 0.0f;
		glyph->uv[1].x = 0.0f;
		glyph->uv[1].y = 0.0f;
		return;
	}


	SFont* fontPtr = &fonts[fontInfo->fontIndex];
	glyph->width = scaled.width;
	glyph->height = scaled.height;
	glyph->offset.x = scaled.xoffset;
	glyph->offset.y = scaled.yoffset;
	glyph->xadvance = scaled.advance;
	glyph->uv[0].x = scaled.x / fontPtr->texture_x;
	glyph->uv[0].y = scaled.y / fontPtr->texture_y;
	glyph->uv[1].x = (scaled.x + fontPtr->glyphs[codepoint].width) / fontPtr->texture_x;
	glyph->uv[1].y = (scaled.y + fontPtr->glyphs[codepoint].height) / fontPtr->texture_y;
}

struct nk_user_font UI_LoadUserFont(char* fontname, float scale)
{
	struct nk_user_font userFont;

	// Todo: Add a function to free this!
	tfury_uifont_info *fontInfo = (tfury_uifont_info *)malloc(sizeof(tfury_uifont_info));
	fontInfo->fontIndex = TXT_GetFontIdx(fontname);
	fontInfo->scale = scale;

	SFont* fontPtr = &fonts[fontInfo->fontIndex];

	userFont.userdata.ptr = fontInfo;
	userFont.height = TXT_GetFontInfoIdx(FONTINFO_LINEHEIGHT, fontInfo->fontIndex, scale);
	userFont.width = UI_GetMessageWidth;
	userFont.query = UI_GetGlyph;
	userFont.texture.id = fontPtr->texture;

	return userFont;
}

StrikerTheHedgefox avatar Nov 02 '25 22:11 StrikerTheHedgefox

Another thing that might help, is it seems to break depending on the parent screen resolution and window size.... if I scrunch my window up like this:

Image

Suddenly, it works. So my guess the window size has everything to do with it.

StrikerTheHedgefox avatar Nov 02 '25 22:11 StrikerTheHedgefox

After some time, I tried to reproduce the issue again, but everything still looks correct and properly aligned on my side. It’s possible I’m missing a very specific condition. Below is the source code. Make sure to specify the path to the font before running it.

Source code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <limits.h>
#include <time.h>
#include <stdbool.h>

#include <SDL2/SDL.h>

#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_STANDARD_IO
#define NK_INCLUDE_STANDARD_VARARGS
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#define NK_INCLUDE_FONT_BAKING
//#define NK_INCLUDE_DEFAULT_FONT
#define NK_INCLUDE_COMMAND_USERDATA
#define NK_IMPLEMENTATION
#define NK_SDL_RENDERER_IMPLEMENTATION
#include "nuklear/nuklear.h"
#include "nuklear/nuklear_sdl_renderer.h"

#define NK_GAMEPAD_IMPLEMENTATION
#include "nuklear_gamepad.h"

#define NK_CONSOLE_IMPLEMENTATION
#include "nuklear_console.h"

#define WINDOW_WIDTH 525
#define WINDOW_HEIGHT 562
#define FONT_NAME "fonts\\kenvector_future_thin.ttf"

typedef struct {
    SDL_Window* window;
    SDL_Renderer* renderer;
    struct nk_context* nk_ctx;
    nk_console* console;
    struct nk_font_atlas* atlas;

    bool running;
    float font_size;
    nk_bool bools[8];
    int ints[16];
    int winw, winh;
} app_state;

static void app_init_sdl2_window(app_state* st) {
    //SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER);

    st->window = SDL_CreateWindow(
        "Consecutive Properties (SDL2)",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        WINDOW_WIDTH, WINDOW_HEIGHT,
        SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE
    );
    assert(st->window);

   //SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); // linear

    st->renderer = SDL_CreateRenderer(st->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    //SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
    SDL_RenderSetIntegerScale(st->renderer, SDL_TRUE);
    assert(st->renderer);

    SDL_GetWindowSize(st->window, &st->winw, &st->winh);

}

static void app_update_font(app_state* st) {
    if (st->atlas)
        nk_font_atlas_clear(st->atlas);
    nk_sdl_font_stash_begin(&st->atlas);
    //static const nk_rune ranges[] = {
    //    0x0020, 0x00FF,
    //    0x0400, 0x052F,
    //    0x2DE0, 0x2DFF,
    //    0xA640, 0xA69F,
    //    0
    //};
    struct nk_font_config cfg = nk_font_config(st->font_size);
    cfg.range = nk_font_cyrillic_glyph_ranges();
    //cfg.merge_mode = nk_false;
    //cfg.oversample_h = 1;
    //cfg.oversample_v = 1;
    //cfg.pixel_snap = nk_true;
    struct nk_font* font = nk_font_atlas_add_from_file(st->atlas, FONT_NAME, st->font_size, &cfg);
    nk_sdl_font_stash_end();
    nk_style_set_font(st->nk_ctx, &font->handle);
}

static void app_init_nuklear(app_state* st) {
    st->nk_ctx = nk_sdl_init(st->window, st->renderer);
    st->console = nk_console_init(st->nk_ctx);

    nk_console* con = st->console;
    int* ints = st->ints;
    nk_bool* bools = st->bools;
    ints[5] = 1024;
    ints[6] = 2048;
    ints[7] = 2048;
    st->font_size = 14.0;
    app_update_font(st);

    nk_console_property_float(con, "Font size:", 1, &st->font_size, 100, 0.01, 0.01);

    nk_console_button_onclick(con, "Configure Binds", NULL);

    nk_console_combobox(con, "Active Controller","Gamepad 1;Gamepad 2;Gamepad 3;None", ';', &ints[0]);

    nk_console_checkbox(con, "Controllers Enabled", &bools[0]);
    nk_console_checkbox(con, "Turn Axis Smoothing", &bools[1]);
    nk_console_checkbox(con, "Auto-leveling", &bools[2]);
    nk_console_combobox(con, "Throttle Type", "Buttons;Analog;Analog (Incremental)", ';', &ints[1]);

    nk_console_combobox(con, "Rudder Axis", "Left Stick X;Right Stick X;Triggers(Combined);None", ';', &ints[2]);

    nk_console_combobox(con, "Throttle Axis", "Left Stick Y;Right Stick Y;Trigger Combine;None", ';', &ints[3]);

    nk_console_combobox(con, "Map Zoom Axis", "D-Pad Up/Down;Left Stick Y;Right Stick Y;None", ';', &ints[4]);

    nk_console_property_int(con, "X/Y Deadzone", 0, &ints[5], 16384, 64, 8);
    nk_console_property_int(con, "Rudder Deadzone", 0, &ints[6], 16384, 64, 8);
    nk_console_property_int(con, "Throttle Deadzone", 0, &ints[7], 16384, 64, 8);

    nk_console_combobox(con, "Left Trigger Action", "Brake;Zoom;Throttle Down;None", ';', &ints[8]);

    nk_console_combobox(con, "Right Trigger Action", "Accelerate;Zoom;Throttle Up;None", ';', &ints[9]);


    nk_console_button_onclick(con, "Back", nk_console_button_back);
}

static void app_init(app_state* st) {
    app_init_sdl2_window(st);
    app_init_nuklear(st);
    st->running = true;
}

static void app_frame_nuklear(app_state* st) {
    static float prev = 0.0;
    if (prev != st->font_size) {
        app_update_font(st);
        prev = st->font_size;
    }
    struct nk_context* ctx = st->nk_ctx;
    int flags = NK_WINDOW_SCROLL_AUTO_HIDE | NK_WINDOW_TITLE;
    struct nk_rect pos = nk_rect(0,0,st->winw, st->winh);
    //try this too
    //int flags = NK_WINDOW_SCALABLE | NK_WINDOW_SCROLL_AUTO_HIDE | NK_WINDOW_TITLE | NK_WINDOW_MOVABLE | NK_WINDOW_CLOSABLE;
    //struct nk_rect pos = nk_rect((st->winw - WINDOW_WIDTH) / 2, (st->winh - WINDOW_HEIGHT) / 2, WINDOW_WIDTH, WINDOW_HEIGHT);
    if (nk_begin(ctx, "Consecutive Properties (SDL2)", pos, flags)) {
        nk_console_render(st->console);
    }
    nk_end(ctx);
}


static void app_frame(app_state* st) {
	SDL_Event evt;
	nk_input_begin(st->nk_ctx);
	nk_gamepad_update(nk_console_get_gamepads(st->console));
	while (SDL_PollEvent(&evt)) {
        switch (evt.type) {
        case SDL_QUIT: st->running = false; break;
        case SDL_KEYUP: if (evt.key.keysym.scancode == SDL_SCANCODE_ESCAPE) st->running = false; break;
        case SDL_WINDOWEVENT:
        {
            Uint8 win = evt.window.event;
            if (win == SDL_WINDOWEVENT_RESIZED || win == SDL_WINDOWEVENT_SIZE_CHANGED) {
                st->winw = evt.window.data1;
                st->winh = evt.window.data2;
            }
        }
        }
		nk_sdl_handle_event(&evt);
		nk_gamepad_sdl_handle_event(nk_console_get_gamepads(st->console), &evt);
	}
	nk_input_end(st->nk_ctx);

    app_frame_nuklear(st);

	SDL_SetRenderDrawColor(st->renderer, 0, 0, 0, 255);
	SDL_RenderClear(st->renderer);
	nk_sdl_render(NK_ANTI_ALIASING_ON);
	SDL_RenderPresent(st->renderer);
}

static void app_free_nuklear(app_state* st) {
    nk_gamepad_free(nk_console_get_gamepads(st->console));
    nk_console_free(st->console);
    nk_sdl_shutdown();
}

static void app_free(app_state* st) {
    app_free_nuklear(st);
    SDL_DestroyRenderer(st->renderer);
    SDL_DestroyWindow(st->window);
    SDL_Quit();
}

int main(void) {
    static app_state st = { 0 };
    app_init(&st);
    while (st.running) {
        app_frame(&st);
    }
    app_free(&st);
    return 0;
}

PavelSharp avatar Nov 06 '25 01:11 PavelSharp

Even if you resize the windows? (not the parent window of the program, but the nuklear window.)

StrikerTheHedgefox avatar Nov 06 '25 02:11 StrikerTheHedgefox

@StrikerTheHedgefox Of course, resizing the nuklear window does not trigger the issue. Everything works perfectly 🙂 Interactively tested with the NK_WINDOW_SCALABLE flag. I hope you’ll find some time to make changes in this small demo program.

PavelSharp avatar Nov 06 '25 02:11 PavelSharp

Unfortunately I don't have an environment set up where I can compile this demo right now. Whenever I try to compile the demos of nuklear_console, it errors out when trying to compile the SDL demo (I'm on windows, using mingw). My own project works in MSVC, but that took a lot of time and headache to set up. I'll try to set up a linux VM later, and see if I can get those demos going.

StrikerTheHedgefox avatar Nov 06 '25 02:11 StrikerTheHedgefox

@StrikerTheHedgefox Actually, I’m working in VS on Windows. I’m going to share my CMakeLists.txt, which handles almost everything automatically, but you’ll need to create a folder include\nuklear and put nuklear.h and nuklear_sdl_renderer.h there. But anyway, take your time

Here you go
cmake_minimum_required (VERSION 3.8)

if (POLICY CMP0141)
  cmake_policy(SET CMP0141 NEW)
  set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()

project ("Nuklear_Console" VERSION 1.0 LANGUAGES C)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")


include(FetchContent)
#FetchContent_Declare(
#    glfw
#    GIT_REPOSITORY https://github.com/glfw/glfw.git
#    GIT_TAG 3.3.8
#)
#FetchContent_MakeAvailable(glfw)

FetchContent_Declare(
    nuklear_gamepad
    GIT_REPOSITORY https://github.com/RobLoach/nuklear_gamepad.git
    GIT_TAG 49c1cba
)
FetchContent_MakeAvailable(nuklear_gamepad)  

FetchContent_Declare(
    nuklear_console
	GIT_REPOSITORY  https://github.com/RobLoach/nuklear_console.git
	GIT_TAG         "${master}"
	GIT_SHALLOW     TRUE
)	
FetchContent_MakeAvailable(nuklear_console)  

FetchContent_Declare(
    sdl2
    GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
    GIT_TAG release-2.28.4
    GIT_SHALLOW     TRUE
)
FetchContent_MakeAvailable(sdl2)

#add_library(nuklear INTERFACE)
#target_include_directories(nuklear INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src)


set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")

function(add_program TARGET_NAME)
    set(SOURCE_FILE ${SRC_DIR}/${TARGET_NAME}.c)
    add_executable(${TARGET_NAME} MACOSX_BUNDLE ${SOURCE_FILE})
    set_target_properties(${TARGET_NAME} PROPERTIES WIN32_EXECUTABLE $<CONFIG:Release>)
    target_link_options(${TARGET_NAME} PRIVATE "$<$<C_COMPILER_ID:MSVC>:/ENTRY:mainCRTStartup>")
    target_include_directories(${TARGET_NAME} PRIVATE ${INCLUDE_DIR})
    target_compile_options(${TARGET_NAME}
        PRIVATE
            $<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wall -Wextra -pedantic>
            $<$<C_COMPILER_ID:MSVC>:/W4>
    )
    target_link_libraries(${TARGET_NAME} PRIVATE nuklear_gamepad nuklear_console SDL2::SDL2 SDL2::SDL2main) #glfw 
endfunction()

add_program(main)

PavelSharp avatar Nov 06 '25 02:11 PavelSharp

Thanks, that's very helpful. Appreciate it.

StrikerTheHedgefox avatar Nov 06 '25 03:11 StrikerTheHedgefox