v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

Editing 40d:Macro design

Jump to navigation Jump to search

Warning: You are not logged in.
Your IP address will be recorded in this page's edit history.

You are editing a page for an older version of Dwarf Fortress ("Main" is the current version, not "40d"). Please make sure you intend to do this.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
{{quality|superior}}{{av}}
 
 
Playing Dwarf Fortress means lots of typing. Macros can reduce this typing, but they must be planned and designed carefully. This page discusses how to design a macro and avoid common problems. The specific operation or structure for which you are creating a macro is beyond the scope of this page.
 
Playing Dwarf Fortress means lots of typing. Macros can reduce this typing, but they must be planned and designed carefully. This page discusses how to design a macro and avoid common problems. The specific operation or structure for which you are creating a macro is beyond the scope of this page.
  
== Macro delay ==
+
== Macro Delay ==
 
Forum and wiki participants have observed that some macros can take hours to run. This happens because there is a built-in delay between each macro command; since the game as shipped includes no preset macros, this delay is set to a value that allows the human player to see each move and debug any mistakes.
 
Forum and wiki participants have observed that some macros can take hours to run. This happens because there is a built-in delay between each macro command; since the game as shipped includes no preset macros, this delay is set to a value that allows the human player to see each move and debug any mistakes.
  
Line 45: Line 44:
 
Most of the time a macro takes to run is spent moving the cursor around. This can be sped up through the use of the "_FAST" versions of the move commands and by moving diagonally.
 
Most of the time a macro takes to run is spent moving the cursor around. This can be sped up through the use of the "_FAST" versions of the move commands and by moving diagonally.
  
=== Fast movement ===
+
=== Standard Movement ===
When you hold the {{key|Shift}} key in the game UI and press an arrow key, the cursor jumps ten squares instead of one. Similarly, each cursor command has a "_FAST" version that jumps ten squares in the same time a normal movement command takes to travel on square.
+
When you hold the {{key|Shift}} key in the game UI and press an arrow key, the cursor moves ten squares instead of one. Similarly, each cursor command has a "_FAST" version that jumps ten squares in the same time a normal movement command takes to travel on square.
  
 
The following code,
 
The following code,
Line 57: Line 56:
 
  [MACRO:CURSOR_UP:3]
 
  [MACRO:CURSOR_UP:3]
  
is exactly the same action in only 4 commands.
+
is the exact same action in only 4 commands.
  
 
=== Backpedaling ===
 
=== Backpedaling ===
Line 74: Line 73:
 
  [MACRO:CURSOR_Down:2]
 
  [MACRO:CURSOR_Down:2]
  
Is exactly the same cursor position change but in only 6 moves. This can have [[#Edge collision|side effects]] however and must be done carefully.
+
Is the exact same cursor position change but in only 6 moves. This can have side effects however (covered below) and must be done carefully.
  
=== Diagonal movement ===
+
 
 +
=== Diagonal Movement ===
 
Most people using modern keyboards are familiar with the T-shaped arrow key block. The numeric keypad has arrows too, and on some keyboards the {{key|1}} {{key|3}} {{key|7}} {{key|9}} keys have arrows as well. Regardless of whether your numeric keypad has arrows on it, you can move with the {{key|1}} {{key|3}} {{key|7}} {{key|9}} keys. Diagonal movement is also possible in macros, and it can be used to reduce the number of commands required.
 
Most people using modern keyboards are familiar with the T-shaped arrow key block. The numeric keypad has arrows too, and on some keyboards the {{key|1}} {{key|3}} {{key|7}} {{key|9}} keys have arrows as well. Regardless of whether your numeric keypad has arrows on it, you can move with the {{key|1}} {{key|3}} {{key|7}} {{key|9}} keys. Diagonal movement is also possible in macros, and it can be used to reduce the number of commands required.
  
Line 98: Line 98:
 
This saved us 12 unneeded commands.
 
This saved us 12 unneeded commands.
  
The "_FAST" works in the game and in your scripts on diagonals too. Further bringing down the previous example command count to just,
+
The "_FAST" works in the game and in your scripts on diagonals too. Further bringing down the the previous example command count to just,
  
 
  [MACRO:CURSOR_UPRIGHT_FAST:1]
 
  [MACRO:CURSOR_UPRIGHT_FAST:1]
Line 108: Line 108:
 
Diagonal movement commands are written as '''vertical''' then '''horizontal''' with no separating "_"
 
Diagonal movement commands are written as '''vertical''' then '''horizontal''' with no separating "_"
  
=== Final cursor placement ===
+
=== Cursor Return ===
 
When designing scripts, it's a good idea to plan where to leave off. The two common ideas are:
 
When designing scripts, it's a good idea to plan where to leave off. The two common ideas are:
 
* Back where the script started, which is less disorienting to the user. This is best for macros that are intended to be used once.
 
* Back where the script started, which is less disorienting to the user. This is best for macros that are intended to be used once.
Line 117: Line 117:
  
  
= Troubleshooting =
+
= Problems to avoid =
 
 
== Off-by-one errors ==
 
When your script doesn't run as planned, check if you went too far on a movement action. This can happen if you confuse the number of squares ''designated'' with the number of squares ''moved''.
 
  
For example, to make a '''5x5''' box, use 4's instead of 5's:
+
== A step to far ==
 +
When your script doesn't run as planned, check if you went too far on a movement action. To make a 5x5 box the code is
  
 +
//written for ease of reading
 
  [MACRO:SELECT:1]
 
  [MACRO:SELECT:1]
  [MACRO:CURSOR_LEFT:'''4''']   
+
  [MACRO:CURSOR_LEFT:4]   
  [MACRO:CURSOR_UP:'''4''']
+
  [MACRO:CURSOR_UP:4]
 
  [MACRO:SELECT:1]
 
  [MACRO:SELECT:1]
  
The cursor's initial position always counts as 1 "extra" square, since you're defining movement, not a size.
+
Those are 4's not 5's. The cursors current position is always 1, since it's really movement your defining not a size. Its an easy concept but also easy to forget/mess up.
 
 
#    1 square ''designated'', '''0''' squares ''moved''
 
 
##    2 squares ''designated'', '''1''' square ''moved''
 
 
###  3 squares ''designated'', '''2''' squares ''moved''
 
  
== Edge collision ==
+
==Edge Collision==
When the cursor hits an edge of the map, it stops there, no matter how far your script wants to travel that way. This is per command, and if you're not expecting to hit an edge, this will corrupt that execution of the script. To avoid this, the script-runner must ensure that the script has enough room to run when it is started. The script-designer can help by clearly documenting how much space is needed.
+
Edge Collision can be helpful in several situations. When you hit a edge you stop there, no matter how far your script wants to travel that way. This is per command and if your not expecting to hit a wall, it will corrupt that exeicution of the script. There is no way to avoid this. And in most cases, it's the script-runner's fault not the script-designer's.
  
Scripts can also run into trouble with [[#Backpedaling|backpedaling optimizations]]. Backpedaling can extend your script's running area beyond the area where it is making changes. If the script-runner only leaves enough space for the changes themselves, there is a risk that any _FAST jumps outside that area will be shortened by hitting an edge, and any subsequent backpedaling operations will then start from the wrong position. Therefore, it is recommend to only use backpedaling that does not go outside of your script's work area.
+
However as a designer you can run into trouble with backpedaling optimizations as mentioned above. Backpedaling can jump you out of the working area of your script and then return, as long as there is enough extra space around your script area to do so. If an edge happens to be there, instant problem.
  
For example, if your script operates inside a 17x4 rectangle, getting across it with the following code,
+
:If your script is made inside a 17x4 rectangle, getting across it with the following code,
  
 
  [MACRO:CURSOR_RIGHT_FAST:2]
 
  [MACRO:CURSOR_RIGHT_FAST:2]
 
  [MACRO:CURSOR_LEFT:3]
 
  [MACRO:CURSOR_LEFT:3]
  
will place the cursor incorrectly if an edge is 19 squares away.
+
is fine, as long as an edge wasn't 19 squares away.
  
For script areas of 6, 7, 8, or 9, it may be wise to avoid backpedaling entirely, since any _FAST operation would move the cursor outside that range. But with a script area that small, speed probably isn't as much of an issue.
+
It's recommend to only use backpedaling that does not go outside of your script's work area.
 +
 
 +
With backpedaling movements, that are larger than 10 spaces, a simple change of order of operations can fix this issue. Here is the above example, with an order changes
 +
 
 +
[MACRO:CURSOR_RIGHT_FAST:2]
 +
[MACRO:CURSOR_LEFT:3]
  
For areas larger than 10 spaces, reordering the commands can keep the cursor in-range while still using backpedaling optimizations. The above example is equivalent to this:
+
is really just
  
 
  [MACRO:CURSOR_RIGHT_FAST:1]
 
  [MACRO:CURSOR_RIGHT_FAST:1]
Line 157: Line 155:
 
  [MACRO:CURSOR_LEFT:3]
 
  [MACRO:CURSOR_LEFT:3]
  
Which we can reorder to:
+
so we can reorder it to
  
 
  [MACRO:CURSOR_RIGHT_FAST:1]
 
  [MACRO:CURSOR_RIGHT_FAST:1]
Line 163: Line 161:
 
  [MACRO:CURSOR_RIGHT_FAST:1]
 
  [MACRO:CURSOR_RIGHT_FAST:1]
  
This is the same run time and number of commands, yet the cursor says inside the script area. The backpedaling "LEFT:3" command now backs up in the space the first "_FAST" command had already traveled. (Note that if it had been placed ''first'', the cursor would have backpedaled out the other side.)
+
This is the same run time and number of commands, yet the cursor says inside the script area.  
 +
:For script areas of 6, 7, 8, or 9 your just out of luck and I would suggest not backpedaling, but with a script area so small, speed isn't that much of an issue.
  
{{Category|Interface}}
+
:The backpedaling "LEFT:3" command, travels over the same area the previous "_FAST" command had covered. If it had been placed first, the cursor would have backpedaled out the other side.

Please note that all contributions to Dwarf Fortress Wiki are considered to be released under the GFDL & MIT (see Dwarf Fortress Wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Cancel Editing help (opens in new window)

This page is a member of 1 hidden category: