RedI Furcadia Protocol (RFPv015)

This documentation is free, but it is licensed under the terms of the
GNU Free Documentation License as published by the Free Software
Foundation; either version 1.2 of the License, or (at your option)
any later version.

http://www.gnu.org

Basically, ^that^ means that you cannot remove the following credits from the original content if you modify, redistribute, or burn this document.

Credits:

Contents:
  1. Introduction
  2. Data sent from server to client
  3. Data sent from client to server (common access)
    1. Cookies
    2. Interaction
    3. Manipulation
    4. Movement
    5. Roses
    6. Server Control
  4. Data sent from client to server (Dream owner access)
  5. Data sent from client to server (Beekin access)
  6. Example connection
  7. Furcadia file formats
  8. Conversion functions
  9. Conclusion


Notes:
  1. All Furcadia number strings are stored in 2 bytes.
  2. All X coordinates are halved from what is perceived in Furcadia.
  3. Furcadia uses UNIX pipes ( | ) to represent spaces.
  4. All numbers are stored in Base95 format when sent to the client. This way, each number has a specific
    length that the client can read and a procedure to follow without receiving errors.
  5. All lines sent from server to client and vice versa are terminated with a new line character (\n, \r, vbCr, or Chr$(10)).
  6. The MOTD is sent in one packet.
  7. {foo} is a string.
  8. (foo) is a Furcadia number (Base95).
  9. Any characters enclosed within [ ] are optional.


Introduction:

Greetings! The RedI Furcadia Protocol is intended to contain all the core information you need to understand
Furcadia in one document. This document was written to spread our knowledge of Furcadia to those who wish to
learn it, and to be a reference to those who already understand it. We hope the neophytes learn much from this
document and the veterans use it as a constant reference. Enjoy the document and thank you for reading!



The following are lines sent from the server to the client:

Nope.Invalid connection.
Invalid name or password.Invalid login.
Name already taken: Please select another name.Provided name is already taken.
DragonroarPlays introduction sound (Welcome!).
V{XXXX}Version of the protocol the client should be reading.
ENDEnd of MOTD; begin login.
&&&&&&&&&&&&&Successful login.
!(n)Client plays sound 'n'.
%(n)Item 'n' is placed at furre's feet.
%0{name}'Name' is offline.
%1{name}'Name' is online.
([{foo}]Writes to output ['foo'].
)(x1)(y1)Furre is removed from (x1,y1).
/{colors}(x1)(y1)(n)(x2)(y2)Animates a furre from (x1,y1) to (X2,y2) with frame number 'n'.
1(x1)(y1)(n)Draws floor number 'n' at (x1,y1).
6(x1)(y1)(x2)(y2)(n)Execute a self-induced DS trigger.
x and y are furre coordinates.
'n' is trigger location in DS.
7(x1)(y1)(x2)(y2)(n)Execute an other-induced DS trigger.
x and y are furre coordinates.
'n' is trigger location in DS.
8-triggerIt exists, but I'm not quite sure yet. :)
;{map.map}Client loads map.map.
<{colors}(x1)(y1)(n)"Draws a furre at (x1,y1) with frame number 'n'.
=Draw all queued drawing data; refresh client.
>(x1)(y1)(n)Draws object number 'n' at (x1,y1).
@(x1)(y1)[(x2)(y2)]Camera positioned at [from] (x1,y1) [to (x2,y2)].
[[{foo}]Client is booted [with message 'foo'].
]!Display warning of adult content.
]#{n} {o}Display message box ID 'n' with style 'o'.
]&{key} pp{name} {n}Display portrait of 'name'.
]-#(n)[o][(gender)(species)(markings)]Draws specitag 'n'.
[If 'n' = A then draw furre specitag using 'gender', 'species', and 'markings'.]
[If 'n' = B then draw Beekin badge 'o'.]
]aClient requests gate data.
]cc{background.pcx}Client uses background.pcx as background.
]f{colors}(gender)(species)(markings){name}Portrait is displayed with 'colors' depending on 'gender', 'species', and 'markings' with 'name'.
]j(n)Plays m(n).mid from the client's path.
]q {n} {n}Request to download dream 'n'.
]r {patch}Uses 'patch' as the client's graphics.
]s(x1)(y1)(foo)Renders text 'foo' at (x1,y1).
]t(x1)(y1)Removes text as (x1,y1).
]uClient requests rgate data.
]va(x1)(y1)Dragon breath at (x1,y1).
]vb(x1)(y1)Phoenix flame at (x1,y1).
]wClient version request.
]}{color}Color buffer check for client.
^(n)Item 'n' is placed in furre's paws.
polo {n}Pong.



The following are lines sent from the client to the server (common access):

Cookies:
"cookies-acceptAccept cookies from others.
"cookies-rejectReject cookies from others.
"eat-cookieEat a cookie from one's description.
"give-cookie {n} [{o}]Give a cookie from one's description to furre 'n' [with message 'o'].
"make-cookie {n} [{o}]Makes a cookie for furre 'n' [with message 'o'].
"make-secret {n} [{o}]Makes a cookie for furre 'n' [with message 'o'] without alerting others.
"munch-cookieEat a cookie from one's description and alert others.
"secret-cookie {n} [{o}]Makes a cookie for furre 'n' [with message 'o'] without alerting others.

Interaction:
"{foo}Says 'foo'.
-{foo}Yells 'foo'.
:{foo}Emotes 'foo'.
declineReject a joining/summoning furre's request.
getPicks up or drops an object.
goallegGo directly to Allegria map.
gobackGo directly to previous map.
gomap {n}Go directly to map 'n'.
gostartGo directly to Vinca map.
helpRequests help from Beekin Help Channel.
"infoDisplays information held about one's character on the server.
join [{n}]Request to join the company of a furre ['n'].
l (x1)(y1)Looks at a furre at (x1,y1).
onln {n}Request 'n' online status.
summon [{n}]Request a furre ['n'] to join one's company.
useUse the object in the furre's paws.
wh {n} {o}Whisper 'o' to 'n'.
vascodagamaFinished download dream or patch.
whichDisplays the heimdall (server process that controls character interaction) that one's character resides on, current index, and one's global ID.
whoRetrieve list of users on map from the server.

Manipulation:
breathBreaths dragon breath while in Dragon form.
chcol {colors}(gender)(species)(markings)Silver Sponsorship members can change colors, gender, species, or markings online.
chdesc {description}Silver Sponsorship members can change description to 'description' online.
color {colors}(gender)(species)(markings)Silver Sponsorship members can change colors, gender, species, or markings online.
dragonTransform into Dragon form.
desc {description}Change description to 'description' online.
eagleTransform into Eagle form while in Gryphon form.
flameFlames Phoenix flame while in Phoenix form.
gryffeTransform into Gryphon form.
phoenixTransform into Phoenix form.
portrchngSwap to next available portrait.
wingsTransform into furre with wings.

Movement:
<Rotate counter-clockwise.
>Rotate clockwise.
lieToggles from lying to sitting to standing.
liedownGo directly to lying down frame.
m 1Move southwest.
m 3Move northwest.
m 7Move northeast.
m 9Move southeast.
sitGo directly to sitting down frame.
standGo directly to standing up frame.

Roses:
"discard-roseRemoves a rose from one's description.
"discard-red-roseRemoves a red rose from one's description.
"discard-white-roseRemoves a white rose from one's description.
"discard-yellow-roseRemoves a yellow rose from one's description.
"give-rose {n} [{o}]Give a rose to furre 'n' [with message 'o'].
"give-red-rose {n} [{o}]Give a red rose to furre 'n' [with message 'o'].
"give-white-rose {n} [{o}]Give a white rose to furre 'n' [with message 'o'].
"give-yellow-rose {n} [{o}]Give a yellow rose to furre 'n' [with message 'o'].

Server Control:
=newsToggles news channel.
=eventToggles event channel.
ROLL {n}d{o}Rolls 'n' die with 'o' sides with detailed results.
Winver {X}Version of user's Windows.
connect {name} {password} {hash}Connect to server using 'name' and 'password'. 'hash' is sent to the server and a response is sent back activating the client.
create {name} {password} {e-mail} N YCreate a character with 'name' using 'password' at 'e-mail'. Not sure what N Y means.
desctagsToggles description tags.
iamhereKeep the client's connection alive.
marco {n}Ping.
polon {n}Pong.
quitQuit Furcadia.
reconnectForce a reconnection.
repq {n} {o}Reply to question 'n' with answer 'o'.
rgateRequest to upload a dream.
roll {n}d{o}Rolls 'n' die with 'o' sides.
setemail {n}Set one's e-mail address to 'n'.
tdgate {n}Register dream ID 'n'.
timeRequest Furcadia central time.
version {n}Send client's version 'n'.

Trade:
"trade-acceptFinalize a trade.
"trade-add {n}Add item 'n' to trade. *
"trade-endEnds a trade.
"trade-rejectReject a trade.
"trade-remove {n}Remove item 'n' from trade. *
"trade-start [{n}]Begin a trade [with furre 'n'].
"trade-statusView status of a trade.
* Items to trade: b (butterfly wings), c (classics), d (dragon), g (gryffe), p (phoenix), t (triwings)



The following are lines sent from the client to the server (Dream owner access):

"eject {n}Eject user 'n' from dream.
"emit {n}Emit message 'n' to furres in radius.
"emitloud {n}Emit message 'n' to everyone.
"entrymusic {n}Set dream music to 'n'.
"entrytext {n}Set dream text to 'n'.
"pads-allFurres can upload dreams to any upload pad.
"pads-ownerOnly dream owner can upload dreams to upload pad.
"pads-sharedDream owner and shared users can upload dreams to upload pad.
parentalSet a parental rating on one's dream.
"share {n}Share control of dream with 'n'.
shieldDirect all summoned furres to the entrance of one's dream.
unloadUnload a dream.
unload allUnload all dreams.
unload {n}Unload dream 'n'.
"unshare {n}Unshare dream ownership with 'n'.
"uploads-allAll furres can upload a dream to any empty spot.
"uploads-ownerOnly dream owner can upload a dream to any empty spot.
"uploads-sharedOnly dream owner and shared users can upload a dream to any empty spot.



The following are lines sent from the client to the server (Beekin access):

bbJoin Beekin channel.
"block {n} {o} {p}Ban furre 'n' for 'o' hours because reason 'p'.
"boot {n} {o}Boot furre 'n' with reason 'o'.
"booty {n} {o}Boot furre 'n' with reason 'o'.
c {n}Claim 'n' help request.
claim {n}Claim 'n' help request.
clear {n}Clear 'n' help request from help queue.
isbeek {n}Beekin access levels for 'n'.
jg {n}Join group 'n'.
leaveGo off duty.
"listList available Beekin commands.
"listfFurres requesting assistance and Beekins on duty.
obJoin Guardian channel.
ondutyCount of available Beekins in their respective groups.
queQueued help requests in Help Channel.
rap {n}View rap sheet of 'n'.
report 'n'Report of a furre and their history.
"sendd {n} {o}Send 'n' to Dream Channel with reason 'o'.
"sendg {n} {o}Send 'n' to Guardian Channel with reason 'o'.
"sendh {n} {o}Send 'n' to Help Channel with reason 'o'.
"sendw {n} {o}Send 'n' to Welcome Channel with reason 'o'.
staffdreamGo to staff dream map.
tellgroup {n}Tell 'n' to one's Beekin group.
telltrainees {n}Tell 'n' to all Beekin trainees.
"transd {n}Transfer 'n' to Dream Channel.
"transg {n}Transfer 'n' to Guardian Channel.
"transh {n}Transfer 'n' to Help Channel.
"transw {n}Transfer 'n' to Welcome Channel.
"url {n}Transfer 'n' to Dream Channel.



An example of a regular connection (to Chess map):
(Red is client; Green is server)

MOTD
Dragonroar
V0013
END

connect Xemberad PWD machineID
desc Live simply so that others may simply live. [Are you new? Need help? Just ask. #SA]
color ..I"- 8<83!#
\responseID
&&&&&&&&&&&&&
]w
]marco 99
([*] News Channel on.
([*] Talzhemir channel on. Mrrelcome!
([*] Welcome to the Felorin channel - all Felorin, all the time.
]ccmarbled.pcx
<
]} !
~
;chess.map
1z (xI (xJ (.7 ( # + ( # - ( # / ( # 1 ( # 3 ( # 5 ( # 7 ( # 9 ( # ; ( # = ( # ? ( # A ( # C ( # E ( # G ( # I ( # K ( # M ( # O (+( Q (+) ('y S (+* ('z S (++ ('{ S ( ' (
> ' 0#6 ' 6 ' 8 ( 4#? ( 5#; ) 0 ) 1#9 * 0 + @ , B - 6#8 - ?#; - @#? - A / 9#> / >#5 / ?#9 0 ; 0 = 0 O#5
0 !mL *Q
]r default 12345
%#?
<..I"- 8<83 & 3
<..I"- 8<83 & 3 _
8 #:ntd
6 & 3 & 3 ! & 3
@ & >
%#?
~
) & 3
<..I"- 8<83 & > _
=
@ & >
=
@ & A
%
~
) & >
<..I"- 8<83 & A _
=
<..I"- 8<83 & A _
<..I"- 8<83 & A _
]}..I"- 8<83!#
version 21.0
polon 99
Winver 5.1
vascodagama
quit



Furcadia file formats:

Map File Format:
This format is for unencrypted maps only.

MAP V01.XX Furcadia\n
height=NUMBER\n
width=NUMBER\n
revision=NUMBER\n
patcht=PATCH TYPE\n
patchs=DIRECTORY OR SERVER-NAME\n
encoded=1 OR 0\n
BODY\n
width * height = Floor entry
(unsigned short, entries stored starting at 0,0, then 0,1, etc.)
width * height = Object entry
(unsigned short, entries stored starting at 0,0, then 0,1, etc.)
width * height * direction = Wall entry
(unsigned byte, entries stored starting at 0,0, then 0,1, etc...
direction consists of northwest wall, then the northeast wall)

FSH File Format:
This format applies to both encrypted and unencrypted FSHes. The only difference is that
the palette entries for encrypted FSHes vary from entry to entry, so I think it's possible
that there's some sort of checksum involved.

unsigned short - chunk count (a chunk is a FSH entry)
unsigned short * (chunk count) - chunk size
chunk * chunk count - chunks

Chunk:
unsigned byte - width
unsigned byte - height
signed byte - X Offset
signed byte - Y Offset
width * height - Index of palette color used at specified pixel
(The entries are reflected, that is, the last row is stored first.
So, in a 32 by 64 entry, drawn location 0,64 is the first byte read,
1,64 is the second byte read, etc.)

FS2 File Format:
This file format is very similar to the FSH in the respect that it stores images the same way.

PositionTypeDescription
00hchar[7]'FSH2 001'
08hu?shortImage Entries (chunks)
0Ah??????
10h---Entries start

Entry:
unsigned byte - width
unsigned byte - height
signed byte - X Offset
signed byte - Y Offset
unsigned? short - Object # to replace
width * height - Index of palette color used at specified pixel
(The entries are reflected, that is, the last row is stored first.
So, in a 32 by 64 entry, drawn location 0,64 is the first byte read,
1,64 is the second byte read, etc.)

FBJ File Format:
This format can be tricky because the entries' properties can range from one to three bytes.

PositionTypeDescription
00hchar[3]'FO01' - Version Information
04hu?shortNumber of Entries
06hu?short???
08h---FBJ Entries...

Entries (length dependent upon if x, y coords are used)
(all bytes are signed):

Properties:
(X == 0) && (Y == 0)
(length: 1 byte)
---------------------------------
Nothing::00h
Walkable::01h
Gettable::02h
Gettable and Walkable::03h
Sittable::04h
Sittable and Walkable::05h
Sittable and Gettable::06h
Sittable, Gettable, & Walkable::07h

(X <> 0) && (Y == 0)
(length: 2 bytes)
---------------------------------
Nothing::08h, XXh
Walkable::09h, XXh
Gettable::0Ah, XXh
Gettable and Walkable::0Bh, XXh
Sittable::0Ch, XXh
Sittable and Walkable::0Dh, XXh
Sittable and Gettable::0Eh, XXh
Sittable, Gettable, & Walkable::0Fh, XXh

(X == 0) && (Y <> 0)
(length: 2 bytes)
---------------------------------
Nothing::10h, YYh
Walkable::11h, YYh
Gettable::12h, YYh
Gettable and Walkable::13h, YYh
Sittable::14h, YYh
Sittable and Walkable::15h, YYh
Sittable and Gettable::16h, YYh
Sittable, Gettable, & Walkable::17h, YYh

(X <> 0) && (Y <> 0)
(length: 3 bytes)
---------------------------------
Nothing::18h, XXh, YYh
Walkable::19h, XXh, YYh
Gettable::1Ah, XXh, YYh
Gettable and Walkable::1Bh, XXh, YYh
Sittable::1Ch, XXh, YYh
Sittable and Walkable::1Dh, XXh, YYh
Sittable and Gettable::1Eh, XXh, YYh
Sittable, Gettable, & Walkable::1Fh, XXh, YYh

DSB File Format:
The last file format is quite useful because if you get it in your cache, you can get the DS to the dream.

PositionSizeDesc
00h04hDSB1
04h0FhDon't care
15hTo EOFTriggers
Triggers:
Position
00h2Type (unsigned short)
02h2Subtype (unsigned short)
04h2Parameter 1 (signed? short)
06h2Parameter 2
08h2Parameter 3
0Ah2Parameter 4
0Ch2Parameter 5
0Eh2Parameter 6
10h2Parameter 7
12h2Parameter 8

Official documentation for Kylix's file formats can be found
here.



Conversion functions:

C/C++
// Furcadia string to integer
short furc_ctos(const char *charin)
{
if (((unsigned char) charin[0] < 32) || ((unsigned char) charin[0] > 127))
return -1;
if (((unsigned char) charin[1] < 32) || ((unsigned char) charin[1] > 127))
return -1;
return (((unsigned char) charin[0] - 32) * 95) + ((unsigned char) charin[1] - 32);
}

// Integer to string
void furc_stoc(char *charout, short intin)
{
// Boundaries
if (intin <= 0)
intin = 0;
if (intin >= 9025)
intin = 9025;

// Conversion
charout[0] = (unsigned char)( (intin / 95) + 32 );
charout[1] = (unsigned char)( (intin % 95) + 32);
charout[2] = '\0';
}

Visual Basic
Public Function FurcToInt(Text As String) As Integer
'Converts a Furcadian number string to an Integer
Dim NumberString As String
Dim BigNumber As Integer, SmallNumber As Integer, WholeNumber As Integer

NumberString = Text
BigNumber = (Asc(Left$(NumberString, 1)) - 32)
BigNumber = BigNumber * 95
SmallNumber = Asc(Right$(NumberString, 1)) - 32
WholeNumber = BigNumber + SmallNumber
FurcToInt = WholeNumber
End Function

Public Function IntToFurc(Number As Integer) As String
'Change Integer to a Furcadia number string
Dim RetStr As String
Dim charnum As Integer
Dim FrameValue As Integer

charnum = Int(Number / 95) + 32
RetStr = Chr$(charnum)
FrameValue = Number Mod 95
charnum = Int(FrameValue) + 32
RetStr = RetStr + Chr$(charnum)
IntToFurc = RetStr
End Function



Conclusion:

We hope you found the document useful.
If there is any information you wish to be made known to the Furcadia users and the public (with all due credit, of course),
please contact
Kylix or Xemberad via e-mail or Furcadia to share what you know!
Good bye!



_=[~~ Portions copyrighted Kylix and Xemberad 2004 :: Last updated: January 4th, 2004 ~~]=_