[Question]
  [
Anyone remember [Boaty](https://en.wikipedia.org/wiki/Boaty_McBoatface)?
You could totally make any old word, right?
* Write a function to turn a string into Somethingy McSomethingface.
* It should accept one string as input. Ignore the case of the input.
* If the word ends in 'y', your function should not add an additional 'y' to the first instance, but should remove it in the second instance.
* If the word ends in 'ey', it should not have an additional 'y' added in the first instance, but should remove both in the second instance.
* The output should only have upper case letters in the first character, the 'M' of 'Mc' and the first character after 'Mc'.
* it only needs to work with strings of 3 or more characters.
Examples:
```
boat                  =>  Boaty McBoatface
Face                  =>  Facey McFaceface
DOG                   =>  Dogy McDogface
Family                =>  Family McFamilface
Lady                  =>  Lady McLadface
Donkey                =>  Donkey McDonkface
Player                =>  Playery McPlayerface
yyy                   =>  Yyy McYyface
DJ Grand Master Flash =>  Dj grand master flashy McDj grand master flashface
```
  
[Answer]
# [V](https://github.com/DJMcMayhem/V), 27 ~~28~~ ~~30~~ bytes
```
Vu~Ùóe¿y$
Hóy$
ÁyJaMc<Esc>Aface
```
[Try it online!](https://tio.run/##K/v/P6y07vDMw5tTD@2vVOHyOLwZSB5urPRK9E2WdkxLTE79/z8tNTI5NRIA "V – Try It Online")
`<Esc>` represents `0x1b`
* Golfed two bytes after learning that we did not need to support inputs with less than 3 characters.
* 1 byte saved thanks to @DJMcMayhem by working on the second line before the first one, thus removing the `G`
The input is in the buffer. The program begins by converting everything to lowercase
`V` selects the line and `u` lowercases it
`~` toggles the case of the first character (converting it to uppercase)
and `Ù` duplicates this line above, leaving the cursor at the bottom line
`ó` and replaces `e¿y$`, compressed form of `e\?y$` (optional `e` and a `y` at the end of the line), with nothing (happens on the second line)
`H` goes to the first line
`ó` replaces `y$` (`y` at the end of the line) with nothing on the first line
`Á` appends a `y` to the end of the first line
`J` and joins the last line with the first with a space in the middle, and the cursor is moved to this space
`a` appends `Mc` (`<Esc>` returns to normal mode)
`A` finally, appends `face` at the end of the line
[Answer]
# Python, 144 bytes
```
def f(s):
 s=s[0].upper()+s[1:].lower()
 y=lambda s:s[:-1]if s[-1]=='y'else s
 t=y(s)
 u=s[:-2]if s[-2:]=='ey'else y(s)
 return t+'y Mc%sface'%u
```
[Try it online here](https://tio.run/##TY7LCsIwEEX3@YrZSFp8oF0Gsiu6UfyA0EVsJ1isScmkSL6@Nlofs5l7Lodh@hiuzhbj2KABk1EuGJAkta02Q9@jz/IlqZ2oNp17JGIQZafvl0YDCVJivataA6SmLSWPHDtCIAZBxukYg0EmqZilQiQLZ@1teAyDtxCWPMKpXpDRNfLFwJhxHgJSqPXkthYUg2n4xenAV@@8T@6cy/PhV9/bLn7oqJtvLp294ZfgL74mYSVeTe9bGzKTfT7I83F8Ag)
[Answer]
# Excel, ~~204~~ ~~144~~ ~~137~~ 165 bytes
```
=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(REPT(REPLACE(LOWER(A1),1,1,UPPER(LEFT(A1)))&"~",2),"~","y Mc",1),"yy ","y "),"ey~","~"),"y~","~"),"~","face")
```
From the inside outwards:
```
REPLACE(LOWER(A1),1,1,UPPER(LEFT(A1)))      Replaces PROPER to handle space-delimited cases
REPT(%&"~",2)                   Duplicate.                    Donkey~Donkey~
SUBSTITUTE(%,"~","y Mc",1)      Replace first ~.              Donkeyy McDonkey~
SUBSTITUTE(%,"yy ","y ")        Handle words ending in 'y'.   Donkey McDonkey~
SUBSTITUTE(%,"ey~","~")         Handle words ending in 'ey'   Donkey McDonk~
SUBSTITUTE(%,"y~","~")          Handle words ending in 'y'    Donkey McDonk~
SUBSTITUTE(%,"~","face")        Adding face.                  Donkey McDonkface
```
---
Old answer, creating all bits separately, and then concatenating (176 bytes).
Does not handle space-delimited cases correctly.
```
=PROPER(A1)&IF(LOWER(RIGHT(A1,1))="y",,"y")&" Mc"&IF(LOWER(RIGHT(A1,2))="ey",LEFT(PROPER(A1),LEN(A1)-2),IF(LOWER(RIGHT(A1,1))="y",LEFT(PROPER(A1),LEN(A1)-1),PROPER(A1)))&"face"
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~42~~ ~~37~~ 35 bytes
```
{S/y$//~"y Mc{S/e?y$//}face"}o&tclc
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYPu/Oli/UkVfv06pUsE3GchJtQdxa9MSk1OVavPVSpJzkv9bcxUnViqkaajEayqk5Rcp2CTlJ5YouAGVKLj4uwMZuZk5lQo@iSmVCi75edmplQoBOYmVqUV2/wE "Perl 6 – Try It Online")
[Answer]
# [C# (.NET Core)](https://www.microsoft.com/net/core/platform), ~~122~~ ~~108~~ ~~139~~ ~~175~~ ~~180~~ ~~179~~ 154 bytes
Thanks a lot, lee!
```
s=>((s.EndsWith("y")?s:s+"y")+" Mc"+(s+"$").Replace("ey$","")+"face").Replace(s,s.ToUpper()[0]+s.Substring(1).ToLower()).Replace("y$","").Replace("$","");
```
[Try it online!](https://tio.run/##TVDRagIxEHy@@4ol@JDj7NG@arUPtQpFqdQWEfEhxqihZ3Jkc8oh9@3XjVewITCzO7AzjMQHaZ1qStTmAIsKvTr14yi8uCi3uZYgc4EIc2cPTpziaxz97dELT3C2egczoQ1P4ojU6CwcaFOUHgZg1GW9gSvbWuFZl42FVASjj8ltOOm8IjIVuwAja35UIPNcVMoRqarb/h0mTphgQukcjCnPkUEdYtIfl0Y@o3eUvwstDmFF3g0Ohpxj9mZ2uNT@yFnFkhfsYRpIymAmWcpp6rAk@1RFTuE4U1WHPIO@D2HvCnYx@7LfRaEcT9aPmxSzRbltDflTQtrUXoL279jfrfuinfsNUPA99S7kEXgoDKmytrUkaKHH6NUatLnKlk57NdWGMkAKrAeMYMUxSUIFdRwD1HHd/AI "C# (.NET Core) – Try It Online")
# C# (.NET Core, with LINQ), 152 bytes
```
s=>((s.Last()=='y'?s:s+"y")+" Mc"+(s+"$").Replace("ey$","")+"face").Replace(s,s.ToUpper()[0]+s.Substring(1).ToLower()).Replace("y$","").Replace("$","");
```
[Try it online!](https://tio.run/##TVHfa8IwEH5u/oojCCbUle1VV/cwURiVyX4wRHyINWpZTbpcqxTxb@8uVtAQ@O7uI3dfvkvxIbVONxVmZgufNZZ6P2D3WZRk5m/AAn9YUa3yLIU0V4gwc3br1J6dWHCtY6lKgoPN1jBVmRGSBcQGB@UgM0VVQgxGHxdLOPGVVSXv8bFKNcHofXJJ9lleU5CotYeRNb/aB7Nc1dpRUNeX@htMnDJ@CEl0MCY9Ow5nL5PuuDLpM5aOPtGDFocwp9kNxkMhMEromZBx3K27L9jHkNdchhymKQ8FZR0uow9d5CRNcF13aKLnN17qjcEeRl/2uyi0E3LxuAwx@qxW7TjxJIlL7NFzd82uvW6FNh80QLI3tAiV7kB4u5AMaz2TnvMuBq/WoM119OOyUtNaSAOEwPvACeYCpfQGnBkDOLNz8w8 "C# (.NET Core) – Try It Online")
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~61~~ 49 bytes
```
->s{s.capitalize=~/(e)?y$|$/;"#$`#$1y Mc#$`face"}
```
[Try it online!](https://tio.run/##DcxBCsIwEEDRqwxJBF3Y4lpSN0U3igcQwTQmGFptMVNkTOLVY3bvb/577ihbmdeND77SanKoBvc18lcvzWpHIop6y7i4cbEhOOkiq7RhKS8@oRsVwr4ktOdDwdMNBEd1J2jHV28oVUbpB4SIEaYZPTAeMIFsgAd7wWsqmz8 "Ruby – Try It Online")
Saved 12 sweet bytes thanks to @MartinEnder:
* a slimmer regular expression, which made use of
* some of [Ruby's special global variables](http://ruby-doc.org/core-2.5.0/Regexp.html#class-Regexp-label-Special+global+variables) which I tend to forget, and
* bracketless string interpolation (see e.g. <https://codegolf.stackexchange.com/a/52357/11071>), which I never knew existed.
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 26 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
ëO╛εh╕⌠î&!}∞┌C^U╟«äδ◙Bg⌠└¿
```
[Run and debug it](https://staxlang.xyz/#p=894fbeee68b8f48c26217decda435e55c7ae84eb0a4267f4c0a8&i=boat%0AFace%0ADOG%0AFamily%0ALady%0ADonkey%0A+ey%0Ayyy&a=1&m=2)
```
^           convert input to upper case                     "FACE"
B~          chop first character and push it back to input  70 "ACE"
v+          lowercase and concatenate                       "Face"
c'yb        copy, push "y", then copy both                  "Face" "Face" "y" "Face" "y"
:]          string ends with?                               "Face" "Face" "y" 0
T           trim this many character                        "Face" "Face" "y"
+           concatenate                                     "Face" "Facey"
p           output with no newline                          "Face"
"e?y$"z     push some strings                               "Face" "e?y$" ""
" Mc`Rface  execute string template; `R means regex replace " Mc Faceface"
            result is printed because string is unterminated
```
[Run this one](https://staxlang.xyz/#c=%5E+++++++++%09convert+input+to+upper+case++++++++++++++++++++%09%22FACE%22%0AB%7E++++++++%09chop+first+character+and+push+it+back+to+input+%0970+%22ACE%22%0Av%2B++++++++%09lowercase+and+concatenate++++++++++++++++++++++%09%22Face%22%0Ac%27yb++++++%09copy,+push+%22y%22,+then+copy+both+++++++++++++++++%09%22Face%22+%22Face%22+%22y%22+%22Face%22+%22y%22%0A%3A]++++++++%09string+ends+with%3F++++++++++++++++++++++++++++++%09%22Face%22+%22Face%22+%22y%22+0%0AT+++++++++%09trim+this+many+character+++++++++++++++++++++++%09%22Face%22+%22Face%22+%22y%22%0A%2B+++++++++%09concatenate++++++++++++++++++++++++++++++++++++%09%22Face%22+%22Facey%22%0Ap+++++++++%09output+with+no+newline+++++++++++++++++++++++++%09%22Face%22%0A%22e%3Fy%24%22z+++%09push+some+strings++++++++++++++++++++++++++++++%09%22Face%22+%22e%3Fy%24%22+%22%22%0A%22+Mc%60Rface&i=boat%0AFace%0ADOG%0AFamily%0ALady%0ADonkey%0A+ey%0Ayyy&a=1&m=2)
[Answer]
# [SOGL V0.12](https://github.com/dzaima/SOGLOnline), 38 [bytes](https://github.com/dzaima/SOGL/blob/master/chartable.md)
```
lW y≠F
u⁽³:F y*+pF‽j:lW e=⌡j}"‰θ`√►׀‘p
```
[Try it Here!](https://dzaima.github.io/SOGLOnline/?code=bFclMjB5JXUyMjYwRiUwQXUldTIwN0QlQjMlM0FGJTIweSorcEYldTIwM0RqJTNBbFclMjBlJTNEJXUyMzIxaiU3RCUyMiV1MjAzMCV1MDNCOCU2MCV1MjIxQSV1MjVCQSV1MDVDMCV1MjAxOHA_,inputs=Ym9hdA__,v=0.12)
[Answer]
# [Python 3](https://docs.python.org/3/), 80 bytes
Long time avid reader, my first submission at last !
```
lambda y:re.sub("([\w ]+?)((e)?y)?$",r"\1\3y Mc\1face",y.capitalize())
import re
```
[Try it online](https://tio.run/##JYvBCsIwEETP@hVLEZpgEcSboL2Igih6FeNh26Y0mCZlE5H152urp3nDm@k4Nt6t@nqjeottUSHwmvQivAqRiLt6w2OeSyG0zFnmsySjRC3ViuFcqmWNpU4yXpTYmYjWfLSQcmrazlME0n3tCQIYB2nhMaYZpPvhMebucvjX1tjbSCes@Ce8e@ofXS2yppGY/@oIB0JXwRlD1AR7i6FJ19NJR8ZFEYaJipvtMK1FkLL/Ag "Python 3 – Try It Online")
[Answer]
## [Retina](https://github.com/m-ender/retina/wiki/The-Language), 29 bytes
```
.+
$T
0`(e)?y$|$
$1y Mc$`face
```
[Try it online!](https://tio.run/##K0otycxLNPyvquGe8F9Pm0slhMsgQSNV075SpUaFS8WwUsE3WSUhLTE59f//pPzEEi43IJPLxd8dyMjNzKnk8klMqeRyyc/LTq3kCshJrEwtAgA "Retina – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/2/), ~~88~~ 92 bytes
```
lambda s:(s+'y'*-~-(s[-1]in'yY')).title()+' Mc'+re.sub('e?y$','',s.title())+'face'
import re
```
[Try it online!](https://tio.run/##NYq7DoIwFIZneYozmJxWLomOJuhidNE4E2Ao0MZGaElbhy6@ei0ap//yfbN3D612QZRNGNnUDQzsntgUPW7yd05snW9bqdBXSGnhpBs5oSnCrcfU8MK@OoL86NeYIWb2L0RDsJ5jIqdZGweGB6ENWJAKauw0c5gBnhcl5ul@@c1JjtXSrmzwX6DVk3ts98lqNlI5sPFsXHmIUBBLwwc "Python 2 – Try It Online")
[Answer]
# Java 8, ~~121~~ ~~112~~ ~~107~~ 106 bytes
```
s->(s=(char)(s.charAt(0)&95)+s.toLowerCase().substring(1)).split("y$")[0]+"y Mc"+s.split("e?y$")[0]+"face"
```
-1 byte thanks to *@OliverGrégoire*.
**Explanation:**
[Try it online.](https://tio.run/##jU9NSwMxEL33VwxBJKE01IMHKVXEope2Cp6k9DCbTWvabLLsZCtB9rev2bp6kxUSkpl58z4OeMLJIT@2yiIRrNC4zxGAcUFXO1Qa1l0J8Boq4/ageP8hMUv9Jt10KGAwCtbgYA4tTW45zbl6x0pwkt17H/hUXN5cizHJ4Jf@Q1cPSJoLSXVGZ0Z@JVJVWhM4ixdMbKbbMYuwUizt9H199zvpvLF29q1f1plN@r2Nkzc5FClI73WzRdGHiBR0IX0dZJkmwTrupOIs8xiYOCf6G/TYKQ6BFs9P/yAqjI2DsCXmw6CFd0c9DHuxGHU1CItvP1TNqGm/AA)
```
s->                         // Method with String as both parameter and return-type
  (s=                       //  Replace and return the input with:
     (char)(s.charAt(0)&95) //   The first character of the input as Uppercase
     +s.toLowerCase().substring(1))
                            //   + the rest as lowercase
  .split("y$")[0]           //  Remove single trailing "y" (if present)
  +"y Mc"                   //  Appended with "y Mc"
  +s.split("e?y$")[0]       //  Appended with the modified input, with "y" or "ey" removed
  +"face"                   //  Appended with "face"
```
[Answer]
# JavaScript, ~~103~~ ~~96~~ 94 bytes
Pretty naïve first pass at this.
```
s=>(g=r=>s[0].toUpperCase()+s.slice(1).toLowerCase().split(r)[0])(/y$/)+`y Mc${g(/e?y$/)}face`
```
[Try it online](https://tio.run/##NYtBDoIwFESv4oJFG7DoAaoLiW4wrlwhya@lkGLpbyjRNMazVzBxNTPvZXrxFF6O2k1ri42KLY@e70jHR77z1aZmE16dU@NBeEVo6pk3WiqypbMo8fUXzDujJzLS@UJJHpKcphBWZ5m8O5Kr/QI@rZAKokTr0ShmsCMV3FFMkMFxURkUl9NvDNqEuZSiWaJA@1ABajYIR1rKetQWbhZo/AI)
[Answer]
# vim, 35 34 bytes
```
Vu~Yp:s/ey$
:%s/y$
kgJiy Mc<ESC>Aface<ESC>
```
`<ESC>` is `0x1b`
### Ungolfed
```
Vu~                      # Caseify McCaseface
Yp                       # dup line
:s/ey$ 
:%s/y$                   # Get the suffixes right
kgJiy Mc<ESC>Aface<ESC>  # Join lines and add the extra chars
```
[Try it online!](https://tio.run/##K/v/P6y0rrKywKpYP7VShctKtVgfSGWne2VWKvgmSzumJSanSv//n5SfWAIA "V – Try It Online")
Saved 1 byte thanks to DJMcMayhem
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, ~~47~~ 39 bytes
*Saved 6 bytes with @OlegV.Volkov's suggestions, 1 with @mwellnhof's, and 1 on my own*
```
$_=lc^$";$_=s/y?$/y Mc/r.s/e?y$//r.face
```
[Try it online!](https://tio.run/##K0gtyjH9/18l3jYnOU5FyRrIKNavtFfRr1TwTdYv0ivWT7WvVNEHstISk1P//3dL9M3MSY38l19QkpmfV/xftwAA "Perl 5 – Try It Online")
[Answer]
# C++ 14 (g++), ~~181~~ ~~171~~ ~~148~~ ~~147~~ 134 bytes
```
[](auto s){s[0]&=95;int i=1,b;for(;s[i];)s[i++]|=32;b=s[--i]-'y';return s+(b?"y":"")+" Mc"+(b?s:s.substr(0,s[i-1]-'e'?i:i-1))+"face";}
```
Note that clang will not compile this.
Credit goes to [Kevin Cruijssen](https://codegolf.stackexchange.com/a/160529/79343) and [Olivier Grégoire](https://codegolf.stackexchange.com/users/16236/olivier-gr%C3%A9goire) for the `&95` trick.
Thanks to [Chris](https://codegolf.stackexchange.com/users/58834/chris) for golfing 11 bytes.
Try it online [here](https://tio.run/##dY9Ra4MwFIWf568IGayKdbQbe5ip68tooax0705KjGkXprEk8UG6/naXxDIGS16813P8zrmS0yk5EjLgTrWgARkY8iK0LzI6y3xW3GXPT4hxBVg2n5bo0IoQyZwVKNLPOC6@s8cHVGYyTxJWJJN@ggRVneBAxmG5hD1MIYxiCLYEGkGm8l52pVQinE11QjLXEJ0sWarXSH94wIRCdBlQENwyTuquomDBWg1Q3LwEDWY8jMA5uJGqSlMtM34EZYuVvh2aCdHVI22nwGIBmtDIkVnhB/@1r@hK9xl0ZXv/oUb2oa@7tSH1cIBa9Vc2rO7HUrM5a43hC3jDlcXNdMBG9t7c8i9q4XFzXW4NX8B7jXsqTMC4OQJGwxfQ97ZeDweqVe/lm/1aYF7tt1gqKvarGstP@yMbYA0wGsAarv9yBfxpuww/).
Ungolfed version:
```
[] (auto s) { // lambda taking an std::string as argument and returning an std::string
    s[0] &= 95; // convert the first character to upper case
    int i = 1, // for iterating over the string
    b; // we'll need this later
    for(; s[i] ;) // iterate over the rest of the string
        s[i++] |= 32; // converting it to lower case
    // i is now s.length()
    b = s[--i] - 'y'; // whether the last character is not a 'y'
    // i is now s.length()-1
    return s + (b ? "y" : "") // append 'y' if not already present
    + " Mc"
    + (b ? s : s.substr(0, s[i-1] - 'e' ? i : i-1)) // remove one, two, or zero chars from the end depending on b and whether the second to last character is 'e'
    + "face";
}
```
[Answer]
# [V](https://github.com/DJMcMayhem/V), ~~38~~ ~~36~~ 32 bytes
-5 byte thanks to @Cows quack
```
Vu~hy$ó[^y]$/&y
A Mc<esc>póe¿y$
Aface
```
`<esc>` is a literal escape character and `[^` is encoded as `\x84`
[Try it online!](https://tio.run/##K/v/P6y0LqNS5fDm6LjKWBV9tUouRwXfZJvU4mS7gsObUw/tr1ThckxLTE79/x9EVv7XLQMA "V – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 30 bytes
```
™D'y©Ü®«s¤®Qi¨¤'eQi¨]’McÿŠÑ’ðý
```
[Try it online!](https://tio.run/##MzBNTDJM/f//UcsiF/XKQysPzzm07tDq4kNLDq0LzDy04tAS9VQQHfuoYaZv8uH9RxccnghkHt5weO///y75edmplQA "05AB1E – Try It Online")
or as a [Test suite](https://tio.run/##MzBNTDJM/V9TVvn/UcsiF/XKQysPzzm07tDq4kNLDq0LzDy04tAS9VQQXVv7qGGmb/Lh/UcXHJ4IZB7ecHjv/0qlw/sVdO0UDu9X0vmflJ9YwuWWmJzK5eLvDmTkZuZUcvkkplRyueTnZadWcgXkJFamFgEA)
[Answer]
# [Python 3](https://docs.python.org/3/), ~~117~~ 114 bytes
*-3 bytes thanks to Dead Possum*
```
def f(s):s=s.title();return s+'y'*(s[-1]!='y')+' Mc'+([s,s[:-1],0,s[:-2]][(s[-1]=='y')+((s[-2:]=='ey')*2)])+'face'
```
[Try it online!](https://tio.run/##PYzBDoIwEETvfMV6agtoFG81vRG9aPyApjEIbWzEQtj1wNdjgcS9zLzd2elHenXhOE2NdeA4CokKd@SptVycBkvfIQBmbGQpR709mI2KXmQMbjXLuMYctYzrfL@Ywhi95tSa4zMVckYbOS2Eic@uqi2byCI96gotKNDs2VXEcmDn@Ra1vF9W/Ph2nN21ahYtu/COXSZx3QAefIB/kUwgTj/4QNxxL8T0Aw "Python 3 – Try It Online")
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 87 bytes
* thanks to @Shaggy for 5 reducing 5 bytes
```
s=>(g=r=>Buffer(s.replace(r,"")).map((x,i)=>i?x|32:x&~32))(/y$/)+`y Mc${g(/e?y$/)}face`
```
[Try it online!](https://tio.run/##dY7NasMwEITvfQohQpFoakNyK8iBEBIoDe01t6i25DqRLSO5xaI/r@5q5TiHYJ92dvebYU78i9vUFHXzWOlMdJJ1liUkZ4Yl608phSE2MqJWPBXEzDGmNCp5TUg7LyhLilX7s1w8tfd/ywWlJHazmD4cHdqns@@cxGIFh1/pzccu1ZXVSkRK50QS/K55gyliDOG1l@CBCSymdzfwNlwDDBJgmOPw5nV3YTc6B9SPqdiyUO4aDEtI9mLc8MKzAQfpYT8mWujqLNy1CCyhSnUe598Ud8Jc@H4BQ6/GLc4N@QcH7MFNVHlGO8OrDO25bYRBW8Xtx9DshPLwK/ufhF9oOvbo87t/ "JavaScript (Node.js) – Try It Online")
[Answer]
# [K4](http://kx.com/download/), ~~74~~ ~~69~~ 68 bytes
**Solution:**
```
{$[r;x;x,"y"]," Mc",_[r:0&1-2/:"ye"=2#|x;x:@[_x;0;.q.upper]],"face"}
```
**Examples:**
```
q)k)f:{$[r;x;x,"y"]," Mc",_[r:0&1-2/:"ye"=2#|x;x:@[_x;0;.q.upper]],"face"}
q)f each ("boat";"Face";"DOG";"Family";"Lady";"Donkey";"Player")
"Boaty McBoatface"
"Facey McFaceface"
"Dogy McDogface"
"Family McFamilface"
"Lady McLadface"
"Donkey McDonkface"
"Playery McPlayerface"
```
**Explanation:**
Figure out if the last characters are equal to `"ey"`, convert result to base-2 so we can ignore words that end `"e?"`. Index into a list of numbers of characters to trim.
Managed to shave 5 bytes off my code to determine whether the last two chars at `"ey"` but struggling to better it...
```
{$[r;x;x,"y"]," Mc",_[r:0&1-2/:"ye"=2#|x;x:@[_x;0;.q.upper]],"face"} / the solution
{                                                                  } / lambda function
                                                            ,"face"  / join with "face"
                    _[                  ;                  ]         / cut function
                                           @[_x; ;        ]          / apply (@) to lowercased input
                                                0                    / at index 0
                                                  .q.upper           / uppercase function
                                         x:                          / save back into x
                                      |x                             / reverse x
                                    2#                               / take first two chars of x
                               "ye"=                                 / equal to "ye"?
                             2/:                                     / convert to base 2
                           1-                                        / subtract from 1
                         0&                                          / and with 0 (take min)
                       r:                                            / save as r
             ," Mc",                                                 / join with " Mc"
 $[r;x;x,"y"]                                                        / join with x (add "y" if required)
```
**Bonus:**
**67 byte** port in [K (oK)](https://github.com/JohnEarnest/ok):
```
{$[r;x;x,"y"]," Mc",((r:0&1-2/"ye"=2#|x)_x:@[_x;0;`c$-32+]),"face"}
```
[Try it online!](https://tio.run/##y9bNz/7/v1olusi6wrpCR6lSKVZHScE3WUlHQ6PIykDNUNdIX6kyVcnWSLmmQjO@wsohOr7C2sA6IVlF19hIO1ZTRyktMTlVqVbJJT8vO7VS6f9/AA "K (oK) – Try It Online")
[Answer]
# [Ruby](https://www.ruby-lang.org/), 69 bytes
```
->s{"#{(s.capitalize!||s)[-1]==?y?s:s+?y} Mc#{s.gsub /e?y$/,""}face"}
```
Explanation:
```
->s{                                                                } # lambda 
    "#{                                 } Mc#{                }face" # string interpolation
       (s.capitalize!||s) # returns string capitalized or nil, in that case just use the original string
                         [-1]==?y # if the last character == character literal for y
                                 ?s:s+?y # then s, else s + "y"
                                              s.gsub /e?y$/,"" # global substitute
                                                               # remove "ey" from end
```
[Try it online!](https://tio.run/##KypNqvyfpmCrEPNf1664Wkm5WqNYLzmxILMkMSezKlWxpqZYM1rXMNbW1r7SvtiqWNu@slbBN1m5ulgvvbg0SUE/1b5SRV9HSak2LTE5Van2f0FpSbFCWnR6aklx7H@X/Lzs1EoA "Ruby – Try It Online")
[Answer]
# [Jstx](https://github.com/Quantum64/Jstx), 27 [bytes](https://quantum64.github.io/Jstx/codepage)
```
h</►yT↓►y/◙♂ Mc♀/◄eyg►yg/íå
```
Explanation
```
      # Command line args are automatically loaded onto the stack
h     # Title case the top of the stack
<     # Duplicate the top value on the stack twice
/     # Print the top value on the stack
►y    # Load 'y' onto the stack
T     # Returns true if the 2nd element on the stack ends with the top
↓     # Execute block if the top of the stack is false
  ►y  # Load 'y' onto the stack
  /   # Print the top value on the stack
◙     # End the conditional block
♂ Mc♀ # Load ' Mc' onto the stack
/     # Print the top value on the stack
◄ey   # Load 'ey' onto the stack
g     # Delete the top of the stack from the end of the 2nd element on the stack if it exists
►y    # Load 'y' onto the stack
g     # Delete the top of the stack from the end of the 2nd element on the stack if it exists
/     # Print the top of the stack
íå    # Load 'face' onto the stack
      # Print with newline is implied as the program exits
```
[Try it online!](https://quantum64.github.io/Jstx/JstxGWT-1.0.1/JstxGWT.html?code=aDwv4pa6eVTihpPilrp5L%24KXmeKZgiBNY%24KZgC_il4RleWfilrp5Zy_DrcOl&args=Ym9hdA%3D%3D)
[Answer]
# [Red](http://www.red-lang.org), 143 142 bytes
```
func[s][s: lowercase s s/1: uppercase s/1
w: copy s if"y"<> last s[append w"y"]rejoin[w" Mc"parse s[collect keep to[opt["y"|"ey"]end]]"face"]]
```
[Try it online!](https://tio.run/##VYuxDsIgFEX3fsXL@4Gma2OcjC4ajSthQHgkVQQCNITEf0c6qHU859wbSNUrKWC802PVs5UschZHMC5TkCISRIj9MMLs/Uf0Q5dHkM6XFieNBTdbMCImiEy0mVWQm@SB7m6yLCOcJHoRli@TzhiSCR5EHpJjzifWxi@k9mhXzlELSch59WGyCTTgzYmE3Rf3S//h7nz4i8/JlJU4CrVG5eyD1uJiRKGA9Q0 "Red – Try It Online")
Ungolfed:
```
f: func[s][
   s: lowercase s                      ; make the entire string lowercase
   s/1: uppercase s/1                  ; raise only its first symbol to uppercase 
   w: copy s                           ; save a copy of it to w
   if "y" <> last s[append w "y"]     ; append 'y' to w if it doesn't have one at its end
   rejoin[w                            ; assemble the result by joining:
          " Mc"
          ; keep the string until "y", "ey" or its end
          parse s[collect keep to [opt ["y" | "ey"] end]]
          "face"
    ]
]
```
[Answer]
# PHP: 132
```
<?php function f($s){$s=ucfirst(strtolower($s));return $s.(substr($s,-1)=='y'?'':'y').' Mc'.preg_replace('/(ey|y)$/','',$s).'face';}
```
## Explanation:
```
<?php
function f($s)
{
    // Take the string, make it all lowercase, then make the first character uppercase
    $s = ucfirst(strtolower($s));
    // Return the string, followed by a 'y' if not already at the end, then ' Mc'
    // and the string again (this time, removing 'y' or 'ey' at the end), then
    // finally tacking on 'face'.
    return $s
        . (substr($s, -1) == 'y' ? '' : 'y')
        . ' Mc'
        . preg_replace('/(ey|y)$/', '', $s)
        . 'face';
}
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~77~~ ~~75~~ ~~74~~ 73 bytes
```
2ḶNṫ@€⁼"“y“ey”S
ØA;"ØaF
¢y⁸µ¢Uyµ1¦
Çṫ0n”yẋ@”y;@Ç;“ Mc”
⁸JU>ÑTị3Ŀ;@Ç;“face
```
[Try it online!](https://tio.run/##y0rNyan8/9/o4Y5tfg93rnZ41LTmUeMepUcNcyqBOBVIzA3mOjzD0Vrp8IxEN65DiyofNe44tPXQotDKQ1sNDy3jOtwO1GaQB1RX@XBXtwOItnY43G4N1K3gmwzkcgE1eIXaHZ4Y8nB3t/GR/TDZtMTk1P///6s75SeWqAMA "Jelly – Try It Online")
Any golfing suggestions are welcome (and wanted)!
[Answer]
# Pyth, ~~36~~ 34 bytes
```
++Jrz4*\yqJK:J"e?y$"k+" Mc"+K"face
```
[Try it online!](http://pyth.herokuapp.com/?code=%2B%2BJrz3%2a%5CyqJK%3AJ%22%28e%29%3Fy%24%22k%2B%22+Mc%22%2BK%22face&input=donkey&test_suite=1&test_suite_input=boat%0AFace%0ADOG%0AFamily%0ALady%0ADonkey%0APlayer%0Ayyy%0ADJ+Grand+Master+Flash&debug=0)
Explanation:
```
++Jrz4*\yqJK:J"(e)?y$"k+" Mc"+K"face
  Jrz4                                  Set J to the titlecase of z (input)
           K:J"e?y$"k                   Set K to (replace all matches of the regex e?y$ in J with k (empty string))
         qJ                             Compare if equal to J
      *\y                               Multiply by "y" (if True, aka if no matches, this gives "y", else it gives "")
 +                                      Concatenate (with J)
                             +K"face    Concatenate K with "face"
                       +" Mc"           Concatenate " Mc" with that
+                                       Concatenate
```
[Answer]
# [Elixir](https://elixir-lang.org/), ~~112~~ ~~110~~ ~~107~~ 106 bytes
*now as short as java*
```
fn x->x=String.capitalize x;"#{x<>if x=~~r/y$/,do: "",else: "y"} Mc#{String.replace x,~r/e?y$/,""}face"end
```
[Try it online!](https://tio.run/##LY89D4IwEIZ3fsXlcICEj10RF6Ix0TA4GocCV9NYW1IYiop/HSlxet5cnsvdS1JYYSauDSjIYrhipVmPESBnNTkW5cFhz55CDi6dWLOw0OpBA96g0V4wcQU2zu320huh7knNWtEzKV4EdoP@22a54GC3369Jh1UaNXoNiBHJjuYw4Ajn2n//lw21cr4ONppt2jkfcVweItVMYRKo0PvkcCwTobqW6j6QrCK5hnnuDNfhBw "Elixir – Try It Online")
Explanation:
```
x=String.capitalize x
```
Gets `x` with the first character in uppercase and all others lowercase.
```
#{ code }
```
Evaluate the code and insert it into the string.
```
#{x<>if x=~ ~r/y$/, do: "", else: "y"}
```
Concatenates **x** with `y` if it does not end with `y` (ie it does not match the regex `y$`).
```
#{String.replace x, ~r/e?y$/, "")}
```
Removes trailing `ey` and trailing `y`.
[Answer]
# [PHP](https://php.net/), 45  ~~46~~ bytes
```
<?=($s=ucfirst(fgets(STDIN)))."y Mc{$s}face";
```
[Try it online!](https://tio.run/##K8go@P/fxt5WQ6XYtjQ5LbOouEQjLT21pFgjOMTF009TU1NPqVLBN7lapbg2LTE5Vcne7v//5MSS/yn56QA "PHP – Try It Online")
[Answer]
## Pyth, ~~60~~ 59 bytesSBCS
```
K"ey"Jrz4Iq>2JK=<2J=kK.?=k\yIqeJk=<1J))%." s÷   WZÞàQ"[JkJ
```
[Test suite](https://pyth.herokuapp.com/?code=K%22ey%22Jrz4Iq%3E2JK%3D%3C2J%3DkK.%3F%3Dk%5CyIqeJk%3D%3C1J%29%29%25.%22+s%C2%9C%C2%82%C2%8C%C3%B7%09WZ%C3%9E%C3%A0Q%22%5BJkJ&test_suite=1&test_suite_input=boat%0AFace%0ADOG%0AFamily%0ALady%0ADonkey%0APlayer%0Ayyy%0ADJ+Grand+Master+Flash&debug=0)
They don't display here, but three bytes, `\x9c`, `\x82`, and `\x8c` are in the packed string between `s` and `÷`. Rest assured, the link includes them.
Python 3 translation:
```
K="ey"
J=input().capitalize()
if J[-2:]==K:
    J=J[:-2]
    k=K
else:
    k="y"
    if J[-1]==k:
        J=J[:-1]
print("{}{} Mc{}face".format(J,k,J))
```
]