Currently trying to work out its particulars.
It adds drawing space out on the edges. I do like this, as it means extra drawing space, and can put down information that doesn't take over screen space on the game itself. It is also a handy way to produce a 1-to-1 scale visuals of things that are just off-screen. This idea was one of the things I loved seeing in lsnes, and it's nice to see it's in BizHawk as well.
However, the implementation details strike at me...
Let's start with the drawing origin. The coordinates of 0,0 where our top-left corner is. With BizHawk's client.SetGameExtraPadding, 0,0 is the top-left corner of the new drawing area, while lsnes' gui.top_gap and gui.left_gap has 0,0 always remain at the top-left corner of the game's area, with negative coordinates needed to reach the extended drawing area.
BizHawk's coordinates move relative to game drawing. So now we need to include an offset to keep whatever needs to remain as a game overlay. lsnes is static relative to game drawing, so an offset isn't necessary. Keeping an offset means extra information that needs to be tracked by the one making the script.
There's minimal interference between multiple scripts if the only gaps created are below and to the right, as 0,0 isn't moved anywhere. A few sample scripts I've seen leaves the left and top completely alone, probably for this reason. Once a second script is run, where one script has no prior information on the left or top, the display of that script gets ruined immediately with non-zero left or top extension.
Now, access to what the current drawing area is...
I'm not aware of any functions to give me the information of the current gaps. If I create a chain of scripts, I can't conveniently assign an off-screen space based on the order of scripts running. I'm not positive of any clean way to communicate between different scripts outside of global variables, and I have not experimented with how BizHawk handles them between scripts. If there are functions that do return numbers on the current gaps, I clearly haven't looked through the function list enough, and I apologize.
lsnes gap functions return a number specifying what the gap was previously if the same gap was called a second time that frame. When I'm chaining scripts, I just use a delta gap, which adds extra space on top of the space already there, and work in the number I was given to place the off-screen data further out so it doesn't overlap with previous off-screen data that's already there.
It can be as simple as giving client.SetGameExtraPadding a set of return values. There's no requirement for the script to have left, top, right, bottom= client.SetGameExtraPadding(l,t,r,b) to run it, it can just discard the return values and run client.SetGameExtraPadding(l,t,r,b) without assigning its returned values to anything, and if the script does want the return values, it can make use of it.
This third point does not irritate me, but it is still a difference between lsnes and BizHawk. There is one thing BizHawk does that is inconvenient with it, but other than that, nothing too major.
BizHawk's client.SetGameExtraPadding is something that you run once, and the gaps remain indefinitely until the function is called again. Assuming the information can be given to scripts later in the chain, a later script could theoretically make the one call and keep the values given in its own local variables and maintain proper position.
lsnes requires that its gap functions are called every time it wants to paint an update. Otherwise, the next time on_paint is called, the borders snap back to what they were originally, and you're back to the standard drawing area. Of course, the gap functions do return an important value if there's any desire to chain up some scripts.
The only problem is that the gaps created in BizHawk is that they last beyond the lifetime of the script. It doesn't feel as dynamic as how lsnes handles it, but assuming the code under client.SetGameExtraPadding isn't too expensive, I suppose it can be called every frame anyway so scripts can dynamically adjust themselves based on which ones are running or what sequence they're put in. Well, if the drawing area information can be picked up by the other scripts, that is.
Mostly, these are stuff that me, as a well-practiced lua script maker, can spot and get annoyed by. Novice script users probably won't worry too much about it, I mean, it's extra screen space that's easy to get. And it is useful as it stands right now.
Now, making the change in origin, keeping the 0,0 at the game's corner instead of the extended corner, will break scripts relying on this.
Adding how much information is given back to the user is probably not going to break any existing scripts.
The third point isn't critical, and since persistence is the current behavior, I would keep it persistent.
I do get annoyed by designs that don't turn out elegant, or at least doesn't fit my view (I'm me, therefore I'm important. Sorry). I hope my reasoning reflects well on anyone working on the lua functions.