Barring lucky pulls for better pilots my season 17 team is ready

Barring lucky pulls for better pilots my season 17 team is ready

The shoulder cannon Leo's lack their third core l, but given how ungodly expensive they grind is I am treating them as not making it.

I have backups for when this team inevitably stalls at Diamond like last season's team, but I am curious on how far they can as even odds are that g-unit content will drop right around s18 or possibly just after.

u/Cultural_Sand_9323 — 12 days ago

I want to be able to put in someone's friend code to fight their ML team

Title is self explanatory I would think.

Keeps player interaction at the current 'non-existent' but also allows people to go look up those weird and wonderful gimmick teams (oops All Char. Grampa Brigade, Wall of Zam, Zaku Patrol, etc etc.)

I forget where I found this other than the page was non-english, and i want a full squad of the little goofballs.

reddit.com
u/Cultural_Sand_9323 — 1 month ago

Day 3 150k

I won't have the benefit of helpful bonuses next season, so I'm savoring this as 'huh when the stars align my team of gooners can actually pull through.'

I dare not risk rerolling any of my opponents.

10 SSP chips secured. Next item on the agenda.... Stuck between waiting for 1.5 and trying to roll the pity banner til I either get it can Io Flemming g or rx78 amuro for double defenders.

u/Cultural_Sand_9323 — 1 month ago

Team Lowest Bidder - Success!

THE MEME TEAM LIVES!

Though... Given what I went through Diamond? I'm definitely hitting a wall til I get better defensive units, and get units SSP'd.

However I have demonstrated that Team Lowest Bidder even incomplete and even when terrain incompatable with itself? Can make it to Master.

Getting 150 for top reward in master? At this point.... No. Too much to do between SSPing units, getting dupes to plug holes for terrain (and hope that we get the G-Unit variants, though I'd count the MPD Build divers suits as leos too if those ever get added, waht with their gunpla kits coming with parts to make the stock leo.) Plus I need better defensive pilots and ... I really wish I'd been able to grab Milliardo Peacecraft support unit because good god.

Pilots:
Treize (Gundam Wing.)
(Plan on swapping treize out for UR Io Flemming for double defense)
UR Nu Gundam Amuro Rey
UR Mark Guilder (forget what unit.)
Noin EW (SP'd)
(Plan on swapping out for UR Amuro Rey for double defense)
UR Oliver May

Support:
Lady Une & Fortress Barge (One Star)
(If at all possible i plan on swapping out for Moorin due to the heal being better for the format than energy generation.)

Still. Team Lowest Bidder has, in spite of all defecancies, made it!
Edit: current score is 130k.

...in spitting distance if the prize.

u/Cultural_Sand_9323 — 1 month ago

Team Lowest Bidder Day 1 Season 15.5

I'm assuming I've found the wall with my current setup.

As one poster to a prior thread pointed out, half my team is terrain incompatible with itself. So 'oh... well noin wandered a bit far. She's dead'

Or on the opposite end. noin being the last woman standing.

But As also has been pointed out. I need double defender pilots.

Literally before Diamond league. Just a straight rocket straight up. Then Diamond and. 'Ah.... I'm only up by 20k points and with unit comp working against me I shouldn't be surprised.'

I may be able to break into master league this season, as I'm actually double where I ended up sitting at the end of Season 15 with the all chibi squad. But I've hit a point where 'Well, wha'd you expect out of this when half the squad is gimped and the whole squad is made of pure jank?'

SSP is going to take.... awhile, but I'm probably going after the shoulder cannon leos first because they gain space terrain, which will let me shuffle my squad around better.

Past that. 'Her'es hoping gacha decides to give me what other people consider filler' for the sake of dupes, or bandai decides to release the G-Unit leo and AWAC leo in a future update.

u/Cultural_Sand_9323 — 1 month ago

In all seriousness. How far can these guys go?

Finally fsrmed SP chips for all of em.

Nowhere near ssp for even one unit, and I have three units that don't match the terrain.

I don't have high hopes as is. But

The memes demand sacrifice!

Edit:
I have an SP'd ramba ral from gundam challange mode that i'm going ot see if he slots in better where EW Trowa is
And I'm looking at gacha UR Duo as a slot in for either noin or treize. Noin's attractive right now because she has an active movement skill.

Not sure what gear would help though.

Eh well. We find out how nuts i am, Monday. Time enough to hopefully finish leveling pilots and round out any weapons that aren't max leveled.

u/Cultural_Sand_9323 — 1 month ago

Assuming I end up ssp'ing all those and maxing the pilots, opinions on Team Lowest Bidder?

Unless g-unit introduces anything (if it ever gets added) or there is a compelling reason to use one of the Leo's not shown? That's going to be my eventual squad.

I am less certain on the pilots and took a guess on positioning.

u/Cultural_Sand_9323 — 1 month ago

OK, clearly I'm not doing something right here but I don't know what it is.

I'm getting bodied by teams with ten or fifteen fewer points than mine. So obviously I am not doing something correctly, even though sadly this is my best single squad as far as I know (I have all the SD units from the event last month.)

My account started early august. Not thirty days old yet. Just a case of needing time to develop a bench?

u/Cultural_Sand_9323 — 2 months ago

Flair Tags Added; Suggestions welcome

Well that's sorted. Lemme know if there isn't enough.

Sub's kinda under construction. Doing what I can to bring it up to snuff.

reddit.com
u/Cultural_Sand_9323 — 2 months ago
▲ 19 r/Earth25

Hey before the purge: Anyone able to archive/collect the three commas plotline into one document?

Because honestly? that one was pretty swanky. Turned out to be the big bang before the end.

Be a shame to lose it.

reddit.com
u/Cultural_Sand_9323 — 2 months ago

Nu-Gundam Paintjob Leo Variant When?

It has to either literally have the same stats as a standard leo and just embrace the meme.

or be UR.

There are no other acceptable outcomes.

u/Cultural_Sand_9323 — 2 months ago

I have an AI generated python script that lets me play Gundam G Generation in Waydroid that works and i don't know why or if it can be improved

Disclaimer: This was AI-assisted/generated. I understand enough Python to modify things and debug them, but I am very much not an expert in Wayland, waydroid, Android input, or Linux input subsystems. I spent roughly a long throwing diagnostics at this problem until something finally worked because I wanted to play a game and the problem is above my pay grade.

OS: Linux Mint 22.1 (experimental wayland rendering engine)
Physical hardware:
Haswell Era i5
RX550
16gb ram

Problem I wanted to solve: Apparently Waydroid just tells liniage 'OK this is a mouse' and liniage goes 'OK I can work with that.' And for most things that works. F-Droid, Google play store, PiePipe, Gems of war, a few other things I tossed in to test. Gundam G Eternal? 'No I refuse to recognize this 'mouse' device.

I have accidentally built (For a given definition of 'built' given AI involvement) a mouse-to-touchscreen bridge for Waydroid, and I would like someone smarter than me to explain why the hell it works.

TL;DR: I have a game running under Waydroid that doesn't properly respond to normal mouse input. Waydroid's native Wayland mouse handling produces bizarre/inconsistent touch coordinates in this particular game.

So I wrote a Python script that:

  • reads the physical mouse through evdev
  • asks Cinnamon Wayland where the actual mouse cursor is via D-Bus
  • keeps a persistent Waydroid shell open
  • converts left-clicks into Android input tap X Y
  • converts click-and-drag into Android motionevent DOWN/MOVE/UP

And... it works.

It works well enough that I can actually play the game. I can click things, hold things, and drag the game map/diagrams around.

The weird part is that Waydroid's own pointer handling was giving me a completely different result.

Here's the script:

#!/usr/bin/env python3

import subprocess
import threading
import time
from evdev import InputDevice, ecodes


# ------------------------------------------------------------
# Configuration
# ------------------------------------------------------------

MOUSE_DEVICE = "/dev/input/event2"

# How long the mouse button must remain down before movement
# is considered a drag rather than an ordinary click.
DRAG_DELAY = 0.15

# Minimum time between Android MOVE events.
# Prevents the mouse from flooding Waydroid.
MOVE_INTERVAL = 0.03


# ------------------------------------------------------------
# Mouse
# ------------------------------------------------------------

mouse = InputDevice(MOUSE_DEVICE)


# ------------------------------------------------------------
# Persistent Waydroid shell
# ------------------------------------------------------------

print("Starting persistent Waydroid shell...")

waydroid = subprocess.Popen(
    [
        "sudo",
        "waydroid",
        "shell",
    ],
    stdin=subprocess.PIPE,
    stdout=subprocess.DEVNULL,
    stderr=subprocess.DEVNULL,
    text=True,
    bufsize=1,
)


# ------------------------------------------------------------
# Cinnamon cursor position
# ------------------------------------------------------------

def get_cursor_position():
    try:
        result = subprocess.run(
            [
                "gdbus",
                "call",
                "--session",
                "--dest",
                "org.Cinnamon",
                "--object-path",
                "/org/Cinnamon",
                "--method",
                "org.Cinnamon.Eval",
                "global.get_pointer()",
            ],
            capture_output=True,
            text=True,
            timeout=0.2,
        )

        # Expected result:
        #
        # (true, '[497,872,16]')
        #
        text = result.stdout.strip()

        start = text.find("'[")
        end = text.find("]'", start)

        if start == -1 or end == -1:
            return None

        coords = text[start + 2:end]
        x, y, _ = coords.split(",")

        return int(x), int(y)

    except Exception:
        return None


# ------------------------------------------------------------
# Android input helpers
# ------------------------------------------------------------

def android_command(command):
    try:
        waydroid.stdin.write(command + "\n")
        waydroid.stdin.flush()
    except (BrokenPipeError, OSError):
        print("Waydroid shell connection lost.")


def android_tap(x, y):
    print(f"CLICK {x},{y}")

    android_command(
        f"input tap {x} {y}"
    )


def android_down(x, y):
    print(f"DOWN {x},{y}")

    android_command(
        f"input motionevent DOWN {x} {y}"
    )


def android_move(x, y):
    print(f"MOVE {x},{y}")

    android_command(
        f"input motionevent MOVE {x} {y}"
    )


def android_up(x, y):
    print(f"UP {x},{y}")

    android_command(
        f"input motionevent UP {x} {y}"
    )


# ------------------------------------------------------------
# State
# ------------------------------------------------------------

button_down = False
dragging = False

press_time = 0
last_move_time = 0

last_x = None
last_y = None


# ------------------------------------------------------------
# Startup
# ------------------------------------------------------------

print(f"Listening to: {mouse.name}")
print("Cinnamon-cursor Waydroid mouse-to-touch bridge running.")
print("Left click -> Android tap")
print("Hold + move -> Android touch drag")
print("Ctrl+C to stop.")


# ------------------------------------------------------------
# Main event loop
# ------------------------------------------------------------

try:

    for event in mouse.read_loop():

        # ----------------------------------------------------
        # Mouse movement
        # ----------------------------------------------------

        if event.type == ecodes.EV_REL:

            # Ignore movement unless left mouse button is down.
            if not button_down:
                continue

            # Get the actual Cinnamon cursor position.
            position = get_cursor_position()

            if position is None:
                continue

            x, y = position

            # If this is the first movement after pressing,
            # determine whether we've crossed the drag threshold.
            if not dragging:

                if time.monotonic() - press_time >= DRAG_DELAY:

                    dragging = True

                    android_move(x, y)

                    last_x = x
                    last_y = y
                    last_move_time = time.monotonic()

                continue

            # ------------------------------------------------
            # Already dragging
            # ------------------------------------------------

            now = time.monotonic()

            if now - last_move_time < MOVE_INTERVAL:
                continue

            # Don't send redundant coordinates.
            if x == last_x and y == last_y:
                continue

            android_move(x, y)

            last_x = x
            last_y = y
            last_move_time = now


        # ----------------------------------------------------
        # Mouse buttons
        # ----------------------------------------------------

        elif event.type == ecodes.EV_KEY:

            # Left button pressed
            if event.code == ecodes.BTN_LEFT and event.value == 1:

                position = get_cursor_position()

                if position is None:
                    continue

                x, y = position

                button_down = True
                dragging = False
                press_time = time.monotonic()

                last_x = x
                last_y = y

                # We don't immediately send DOWN.
                #
                # This lets a normal click continue using
                # Android's reliable "input tap" command.
                #
                # If the button is held long enough and the
                # mouse moves, we start a real touch sequence.

            # Left button released
            elif event.code == ecodes.BTN_LEFT and event.value == 0:

                if not button_down:
                    continue

                position = get_cursor_position()

                if position is None:
                    position = (last_x, last_y)

                x, y = position

                hold_time = time.monotonic() - press_time

                # ------------------------------------------------
                # Ordinary click
                # ------------------------------------------------

                if not dragging:

                    android_tap(x, y)

                # ------------------------------------------------
                # Drag release
                # ------------------------------------------------

                else:

                    android_up(x, y)

                button_down = False
                dragging = False


except KeyboardInterrupt:

    print("\nStopping...")


finally:

    try:
        waydroid.stdin.close()
    except Exception:
        pass

    try:
        waydroid.terminate()
    except Exception:
        pass

    print("Stopped.")

So my question is:

This works. Can someone with two functional brain cells that know Python, Wayland, and/or Android input explain WHY it works?

And, more importantly:

How would you make it better?

Things I'd especially like to understand:

  1. Why does asking Cinnamon's global.get_pointer() give me a better coordinate than Waydroid's native Wayland pointer handling?
  2. Why does input tap X Y work reliably when Waydroid's normal pointer input doesn't?
  3. Why does motionevent DOWN/MOVE/UP let me drag game areas even though ordinary Android scrollbars don't seem to respond?
  4. How should the mouse-down/mouse-up timing ideally be translated into touchscreen events?
  5. Is there a better way to obtain the Wayland cursor position than going through Cinnamon's D-Bus API?
  6. Is there a cleaner way to maintain the Waydroid connection than what I've hacked together?
  7. How portable is this outside Cinnamon/Wayland?
  8. And finally: how badly have I reinvented something that already exists?

I'm not claiming this is good code.

I'm claiming it works, which is currently winning the argument.

reddit.com
u/Cultural_Sand_9323 — 2 months ago

I have an AI generated python script that lets me play Gundam G Generation that works and i don't know why or if it can be improved

Disclaimer: This was AI-assisted/generated. I understand enough Python to modify things and debug them, but I am very much not an expert in Wayland, Android input, or Linux input subsystems. I spent roughly a long throwing diagnostics at this problem until something finally worked because I wanted to play a game and the problem is above my pay grade.

OS: Linux Mint 22.1 (experimental wayland rendering engine)
Physical hardware:
Haswell Era i5
RX550
16gb ram

Problem I wanted to solve: Apparently Waydroid just tells liniage 'OK this is a mouse' and liniage goes 'OK I can work with that.' And for most things that works. F-Droid, Google play store, PiePipe, Gems of war, a few other things I tossed in to test. Gundam G Eternal? 'No I refuse to recognize this 'mouse' device.

I have accidentally built (For a given definition of 'built' given AI involvement) a mouse-to-touchscreen bridge for Waydroid, and I would like someone smarter than me to explain why the hell it works.

TL;DR: I have a game running under Waydroid that doesn't properly respond to normal mouse input. Waydroid's native Wayland mouse handling produces bizarre/inconsistent touch coordinates in this particular game.

So I wrote a Python script that:

  • reads the physical mouse through evdev
  • asks Cinnamon Wayland where the actual mouse cursor is via D-Bus
  • keeps a persistent Waydroid shell open
  • converts left-clicks into Android input tap X Y
  • converts click-and-drag into Android motionevent DOWN/MOVE/UP

And... it works.

It works well enough that I can actually play the game. I can click things, hold things, and drag the game map/diagrams around.

The weird part is that Waydroid's own pointer handling was giving me a completely different result.

Here's the script:

#!/usr/bin/env python3

import subprocess
import threading
import time
from evdev import InputDevice, ecodes


# ------------------------------------------------------------
# Configuration
# ------------------------------------------------------------

MOUSE_DEVICE = "/dev/input/event2"

# How long the mouse button must remain down before movement
# is considered a drag rather than an ordinary click.
DRAG_DELAY = 0.15

# Minimum time between Android MOVE events.
# Prevents the mouse from flooding Waydroid.
MOVE_INTERVAL = 0.03


# ------------------------------------------------------------
# Mouse
# ------------------------------------------------------------

mouse = InputDevice(MOUSE_DEVICE)


# ------------------------------------------------------------
# Persistent Waydroid shell
# ------------------------------------------------------------

print("Starting persistent Waydroid shell...")

waydroid = subprocess.Popen(
    [
        "sudo",
        "waydroid",
        "shell",
    ],
    stdin=subprocess.PIPE,
    stdout=subprocess.DEVNULL,
    stderr=subprocess.DEVNULL,
    text=True,
    bufsize=1,
)


# ------------------------------------------------------------
# Cinnamon cursor position
# ------------------------------------------------------------

def get_cursor_position():
    try:
        result = subprocess.run(
            [
                "gdbus",
                "call",
                "--session",
                "--dest",
                "org.Cinnamon",
                "--object-path",
                "/org/Cinnamon",
                "--method",
                "org.Cinnamon.Eval",
                "global.get_pointer()",
            ],
            capture_output=True,
            text=True,
            timeout=0.2,
        )

        # Expected result:
        #
        # (true, '[497,872,16]')
        #
        text = result.stdout.strip()

        start = text.find("'[")
        end = text.find("]'", start)

        if start == -1 or end == -1:
            return None

        coords = text[start + 2:end]
        x, y, _ = coords.split(",")

        return int(x), int(y)

    except Exception:
        return None


# ------------------------------------------------------------
# Android input helpers
# ------------------------------------------------------------

def android_command(command):
    try:
        waydroid.stdin.write(command + "\n")
        waydroid.stdin.flush()
    except (BrokenPipeError, OSError):
        print("Waydroid shell connection lost.")


def android_tap(x, y):
    print(f"CLICK {x},{y}")

    android_command(
        f"input tap {x} {y}"
    )


def android_down(x, y):
    print(f"DOWN {x},{y}")

    android_command(
        f"input motionevent DOWN {x} {y}"
    )


def android_move(x, y):
    print(f"MOVE {x},{y}")

    android_command(
        f"input motionevent MOVE {x} {y}"
    )


def android_up(x, y):
    print(f"UP {x},{y}")

    android_command(
        f"input motionevent UP {x} {y}"
    )


# ------------------------------------------------------------
# State
# ------------------------------------------------------------

button_down = False
dragging = False

press_time = 0
last_move_time = 0

last_x = None
last_y = None


# ------------------------------------------------------------
# Startup
# ------------------------------------------------------------

print(f"Listening to: {mouse.name}")
print("Cinnamon-cursor Waydroid mouse-to-touch bridge running.")
print("Left click -> Android tap")
print("Hold + move -> Android touch drag")
print("Ctrl+C to stop.")


# ------------------------------------------------------------
# Main event loop
# ------------------------------------------------------------

try:

    for event in mouse.read_loop():

        # ----------------------------------------------------
        # Mouse movement
        # ----------------------------------------------------

        if event.type == ecodes.EV_REL:

            # Ignore movement unless left mouse button is down.
            if not button_down:
                continue

            # Get the actual Cinnamon cursor position.
            position = get_cursor_position()

            if position is None:
                continue

            x, y = position

            # If this is the first movement after pressing,
            # determine whether we've crossed the drag threshold.
            if not dragging:

                if time.monotonic() - press_time >= DRAG_DELAY:

                    dragging = True

                    android_move(x, y)

                    last_x = x
                    last_y = y
                    last_move_time = time.monotonic()

                continue

            # ------------------------------------------------
            # Already dragging
            # ------------------------------------------------

            now = time.monotonic()

            if now - last_move_time < MOVE_INTERVAL:
                continue

            # Don't send redundant coordinates.
            if x == last_x and y == last_y:
                continue

            android_move(x, y)

            last_x = x
            last_y = y
            last_move_time = now


        # ----------------------------------------------------
        # Mouse buttons
        # ----------------------------------------------------

        elif event.type == ecodes.EV_KEY:

            # Left button pressed
            if event.code == ecodes.BTN_LEFT and event.value == 1:

                position = get_cursor_position()

                if position is None:
                    continue

                x, y = position

                button_down = True
                dragging = False
                press_time = time.monotonic()

                last_x = x
                last_y = y

                # We don't immediately send DOWN.
                #
                # This lets a normal click continue using
                # Android's reliable "input tap" command.
                #
                # If the button is held long enough and the
                # mouse moves, we start a real touch sequence.

            # Left button released
            elif event.code == ecodes.BTN_LEFT and event.value == 0:

                if not button_down:
                    continue

                position = get_cursor_position()

                if position is None:
                    position = (last_x, last_y)

                x, y = position

                hold_time = time.monotonic() - press_time

                # ------------------------------------------------
                # Ordinary click
                # ------------------------------------------------

                if not dragging:

                    android_tap(x, y)

                # ------------------------------------------------
                # Drag release
                # ------------------------------------------------

                else:

                    android_up(x, y)

                button_down = False
                dragging = False


except KeyboardInterrupt:

    print("\nStopping...")


finally:

    try:
        waydroid.stdin.close()
    except Exception:
        pass

    try:
        waydroid.terminate()
    except Exception:
        pass

    print("Stopped.")

So my question is:

This works. Can someone with two functional brain cells that know Python, Wayland, and/or Android input explain WHY it works?

And, more importantly:

How would you make it better?

Things I'd especially like to understand:

  1. Why does asking Cinnamon's global.get_pointer() give me a better coordinate than Waydroid's native Wayland pointer handling?
  2. Why does input tap X Y work reliably when Waydroid's normal pointer input doesn't?
  3. Why does motionevent DOWN/MOVE/UP let me drag game areas even though ordinary Android scrollbars don't seem to respond?
  4. How should the mouse-down/mouse-up timing ideally be translated into touchscreen events?
  5. Is there a better way to obtain the Wayland cursor position than going through Cinnamon's D-Bus API?
  6. Is there a cleaner way to maintain the Waydroid connection than what I've hacked together?
  7. How portable is this outside Cinnamon/Wayland?
  8. And finally: how badly have I reinvented something that already exists?

I'm not claiming this is good code.

I'm claiming it works, which is currently winning the argument.

reddit.com
u/Cultural_Sand_9323 — 2 months ago