G-Code Basics: Program Format and Structure

G-Code Basics: Program Format and Structure

CNCCookbook’s G-Code Tutorial: CNC Programing

Blocks = Lines of G-Code

A line of g-code is commonly called a “Block”. Up until now, we’ve been typing in one block at a time rather than trying to create full g-code program. You can get a lot done that way. As I’ve been saying, it’s like having a really nice manual machine with DRO’s and Power Feeds on all axes. But, there’s a lot more power waiting to be unleashed if we delve a little deeper into the g-code language.

So the first thing you have to know is how to create blocks since they’re the basic unit of a g-code part program.

Beginning a Block

A block can contain a number of optional parts. Certain parts of a block have to come first if they are to be present in the block. In particular, it can optionally begin with a Sequence Number, a Block Skip, a Program Number, or a Tape Start/End character (“%”). Let’s look at the function of each of these beginning parts, and remember, a block doesn’t have to have any of them.

Tape Start/End

The percent “%” is used to denote the beginning and end of a program. Put one as the first line (block) and one as the last line (block) of any g-code program. Not all controllers require this. Most will ignore anything after the “%”, so you can put comments there. Such comments are referred to as being in the “Leader” section. All these references to “Leaders” and “Tape” may seem odd to relative newcomers to cnc. They have a historical origin dating back to when nc programs were stored on punched paper tape. There are still machines out there happily churning out parts that worked this way, but by now their controllers have often been upgraded or at least the tape reader has been replaced with a serial port or USB key front end.

Program Numbers

Programs and subprograms need a number for reference, and this is provided by the Program Number. A Program Number is an “O” word (in g-code we refer to the letters as “words” because each is a “word” telling the controller something to do). Your controller may or may not require a Program Number, but it is a good idea to provide one. A program that has the proper tape start/end and program numbers would look like this:

% A simple do-nothing g-code program



Not much to it, eh? We’ll keep embellishing this little program to make our point as we add various constructs.

Block Skip (also called Block Delete)

The block skip is a handy way to make blocks drop out of the program temporarily without deleting them. Just start the line with a slash (‘/’) and the controller can ignore the line. These block skips may optionally be numbered on some controllers, and potentially each number can be controlled via the operator control panel. For many Fanuc controllers, up to 9 different block skip numbers may be used. Here is a line with a rapids (G00) move that has been disabled via block skip:

/G00 X0 Y0 Z0

And here is the same line disabled by block skips 1 and 3:

/1/3G00 X0 Y0 Z0

These blocks skips are there so the operator can make quick changes or have optional sections of code that can be turned off and on from the control panel. In G-Wizard Editor, the BLK DEL function on the tool bar is used to turn block skips on or off.

You probably wont use them much until you’re pretty far along in your g-code work, so for now, just be aware that they’re available.

Sequence / Line Numbers

We’ve saved the best for last: sequence numbers. A sequence number provides a unique way of identifying a particular block. You don’t have to sequence all the blocks, but it is common to do so. If our simple do-nothing program suddenly had a line that did something, and had a sequence number, it might look like this:

% A do something simple g-code program


N100 G00 X0 Y0 Z0


Sequence numbers will not ever have a decimal point or negative sign–they’re always positive integers. Renumbering a program to keep the sequence numbers consistent can be a real pain, so rely on your g-code editor to do that work. Here is the sequence numbering revision panel from G-Wizard Editor:

Sequence renumbering

G-Code Resequencing Command from GWE…

You can tell from the options some of the things you need to keep in mind–we don’t sequence number program numbers or tape start/end lines, for example. If a line has a sequence number, the only thing that may come before it is a block skip character. Otherwise, the sequence number should be the first thing on the line.

Spaces in G-Code Programs

Now is a good time to mention that g-code ignores spaces in many cases. They’re there simply to make the code more readable by us humans, so use them to your benefit. You can stick spaces between a word and the number that goes with the word (that number is called the “address”, see Word Address Format below):

G00 can be G 00

X0 can be X 0

Decide what you like to see in terms of readability and stick with it. Depending on your g-code editor, it may have tools to help you manage this sort of formating automatically. G-Wizard CNC Simulator and Editor certainly does.

Leaving Out Optional G-Code Information to Save Memory

As mentioned, spaces are optional, sequence numbers are option unless they’re being used for subprograms or macros (more on these later), and there are potentially other things in the g-code language that are optional. It’s worth keeping in mind that if you’re on an older controller, one of the constant challenges is the memory capacity of the controller. Stripping out spaces and unused sequence numbers can free up quite a few bytes by making your g-code programs smaller. Don’t overlook the opportunity to do something like this if you have to in order to get the job done.

Word Address Format

As was mentioned, a letter in a g-code program is referred to as a word. Associated with each word is an address, which is a number that goes with the word. For example, when we’re talking coordinates, the address is the coordinate value for the axis: “X0” is the X-word with a “0” address.

Depending on the function of the Word, the address must take a certain format. For example, we mentioned that the addresses (sequence numbers) associated with “N” words have to be positive integers, they’ll have no decimal points or signs.

Even the “G” word from which the name “G-Code” comes from has an address that determines which G-Code we’re talking about–“G00” is the G-Word with a “00” address and initiates rapid motion modes.

A good CNC Simulator will have the ability to define the Word Address formats to fit whatever your controller expects (they can vary quite a lot from one g-code dialect to the next). G-Wizard Editor uses the following screen for defining Word Address Formats:

Word Address Format

Setting up the Word Address format for the “M” word…

To use it, select the letter for the Word in the pulldown menu at top left. The configuration options are in the left column. Samples are provided on the right to show what’s valid and what isn’t.

Blocks Don’t Necessarily Execute Left to Right

One of the things I struggled with when first learning g-code was the idea that while blocks mostly execute top to bottom unless you tell them to do something different explicitly via macros and subprograms, blocks don’t necessarily execute left to right. In fact, each controller may define its own peculiar ordering, though they do try to be similar. Here, for example, is the order of execution for RS-274 G-Code:

1. Comment
1.1 Comment message
2. Set feed rate mode (G93, G94, G95).
3. Set feed rate (F).
4. Set spindle speed (S).
5. Select tool (T).
6. Change tool (M6).
7. Spindle on or off (M3, M4, M5).
8. Coolant on or off (M7, M8, M9).
9. Enable or disable overrides (M48, M49).
10. Dwell (G4).
11. Set active plane (G17, G18, G19).
12. Set length units (G20, G21).
13. Cutter radius compensation on or off (G40, G41, G42)
14. Cutter length compensation on or off (G43, G44, G49)
14.5 Do scaling G50/G51.
15. Coordinate system selection (G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3).
16. Set path control mode (G61, G61.1, G64)
17. Set absolute or incremental mode (G90, G91).
18. Set retract mode (G98, G99).
18.6 Do G68/69 coordinate rotation. Scaling before rotation.
18.7 Do G15/16 polar coordinates.
19. Go to reference location (G28, G30) or change coordinate system data (G10) or set axis offsets
(G92, G92.1, G92.2, G94).

20. Perform motion (G0 to G3, G33, G34, G38.x, G73, G76, G80 to G89), as modified (possibly) by G53.

21. Stop (M0, M1, M2, M30, M60).
22. M97, M98, M99

As you can see, the order is all over the map. This was done to try to have operations that depend on one another happen in the preferred order. For example, if you are turning coolant on or off in the same line you’re potentially going to perform a cutting motion, you’d want the coolant on before the cutting begins, not afterward.


As we’ve mentioned in some of the other articles, G-Code is a modal language. Many times when we execute a particular word, it sets up a mode that carries forward. After we execute “G00”, we’ve put the controller into rapids mode. Any coordinate words will result in rapids motion to the coordinate. These modes are another reason to be aware of the order of execution of the words in a block as many words create modes that have an impact on other words that follow.

Forcing the Order of Execution

If you have any doubt about the order things are happening in, or more importantly, if you care what order the words are executed in, the best answer is to put them into consecutive blocks. This way there is no ambiguity. You could try to remember the arbitrary order for your controller, but that’s a lot more error prone!

Don’t Cram Too Much Into a Block!

A corrolary to the ideas about forcing order of execution is not to try to cram too much into a block. The g-code often won’t let you anyway–you can’t just slam a whole bunch of moves into the same block, for example. So don’t get in too much of a hurry. Keep things together that it makes sense to have together and let things where it doesn’t make sense spread into their own blocks to make the code more clear.

Word Conflicts and Code Groups

Since words are modal, the possibility of conflicts exists. For example, if you entered “G00” (rapids linear motion) and “G01” (feedrate linear motion) in the same block, there is a conflict because the controller can’t do both. Generally, it will choose the last one but sometimes it will create an error.

Fanuc and others try to keep conflicts straight using what are called “Code Groups”. If two words belong to the same group, then they conflict with each other and should not be used in the same block.


Speaking of making sense and being clear, don’t forget to add comments to your code in various places. Anything you place in parenthesis is a comment that is ignored when executing the g-code program. For example:

% A do something simple g-code program


N100 G00 X0 Y0 Z0 (Rapid to Part Zero)


The comment tells why we’re moving to that particular location. There’s no need to over-comment the code–things that are obvious shouldn’t need comments. Try commenting anything that was hard to figure out when you wrote the g-code. The comments can serve as a reminder for what you learned and what you were trying to accomplish. If you’re trying to read some g-code and scratching your head, add some comments when you figure it out. The next guy to read that code will thank you.

Comments as Headers Delineating Sections

Comments are a good way to delineate different sections of the g-code. Put one at the top that has all the salient information about your program that the operator and future programmers will find convenient to have:



( A do something simple g-code program ——————–)

( Written by Bob Warfield, July 18, 2011 ———————)



N100 G00 X0 Y0 Z0 (Rapid to Part Zero)


A really complete program header ought to include things like:

– Program file name.

– Program author

– Version date

– Modification history–a line for each version telling what changed, who made the changes, and the date.

– Machine and control the program is intended for

– Units: inches or mm

– Setup information: What stock material is expected, what size, etc.?

– Work Coordinates: What’s expected by way of work coordinates? Where is Part Zero?

– Customer info: Job shops will want information about what customer and job # the program is part of.

It’s a good idea to have a header for each subprogram as well, though there is no need to repeat all the same information that’s already in the main program’s header.

CAM Programs and Other Software Often Create Special Comments

CAM Programs and other software will often use comments as a good place to store additional information that there is no other way to encode into the g-code. Here is a typical example from the HSMWorks CAM program:

(T1 D=0.4724 CR=0. – ZMIN=-0.77 – FLAT END MILL)

It’s telling us the name of the CAM file was “TANKCONSTANTSCALLOP”. Immediately below is a tool definition. This program uses exactly one tool “T1” with the following characteristics:

– Tool Diameter = 0.4724

– Corner Radius = 0

– Z Minimum = -0.77

– Tool Type = Flat End Mill

Here’s an example from OneCNC:

N10 (MACH3 MILL – )

They went to a format that has more information for human operators.

Keep an eye out for these if you’re editing g-code generated by a CAM program. They may give you some useful information and you may not want to delete these comment if they’re something some other software may want to access for some reason.


You now have a solid foundation for using CNC machines as a manual machine substitute, and you’ve seen the basics of how g-code programs are put together from g-code blocks. That’s a good starting point. From here on we’ll be adding bricks to that foundation around special topics that will allow you to create more and more powerful g-code programs.


1. Get your CNC Controller’s manual and go through G-Wizard Editor’s Word Address Formats to verify that GWE is configured correctly for your controller.

2. Put together a simple header format that you plan to use for your g-code programming. Use it to create a simple do-nothing program that can serve as the initial template when you create a new g-code file.

3. If you use a CAM program, investigate what its options are for headers in the g-code file it posts.

4.  Have a look at some sample gcode files.

Next Article: Linear Motion G00 and G01

Recently updated on March 20th, 2024 at 08:06 am