Grid and direction
grid-and-direction-1
This contract defines the behaviour of square grids: a tile map, a chess board, or a dungeon map.
It decides how your grid is numbered, which cells are neighbours, how distance works, and how a rule breaks a tie.
Use in your game
Opens the authoring tool with this contract added and its questions unanswered. Or download the ZIP and add it later.
What is in the ZIP
The ZIP holds the contract and its acceptance tests. In the authoring tool, choose Add contract and pick this ZIP. If you keep your design as files, put them in contracts/ and fill in the answers there.
Questions
Up to 10 questions. Some appear only after earlier answers.
- Where is this grid's first cell, and which way do its row and column numbers grow?
- When you write a cell with two numbers, does the row or column come first?
- Do the first row and column use zero or one?
- A point lies exactly on the line between two cells. Which cell owns it?
- When your rules say nearest or within some distance, how do they measure between cells?
- From one cell, which other cells can a thing reach in one step?
- When a rule says two cells are next to each other, do corners count?
- In what order does an authored layout list its cells?
- A rule rates two cells equally and must pick one. How does it decide?
- When your rules turn a facing by an amount, which way does the amount go on the grid?
Try the answers
Pick answers to see which rules and tests apply. Nothing is saved here: the ZIP and the authoring tool start unanswered.
Where is this grid's first cell, and which way do its row and column numbers grow?
Why this is asked
Every later rule needs one shared reading of row and column numbers. This contract only carries columns that grow right; state a left-growing grid in your own prose.
When you write a cell with two numbers, does the row or column come first?
Why this is asked
Swapping the two numbers turns rows into columns. A square grid can hide that mistake, so the order must be clear.
Do the first row and column use zero or one?
- Asked when
- Origin and axes is Top left or Bottom left.
Why this is asked
Starting at zero or one changes every written cell address. Naming it prevents an off-by-one shift between the design and the build.
A point lies exactly on the line between two cells. Which cell owns it?
Why this is asked
A boundary point needs one owner. Different rounding rules can place the same point in different cells, especially beside zero.
When your rules say nearest or within some distance, how do they measure between cells?
Why this is asked
Games often use several distance rules. This answer only controls what your written rules mean by nearest or within a distance.
From one cell, which other cells can a thing reach in one step?
Why this is asked
Movement neighbours do not follow automatically from distance or effect range. A game can use different cells for each.
When a rule says two cells are next to each other, do corners count?
Why this is asked
Movement and effects can count neighbours differently. This answer keeps words such as next to from changing meaning between rules.
In what order does an authored layout list its cells?
Why this is asked
Drawing, updates, and save files may use different orders. This answer covers only layouts designers write and read.
A rule rates two cells equally and must pick one. How does it decide?
Why this is asked
Equal choices are common and rarely written down. A fixed answer stops two builds from choosing different cells.
When your rules turn a facing by an amount, which way does the amount go on the grid?
Why this is asked
Axis direction does not decide turn direction. Naming clockwise or counter-clockwise prevents equivalent formulas from reading as opposite rules.
Numbers and rules1 number, 1 rule
Numbers
Each setting takes a number, or a reference to a named value in your tuning. Stay inside any range shown.
Cell size
cell-size
The length of one cell in your position units. For centre-based cells, measure from one centre to the next. Use a positive size when rules read positions. Use zero when they only read whole cells. Changing this number changes which cell holds a position.
Rules
cell-size >= 0
Lists1 list
Some settings are lists of rows.
Directions
directions
List every direction word your game uses. Each row says whether it follows the grid or a piece. A grid direction also says where it points. An empty list means the game names no directions. If ties use this order, list every grid-fixed neighbour that can tie. The validator cannot check this; a reviewer does.
Each row is: id, frame, points, order.
Every field
| Field | Kind | When it appears | Meaning |
|---|---|---|---|
id |
string | Required | The direction word your game uses, such as north, forward, or starboard. Write it in lowercase with hyphens between words. |
frame |
choice: grid, piece | Required | Whether the direction follows the grid or a piece. A grid direction always points the same way: north stays north. A piece direction changes when that piece turns: forward, left, and behind turn with it. |
points |
choice: up, down, left, right, up-left, up-right, down-left, down-right | Present when row frame is Grid. | Where this grid-fixed direction points on the grid. Omit it for a direction that follows a piece. This does not decide whether movement is allowed that way. |
order |
integer | Present when Tie break between cells is Direction order and row frame is Grid. | This direction's place in the tie-breaking walk. One is tried first. Give each grid-fixed direction a different number. Use it only when ties follow direction order. |
For builders
Exact mechanism wording and 22 pack tests
Exact mechanism wording
The mechanism is one grid of equal square cells. A row runs across it, and a column runs down it. When a game names a cell with two whole numbers, coordinate-order says which one comes first; a layout may name cells by their contents instead. The grid may be a bounded rectangle with a first cell in one corner, or run on in every direction with signed numbers and no first cell; the first question says which.
The grid's own frame. Every answer below is read against the grid as this package declares it: the layout your content writes out, or your own chapter's sentence about which way the numbers grow. Up, down, left and right mean those directions on the declared grid. On a bounded grid where content writes the grid out row by row, the first written row is nearest the declared origin corner: the top row for top-left, and the bottom row for bottom-left. These directions never follow the finished picture, which a build may draw any way its presentation chapter allows. A Delegated view can never change a Fixed answer.
Where a game also has positions — things resting between cells rather than on them — zero is the same place for cells and for positions, and where a cell-ownership option makes the cell at zero a different width, that option says so. Two neighbouring cells share a line, and cell-ownership says which cell the line belongs to. Every conversion below divides by the cell size and, where the grid counts from 1, adds 1. Each cell-ownership option that uses positions states how position zero and shared lines are treated.
Several nearby decisions are deliberately not here — the grid's edge, sharing a cell, corner-cutting, pathfinding, a third axis, cells that are not squares, whether a sweep sees its own changes. The note at the end says where each lives.
Verification pack
sha256:b17529b6bce460ee83f7c460f2e73c39d5c32051637613867e42ef85b6e0996a
The format calls an adoption with its matching pack Checked: the tests travel with it, but a game has not necessarily passed them. Without the pack the adoption is Promised: the builder still owes the chosen behavior.
22 pack tests
Placeholders are filled from the adoption's answers, values, rows, and verification inputs.
the numbers grow one way
axes-grow
Applies for every adoption
In Instance the two numbers grow Bind growth phrase, one per cell. The layout this is read against is the one this package declares, not the finished picture: a build may draw the grid any way its presentation chapter allows and still has to number it this way.
- Given
Instanceas this package lays it out, with at least two rows and at least two columns- When
- a cell is located in the layout
- the cells one step from it across and down are located
- Then
- the numbers grow
Bind growth phrase - moving one cell that way raises exactly one of the two numbers by one and lowers neither
- moving one cell the opposite way lowers exactly one of them by one
- the numbers grow
- Diagnostics
Instance-cell-addressesInstance-declared-layout
the grid has a first cell, in one named corner
the-first-cell-is-in-one-corner
Applies when Origin and axes is Top left or Bottom left.
Instance is a bounded rectangle whose first cell — the one whose two numbers are both smallest — is Bind corner phrase. A build that numbers from the opposite corner fails this test even when every layout still loads.
- Given
Instanceas this package lays it out- When
- the cell whose two numbers are both the smallest on the grid is located in the layout
- Then
- that cell is
Bind corner phrase - no other corner of
Instanceholds a smaller pair of numbers - the grid is bounded: every cell of it lies inside the declared number of rows and columns
- that cell is
- Diagnostics
Instance-cell-addressesInstance-declared-layout
the grid runs on in every direction
the-grid-has-no-first-cell
Applies when Origin and axes is Unbounded right and down or Unbounded right and up.
Instance has no first cell. Its numbers are signed and it runs on in every direction, so a cell at a negative number is as ordinary as any other and no rule may assume a corner to count from. Six of thirteen externally surveyed grids are this shape, including two of the four format specifications, which is why it is an answer here rather than an omission.
- Given
Instanceand the cell this package puts at zero on both axes- When
- cells are addressed on every side of that cell, including at negative numbers on each axis
- a rule of this game reads or writes one of those cells
- Then
- every one of those cells is a legal address and is handled the same way as any other
- no rule of this game assumes a first cell, a last cell, or a corner
- nothing shifts the numbers to make them positive before a rule of this game reads them
- Diagnostics
Instance-cell-addressesInstance-negative-coordinate-trace
a written pair names the cell this package means
coordinate-reading
Applies when Coordinate order is Column first or Row first.
In Instance, Bind pair phrase, and Bind start phrase. The test asks for a grid whose rows and columns differ in number on purpose: on a square grid a build that reads the pair backwards passes every test anyone would think to write, and ships transposed.
One surveyed game numbers its authored map files from one and its engine from zero, and records that nowhere but a source comment. The numbers this test is about are the ones this package's own material writes.
- Given
Instancewith a different number of rows and columns, so that reading a pair the wrong way round cannot land on a real cell by luck, or a stated reason why no such grid exists in this game- When
- the build resolves a cell that this package's own material writes as a pair of numbers
- Then
Bind pair phraseBind start phrase- the cell the build resolves is the cell this package's material means
- the same pair with its two numbers swapped resolves to a different cell, or to no cell at all
- Diagnostics
Instance-resolved-cellInstance-source-reference
every position belongs to exactly one cell
every-position-has-one-cell
Applies when Cell ownership is Next cell along or Truncate toward zero or Cell centres are whole numbers.
Within this adoption's verification scope — Inputs scope — every position of Instance lands in exactly one cell, never in two and never in none, and the cell is found by Bind conversion phrase. Converting back and forth closes the loop.
The scope and seeds are this game's, supplied through this adoption's verification inputs; the check and its oracle are the contract's. Rounding down and cutting the fraction off agree everywhere the numbers are positive and part company on the other side of zero, which is why the scope should reach both sides wherever this game has them.
- Diagnostics
Instance-position-to-cell-trace- first-position-owned-twice
- Holds
the position belongs to exactly one cell of
Instance, found byBind conversion phrase; and converting that cell back to a position inside it and converting again returns the same cell- Seeds
Inputs seeds- Scope
Inputs scope
a position on a shared line belongs to one cell
boundary-belongs-to-one-cell
Applies when Cell ownership is Next cell along or Truncate toward zero or Cell centres are whole numbers.
In Instance, a position exactly on the line between cells 5 and 6 is in Bind positive case phrase, and a position on a line below zero is in Bind negative case phrase. Real cell numbers are named here on purpose: this is the decision in the definition whose answers are easiest to state backwards, so the test states the winning one as a worked case rather than as a label. Cells 5 and 6 exist whether this grid counts from 0 or from 1, and where counting starts at 1 the conversion adds its one step and this case is unchanged.
The second clause asks about positions below zero rather than about cells at negative numbers, and the difference is not pedantry: a bounded board numbered from zero has no negative cells, yet where the cell numbers name centres the outer half-cell band of that same board sits at negative positions — which is exactly where two of the three conversions part company. Where no rule of this game ever reads a position below zero on either axis, the clause has nothing to check.
The last clause is worth reading twice: one answer, everywhere in the build, rather than one answer per system that happens to ask.
- Given
the cells numbered 5 and 6 on one axis of
Instance, and any position your rules read that lies below zero on either axis- When
- a position is placed exactly on the line between cells 5 and 6
- a position below zero is placed exactly on a line between two cells
- a position is placed exactly where four cells meet
- Then
- the position between cells 5 and 6 is in
Bind positive case phrase - wherever a position your rules read lies below zero, the position on the line there is in
Bind negative case phrase - neither of those positions is in any other cell
- the position where four cells meet is in the single cell picked by applying that same rule on both axes at once
- every rule in the build that asks which cell any of those positions is in gets the same answer
- the position between cells 5 and 6 is in
- Diagnostics
Instance-boundary-owner-report
distance between two cells is measured one way
distance-is-measured
Applies when Distance metric is No diagonals or Diagonals count the same or Octile or Straight line.
Where a rule of Instance says nearest, in range, or within, the distance it means is Bind metric phrase. It is zero from a cell to itself, it does not depend on which cell is asked about first, and — the clause that matters most — every such rule returns the same number for the same pair. One worked case pins the arithmetic where a near-enough value would pass unnoticed: measured from one cell, Bind worked case phrase.
Seven of nine externally surveyed games measure distance more than one way, and one carries five measures at once. This test does not forbid that: a route planner's own estimate is craft and is outside Inputs scope. What it forbids is two rules telling a player two different things about the same two cells.
- Diagnostics
Instance-distance-trace- first-disagreeing-rule
- Holds
the distance the rule uses between the two cells is
Bind metric phrase; the distance from a cell to itself is zero; it is the same whichever cell is asked about first; every rule inInputs scopereturns the same number for the same pair; and the worked case holds — measured from one cell,Bind worked case phrase- Seeds
Inputs seeds- Scope
Inputs scope
two distances count as equal by a declared rule
equal-distance-is-decided
Applies when Distance metric is Straight line or Octile.
Instance measures distance with a rule that does not come out in whole cells, so two distances being the same is itself a decision, and this game declares how:
Inputs scope
That rule decides which pairs reach the tie-break question and which are settled before it, and it is the only comparison the build may use.
Asking for it out loud is worth one line of an adoption. In a blind two-build experiment on this definition, one builder met exactly this gap, invented a tolerance of sixteen times the smallest representable step, got the right answer, and did not record the decision — the one number in that build the package had not supplied, sitting directly under a scored check.
- Given
- the rule this game declares for deciding that two distances are the same:
Inputs scope - two candidates whose distances from one cell are the same under that rule, and two more whose distances that rule tells apart
- the rule this game declares for deciding that two distances are the same:
- When
- a rule of this game ranks each pair by distance
- the same two pairs are ranked again with the two distances worked out in the opposite order
- Then
- the first pair reaches the tie-break and the second does not
- the rule supplied in this adoption's verification scope is the only comparison used: no other tolerance, rounding or nearly-equal test appears anywhere in the build
- both rankings come out the same, whichever order the two distances were worked out in
- Diagnostics
Instance-distance-traceInstance-tie-break-report
one step reaches exactly the neighbouring cells
one-step-moves
Applies when Adjacency for movement is Four neighbours or Eight neighbours.
From any cell of Instance, one step reaches exactly Bind movement neighbours phrase, with nothing standing in the way. What happens when a step would leave the grid, and whether something in the way blocks it, are settled elsewhere in this package; this test fixes only which cells a step can reach at all.
- Diagnostics
Instance-reachable-in-one-step- first-unexpected-destination
- Holds
of the cells on the grid, the ones a thing can move to from this cell in one step, with nothing standing in the way, are exactly
Bind movement neighbours phrase— no more and no fewer- Seeds
Inputs seeds- Scope
Inputs scope
next to means the same cells in every rule
next-to-means
Applies when Adjacency for effects is Four neighbours or Eight neighbours.
Wherever a rule of Instance says one cell is next to another, it means Bind effect neighbours phrase — and it means the same thing in every rule that says it. This is asked apart from movement because games answer the two differently, sometimes without noticing: one surveyed game plans routes over four neighbours while targeting by straight line, and one engine hands back four surrounding cells while its own direction list carries sixteen.
- Diagnostics
Instance-neighbour-set-per-rule- first-disagreeing-rule
- Holds
wherever a rule of this game treats one cell as next to another, the cells it means are exactly
Bind effect neighbours phrase, and the answer is the same in every such rule- Seeds
Inputs seeds- Scope
Inputs scope
this package's own material lists every cell once
authored-order-lists-every-cell
Applies when Enumeration order is Rows then columns or Columns then rows or Block tiled.
An authored layout of Instance lists every cell exactly once, Bind order phrase, and reading that layout back gives the same cells in the same places.
This does not set save-file order, drawing order, update order, or the order in which rules visit cells. Naming the authored order stops a rule from quietly depending on one of those other orders.
- Scope
an authored layout of
Instance, with every cell distinguishable from every other, read from the first cell to the last as designers write it- Holds
the material lists every cell of
Instanceexactly once,Bind order phrase, and a board written out and read back arrives cell for cell the same- Diagnostics
Instance-authored-order-sequence- first-cell-out-of-order
- cells-listed-twice-or-never
the blocks this material is written in are declared
block-layout-is-declared
Applies when Enumeration order is Block tiled.
Instance is written in blocks, so three things have to be readable before the material can be read at all: how big a block is, what order the blocks come in, and what order the cells inside a block come in. They are set out at Inputs scope, and this test reads the material against that place.
The three worlds in the external tally that store their grids this way are all too large to hold at once, and none of them states these three things in an authored artifact. The pointer is what this contract can carry; following it is a reviewer's job.
- Given
an authored layout of
Instance, and the block size and the two orders asInputs scopesets them out- When
- the material is read back cell by cell
- Then
- the blocks come in the order that place sets out, and the cells inside each block come in the order it sets out
- every block holds the number of cells that place states, apart from any partial block it also describes
- reading the same material twice gives the same sequence
- Diagnostics
Instance-authored-order-sequenceInstance-block-boundaries
a tie between two cells settles the same way every time
tie-break-settles
Applies when Tie break between cells is Lower column wins or Lower row wins or Direction order or Named priority list.
When a rule of Instance must pick between two candidates it ranks equally, it picks Bind tie phrase. The adoption demonstrates that answer with this worked case: Inputs scope. The test repeats the case after reversing creation and drawing order. A choice that changed would be a different answer to this question.
- Given
a rule of this game that must pick one cell, and the worked pair of equally ranked candidates described here:
Inputs scope- When
- the rule runs
- the same situation is set up again, with the two candidates created in the opposite order and drawn in the opposite order
- Then
- the rule picks
Bind tie phrase - it picks the same candidate both times
- the order the candidates were created in, the order they are drawn in, where the pointer is, and how the animation runs change nothing
- the rule picks
- Diagnostics
Instance-tie-break-reportInstance-candidate-set
a tie between two cells goes to whichever came first
tie-break-follows-arrival
Applies when Tie break between cells is Arrival order.
A tie in Instance goes to whichever candidate came first, by the moment Inputs scope names — one moment, chosen and written down, rather than whichever of created, placed and stored happens to be handy at the call site. This is the plurality answer in the wild: five of nine externally surveyed games settle ties this way.
The test holds a build to the part it can be held to — a run replayed from a fresh start makes the same choice. Whether these ranks survive a save and reload is this game's own persistence rule, stated where that pointer leads, and this contract records the pointer rather than checking what it says.
- Given
a rule of this game that must pick one cell, and two candidates the rule ranks equally, one of which came first by the moment
Inputs scopenames- When
- the rule runs
- the same run is played again from a fresh start with the same inputs
- Then
- the rule picks the candidate that came first by that moment, and not by any other moment in the two candidates' histories
- the replayed run picks the same candidate, because it builds the two candidates in the same order
- nothing about where the candidates sit on the grid changes the choice
- Diagnostics
Instance-tie-break-reportInstance-arrival-order-log
a tie between two cells comes out the same way in a replay
tie-break-is-arbitrary
Applies when Tie break between cells is Deliberately arbitrary.
Instance promises no order between two candidates it ranks equally: the choice may come out either way. That is a decision rather than a shrug — two surveyed sources choose it on purpose, one of them deliberately mixing the choices so the leftmost candidate is not always favoured.
This test checks only what a build can be held to: one run, replayed from a fresh start with the same inputs, picks the same candidate. The design's real claim — that nothing a player sees depends on which one was taken — is recorded in the answer itself and cannot be tested here, because nothing can rerun a moment with the tie settled the other way. Nothing further is promised either: a save and reload may choose differently.
- Given
a rule of this game that must pick one cell, and two candidates the rule ranks equally
- When
- the rule runs
- the same run is played again from a fresh start with the same inputs
- Then
- one of the two candidates is picked, and the run carries on
- the replayed run picks the same candidate
- no rule of this game reports which candidate was picked as a promise a player or another rule may rely on
- Diagnostics
Instance-tie-break-reportInstance-tie-occurrence-log
a tie between two cells is drawn from a declared stream
tie-break-is-drawn
Applies when Tie break between cells is Random from a declared seed.
A tie between two candidates in Instance is drawn at random from a stream this game declares, so the same seed and the same inputs pick the same candidate every time. Random here means reproducible: a draw from an undeclared source would make two faithful builds of this spec disagree, which is what a declared stream prevents.
- Given
a rule of this game that must pick one cell, two candidates the rule ranks equally, and a run started from a named seed
- When
- the rule runs
- the same run is replayed from the same seed with the same inputs
- the same situation is reached in a run started from a different seed
- Then
- the candidate picked is drawn from the stream this game declares for it, and from no other source of randomness
- the replay picks the same candidate
- the draw consumes from that stream exactly as this game's own determinism rules say it does
- Diagnostics
Instance-tie-break-reportInstance-stream-consumption-log
a tie between two cells is put to the player
tie-break-asks-the-player
Applies when Tie break between cells is Player chooses.
Instance does not settle a tie between two equally ranked candidates by itself: the player is asked. Where a rule cannot ask — an automatic step, a replay, a resolution with nobody watching — it does not guess. It does not run, and nothing changes.
- Given
a rule of this game that must pick one cell, and two candidates the rule ranks equally
- When
- the rule runs and the player can be asked
- the rule runs where the player cannot be asked
- Then
- in the first case the player is asked which candidate they mean, and the game picks neither on its own
- in the second case the rule does not run and nothing about the game state changes
- no candidate is ever picked because of the order things were created in, the order they are drawn in, or where the pointer is
- Diagnostics
Instance-tie-break-prompt-logInstance-state-before-after
no rule ever faces a tie between two cells
no-tie-ever-arises
Applies when Tie break between cells is Not applicable.
Instance answers the tie-break question with not-applicable, and this is that answer checked rather than assumed: across Inputs scope, no rule ever has to choose between two candidates it ranks equally. Where a rule does meet a tie, it affects both alike and picks neither.
Three corpus packages state exactly this claim in their own prose, and all nine externally surveyed games face the tie instead. It has a real failure mode — a rule quietly taking whichever candidate happened to be first in some list — and that is what this test looks for.
- Diagnostics
Instance-tie-occurrence-log- first-unresolved-tie
- Holds
no rule of this game reaches a point where two candidates are ranked equally and one of them has to be chosen: either the situation cannot arise, or the rule affects every tied candidate alike
- Seeds
Inputs seeds- Scope
Inputs scope
a positive turn goes one way
a-positive-turn-goes
Applies when Turn direction is Clockwise or Counter clockwise.
In Instance, a positive turn moves a facing Bind turn phrase on the declared grid, and turning back by the same amount returns the facing exactly. Naming the turn on the grid is deliberate: two corpus packages describe this same turn in opposite words, one counting from an axis and one naming the clock, and a reader has to do arithmetic to find out they agree.
- Given
something standing on
Instancethat has a facing, with that facing recorded- When
- it turns by a positive amount
- it then turns by the same amount the other way
- Then
- the first turn moves its facing
Bind turn phraseon the grid as this package lays it out - the second turn brings the facing back exactly to where it started
- every rule of this game that turns something turns it the same way for a positive amount
- the first turn moves its facing
- Diagnostics
Instance-facing-before-afterInstance-turn-log
Row.id points Bind points phrase
grid-direction-points
Applies when row frame is Grid.
In Instance, the word Row.id means the direction Bind points phrase. It is fixed to the grid: it points the same way whoever uses it, and it never follows anything's facing. Naming it says nothing about whether anything may move that way — the movement question decides that, and a game whose pieces move to four neighbours may still name a diagonal for an effect or a line of sight.
Writing the word down here is what stops a second document in this package using it for a different direction. One surveyed format ships eight named compass directions and never says where any of them points.
- Given
a cell of
Instancewith a cell on every side of it- When
- a rule of this game moves something, points something, or reads a cell
Row.idof that cell
- a rule of this game moves something, points something, or reads a cell
- Then
- the cell it uses is the one
Bind points phrase - the word
Row.idmeans that same direction in every rule of this package and never another - the direction does not change with whatever is using it
- the cell it uses is the one
- Diagnostics
Instance-direction-resolutionInstance-cell-addresses
Row.id takes place Row.order in the direction walk
direction-walk-order
Applies when Tie break between cells is Direction order and row frame is Grid.
When Instance settles a tie by walking its directions, Row.id — the direction Bind points phrase — is tried at place Row.order. The number is on the row so that the walk is visible here rather than inferred from the order the rows happen to sit in.
- Given
a rule of this game settling a tie by walking the directions, and a tied candidate lying
Bind points phrasefrom whatever is choosing- When
- the walk runs
- Then
Row.idis tried at placeRow.orderin the walk, after every direction with a smaller number and before every direction with a larger one- the candidate lying that way is taken exactly when no direction tried earlier holds a tied candidate
- the walk runs in this order every time, whatever built the situation up
- Diagnostics
Instance-tie-break-reportInstance-direction-walk-trace
Row.id is read from the facing of whatever uses it
piece-direction-follows-facing
Applies when row frame is Piece.
In Instance, the word Row.id is read from the facing of whatever uses it, so it points somewhere else after that thing turns, and it can mean two different directions for two things standing on the same cell. That is the whole difference from a word fixed to the grid, and it is worth stating in a package that uses both kinds.
- Given
a thing standing on a cell of
Instance, with a facing and a cell on every side of it- When
- a rule of this game moves it, points it, or reads a cell
Row.idof it - the thing turns, and the same rule runs again
- a rule of this game moves it, points it, or reads a cell
- Then
- the direction the word
Row.idnames is read from that thing's own facing, not from the grid - after the turn,
Row.idnames a different direction on the grid, turned by exactly as much as the facing was - two things with different facings, standing on the same cell, resolve
Row.iddifferently
- the direction the word
- Diagnostics
Instance-direction-resolutionInstance-facing-before-after