Niche FFXI Tips, Tricks And Other Oddities...

Eorzea Time
10:11 PM
 
 
 
Language: JP EN FR DE
Version 3.1
New Items
users online
Forum » FFXI » General » Niche FFXI Tips, Tricks and other oddities...
Niche FFXI Tips, Tricks and other oddities...
Offline
Posts: 5,190
By RadialArcana 2025-02-15 06:26:14
Link | Quote | Reply
 
How does Gearswap break the 1 second server rule? It obviously swaps gear around faster than the actual game is supposed to allow.
Offline
Posts: 777
By Kaffy 2025-02-15 06:33:24
Link | Quote | Reply
 
[+]
 Carbuncle.Maletaru
Online
Server: Carbuncle
Game: FFXI
user: maletaru
Posts: 3,224
By Carbuncle.Maletaru 2025-02-15 06:36:19
Link | Quote | Reply
 
RadialArcana said: »
How does Gearswap break the 1 second server rule? It obviously swaps gear around faster than the actual game is supposed to allow.

I haven't actually looked at the code for GS, but AFAIK it just sends a (series of?) packet saying "equip these 16 items". It doesn't send /equipset 102 to the server.

It can send these packets as often as it wants. Sometimes it sends commands saying "equip these 16 items, then cast this spell, then equip these 16 items" all in a single command.

It works entirely differently from in-game macros, which is why I keep insisting on how GD different it is, despite ignorant trolls saying "GS is just in-game macros in a .lua file" over and over for years. They're absolutely nothing alike.
[+]
Offline
By Shichishito 2025-02-15 06:37:15
Link | Quote | Reply
 
I don't think it's a "server rule". The server takes information in chunks called packets afaik, in FFXI case that hapens in a set interval of 2 or 3 times each second, either way extremely few for todays standards.

The up rounding to a full second is a macro specific thing that happens on your PC within FFXI, independant from server packets.
[+]
Offline
Posts: 5,190
By RadialArcana 2025-02-15 06:43:11
Link | Quote | Reply
 


So in theory an addon could be made that removed this 1 second limitation for everyone, not just people using GS.
 Shiva.Thorny
Offline
Server: Shiva
Game: FFXI
user: Rairin
Posts: 3,214
By Shiva.Thorny 2025-02-15 07:04:52
Link | Quote | Reply
 
When the client is told to create a packet, it goes through a series of checks before adding it to the internal packet queue. For equipset, it checks if another equipset has been sent in the last 1 second. For single slot equip, it checks if another single slot equip of the same slot has been sent in the last second. If either is true, the packet won't be queued. It's not macro specific, typed commands or multiple macros or even equip screen swaps will still face the same limits. If you've ever tried to move a bunch of items quickly with the ingame interface, you've probably noticed that they don't go through if you move faster than 1 item/sec (same issue here).

When windower inserts packets, none of these checks are followed. The server doesn't enforce any of it.

It would be possible to hook the function that evaluates whether another packet can be sent and alter the result for specific packets. I am not sure if it'd allow you to guarantee the same order (equipset->action->equipset) in the actual outgoing block like GS. Probably can't do it in an addon either, you'd need at least a sidecar DLL file since windower's plugin API isn't public. Definitely an interesting idea for people who wanted to split the difference and have better precasts without committing to a full GS file.
 Phoenix.Iocus
Offline
Server: Phoenix
Game: FFXI
user: androwe
Posts: 1,869
By Phoenix.Iocus 2025-02-15 07:44:49
Link | Quote | Reply
 
Not looking to divert. Just asking tinfoil questions.

Is there any reason that equipsets would execute in game actions faster than macros using gearswap in the background that mimics just the basic functionality of equipsets?
 Shiva.Thorny
Offline
Server: Shiva
Game: FFXI
user: Rairin
Posts: 3,214
By Shiva.Thorny 2025-02-15 07:51:49
Link | Quote | Reply
 
Phoenix.Iocus said: »
Is there any reason that equipsets would execute in game actions faster than macros using gearswap in the background that mimics just the basic functionality of equipsets?

Not really. If you mean measurable performance, they will both be the first frame after the next packet interval so the difference will be less than 1/30 second and depend on which aligns closer to the frame timing-wise than anything based on performance. (If the technically slower option resulted in a frame occurring sooner after the packet interval, it might be effectively faster.)

In terms of cpu time, it'd be difficult to gauge but I assume gearswap is slower than client. In this case, you're talking about nanoseconds, it doesn't matter at all.
[+]
 Asura.Pergatory
Offline
Server: Asura
Game: FFXI
user: Pergatory
Posts: 1,464
By Asura.Pergatory 2025-02-15 15:45:23
Link | Quote | Reply
 
Maquette Ring works in Ambuscade
[+]
 Fenrir.Svens
Offline
Server: Fenrir
Game: FFXI
user: Tenkey
Posts: 137
By Fenrir.Svens 2025-02-15 21:18:49
Link | Quote | Reply
 
Buffs that persist upon zoning appear to the left/before the food icon, buffs that wear upon zoning appear to the right/after the food icon. Just in case you want to load up on the absolute maximum amount of buffs for whatever reason.
[+]
 Cerberus.Dekar
Offline
Server: Cerberus
Game: FFXI
user: Dekar1
Posts: 256
By Cerberus.Dekar 2025-02-15 21:24:46
Link | Quote | Reply
 
Sigil works in Odyssey for the Regen, Refresh, and extended food duration.
[+]
Offline
Posts: 777
By Kaffy 2025-02-27 18:06:59
Link | Quote | Reply
 
Real minor one here, but I like it. When you set your home point, the game saves your position and camera angle relative to the home point so you can take off running in the right direction and see what you want to. Warping to another homepoint sets your position and camera to a default.
[+]
 Fenrir.Skarwind
Offline
Server: Fenrir
Game: FFXI
user: Skarwind
Posts: 3,425
By Fenrir.Skarwind 2025-02-27 18:25:07
Link | Quote | Reply
 
Asura.Pergatory said: »
Maquette Ring works in Ambuscade

IIRC all of the legion items do. I used to use that STR/DA ring at one point.
[+]
 Carbuncle.Nynja
Offline
Server: Carbuncle
Game: FFXI
user: NynJa
Posts: 5,027
By Carbuncle.Nynja 2025-02-27 18:55:29
Link | Quote | Reply
 
Kaffy said: »
Warping to another homepoint sets your position and camera to a default.
I think this was one of the things that set off red flags on the iteration of superwarp.
 Bahamut.Senaki
Offline
Server: Bahamut
Game: FFXI
user: Senaki
Posts: 207
By Bahamut.Senaki 2025-02-27 22:18:31
Link | Quote | Reply
 
You can learn the Blu Spell "Mighty Guard" from the RoV fight Mission 3-17 (No Time like the Future). This bypasses the need to farm access to Shinryu.
[+]
 Asura.Anybody
Offline
Server: Asura
Game: FFXI
user: Sisqo
Posts: 27
By Asura.Anybody 2025-02-28 00:59:35
Link | Quote | Reply
 
You don't lose invisible if you get onto a mount.
Online
Posts: 53
By Hovann 2025-02-28 13:56:07
Link | Quote | Reply
 
Hold [Tab] and [Shift] while on your non-chocobo/non-vehicle/non-floating mount and you can moonwalk with it by going backwards.

And if you turn your mount as you press those two and hold the opposite direction, you can moonwalk sideways while blaring the first few notes of Billie Jean.
[+]
Offline
By LightningHelix 2025-02-28 14:05:24
Link | Quote | Reply
 
Bahamut.Senaki said: »
You can learn the Blu Spell "Mighty Guard" from the RoV fight Mission 3-17 (No Time like the Future). This bypasses the need to farm access to Shinryu.
You can also learn it from someone else's mission 3-17, because you can't repeat that mission yourself once you're past it.

And if the person who doesn't have the clear yet disconnects on purpose, you can kill it and then have them reconnect without the clear, in case you don't learn it the first time!
[+]
Offline
Posts: 1,958
By Felgarr 2025-02-28 16:12:23
Link | Quote | Reply
 
Hovann said: »
Hold [Tab] and [Shift] while on your non-chocobo/non-vehicle/non-floating mount and you can moonwalk with it by going backwards.

And if you turn your mount as you press those two and hold the opposite direction, you can moonwalk sideways while blaring the first few notes of Billie Jean.

I like to do this with crawler mounts and pretend I'm in Tokyo Drift.
[+]
 Asura.Buffyslyph
Offline
Server: Asura
Game: FFXI
Posts: 112
By Asura.Buffyslyph 2025-02-28 19:22:51
Link | Quote | Reply
 
You don't have to pay for ffxi if you turn your subscription off.
[+]
 Leviathan.Wiccaan
Offline
Server: Leviathan
Game: FFXI
user: Wiccaan
Posts: 29
By Leviathan.Wiccaan 2025-03-05 18:32:32
Link | Quote | Reply
 
Regarding the equipment set discussions above; I have released a new addon for Ashita v4, called quicksets, that accomplishes the desired effect. This allows you to stack multiple equipsets into a single command/macro, and allows them to be properly queued and sent to the server. The order in which things are done in the macro are preserved properly as well (ie. equipset -> action -> equipset) as long as the player is not using another addon or plugin that is rewriting the manner in which equip/equipset packets are being sent.

With my addon, you can now do things such as:
Code
/equipset 1
/ma "Cure" <t>
/equipset 2

Normally the client would give a command error on the second equipset attempt.

For those interested, you can find my new quickset addon on the Ashita Discord server, in the 'v4-beta-plugins' channel.

~~~

For any of the fellow nerds that are interested in how this works, there are three different patches that need to be done to the client in order for this to work.

1. /equipset Command Delay

The equipset command has a built-in delay it uses to prevent the command from being used too fast. This delay is 900ms and is checked after some other validation takes place first. The delay check looks like this:
Code
    ret = FUNC_Equipset_CheckReuseDelay(); // This function is just: return FUNC_ntTimeNowGet() - PTR_LastEquipsetTime > 900;
    if (ret)
    {
        PTR_LastEquipsetTime = FUNC_ntTimeNowGet();

        // process and perform the equipset here..
    }


If the 'FUNC_Equipset_CheckReuseDelay' function returns false, then the timing check failed and the equipset attempt is blocked. Otherwise, the equipset attempt is allowed and the 'PTR_LastEquipsetTime' is updated with the current timestamp, then the equipset attempt is processed. The patch here is to ignore the time check and just always process the equipset attempt.

2. Command System Delay

When the game client processes a command handler, it uses the handlers return value to determine if additional command attempts should be allowed to happen without a delay. This is used as a means to prevent spamming certain commands and causing extra traffic to the server that does not need to happen. The last part of the equipset command handler determines if the equipset attempt was successful or not and if continued use of the command should be prevented/delayed or not. That looks like this:
Code
    if (FUNC_Equipset_Equip(equip_set_id, echo))
        return cmd_num;
    else
        return -cmd_num;


To prevent the client from blocking multiple equipset commands in a row, a patch is needed here to alter the return value.

3. Equipset Packet Queueing

The game client is designed to queue packets into chunks and send them at a calculated interval. (This system was designed with 56k modems in mind, allowing the game to function on dial-up internet.) This queue system has several arguments that are used when the client is attempting to queue a packet to be sent which determines how the packet will be processed and queued. These arguments include things such as checking for a delay between the same kind of packet attempt, overwriting an existing packet of the same kind that is already queued, or allowing for multiple of the same packet to be present in the same chunk. The call to queue an equipset packet looks like this:
Code
pkt = FUNC_gcZoneSendQueSearch(0x51, 0, 0);
if (!pkt)
    return 0;

// snipped the packet building code here..

FUNC_gcZoneSendQueSet(pkt, 0x48, 0);


The normal behavior of this packet is to not allow additional equipset packets to be queued if one is already present. The first valid equipset attempt is honored and queued, while additional ones are ignored until the queue is processed, send to the server and cleared. The patch here is to change the argument that prevents multiple of the same opcode to be queued.
[+]
Offline
Posts: 966
By Tarage 2025-03-05 18:59:48
Link | Quote | Reply
 
Have another Summoner one: Cait Sith can give Reraise III with infinite duration. Cait Sith's 1hr gives everyone on your party RR3 and casts Arise on any dead party member. The resulting RR3 has no timer and will last until you either tick it off manually or change jobs. I try to always keep it on in case of emergency. Sadly it still gets eaten by trove...
[+]
 Leviathan.Wiccaan
Offline
Server: Leviathan
Game: FFXI
user: Wiccaan
Posts: 29
By Leviathan.Wiccaan 2025-03-05 19:54:46
Link | Quote | Reply
 
From the earlier discussions in this topic; to help dispel the misinformation regarding the way the client treats and handles waits, here is how that works in the client.

The client has a single function that is used to parse and determine the delay times that will be used from a /wait command or an inline <wait..> tag. That function is called FsMacroContainer::_checkWaitCommand and looks like this:
Code
int __stdcall FUNC_FsMacroContainer__checkWaitCommand(char *str, uint32_t *start_time, uint32_t *wait_time)
{
    char *ptr1; // eax
    const char *ptr1_; // esi
    char *ptr2; // eax
    int cnt1; // eax
    int cnt2; // eax
    int wait; // [esp+8h] [ebp-244h] BYREF
    char v10[64]; // [esp+Ch] [ebp-240h] BYREF
    char buffer[512]; // [esp+4Ch] [ebp-200h] BYREF

    ptr1 = strstr(str, "<wait");
    ptr1_ = ptr1;
    if ( ptr1 )
    {
        ptr2 = strstr(ptr1, ">");
        if ( ptr2 )
        {
            ptr2[1] = 0;
            cnt1 = sscanf(ptr1_, "<wait%d>", &wait);
            *ptr1_ = 0;
            if ( cnt1 != 1 )
            {
                wait = 1;
LABEL_6:
                *start_time = FUNC_ntTimeNowGet();
                *wait_time = 1000 * wait;
                return 0;
            }
            if ( (unsigned int)wait <= 60 )
                goto LABEL_6;
        }
        return 0;
    }

    FUNC_FsTextInput_convertToString2(PTR_g_fsTextInput, str, strlen(str), (int)buffer, 512, 0, 0);

    cnt2 = sscanf(buffer, "%s %d", v10, &wait);
    if ( strcmp(v10, "/wait") || wait <= 0 || wait > 60 )
        return 0;

    if ( cnt2 == 1 )
        wait = 1;

    *start_time = FUNC_ntTimeNowGet();
    *wait_time = 1000 * wait;

    return 1;
}


The most common bit of misinformation regarding wait times is that they allow for fractions of a second. This is not true. The client specifically parses (scans) the delay amount from the command/tag as an integer via the '%d' formatter. This means that it will not accept decimal numbers, at all.

The next bit of misinformation is how the client handles the value and if it performs rounding. (ie. people claiming it rounds to the nearest 1) This is not true and there is no rounding performed, at all. Again, the client is reading a signed integer value from the string using the 'sscanf' call. When the '%d' formatter is used, it ignores the decimal place entirely and only uses the whole number given, if one was found.

The manner in which the client treats /wait commands vs. the inline <wait..> tags is also different. This is likely where the misunderstanding is coming from as the command form does not have a default fallback value, while the inline tag does.

When using the /wait command, there is no fallback value if an invalid wait time is given. Instead, the client will simply ignore the wait altogether. The function will fail and return false and the wait_time argument will not be set.

To give some examples of this, here is how this function would treat the following command attempts:
Code
/wait       - Returns false; no wait happens.
/wait 0     - Returns false; no wait happens. 
/wait 0.1   - Returns false; no wait happens.
/wait 0.9   - Returns false; no wait happens.
/wait 1     - Returns true; wait is 1000ms.
/wait 1.1   - Returns true; wait is 1000ms.
/wait 1.9   - Returns true; wait is 1000ms.
/wait 60    - Returns true; wait is 60000ms.
/wait 61    - Returns false; no wait happens.


Here you can see how fractions of a second are not handled and are ignored. The '%d' formatter used with 'sscanf' will only accept a valid integer value and ignore the decimal place entirely. (Note: While not that interesting, it is also valid to prefix numbers in this formatting method with a -/+ to denote a negative or positive number. FFXI will allow for positive prefixes, but considers negative ones invalid as the number falls below its clamped value of 0. This means that it is valid to use /wait 2 and /wait +2 to mean the same thing.)

The function will then check if the value falls within a clamped range to be considered invalid.
This range is: <= 0 || > 60

This means that only values 1 to 60 (inclusive) are valid for the /wait command.

When using the inline <wait..> tags, there is a fallback value of 1. However, the fallback value is only used under certain conditions. There are still times where the wait will be invalid/rejected. The following table shows some examples of how the inline tag is treated:
Code
// The following uses the 1000ms fallback time..

/wave <wait>     - Returns false; wait is 1000ms.

// The following are all treated as a wait of 0..

/wave <wait0>    - Returns false; no wait happens.
/wave <wait 0>   - Returns false; no wait happens.
/wave <wait0.1>  - Returns false; no wait happens.
/wave <wait 0.1> - Returns false; no wait happens.

// The following all only see the wait value of 1..

/wait <wait1>    - Returns false; wait is 1000ms.
/wait <wait 1>   - Returns false; wait is 1000ms.
/wait <wait1.5>  - Returns false; wait is 1000ms.
/wait <wait 1.5> - Returns false; wait is 1000ms.
/wait <wait1.9>  - Returns false; wait is 1000ms.
/wait <wait 1.9> - Returns false; wait is 1000ms.

// The following demonstrate the range limit and negative prefix..

/wave <wait 60>  - Returns false; wait is 60000.
/wave <wait 61>  - Returns false; no wait happens. (Outside the valid range.)
/wave <wait +60> - Returns false; wait is 60000. (Valid positive prefix.)
/wave <wait -60> - Returns false; no wait happens. (Invalid negative prefix.)


Here you can see the fractions are again, ignored entirely and no rounding happens. The value(s) after the decimal are just simply ignored, only making use of the integer value prior to it. (You could consider this a means of flooring, but it's technically not.) The inline wait tag also allows for the delay value to be directly after the word wait, or can contain a space between the word and the number value. It also supports the positive/negative prefixes while negative ones will be considered invalid due to the value range clamping. (1 to 60 inclusive.)

While not important to this discussion, some may notice that this function always returns false when processing an inline tag, even if a valid wait time is returned. This is because the command handler uses the functions return (true/false) to determine if the current processed command is delayed or not. When using a /wait command, the command itself needs to be delayed, and will cause this function to return true when a valid wait is detected. Otherwise, when processing an inline wait tag, the function will return false, allowing the command being processed currently to fire immediately, while then applying the delay to the next command.

~~~

tldr; The client does not support decimals in wait times.
[+]
 Ragnarok.Martel
Online
Server: Ragnarok
Game: FFXI
Posts: 3,011
By Ragnarok.Martel 2025-03-06 10:47:38
Link | Quote | Reply
 
I've tested and posted a much less technical and detailed version of this sort of thing multiple times, but the idea always seems to pop up again. <,<;

Perhaps such an in-depth case by case explanation will sink in better if we can point enough ppl at it. Great post. Thank you.
Offline
Posts: 777
By Kaffy 2025-03-06 11:33:57
Link | Quote | Reply
 
So I guess then the aby vnm trick is only possible because of ja0wait?
 Shiva.Thorny
Offline
Server: Shiva
Game: FFXI
user: Rairin
Posts: 3,214
By Shiva.Thorny 2025-03-06 11:43:35
Link | Quote | Reply
 
Kaffy said: »
So I guess then the aby vnm trick is only possible because of ja0wait?

VNM trick happens because the server cancels the old attempt to pop when it sees a new one. JA0Wait isn't necessary, nor is any mod, if you rest fast enough it could still occur. You wouldn't be able to move as easily though, so you might have to just mash heal while standing in a place near it until it wanders onto you.

It is *much* easier to accomplish consistently if you use an alternative method to get around the delay between rests. Even easier if you also modify the S>C packet to show you standing the whole time, though you'll be sliding around to everyone else.

Edit: I still wouldn't take 'can be done vanilla' to mean it is 110% safe. I highly doubt SE will do anything about it, but it would still be clear intent if you popped it that way numerous times. Exploiting systems using vanilla is still against TOS.
[+]
VIP
Offline
Posts: 914
By Lili 2025-03-06 12:46:43
Link | Quote | Reply
 
Leviathan.Wiccaan said: »
tldr; The client does not support decimals in wait times.

There was, for a while, a JP blog that claimed that <wait 0> tags would force the client to wait for the command to resolve before moving onto parsing the successive. Such "info" certainly did not help reduce the confusion.
Offline
Posts: 112
By Moonlightagb 2025-03-06 18:08:17
Link | Quote | Reply
 
If you turn on the jobemote filter in the chat filters so you can't see them anymore, you can still use the emote even though you can't see it but everyone else will. Doing this allows you to "jobemote nin" and move around instead of being posed in place on top of the frog, and everyone will see a giant frog moving around
 Carbuncle.Nynja
Offline
Server: Carbuncle
Game: FFXI
user: NynJa
Posts: 5,027
By Carbuncle.Nynja 2025-03-06 18:21:05
Link | Quote | Reply
 
I wouldnt do that because someone who doesnt know better is gonna assume you're cheating and mash those GM reports.

I'm sure it looks hilarious to others, but I wouldnt want to risk that on my accts.
 Ragnarok.Jukiro
Offline
Server: Ragnarok
Game: FFXI
user: ikariiiii
Posts: 206
By Ragnarok.Jukiro 2025-03-06 23:02:45
Link | Quote | Reply
 
iirc you can /jobemote nin and then /jump and be able to move around with only the frog mostly visible