if necessary, heading can be compressed from float (or double) to short or even byte before transmission, as stated above. but you only save 2 or 3 bytes.
the whole idea is to send the least data possible, and only when necessary, and THEN compress that (if needed), before transmission.
so the client should know an object's heading, and an object should send a "turn" (rotate) message to the clients, who then do the math. packets only get sent when they change heading.
if a packet already includes entity type info, and that entity type's turn rate is constant, you can send the data in 2 bits: 00= no turn. 01 = turn left. 10 = turn right. 11= undefined.
always send the minimum data possible, and only when you must, and let the client do as much work as possible. then the vast majority of packets will be of the form: timestamp, entity_ID, nochange. or, if you only send change packets (as opposed to state packets), timestamp, entity_ID, change type, value.
In a NON-DETERMINISTIC networked startship flight sim i was able to get steady state down to 23 bytes of data per turn (for the ENTIRE simulation).
in short: its often less data transmitted if you tell the client what to do, when it needs to be done, rather than telling the client the results of doing something every turn.
what to do can often take less data to send than sending the result of doing that something. and only sending state changes, as opposed to sending current state every turn reduces the number of packets transmitted when things don't change.
what this boils down to is you basically want to send inputs (turn left, move forward etc, perhaps sent as a single byte), rather than results like new x,y,z,xr,yr, and zr (6 floats).
for minimal network lag, you should never transmit anything the client can figure out for itself.
in the particular case of a 3D RPG, you'd send a new heading only when it changed. you could send the new heading, or the turn amount, whichever is smaller.
you'd need to transmit 4 bits per turn for movement (0 thru 9 = no move, or one of the 8 cardinal directions). the client could figure it out from there.
for attacks, if the game is determinisitic, you can just send 1 bit for they attacked or not, and let the client resolve it and be guaranteed the server result will be the same. if its non-deterministic, you'll need to send damage and hit location, along with any critical hit type results.