Pixel-Art Rooms: Furniture Grids, Caps and Scoring
A decorated room in Pokémon Emerald is sixteen things on a grid of 16-pixel cells. The decompiled source caps a player’s base at 16 placed decorations and the bedroom at 12, and keeps up to 20 bases in the save, your own and other players’.12 The catalog is 120 decorations in eight categories: 35 dolls, 23 ornaments, 18 mats, 10 posters, 10 cushions, 9 desks, 9 chairs and 6 plants. 71 of them cover a single cell, the mean is 2.43 cells, and 18 of them are surfaces that hold the small ones.23 A base measures 44 to 81 walkable cells, 60.2 on average, so the cap is about a quarter of the floor. Placement is a question each covered cell answers, and nothing in the placement function checks that a path survives.24 Three later games in this post run that model at different budgets: 150 items per room in Animal Crossing: New Horizons, by Nookipedia’s account, with a Sunday letter that grades the room; 150 to 600 indoors in Final Fantasy XIV since Patch 7.5, by housing type; 99 in a Club Penguin igloo, by one fan source.5678 My app, Kiradex, has rooms that its art forge furnishes from a vocabulary of 23 pieces, none of which the player can move. This post measures the canon, states the rules with their numbers, maps them onto SwiftData and SwiftUI, and ends with the brief for a furnishing system that Kiradex has not built yet: a cap of 16 per floor, a path rule that Emerald’s placement function does not have, a weekly score whose every point is listed, and a catalog unlocked only by play.910
TL;DR
- Sixteen is a composition budget, not a storage limit. Emerald places 16 decorations in a base and 12 in the bedroom, yet has room for 150 owned decorations in eight per-category bins, so the player can own more than fits. Each placed decoration costs two bytes, an id and a position with x and y as nibbles, which puts a whole base layout in 32 bytes.111122
- The rules live in the floor. Emerald has five placement permissions (floor, walk-over floor, behind, wall, and on a surface). A desk’s top cells carry a behavior that lets a small decoration stand on them, so once a desk is down, a doll can go on it. 18 decorations hold small things and 14 hold large ones. The bedroom accepts only dolls and cushions.1324
- Caps rise with the platform, and one of them is also a frame budget. Animal Crossing allows 24 items per room in Wild World, 64 in City Folk, 48 in New Leaf and 150 in New Horizons, by Nookipedia’s account. Final Fantasy XIV raised indoor limits by half in Patch 7.5, to 150 through 600, and the notes add that above 400 furnishings on screen, those on another floor stop drawing.57
- A score has listed sources, a fixed day and a bar that rises with the house. Nookipedia’s Happy Home Academy table pays 1,000 points each at 6, 10, 15 and 20 items in a room, plus series, set, category, color and feng shui bonuses, and raises the S threshold from 15,000 to 90,000 as the house grows. The page cites no source for those New Horizons numbers.6
- Catalogs grow by purchase, by play, or by both. In Emerald, 90 of 120 decorations are sold for money, 24 are never sold (prizes, battle points and gifts), and two more cost 6,000 and 8,000 ash gathered a step at a time. Stardew sells a random daily stock; after the first house upgrade, Robin also sells the Furniture Catalogue for 200,000g, which then sells the furniture it lists for 0g in unlimited quantity, while some pieces still come only from the Museum, festivals and other sources. Habbo sells furniture, and some of it is scarce or random on purpose.14151617
- Visitors look and do not touch. An Animal Crossing visitor can use the furniture in another player’s house but cannot “modify the interior in any way”. Habbo visitors cannot drop or move furniture without the owner’s rights. Club Penguin allows one like per design per day, and its Grand Total “will never decrease”, by one fan copy of its help pages.51819
- What this gives Kiradex. A brief, not a shipped feature: placement by cell for 20 of the forge’s 23 pieces; a path rule from the door to the stairs, the host and one front cell of every display group, checked by a walk; 16 pieces per floor, with the starter rooms shipped at 8; six wallpapers and six floors drawn by the forge; a Sunday letter with every point source printed (23,600 at most); a catalog unlocked by play, from the levels and pins available today, derived from the synced collection, the quest stamps the app records on the device, and three new synced counters for steps, room visits and the letter’s house tier; read-only visits once the server can store a layout; a SwiftData model with no unique constraint, because CloudKit sync cannot enforce one; and drag placement that VoiceOver can do without touch.9202122
1. Emerald: sixteen things on a grid, measured from source
The smallest complete version of this genre is the decoration system in Pokémon Ruby, Sapphire and Emerald, and almost all of it is data. I read it from pret’s decompilation of Emerald at commit 731ad5b (committed October 1, 2026) with two scripts that parse the source and never run the game: one for the catalog, the caps, the holding surfaces and the room sizes, and one for where each decoration comes from. Their outputs are saved beside them.214 Every number in this section comes from those two outputs or from the source file a footnote names.
The caps
Three constants set the limits. DECOR_MAX_SECRET_BASE is 16, DECOR_MAX_PLAYERS_HOUSE is 12 and SECRET_BASES_COUNT is 20, the number of bases the save keeps: your own and those received from other players.12 The cap on what you place sits apart from the cap on what you own. The save holds 150 owned decorations in per-category bins: 10 desks, 10 chairs, 10 plants, 30 ornaments, 30 mats, 10 posters, 40 dolls and 10 cushions.112 So the player can own more than a room can hold (a new game starts with every bin empty), and choosing what goes in is the game.23
A placed decoration costs two bytes. A base stores decorations[16], one id each, and decorationPositions[16], one byte each, with x in the high nibble and y in the low, so a base is addressed as a grid of at most 16 by 16 cells, and a whole base layout fits in 32 bytes.1112 I read that size as the reason the save can hold twenty bases, your own and other players’.
The catalog
gDecorations[] has 121 entries. Entry 0, DECOR_NONE, is an empty slot that reuses the small desk’s data, which leaves 120 decorations with ids 1 to 120.32 By category they are 35 dolls, 23 ornaments, 18 mats, 10 posters, 10 cushions, 9 desks, 9 chairs and 6 plants.2 By shape, in cells, they are 71 at 1 by 1, 22 at 1 by 2, 13 at 3 by 3, 5 at 2 by 1, 4 at 2 by 2, 3 at 3 by 2, and one each at 2 by 4 and 4 by 2. The header also declares 3 by 1 and 1 by 3, which no decoration uses. A decoration covers 1 to 9 cells, 2.43 on average.213 Counting the empty slot as a decoration, as my earlier notes for the structures post did, gives 72 one-cell pieces and 19 solid-floor ones; without it the counts are 71 and 18.2
Most of Emerald’s catalog is one cell; the big pieces are desks, the 3-by-3 mats and a few ornaments.243
Prices in the table run from 500 for the cheapest mats to 10,000 for the costliest ornaments and dolls. Three have a price of 0, two shields and a glass ornament, and all three are prizes.23
Five permissions, and surfaces that are data
Each decoration carries one of five permissions. The header names them as “collision and placement permissions, in that order”.13 By count:
| Permission | What it means | Decorations |
|---|---|---|
| Solid floor | blocks the walk, stands on floor | 18: all 9 desks, 9 ornaments |
| Pass floor | walked over, stands on floor | 37: all 18 mats, all 9 chairs, 10 ornaments |
| Behind floor | blocks, and its top row may sit on the back wall | 10: all 6 plants, 4 ornaments |
| Wall | hangs on the back wall | 10: all 10 posters |
| Sprite | a figure that stands on a surface | 45: all 35 dolls, all 10 cushions |
Counts from measure_emerald_decor.py on src/data/decoration/header.h.2
The cleverest part is that a surface is a property of a cell, not of a piece of code. Each decoration is drawn from metatiles, and each metatile carries a behavior byte. Eighteen decorations carry cells with the behavior MB_HOLDS_SMALL_DECORATION: 7 of the 9 desks, 3 bricks, a tire and 7 mats. Fourteen carry MB_HOLDS_LARGE_DECORATION: the same 7 desks and 7 mats.2 A doll that is 1 by 2 needs a “large” cell under it; any other doll or cushion takes a “small” cell or a “large” one.4 So once a desk is placed, the floor has new cells that answer “yes” for a doll, and the same placement function handles both. This is how 16 items make a room look full: 45 of the 120, the sprites, stand on 18 surface pieces.2
Some decorations also act. Eight note mats play a sound when stepped on; a jump mat, a spin mat and a glitter mat do what they say; three balloons and a mud ball pop; there is a breakable door, a slide and a sand ornament. Each is a behavior on the decoration’s metatiles (MB_SECRET_BASE_SOUND_MAT, _JUMP_MAT, _SPIN_MAT, _GLITTER_MAT, _BALLOON, _BREAKABLE_DOOR, MB_SLIDE_SOUTH, _SAND_ORNAMENT), read from the secret base tileset’s attribute file.225
Placement is a question each cell answers
CanPlaceDecoration in src/decoration.c walks the cells the held decoration would cover and asks each one a question. Floor and pass-floor pieces need plain floor (MB_NORMAL) under every cell; only the solid board may cover a hole. No object may stand on the cell. The piece may cover the cell the player stood on when they opened the menu only with a tile of the normal layer type; the function refuses it there when its own tile on that cell has any other layer type. A behind-floor piece needs floor under all but its top row, which may sit on the north wall. A wall piece needs every cell to be north wall. A sprite needs a holding cell under it.4 In the bedroom, the menu refuses every category except dolls and cushions: DecorationItemsMenuAction_AttemptPlace shows gText_CantPlaceInRoom when isPlayerRoom is set.4
Nothing in CanPlaceDecoration checks that a path survives. The only protection the function gives the walk is that conditional rule about the cell you stood on. On my reading of that function, a player can wall off the base’s computer with desks and the game will let them.4 I come back to this in the brief, because a room other people visit needs the check this function does not make.
The rooms the cap is measured against
The 24 base layouts are six styles in four sizes each. Measured with walls from each map.bin, they are 7 to 17 cells wide and 7 to 17 cells deep, from 99 cells (11 by 9) to 196 (14 by 14), with the long thin ones at 7 by 16, 10 by 17 and 17 by 8.226 Walkable cells, read from each layout’s collision bits, run from 44 to 81, 60.2 on average.2 The cap of 16 is 0.27 of an average base’s walkable floor.2 The bedroom, the second floor of both player houses, is 9 by 8 with 54 walkable cells, and its cap is 12.21
Floor alone overstates the crowding, because many of the 16 are mats you walk over or dolls standing on desks. The cap budgets the composition, not the floor.
The cell against the character
The player’s walking sheet is 144 by 32 pixels, nine frames of 16 by 32, so the character’s frame is one cell wide and two cells tall on the 16-pixel metatile grid. The decorating pose is a single 16-by-32 frame.27 The grid cell is the frame’s width, and every decoration is sized in that unit.
How the catalog grows
The source-of-supply script searched the shop, prize and gift scripts for every decoration constant. 90 of the 120 are sold for money at five shops. Three are prize-counter exchanges, fifteen are exchanged for battle points, and ten are given by a script: the three prize-counter items again, two tents for finishing a puzzle house, an ornament from a museum’s upper floor, two shields from the host of the battle facility, and two dolls from residents. Twenty-four are earned and never sold for money.14
Two more are bought by walking. A glass workshop trades a chair for 6,000 and a desk for 8,000 ash, and ash is gathered one unit per step through ash-covered grass while the player carries the sack, up to 9,999 (VAR_ASH_GATHER_COUNT).15 I read that pair as the purest version of unlock by play in the canon: no money changes hands, only steps. The sack shows no count. Its field use is the function for items that cannot be used, and its description is fixed text about gathering and holding volcanic ash.28 Outside the step counter itself, only the workshop’s script reads the count: when the player is short, it subtracts the ash gathered from the price and tells the player the difference as a number of steps still to walk.15
Four decorations, three legendary dolls and one other doll, are referenced by no shop, prize or gift script the search covered. They may arrive by trade or by a link feature; I did not trace them, and the 90 sold and 24 earned-only counts stand on a script search of shop, prize and gift scripts with those four left untraced.14
What Emerald teaches
A decoration system is three tables and one function: a catalog row per piece (permission, shape, category, price, metatiles), a layout whose cells say what they are (floor, north wall, hole), an owned inventory larger than the placed cap, and a placement check that asks each covered cell one question. Surfaces are cells that answer “yes” to a smaller piece. The cap counts placed pieces and nothing else. The gap is the walk: the placement function checks cells, never paths.
2. Animal Crossing: 150 items and a letter on Sunday
This section rests on Nookipedia, a fan wiki, read and saved on October 5, 2026; I did not look for Nintendo’s own figures. Where the wiki cites nothing, I say so.56
The cap and the rooms
Every game in the series caps the items in a room, and the cap has grown. Nookipedia gives 24 “furniture and clothing items” per room in Wild World, 64 in City Folk and 48 in New Leaf. For New Horizons: “A maximum of 150 items can be placed in each room of the house, including wall and ceiling-mounted furniture.”5
New Horizons rooms, by the same page’s upgrade table: the tent is 4 by 4; the house is 6 by 6; the main room expansion makes it 8 by 8; the back, left and right rooms are 6 by 6 each; the second floor and the basement are 10 by 6. “Unlike previous games, only the main room can be expanded in size, as all other rooms have a fixed size.”5 At 150 items in a 6-by-6 room, that is 4.2 items per floor tile, which works only because walls, ceilings and the tops of other furniture take items without using floor (my arithmetic from the two figures).529
Furniture takes “a size in tiles that it takes up when placed, ranging from 1.0×0.5” to 3 by 3, and in New Horizons it “can also now be pushed in half-tile increments”.29 New Horizons sorts it into housewares, miscellaneous items that go on the floor or on a surface, wall-mounted pieces, and ceiling decor, which arrived in version 2.0.29 Of the games whose placement grid this post reads (Emerald’s cells, Stardew’s tiles and New Horizons’), only New Horizons moves furniture by less than a whole tile. I did not read FFXIV’s placement grid, and the finer steps quoted for Habbo are stack heights from a third-party client (section 3).
The catalog
As of version 3.0.2, Nookipedia counts 2,076 furniture items in New Horizons, 1,074 of them added in updates. A series is “around 10 furniture items, as well as a matching wallpaper and flooring”.29 The wiki counts 262 wallpapers as of version 1.9.0 and 215 floorings.3031 Wallpaper and floor change per room, and version 2.0 added an accent wall: “a second wall covering can be applied to single wall in the room”.5
The Happy Home Academy
The scoring half is the part Kiradex borrows. Nookipedia: the Academy “sends an evaluation by mail most Sunday mornings, which cannot be disabled”. The rank is B, A or S, and the S threshold rises with each expansion: 15,000 for the first house, 23,000 after the main room upgrade, then 35,000, 47,000, 60,000, 75,000, and 90,000 with the basement.6
The New Horizons bonuses as the wiki tabulates them:
| Criterion | Points |
|---|---|
| 6, 10, 15 and 20 furniture items in a room | 1,000 at each threshold |
| Lucky items | 777 per item |
| Wall-mounted furniture | 400 per item, three at most |
| 4 or more items from one series | 1,000 per item |
| A complete furniture set | 800 per item |
| 3 or more items from one category | 500 per item |
| 70% or more of a room’s items one color | 200 per item |
| 90% or more one color | 600 per item |
| Red, green or yellow feng shui | 500 |
| Cockroaches | minus 2,500 each |
| Non-furniture items on the floor | minus 1 each |
| Trash on the floor | minus 500 each |
| Directional items facing a wall | minus 300 each |
Nookipedia, “Happy Home Academy,” the New Horizons tables, saved October 5, 2026; uncited on the page.6
Those numbers are the least certain in this section. The bonus and deduction tables carry no citation. The rewards table under them says it “Includes data sourced from the Data Spreadsheet for Animal Crossing New Horizons”, compiled by named contributors, and the per-item points section for New Horizons reads “This section is a stub”.6 So the arithmetic is a fan reconstruction. The brief at the end borrows its shape (listed sources, count thresholds, set and color bonuses, a fixed day) and none of its numbers.
Two choices in it matter for any app that wants a weekly room score. The bar rises with the house, so a bigger room is not an easier top rank. And the letter comes on a fixed day, most Sunday mornings, and the player cannot turn it off.6 Absence is not free there: the house page says that a player who neglects their house “for at least one week” finds it infested with cockroaches, and the table above takes 2,500 points for each.56 The brief keeps the fixed day and drops the penalty.
Visiting
In every game in the series, by the wiki’s account, “a player may enter any other player’s house freely”. They can use the furniture, but cannot drop or pick up items “or modify the interior in any way”.5 A dream visit to another island reaches the same end another way. On the wiki’s page for the character who runs dreams, the New Leaf section says that in a dream “any changes will not be saved and items cannot be brought back to the real world”, and the New Horizons section says her services “work the same as they do in New Leaf”. Uploading a dream earns the host a Dream Bell Exchange Ticket worth 5,000 Bells, and another for each update.32 On my reading, that is the safest kind of visit in this post for a children’s app: the visitor walks through a copy and can change nothing that is kept, and the host is rewarded for sharing.
3. Habbo, Stardew, Final Fantasy XIV, Club Penguin, and where the model came from
Habbo: the room is the product, and the product is sold
Habbo’s own help center states the ownership and visitor rules plainly. “You can own 200 rooms.”33 Floors and walls are permanent once applied: “Wallpaper and flooring are stuck down - so once you put them down, they can’t be picked back up. You can put new wallpaper or floor down if you wish to change the look of your room.”33 Visitors cannot touch: “You can’t drop or manipulate furni in other Habbo’s rooms unless you’re a member of a group, and the owner of that group has enabled you to participate in the building of that room.”18
The furniture economy is purchase-led. “To buy furni you need credits, diamonds or duckets.”18 Builders Club lends furniture up to a limit that rises by 250 for each month of membership, includes saving custom room layouts in the floor plan editor, and promises “Furni limits never go down.”34 The furniture definitions page describes campaign furniture held back “for 4-12 months in order to leave an ample window for traders to build their businesses around them”, rares that “will never be re-released”, crackable rares bought and then cracked “to reveal another, random rare furni”, and LTDs, “a special type of rare, which comes in limited quantities”.17 Trading needs a trading pass, and “There is no guide to what items of furni are worth”.35 Habbo even limits chance inside rooms: “Placing more than three chance elements will disable all randomiser functions in the room.”36
Habbo’s own pages do not give the grid, the stacking heights or a per-room furniture limit; the help center’s search for “furni”, “stack” and “floor plan” returned no article that does.37 The numbers people quote come from Nitro, an open-source third-party client. Its floor plan editor constants allow up to 64 tiles per axis and a 27-step height scheme, as the structures post in this series cited from the same file; my earlier notes add, from that client, a stack-height tool from 0 to 40 in steps of 0.01, which I did not re-read for this post.3839 Treat all three as the client’s, not Sulake’s.
On my reading, Habbo shows what the furnishing loop becomes when the catalog is the business. Its visitor rule is the one to copy; its economy (scarcity on purpose, random contents, trade value) is the one to refuse.
Stardew Valley: a catalog bought once, then free furniture
The Stardew Valley Wiki’s Furniture page, revision 193159, lists 718 item rows across 26 sections, 615 distinct names. Those are my counts of the page’s rows; the Movie Posters section uses other markup and was skipped, and “distinct” folds an item listed in two sections into one.4016 The Wallpaper page, revision 193801, shows 137 wallpapers (123 in the catalog, 12 outside it, 2 unobtainable), and the Flooring page, revision 190285, 97 floorings, both counted from the pages’ icons, not from the game’s data files.404142
The catalog grows two ways at once. Robin and the Traveling Cart each “offer a random selection of furniture each day they are open”. “After the first Farmhouse upgrade, Robin also offers the Furniture Catalogue for sale”, at 200,000g in the page’s Catalogues table, and once placed it sells the furniture it lists for 0g “in unlimited quantity”. 278 rows of the Furniture page name the Furniture Catalogue as a source.1640 The page’s exceptions stay exceptions: “Some furniture can be obtained only by donating items to the Museum”, or at festivals, the casino and other sources.16 So a milestone of play and one large purchase in the game’s own currency end scarcity for what the catalog lists, and only for that.
Placement feedback is per tile: “Furniture will display a green square on tiles where it can be placed. The tile will turn red if the furniture cannot be placed.”16 Wallpaper is one gesture for one surface: wallpapers “cover the whole room they’re placed in”, and to place one “the character must be facing up by its wall”; they are “single-use and do not stack”.41 The farmhouse is 10 by 7 inside before upgrades, on 16-pixel tiles, as the structures post cited from the wiki.39
Final Fantasy XIV: a cap that is also a frame budget
Square Enix’s Lodestone notes for Patch 7.5 raised every housing limit. Indoor furnishings went from 100 to 150 for apartments and private chambers, 200 to 300 for cottages, 300 to 450 for houses and 400 to 600 for mansions; outdoor ones from 20 to 40, 30 to 60 and 40 to 80.7 The same notes give the reason in their own words: “Please note that up to 400 furnishings can be displayed on-screen at once. If more than 400 furnishings are on-screen simultaneously, those on a different floor to your character will stop being displayed, with small, more distant furnishings being hidden first.”7 A cap is a design budget and a rendering budget at the same time.
The notes also add “Furnishings from the FFXIV Furnishing Design Contest”: a community contest whose winning designs became furniture in the patch.7 That is the safe shape for a contest: players make things, the studio judges and ships them.
Plot sizes are not in this post. Square Enix’s housing guide returned HTTP 404 on October 5, 2026, and I tried no other official page, so FFXIV contributes item limits from the Lodestone notes and nothing else.7
Club Penguin: a like a day and a total that never goes down
Every Club Penguin fact here is single-source. The archived official blog posts the Club Penguin Wiki cites returned HTTP 429 from the Wayback Machine twice on October 5, 2026, so I could not check them.43
That Penguin Game reproduces what it presents as the game’s help pages; I did not verify that provenance. Its “Your Igloo” page: “You can Like any igloo design once every day!” Each design “earns its own individual Likes”, which add up to the Grand Total, and “Likes are permanent, so your Grand Total Likes will never decrease, even if you delete an igloo design!” The Popular tab ranks igloos by Grand Total Likes, and an igloo opens to “Everyone” or only to “Friends”.19
The Club Penguin Wiki says that “igloos have a limit preventing more than 99 units of furniture being placed at once”, that most furniture has an ownership limit of 99 of each type, and that an owner can decorate their own igloo “but not other player’s igloos”.8 Decoration was a membership benefit: from November 1, 2005, players without membership could have igloos but not furnish them, and from July 26, 2012, they were given 6 free furniture items, one floor item, four regular items and one wall item.438
The Wiki’s history of the igloo contests: the first was announced in issue 9 of the in-game newspaper, published December 15, 2005, with one winner awarded 5,000 coins. Later contests announced their winners and runners-up one to four weeks after the call, always with coins and sometimes furniture. From the 2008 Halloween contest, characters judged the winners and their comments ran with the igloos; from 2009, a button on the igloo submitted it; the last contest ran in December 2012. One example, 2008’s Ye Olde Igloo Contest, paid ten winners 25,000 coins each and twenty runners-up 15,000.44
The Sims: the people were there to score the house
The grid-and-catalog model has an origin story, and it is a scoring story. My source for it is one interview: Will Wright with Tristan Donovan, published by Game Developer on May 23, 2011. I found no recorded talk by Wright from 1999 or 2000 on the build mode.45
On the inspiration: “one of the original things that was a really inspiration for The Sims was this book, A Pattern Language, by Christopher Alexander.” On scoring: “In some sense I wanted The Sims originally to be an architecture game where it was analyzing these patterns. So the people in The Sims originally were just there to score the architecture.” On the name: “my original name for it was Doll House. We did some test marketing and found out that the name didn’t go very well with males.” On objects: “Everything we put in the world is advertising”, a model he traces to the pheromone trails of SimAnt.45
The Sims Wiki, a fan wiki and a single source, describes the shipped screen. Buy mode lets players “purchase items from an object catalog and place them on the current lot”; The Sims and The Sims 2 sorted that catalog by object function; and the held object’s footprint tiles show green where it may go and red where it may not. The wiki tags that green-and-red sentence to The Sims 2 and The Sims 3, so I do not claim it for the 2000 original.46 The score stayed inside the Sims as a motive, Room in the first game and Environment in the second, which “analyzes the design and content of the room that the Sim is currently standing in”: small rooms, too little light, and dirty or broken things lower it.47
On my reading, every game in this post is that one screen with a different budget: a catalog, a grid the size of a person’s step, a footprint that turns green or red, and a judge.
The caps, side by side
The limits span fifty to one, from Emerald’s bedroom to an FFXIV mansion, but they do not count the same thing: FFXIV’s is an indoor placement limit listed per housing type, Animal Crossing’s is per room, Club Penguin’s per igloo, Emerald’s per base or bedroom, and Kiradex’s per floor. Only the FFXIV and Emerald numbers come from the publisher’s own text or code.247581
4. The craft, as rules with numbers
These are the rules the measurements support, each with the range it rests on. Where a number is my arithmetic or my choice, the row says so. “Cell” means the 16-pixel walking cell, which is also Kiradex’s tile.227
| Element | Rule | Source |
|---|---|---|
| Placed cap | Cap what a room shows, per room, counting wall items. | Emerald 16 per base, 12 in the bedroom; New Horizons 150 per room “including wall and ceiling-mounted furniture”; FFXIV 150 to 600 indoors by home size; Club Penguin 99 (one fan source) |
| Owned cap | Let the player own more than fits, so placing is choosing. | Emerald 150 owned in eight bins against 16 placed; Club Penguin 99 of each type owned (fan source) |
| Cap against floor | In a 2D room with no wall or ceiling layer, stay under one item per three floor cells (my threshold, chosen so that Emerald sits just under it); surfaces and walk-over pieces stretch it. | Emerald 16 against a mean of 60.2 walkable cells, 0.27; New Horizons 150 in a 6-by-6 room is 4.2 per tile, possible only with wall, ceiling and surface placement (my arithmetic) |
| Surfaces | Make holding a small piece a property of a cell, so a desk adds floor for a doll. | Emerald: 18 decorations hold small pieces, 14 hold large, and 45 sprite decorations need one |
| Grid cell | Size the grid to the character’s frame or cell width; go finer only if pieces can be nudged and the art allows it. | Emerald’s player frame 1 by 2 cells of 16 pixels; Stardew 16-pixel tiles; New Horizons half tiles |
| Placement check | Ask each covered cell one question (floor, wall, surface; empty; not on the arrival or host cell) and show the answer per cell. | Emerald CanPlaceDecoration for the per-cell questions, though it refuses the player’s starting cell only for a tile with a non-normal layer type; the arrival and host cells are Kiradex’s rule (7.1); Stardew green or red square per tile; The Sims 2 and 3 green or red footprint (fan wiki) |
| Path | Check that a walk survives every placement (the brief’s addition). | Emerald’s CanPlaceDecoration checks no path, and keeps the cell the player stood on free only of a tile with a non-normal layer type; the Stardew and Sims pages read here describe per-tile feedback and say nothing either way about paths; the brief adds the walk |
| Wallpaper and floor | One per room, changed in one gesture, reversible. | Stardew covers “the whole room” from the wall; New Horizons per room plus one accent wall; Habbo’s are permanent, replace only |
| Catalog size | Big enough that a style is a choice. | Stardew 137 wallpapers and 97 floorings (my counts of wiki icons); New Horizons 262 and 215; New Horizons 2,076 furniture as of 3.0.2 |
| Score | List the sources, fix the day, raise the bar with the house, never punish absence. | Happy Home Academy: most Sundays; B, A, S; S from 15,000 to 90,000; 1,000 at 6, 10, 15 and 20 items; series, set, category, color (fan tables, uncited); the wiki’s house page, which does not name a game, says a house neglected for at least one week fills with cockroaches, and New Horizons’ HHA table deducts 2,500 per cockroach, a penalty this rule refuses |
| Catalog growth | For a 9+ app, grow by play: an earned shelf plus a catalog that opens at a milestone. Never by random or scarce sale. | Emerald 90 of 120 sold, 24 never sold, two more for 6,000 and 8,000 ash; Stardew random daily stock, then after the first upgrade a 200,000g catalog whose listed furniture costs 0g, with Museum, festival and other exclusives outside it; Habbo’s rares, crackables and LTDs as the counterexample |
| Visiting | Visitors look and do not touch; one mark per visitor per day; the host’s total never falls. | Animal Crossing visitors cannot “modify the interior in any way”; Habbo visitors cannot drop or move furniture without rights; Club Penguin one like per design per day, Grand Total never decreases (one fan source) |
| Storage | A placed item is a few bytes: kind, cell, facing. | Emerald: one id byte and one position byte, 32 bytes a base |
Sources: sections 1 to 3 and their footnotes.256781916414033181746141511
Three of these deserve a sentence each.
The cap is a budget for the eye, and sometimes for the GPU. Emerald’s 16 is about a quarter of a base’s floor. FFXIV says outright that past 400 furnishings on screen it stops drawing some of them.27 For a phone app the second reason is real, but on my reading the first decides the number: a cap is what turns a shelf into a composition, which is the reason the October 3 world post gave for choosing sixteen.10
The path rule is the brief’s addition. Emerald’s CanPlaceDecoration guards at most one cell, the one you stood on to open the menu, and never asks whether the door still reaches the computer.4 The Stardew and Sims pages I read describe a footprint colored per tile; they do not say whether either game also checks a path, and I did not look further, so this post claims nothing about them either way.1646 A room other people visit needs that question answered, because a visitor who cannot reach the display has nothing to look at.
Unlock by play is the defensible end of the catalog question for a children’s app. That is my reading, not legal advice: a decoration loop that is bought, random or scarce takes on loot-box and pressure questions a collecting app does not need. Emerald’s earned shelf shows a room loop that needs none of that, and Stardew’s catalog, bought once in the game’s own currency after a milestone of play, shows how to end the scarcity for everything it lists.141617
5. The Apple way: a model that syncs, a drag that snaps, a grid VoiceOver can use
A furnishing screen on iOS needs three things: a record for each placed piece that syncs through iCloud, a way to drag a piece onto a cell, and a way to do the same thing without sight or touch. Everything below comes from Apple’s documentation pages saved as JSON on October 5, 2026, with titles, declarations, abstracts and platforms extracted by a script.48 Nothing here was built or run for this post, and no cost below is measured.
The record: SwiftData, shaped for CloudKit
@Model “Converts a Swift class into a stored model that’s managed by SwiftData”, available from iOS 17.0.49 SwiftData can enforce uniqueness with #Unique, which “Specifies the key-paths that SwiftData uses to enforce the uniqueness of model instances”, from iOS 18.0.50 A placed piece looks like a natural use: one piece per cell.
CloudKit sync rules it out. Apple’s guide to syncing SwiftData says the framework “does include a small number of features that CloudKit doesn’t support natively, such as unique constraints and nonoptional relationships”, and that “CloudKit requires all relationships to be optional.”22 Kiradex’s models are already shaped that way. CardCopy’s comment says “every property has a default and nothing is unique, for CloudKit”, and PriceHistory is “Shaped for CloudKit like CollectionEntry: defaults everywhere, nothing unique”, with a fold that picks the same winner on every device when two devices create the same history.5152
So the uniqueness that matters, one piece per cell, has to be enforced in code: a pure function that runs on every read, resolves two devices’ pieces on one cell to the same winner everywhere, and returns the loser to the tray. One cell is not the only thing two devices can break together. Two edits that each pass every rule on their own phone can fail together, so the function has to rebuild the room through the whole placement check, not only the overlap test. The brief in section 7 specifies it.
The drag: draggable, a drop destination, and the cell under the finger
draggable(_:) “Activates this view as the source of a drag and drop operation” for a Transferable payload, from iOS 16.0.53 dropDestination(for:action:isTargeted:) receives the dropped items and a CGPoint, which its page describes as “the drop location in this view’s coordinate space”, also from iOS 16.0.54 Mapping that point to a cell is arithmetic: subtract the map’s origin and divide by the tile’s size in points.
One finding my earlier notes did not have. The saved page for dropDestination(for:action:isTargeted:) lists iOS 27.2 as the release that deprecates it, with the message “Use dropDestination(for:isEnabled:action:) with an action that takes a DropSession parameter instead.”54 The replacement’s action receives a DropSession, “A description of a drop that is in progress”, instead of a point.54 I did not save the DropSession page, so whether it carries a location in the view’s coordinate space is unread, and the brief names both forms.
For moving a piece already in the room, DragGesture is “A dragging motion that invokes an action as the drag-event sequence changes” (iOS 13.0), and SpatialTapGesture is “A gesture that recognizes one or more taps and reports their location” (iOS 16.0): tap to select a piece, drag to move it cell by cell.5556
Whether the drop point maps cleanly to tile cells under Kiradex’s camera is untested. The room is drawn by RealityKit at a whole number of device pixels per texel, and the SwiftUI overlay that receives the drop sits on top of it; the arithmetic is the same one the camera’s fit already does, but nobody has dropped anything on it yet.10
The grid without touch: VoiceOver
A grid of furniture is a poor fit for swiping element by element, so the design gives VoiceOver its own verbs:
accessibilityElement(children:)“Creates a new accessibility element, or modifies theAccessibilityChildBehaviorof the existing accessibility element” (iOS 13.0), so a multi-cell piece is one element, not six.57accessibilityAction(named:_:)adds a named action; “Actions allow assistive technologies, such as the VoiceOver, to interact with the view by invoking the action” (iOS 16.0). Move left, Move right, Move up, Move down, Turn and Put away are each one action.58accessibilityAdjustableAction(_:)handles swipe up and down as anAccessibilityAdjustmentDirection(iOS 13.0), a fit for cycling a wallpaper or a floor.59accessibilityRotor(_:entries:)creates “an Accessibility Rotor with the specified user-visible label” (iOS 16.0), so a “Furniture” rotor can jump between the room’s pieces.60AccessibilityNotification.Announcementis “A notification that an app posts when it needs to convey an announcement to an assistive app” (iOS 17.0): every refused move is spoken, with its reason.61
A UI test can then audit the screen with XCUIApplication.performAccessibilityAudit(for:_:), listed for iOS 17.0; the saved page carries no abstract and lists Xcode 16.3 for this module path.62 An audit is all it does. In the XCUIAutomation headers installed with Xcode 27.0, the audit “Runs an accessibility audit on the current view”. The same headers add XCUIVoiceOverService, from iOS 27.0, which “Provides programmatic control of VoiceOver for UI testing”: it turns VoiceOver on and off, moves focus forward, backward, into and out of containers, and returns what VoiceOver speaks for the focused element. A search of every header in the framework finds no call that performs a named custom action, turns a rotor, or reads an announcement, so a UI test cannot press Move left or Put away the way a VoiceOver user does.63 The brief tests those actions’ handlers directly, checks the spoken labels with the VoiceOver service, and leaves the actions, the rotor and the announcements to a person with VoiceOver on.
What it costs
Unmeasured. A furnished house is at most 16 small records on each of two floors. If placed pieces join the one objects mesh the engine already builds for the forge’s furniture, a change means rebuilding that mesh; none of it has been profiled on a phone.39
6. The case study: Kiradex’s interiors today
Kiradex is a card-collecting app for iPhone with a small pixel town, Kiradex World, where each collector has a two-floor house and the town has a show hall. Everything in this section was read from the app’s repository on October 5, 2026, never run or changed: the interiors were parsed with a script, and the docs and models were read as text.964
What changed since the structures post
The October 3 structures post said that interiors.py draws the room, the floor above and the hall “each 14 by 11, with a two-row wall band”.39 That was true when it was written. The same day, TestFlight build 26 brought the interior kit: “Rooms sixteen wide with a three-row wall band (cornice, face, wainscot)”, furniture in a 32-pixel rhythm, wall-backed pieces drawn as ground and free-standing ones as objects the collector walks behind.65 Today the forge draws room and room-up at 16 by 12 cells and the hall at 16 by 13, each with a three-row band: cornice, face and wainscot.964 Build 26 falls between the build 23 the structures post describes and the build 35 its evening addendum describes, so both texts are right about their builds.3965
The forge’s furniture
scripts/forge/interiors.py names 23 pieces in its PIECES table, each with a width and a height in cells and a flag for whether it stands free.9
| Kind | Pieces and footprints (cells, w by h) |
|---|---|
| Wall-backed, drawn into the ground (9) | bookshelf 5 by 2; wardrobe 2 by 2; counter, sink and stove 1 by 1 each; fireplace 2 by 2; stairs and stairs down 2 by 3 each; pillar 1 by 3 |
| Free-standing, exported as objects the collector sorts against (14) | bed and rose bed 2 by 3 each; nightstand 1 by 1; table 2 by 2; chair in four facings, 1 by 1 each; sofa 3 by 2; bench 2 by 1; plant 1 by 2; chest, crate and barrel 1 by 1 each |
Parsed from PIECES by measure_kiradex_interiors.py; the file is never imported or run.9
A piece covers 1 to 10 cells, 3.04 on average, against Emerald’s 1 to 9 and 2.43.92 The distinct drawings are fewer than the names: the four chairs are one drawing in four facings, the two beds are two variants, the two stairs two directions, and the counter, the sink and the stove are one counter in three kinds.9
The file’s docstring and its table disagree. The docstring sets the convention as “furniture on the 16-pixel grid in a 32-pixel rhythm, every piece at least two tiles on one axis”.64 In the table, 11 of the 23 are 1 by 1: the four chairs, the counter, the sink, the stove, the nightstand, the chest, the crate and the barrel.9 The rhythm holds for the big pieces and not for the small ones. That is a difference between a comment and the code in one file, scripts/forge/interiors.py, and the brief keeps the small pieces, since a room of only two-tile pieces would have no chairs.
The wall face has a vocabulary of its own, as letters: a picture p, a clock k, a window N, a curtained window K, a banner n, a sconce l, and W where the wall board hangs. Floors are boards o, tiles t, marble s, and a rug r that draws itself as a nine-slice from its neighbors. There are two wall styles, the house’s plaster and timber and the hall’s dressed stone, chosen per interior through FACES.64
The rooms as authored
| Map | Size | Floor cells | Pieces (movable) | Floor under pieces | Free floor | Spots the app dresses |
|---|---|---|---|---|---|---|
room |
16 by 12 | 125 | 14 (13) | 25 | 100 | shelf 5 cells, showcase 2, desk 2; arrival, stairs, host |
room-up |
16 by 12 | 125 | 12 (11) | 27 | 98 | wall board 3 cells, desk 2; arrival at the stairs |
hall |
16 by 13 | 144 | 6 (4) | 8 | 128 after 8 pedestals | 8 pedestals |
Movable excludes the stairs and the pillars. From measure_kiradex_interiors.py.9
The host spot is commented in the file as “where the owner stands when you visit”.64 The forge’s check() already refuses a shelf, case, desk or pedestal spot on the wrong letter, a warp that is not on a door or a stair, an arrival, stair or host cell that is not walkable, and two exported objects on one cell. Its narrower edges matter for the brief. It has no letter check for the wall board’s spots, and its overlap loop reads only the exported objects, the free-standing pieces, so a wall-backed piece drawn into the ground is never in it. It does not check that the door reaches every spot.64
The path rule, run on today’s rooms
I wrote a script that rebuilds the exported letters the way export() does and walks four ways from each floor’s arrival over the forge’s walkable letters, otsrUD.20 On today’s layouts the walk reaches the stair and the host downstairs and the stair upstairs. The cells directly in front of the display spots are a different story:
- Downstairs, the shelf’s five front cells: two are under the barrel and the crate, three are reached.
- The case’s two front cells are both reached.
- The desk’s two front cells: one is under the chair pulled up to it, one is reached.
- Upstairs, the desk is the same, one of two.
- Upstairs, the wall board’s three front cells are under the bed and the nightstand. None is reached.20
So a rule that every spot’s own front cell be reachable would fail four of the forge’s dressed groups across the two floors (the shelf and the desk downstairs, the desk and the wall board upstairs), seven blocked front cells in all, and a rule that each dressed group have one reachable front cell fails one group: the wall board upstairs. The brief uses the group form and fixes the board in the starter re-layout.
The script also tried extra pieces in room. One extra free-standing piece has 733 placements that pass the cell rules; 44 of them cut a target off, and every one of those does it by covering the target cell itself. Two extra pieces, each clear of every target and not overlapping, make 229,891 pairs, and 713 of them cut a target off without covering it: a bed at (9,3) and a nightstand at (6,4), for example, close the pocket in front of the glass case.20 Those 713 are what a per-cell check misses and a walk catches. They are also what two phones can build between them: each piece alone leaves every target reached, so each passes the walk on its own device, and the pair fails only once both are synced (7.7).66 I did not run the search past two extra pieces; at sixteen, how many layouts a per-cell check would pass and a walk refuse is unmeasured.
The collector against the grid
The collector’s sprite cell is 32 by 40 pixels with 7 pixels above the figure and 2 below, so the figure is about 31 pixels tall, and the cell is 2 tiles wide and 2.5 tall, against Emerald’s frame of 1 by 2. WORLD.md describes it as “a 30-pixel figure in a 32 × 40 cell”.2767 The figure’s own width was not measured. I read the cell as the reason the forge draws its furniture in a 32-pixel rhythm on a 16-pixel grid: the collector’s cell is two tiles wide.
What the rooms do not do
The structures post’s honest list still holds for the house: “Rooms have no wallpaper or floor choice and no placeable furniture; the house is dressed from the collection and nothing else.”39 The app dresses the named spots from the collection (binders on the shelf, cards in the case, ribbons and pins on the board, cards on the hall’s pedestals), and the forge places every piece of furniture.6439
The server cannot hold a room yet. Its rooms module says: “Everything here is in memory; a room empties when its last collector leaves and nothing of them is kept.”68 So a visit to another collector’s house today is a visit to a map, and read-only visits to a real collector’s arrangement need the server to store a layout.
Where the room rules are written
The October 3 world post published the room rules: “a furnishing cap of sixteen”; “visits are read-only, a like is once a day, and the room’s total never decreases”; and “A report arrives every Sunday grading the room, with its point sources listed”.10 Those rules are not in the app’s design document. docs/WORLD.md section 4 lists the coin shop (“clothes, hats, backpacks, card-display frames and emotes”) and level-locked cosmetics “that cannot be bought”, and says nothing about furniture, caps, likes or a Sunday report.67 The rules live in the research note docs/research/pixel-art/06-collecting-and-hubs.md, section 5.3, which also asks for the letter to be “a pixel object that appears on the doormat”, for “a stamp on their passport per room visited, with ranks at 30 / 100 / 500”, and, in section 5.7, for patron items “never a bigger furnishing cap”.69 This post treats them as decided because the world post published them, and the brief’s first housekeeping item is to copy them into WORLD.md. The same paragraph of the world post also says “Patron flair stays on the name-plate and the room skin”.10 The brief does not treat the room skin as decided: it reopens it as Blake’s decision (7.5).
The week already exists
Weekly quests rotate by the calendar’s week in Quest.current, the hall’s theme is the week’s quest title, and the prototype notes ask testers about a “Weekly reset on your calendar’s week”.7071 A Sunday letter needs no new clock, though it takes its own key, the Sunday’s date, for a reason 7.4 gives.
7. The brief: what Kiradex builds and the checks it must pass
This is a brief, not a report of shipped work: nothing below exists in the app yet. It is written as a diff against what section 6 measured: the forge’s 23 pieces, two 16-by-12 house floors and a 16-by-13 hall, the dressed spots, a server that keeps nothing, a SwiftData store synced through CloudKit, the weekly quest clock, and the room rules the world post already published.96810 Every element keeps a mechanic measured above and draws everything in Kiradex’s own forge, palette and words. No element names a creature, a place from any game, or a franchise feature, and nothing in a room is thrown, caught, summoned or ridden, so nothing resembles the claimed steps of the game-method patents the world post describes; that is my reading, not legal advice.10 Coordinates are the forge’s, x to the right and y down from the top-left cell. The numbers in this section (the starter eight, the score table, the house-tier thresholds, the unlock schedule) are my proposals, not facts.
7.1 Placement by cell, in the forge’s own vocabulary
An Arrange mode in the house. The placeable pieces are 20 of the forge’s 23: everything except stairs, stairs_down and pillar, which stay part of the layout. The four chairs become one kind with a facing, so the 20 pieces are 17 floor kinds. The wall face’s picture, clock, banner and sconce become four placeable wall items, which makes 21 kinds from today’s forge; windows and the stair opening stay architecture. Section 7.5 adds three new pieces (a display table, a folding screen and a pressed-flower wall item), which brings the count to 24.72 A placed piece is (kind, x, y, facing) at its top-left cell on the floor’s letter map, the same shape ROOM_FURNITURE already uses.964
The rules, cell by cell. The first five are Emerald’s question-per-cell restated for Kiradex’s letters; the sixth is the brief’s addition, a check Emerald’s placement function does not make.4
- A free-standing piece needs every covered cell to be floor (
o,t,sorr) with no other piece on it. - A wall-backed piece (bookshelf, wardrobe, counter, sink, stove, fireplace) needs its top row on the wall band, where the forge already puts them: the fireplace at y = 1, across the face and the wainscot, and the rest at y = 2, on the wainscot.64
- A wall item needs a face cell (
A) in row 1 that is not a window or the stair opening. - No piece on the arrival cell, the two door cells (the forge draws the door two cells wide in the bottom wall), the stair’s walkable cells or the host cell.
- The bookshelf carries its five shelf spots with it, since the spots are relative to the piece, so moving the shelf moves the binders. The glass case
cand the deskdstay fixed letters in this brief. - The path rule. After the placement, a four-way walk over walkable cells from the arrival must still reach the stair cell, the host cell, and at least one cell directly in front of each dressed group: the shelf, the case, the desk, the wall board. A piece that breaks the walk is refused, and the refusal names what it would cut off.
Each of the two orange pieces passes the cell rules; together they wall off the case, and only the walk in rule 6 catches it.2420
Why the group form. On today’s layouts, the cell in front of a spot is often a piece: the barrel and crate under two of the shelf’s five front cells, a chair at each desk, and the bed and the nightstand under all three of the board’s.20 The forge already speaks part of this language: check() refuses overlaps between free-standing objects and shelf, case, desk and pedestal spots on the wrong letter.64 The player gets those rules extended to every footprint, wall-backed pieces included, and to the wall board’s cells, plus the walk.
Acceptance.
- A unit test runs the six rules against
room.json: each of the 24 kinds (the 21 from today’s forge and the three 7.5 adds) is accepted at one cell and refused at one cell for each rule that applies to it. - The path rule passes on both shipped starter floors (7.2), and a test pins that the board upstairs has a reached front cell.
- A property test places random legal sequences of up to 16 pieces in
roomandroom-upand asserts after each step that the walk from the arrival reaches the stair, the host and a front cell of every dressed group. - A regression test places the bed at (9,3) and the nightstand at (6,4) in
roomand asserts the second is refused with a message naming the case.20 - A capture of Arrange mode on the iPhone 18 Pro Max simulator shows a held piece’s footprint tinted per cell, one legal and one illegal.
- The forge’s
check()passes on every layout the app can produce: the test exports the placed layout asROOM_FURNITUREand runs the forge’s check over it, read-only. Because that check reads only exported objects and has no wall-board letter check, the same test also asserts, with the brief’s own validator, that no two placed footprints share a cell, wall-backed pieces included, and that the wall board’s three spots stand on the board’sWcells in the authored map.64
7.2 The cap: sixteen per floor, starter rooms at eight
What. 16 placed pieces per floor map, room and room-up each, wall items included, as New Horizons counts wall and ceiling items in its 150.5 What the collection dresses (binders on the shelf, cards in the case, ribbons and pins on the board) never counts: the cap budgets furniture, and the collection is the point. Owning is not capped by it; a collector can own more than fits, as Emerald’s room for 150 owned against 16 placed allows.2
The numbers. 16 against 125 floor cells is 0.13 per cell, half Emerald’s 0.27, which suits pieces that average 3.04 cells against Emerald’s 2.43 and a collector whose cell is two tiles wide (my arithmetic).9227 The forge’s starter room already holds 13 movable pieces and room-up 11, so a new collector arriving at 13 of 16 would have three choices left.9 The proposal: ship each starter floor with 8 movable pieces, chosen in the forge. Downstairs the bookshelf stays, since it carries the shelf spots; upstairs a bed stays, and the re-layout clears at least one cell in front of the wall board, which no cell is today. The pieces removed go into the collector’s tray rather than vanishing, so 8 slots per floor are the collector’s from the first day.20 The starter pieces are created with fixed ids so that two devices launching cold make the same records, not two sets (7.7).
Patron-blind. The research note’s line holds: patron items are “never a bigger furnishing cap”.69
Acceptance. A unit test places 16 pieces and asserts the 17th is refused with a message naming the cap; a test that binders, cards, ribbons and pins on dressed spots leave the count unchanged; a test that every patron tier sees a cap of 16; a test that both starter floors load with 8 movable pieces and pass the path rule.
7.3 Wallpaper and floor
What. Per floor map, one wall style and one floor style, each changed in Arrange mode with one tap, free and reversible: Stardew’s one gesture for one surface and New Horizons’ per-room choice, not Habbo’s permanence.41533 Styles do not count toward the 16.
The vocabulary that exists. Two wall faces (plaster and blocks), three floors (boards o, tiles t, marble s) and the rug.64 The forge draws by rule from named palette ramps, so a style is a drawer and a ramp. The first set is the 2 faces in 3 ramps each and the 3 floors in 2 ramps each: 6 wall styles and 6 floor styles, every one drawn by the forge, nothing painted by hand. More come by play (7.5).
How it ships. The forge exports each style as atlas cells beside the room’s own, and the app swaps the ground indices of the wall cells and the floor cells; the rug keeps its nine-slice.
Acceptance. A capture of room in each wall style and each floor style, 12 in all; a palette check that every pixel of every style is a forge palette index; a test that changing a style leaves the placed pieces and the dressed spots untouched.
7.4 The Sunday letter: a weekly score with every source printed
What. Once a week, on the first open on or after Sunday at midnight local time, a letter appears on the doormat (an object at the arrival cell) grading the house as it stands. One letter per Sunday, keyed by the date of that Sunday in local time. The quest board’s week cannot be the key: Quest.current takes the calendar’s weekOfYear interval, which starts on whatever day the calendar’s week starts, so a week key and the Sunday rule could disagree.70 A missed week costs nothing. The letter prints every source line with its points, then the total and the house tier. The name is Kiradex’s own, the curator’s note for now, never the name of the game it borrows the rhythm from.
Sources. The shape is the Happy Home Academy’s as Nookipedia tabulates it (count thresholds, a set bonus, a color bonus); the numbers are mine, and the collection is in it.6 Caps are per floor map, as the 16 is.
| Source | Points | Cap | What it borrows |
|---|---|---|---|
| Each placed piece | 100 | 16 pieces a floor | the count thresholds |
| A furnished floor: 6, 10 and 16 pieces | 500 at each | 1,500 a floor | 1,000 at 6, 10, 15 and 20 items |
| A suite: 4 or more pieces of one forge set on one floor | 200 a piece | 16 pieces a floor | 4 or more of one series |
| One ramp: 70% of the floor’s pieces and its two surfaces, wall and floor, in one ramp family | 100 per placed piece on the floor | 16 a floor | 70% one color |
| One ramp at 90% (replaces the 70% line) | 300 per placed piece on the floor | 16 a floor | 90% one color |
| The shelf: all 5 binder places filled from the collection | 500 | once | Emerald’s desks that hold dolls |
| The case: each of its 2 places holds a card | 300 each | 600 | |
| The board: each of its 3 cells holds a pin, stamp or ribbon | 100 each | 300 | |
| Deductions | none | the path rule already refuses a blocked room |
Proposed. Every line is computable from the local room and the collection.
The highest score this table can give is 23,600, computed line by line for both floors at 16 pieces with every bonus met; the suite and ramp lines assume a set and a ramp family large enough for all sixteen, so it is an upper bound, not a layout anyone has drawn. A starter floor at 8 pieces, before sets, ramps or spots, scores 1,300.21
At the top of the scale, composition (sets and ramps) is worth more than count, which is the point of a cap.2421
The letter grades the house in three house tiers, and each threshold is the score the table itself gives a reference house: 4,500 for both floors at 10 pieces with the shelf full; 7,600 for both floors at 16 pieces with the shelf, the case and the board full; and 14,000 for that house with a suite of 8 and 70% one ramp on each floor. A starter house, both floors at 8, scores 2,600, below the first tier.21 The three numbers are my proposal; Blake sets the final ones before the letter ships. Unlike the Academy’s, they do not rise, because the house’s shape never changes (see Not in this brief, below).6 A house tier is not a ribbon. The ribbons the app already keeps come from the town’s collectors and are stored as plaza.ribbons; those are the ribbons the board shows (section 6).73 The house tier is printed on the letter and kept as a number (7.5), and it never goes on the board.
What the score never reads. Patron tier, coins, purchases, likes, anything about another player, or a patron room skin. Every line is computable from the local room and the collection, so a collector can see exactly why they got what they got. If the patron room skin ships, it is drawn over the floor’s ordinary wall style and is not a wall style itself: the floor keeps that ordinary style for scoring, so the ramp lines count the same pieces and surfaces with the skin on or off (7.5).
Forge change. PIECES gains a set tag, drawn as matching material; the first sets are the existing pieces grouped by the material they are drawn in.
Acceptance. A pure function Score.week(room:collection:) with a unit test for every line: a floor at 5, 6, 10 and 16 pieces; a suite of 3 and of 4; 69%, 70%, 89% and 90% one ramp; a shelf with 4 and with 5 binders. A test that the maximum is 23,600. A test that the three reference houses score 4,500, 7,600 and 14,000 and earn the first, second and third house tier, and that the starter house, at 2,600, earns none. A test that reaching a house tier adds nothing to plaza.ribbons and nothing to the board. A test that a Sunday’s letter is generated once (the same Sunday’s date twice gives one letter, the next Sunday another), and that a calendar whose week starts on Monday produces the same keys. A test that two profiles differing only in patron tier get identical scores. A UI capture of the letter on the doormat on a Sunday, with a launch argument that sets the date.
7.5 Unlock by play, never by purchase
What. The catalog a collector owns is derived from play. Three of its six inputs exist today: levels and pins, derived from the synced collection, and quest stamps, recorded on the device only. The other three need new counters, each named and synced:
- Levels. WORLD.md’s curve is
level = floor(sqrt(XP / 40)) + 1.67 One kind or style at every level from 2 to 20, then every second level, the way WORLD.md already gates cosmetics “that cannot be bought”.67 Available today, derived from the synced collection: the app works experience and level out from it, “so every device agrees without anything being stored”.74 - Pins. Each pin unlocks one named piece: Full Set a display table, Vintage a clock, Across the Sea a folding screen. The first and last are new forge pieces.67 Available today, derived from the synced collection by the same calculation.74
- Weekly quests. Each completed weekly quest adds one copy of a basic piece: a chair, a plant, a crate.70 Recorded today, but on the device only: the stamps live in
@AppStorage("quests.stamps"), which is UserDefaults, not the synced store, so they move intoPlayRecord(below) before any piece depends on them.7375 - Steps. One long walk, a piece that costs a large step count, as Emerald’s glass chair costs 6,000 ash gathered a step at a time. Emerald’s sack shows no count, and its workshop states the shortfall only when the player comes back to it; the proposal here is a counter that stays visible on the piece’s tray card, steps walked against steps needed.2815 A pressed flower from the plant on the sill is a separate proposal, a wall item whose unlock is set in the homage post’s brief, the plant growing a stage every 256 steps, standing in flower for 1,024 steps and then dropping one flower, not by this bullet’s counter. New: the app keeps no step count today, so this needs
stepsWalked.73 - Visits. The passport ranks at 30, 100 and 500 rooms visited each unlock a style.69 New: nothing records a visit today, on the device or on the server, so this needs
roomsVisited, the hosts’ ids.7368 - The letter. The first time a collector reaches each house tier, it unlocks a piece. New: the house tiers exist only in this brief (7.4), so this needs
letterTier, the highest house tier reached.
Model diff. The quest stamps and the three new counters live in one synced model, PlayRecord, one record per device, shaped like the app’s others for CloudKit (7.7). The catalog reads every device’s record: steps are summed, stamps and visited hosts are united, and the highest house tier wins. The device keeps its own record’s uid under an @AppStorage key, in the same UserDefaults namespace as plaza.id, the device’s id in the plaza.7375 Each device writes only its own record, so two devices never edit the same one, and nothing needs a merge rule. That holds only while the pointer stays on one device, and a backup restored to a second phone would bring the pointer with it (my reading; no restore was tested). So the record carries a device marker, writer, and the rule is: a restored device makes a new record when its pointer’s record was written by another device. The old record stays, and the catalog still reads it. Which value makes a marker that a backup does not carry to a new phone is not settled in this brief; the test pins the rule. On first launch after the change, the device copies its quests.stamps list into its record once.
What is refused. No furniture or style as an in-app purchase, no coin price on furniture, no random furniture of any kind, no limited-quantity pieces, and no trading of furniture: Habbo’s crackables, rares and trade values are the counterexample.1735 My reading: a 9+ app whose decoration loop is bought or random takes on loot-box and pressure questions the collecting app does not need, and unlock by play avoids them. The one paid exception the research note allows is “one room skin” for patrons, and the world post named it: “Patron flair stays on the name-plate and the room skin”.6910 The same sentence sets the limit: patron flair “never touches a pedestal slot or a judging bonus”.10 This brief reopens the skin as Blake’s decision rather than treating it as settled. If he keeps it, the skin is a visual overlay, not a wall style. The floor keeps the ordinary wall style the collector chose, the skin is drawn over it, and the score reads only the ordinary style, so the ramp lines of 7.4 count the same pieces and surfaces, against the same denominator, with the skin on or off. Dropping the wall from the ramp count instead would not be neutral, because the share counts surfaces as well as pieces. A floor of 16 pieces, 15 of them and the floor style in one ramp and the wall outside it, is 16 of 18, 88.9%, on the 70% line for 1,600 points, 100 for each of the 16 placed pieces, the off-ramp one included; drop the wall and it is 16 of 17, 94.1%, on the 90% line for 4,800, 300 for each of the 16, a judging bonus of 3,200 for the paid skin.76 The test below carves the skin out by name.
Acceptance. A unit test that the owned catalog is a pure function of XP, pins, quest stamps, steps walked, rooms visited and the house tier, and changes with nothing else; a test that two devices’ PlayRecords give the same catalog read in either order (steps summed, stamps and hosts united, the highest house tier); a test that a device’s existing quests.stamps list is copied into its record once and never twice; a test that a device whose pointer names a record with another device’s writer makes a new record, leaves the old one unchanged, and still counts both; a test that no StoreKit product identifier and no coin-shop item maps to a furniture kind or a style, with one named exception: if Blake keeps the patron room skin, its product maps to exactly one overlay and to no wall style, and applying it leaves the floor’s scoring wall style unchanged; a test that a floor scores the same, line by line, and earns the same house tier with the skin on and off, run at every threshold boundary: 5, 6, 10 and 16 pieces, 69%, 70%, 89% and 90% one ramp, each with the ordinary wall in the ramp family and outside it, and houses one point under and at each house-tier threshold; a snapshot test of the catalog tray at level 1 (the starter set only) and at level 20.
7.6 Visits: read-only, a like a day, a total that never falls
What. A visitor walks into a host’s house through its door, using the room warps the town already has for its own collectors’ houses,39 and sees the host’s placed pieces, styles and dressed spots. The visitor can walk and say preset lines, and cannot move, take or add anything: Habbo’s rule, and the end New Horizons’ dream reaches by keeping nothing a visitor changes.1832 A like on the door counts once per visitor per host per local day, and the host’s total never decreases, even when they rearrange: Club Penguin’s rule, from its one fan source.19 Visiting earns the visitor a passport stamp, which the visitor’s device adds to roomsVisited in its PlayRecord (7.5).69
Server diff. Today’s server keeps nothing.68 Visits need two small records per player. The first is the house layout: at most 32 placed pieces across two floors, each a kind, x, y and facing, plus two style ids per floor. As compact JSON with named keys, the longest proposed kind name in every slot and 16-character style ids, that is 1,974 bytes, under 2 KB; as bare number quads it would be 385 (my computation; Emerald’s whole base is 32 bytes).7211 The second is a like total with the day’s set of visitors. Neither holds personal data beyond the player’s handle. The server validates a layout with the same six rules before storing it, so a modified client cannot store an illegal room. The play counters of 7.5 (quest stamps, steps walked, rooms visited, the house tier) are not server records: they sync through the collector’s own iCloud in PlayRecord, and the server never reads them.
Acceptance. Server tests: a layout with an overlap, a blocked path or a 17th piece on a floor is refused; a visitor’s move or place message in a host’s room is refused; two likes from one visitor on one day count once and a like the next day counts; a host who clears the room keeps the total. A two-simulator walk: device A arranges, device B visits and sees the same pieces at the same cells, with a capture from each.
7.7 The model and the screen on iOS 26
SwiftData. Two models, shaped like the app’s others for CloudKit: defaults everywhere, nothing unique, and a uid set to a UUID in init, as Profile, PriceHistory and CardCopy carry one.51775222
@Model final class PlacedPiece {
var uid: String = "" // set once, at creation; orders the repair
var roomMap: String = "room" // "room" or "room-up"
var kind: String = "" // a forge PIECES name
var x: Int = 0
var y: Int = 0
var facing: String = "down"
init() { uid = UUID().uuidString }
}
@Model final class PlayRecord { // one per device (7.5)
var uid: String = "" // the device's pointer to it is an @AppStorage key
var writer: String = "" // device marker: the one device that writes it
var questStamps: [String] = [] // moved from @AppStorage("quests.stamps")
var stepsWalked: Int = 0
var roomsVisited: [String] = [] // hosts' ids
var letterTier: Int = 0 // highest house tier reached, 0 to 3
init() { uid = UUID().uuidString }
}
Wall and floor styles live as strings on Profile, beside lookData.77 No #Unique and no required relationship, because CloudKit supports neither.22 Cell exclusivity, the cap and the walk are enforced in code, by one function. RoomLayout.repair(_:) runs on every read. It sorts a floor’s synced pieces by uid, ascending, and rebuilds the floor from its fixed architecture (the letter map, the stairs and the pillars), adding each piece in that order only if the full placement check of 7.1 accepts it against the pieces already accepted: the cell rules (so no overlap), the cap of 16, and the path rule. A piece the check refuses goes back to the tray. Every device sorts the same records the same way, so every device rebuilds the same room, and where two pieces conflict, the smaller uid wins, the rule PriceBook already uses to pick one of two devices’ price histories.52 The order is by uid, not by a placement time, because a time comes from each phone’s own clock. Overlap is not the only conflict two phones can make. A bed at (9,3) placed on one phone and a nightstand at (6,4) on another each pass the full check on their own device, and together they cut off both cells in front of the case; the rebuild keeps the one with the smaller uid and returns the other.2066 Since taking a piece away never cuts a path, a floor that is already legal passes the rebuild unchanged in any order (my reasoning; the acceptance tests pin it). The starter pieces of 7.2 are the one place where two devices create records without a player acting, so each gets a fixed uid from its floor and slot, starter.room.1 to starter.room-up.8, instead of a random one: two devices that launch cold create the same sixteen uids, not sixteen pairs that the rebuild would split between the floor and the tray. Before it rebuilds, repair folds records that share a uid into one, the way ModelContext.profile() already folds the duplicate profiles sync leaves into the one with the smallest uid.77 Where two copies disagree, because one device moved its starter piece before the other first launched, the fold keeps the copy that is off its starter cell, and between two moved copies the one at the smaller row, then column (my proposal). If putting a piece away deletes its record, a starter piece put away on one phone comes back when a second phone launches cold; this brief does not settle that case.
Placement. Arrange mode overlays a SwiftUI tray on the room’s RealityView. A tray item is draggable with its kind as a Transferable payload; the room view is a drop destination.53 On iOS 26, dropDestination(for:action:isTargeted:) hands the action the drop point in the view’s coordinates, and the point maps to a cell by the camera’s known whole-pixel scale: cell = floor((point - mapOrigin) / tileSizeInPoints).54 Because Apple’s page lists that form as deprecated in iOS 27.2, the brief also builds the DropSession form and reads the location from the session, if it carries one; that page has not been read.54 A placed piece is selected with SpatialTapGesture and moved with DragGesture, snapping cell by cell, its footprint tinted per cell as Stardew tints its tiles.565516
VoiceOver. In Arrange mode each placed piece is one accessibility element, for example Sofa, three by two, column 9, row 8, with the named actions Move left, Move right, Move up, Move down, Turn (chairs only) and Put away.5758 A rotor named “Furniture” lists the room’s pieces.60 A tray item’s Place action puts the piece at the legal cell nearest the arrival and focuses it. Wall and floor styles are adjustable elements: swipe up and down to cycle.59 Every refusal is spoken as an announcement, for example Can’t move: the sofa would cut off the shelf.61 The rules in 7.1 are one function, so voice and touch can never disagree.
Acceptance. A unit test that repair resolves a two-device overlap the same way in either order. The two-device merge regression, run with the two records in both input orders: on room as the forge authors it today, device A places a bed at (9,3) and device B a nightstand at (6,4); each placement passes the full check alone; after both sync, repair returns the same room for both orders, keeps the piece with the smaller uid, puts the other in the tray with a message naming the case, and the walk from the arrival still reaches both cells in front of the case; with the two uids swapped, the other piece is kept.66 A test that repair leaves a legal floor of 16 pieces unchanged, with its records shuffled into several orders. A test that 17 synced pieces on one floor, legal together except for the cap, come back as 16, with the largest uid in the tray. A test that two devices launching cold, each creating the starter pieces, sync to one record per starter cell, 8 per floor, with nothing in the tray, in either sync order; and that a starter piece moved on one device before the other launches stays where it was moved. A UI test that drags a tray item to a cell and finds a PlacedPiece at that cell. Unit tests of the VoiceOver action handlers, called directly on the Arrange model, not through VoiceOver: Place puts a chair at the legal cell nearest the arrival; Move left, Move right, Move up and Move down each move it one cell or refuse with a reason; Turn cycles its facing; Put away returns it to the tray; and every refusal produces the announcement text the screen will post. On an iOS 27 simulator, a UI test that turns VoiceOver on through XCUIVoiceOverService, moves focus to a placed piece and asserts its spoken label, such as Sofa, three by two, column 9, row 8.63 An audit of Arrange mode with performAccessibilityAudit that reports no issues.62 A manual check on a device with VoiceOver on, recorded with its date and build, because no XCUIAutomation call performs a custom action, turns a rotor or reads an announcement: place a chair from the tray, move it four ways with the actions, turn it, put it away, jump between pieces with the Furniture rotor, and hear each refused move announced. Before any of this, one spike: drop a payload on the room in the simulator under the camera’s real scale and log the computed cell against the cell under the finger, since that mapping is untested.
7.8 Housekeeping
- WORLD.md gets the room rules, with this brief’s numbers, so the design document says what the world post published.6710
interiors.py’s docstring and table agree one way or the other: either the docstring says the small pieces are the exception, or the small pieces are redrawn at two tiles. The brief keeps them.9
Not in this brief
- Stacking beyond the shelf’s own spots: no piece on a table, no doll-on-desk surfaces. The surface idea is the next step once the cap and the walk are proven.
- Pieces that act when walked on: no sound mats, no springs, no slides.
- Half-cell placement. The grid stays at whole 16-pixel cells.
- Furnishing the show hall. Its pedestals stay the weekly show’s.
- A furnishing contest. The weekly hall is the contest, judged by its own rules.
- Floor plans: the house’s shape does not change.
- Visits to strangers outside a shared plaza, and any ranking of rooms beyond the host’s own total.
Never, for furnishing
- No franchise vocabulary for any of it: not the base, the decorating computer, the Academy, record mixing, or any decoration’s name. Kiradex’s words only. The games are named in this post as facts about published works, not as features.
- No piece drawn after a game’s decoration: no creature dolls or cushions, no ball-shaped anything, no posters of creatures, no mat named for a move. The forge’s pieces are household furniture, and stay so.
- No creature in any room. Plants are plants.
- No bought, random or limited furniture (7.5).
- Nothing in a room is aimed, thrown, caught, summoned, released to fight, or ridden.
- No code or data from the decompilations in the app or the forge. The decompiled source is for study and measurement; the rules above are restated in Kiradex’s own terms.
Acceptance. A grep of the strings catalog, the forge’s PIECES names and the server’s tables for a word list built from the franchise vocabulary in item 1, plus “decoration”, “doll”, “Happy Home” and “Academy”, returns nothing.
Key Takeaways
If you draw the art
- Draw furniture in the character’s frame or cell width. Emerald’s player frame is one 16-pixel cell wide and its decorations average 2.43 cells; Kiradex’s collector stands in a cell two tiles wide and its pieces average 3.04.2729
- Make a catalog of mostly small pieces with a few large anchors: 71 of Emerald’s 120 decorations are one cell, and its desks and 3-by-3 mats are the anchors the small ones stand on.224
- Draw wallpapers and floors from rules and ramps, so a style is a drawer and a palette, not a new painting: two wall faces in three ramps and three floors in two ramps give Kiradex six of each.64
If you build the engine
- Store a placed piece as kind, cell and facing. Emerald stores one in two bytes, a base in 32.1112
- Check placement per cell, then walk. Emerald’s per-cell check never asks whether the door still reaches anything; on Kiradex’s ground floor, 713 of 229,891 legal pairs of extra pieces cut the stair, the host or a display off without covering it.420
- With CloudKit sync, SwiftData cannot enforce a unique constraint, so one-piece-per-cell is a pure repair function that picks the same winner on every device. Make it rebuild the room through the whole placement check, walk included, in a fixed order: two edits that each pass on their own phone can cut a display off together.225266
- Give VoiceOver verbs, not a grid to swipe through: named move actions, a rotor of pieces, an announcement for every refusal.586061
If you design the loop
- Cap what is placed, not what is owned: Emerald places 16 and stores 150. The cap is the composition.2
- Score on a fixed day with every source listed, raise the bar only when the house grows, and never punish a missed week: the wiki’s house page, which does not name a game, says a house neglected for at least one week fills with cockroaches, and New Horizons’ HHA table deducts 2,500 per cockroach.56
- Grow the catalog by play. Emerald never sells 24 of its 120 decorations for money and sells two more only for ash gathered by walking, Stardew, after the first upgrade, sells a 200,000g catalog that then sells the furniture it lists for 0g, and Habbo’s scarce and random furniture is the counterexample for a children’s app.14151617
- Visitors look, do not touch, and leave one like a day on a total that never falls.51819
FAQ
How many items should a player be able to place in a room?
Enough to compose, few enough to choose. Pokémon Emerald caps a base at 16 placed decorations and the bedroom at 12, about a quarter of an average base’s 60.2 walkable cells. Animal Crossing: New Horizons allows 150 per room, counting wall and ceiling items, by Nookipedia’s account, and Final Fantasy XIV allows 150 to 600 indoors by home size since Patch 7.5. For a 2D room with no wall or ceiling layer, my threshold is a cap under one item per three floor cells, which Emerald’s 0.27 sits just under; Kiradex’s proposed 16 is 0.13 per floor cell.2579
How does Pokémon Emerald’s decoration system work?
It is data. 120 decorations each carry a category, a shape of 1 to 9 cells, a price and one of five permissions (solid floor, walk-over floor, behind, wall, or sprite). CanPlaceDecoration checks each covered cell: plain floor, no object, and, on the cell the player stood on, no tile with a non-normal layer type; wall cells for posters; a holding cell for dolls and cushions, small or large for most of them and large for a 1-by-2 doll. 18 decorations provide small holding cells: seven desks, three bricks, a tire and seven mats. Placed decorations are stored as an id and a position byte each.2411
How does the Happy Home Academy score a room?
By Nookipedia’s tables, which cite no source for New Horizons: an evaluation by mail most Sunday mornings, ranks B, A and S, an S threshold that rises from 15,000 to 90,000 as the house grows, 1,000 points at each of 6, 10, 15 and 20 items in a room, per-item bonuses for series, sets, categories, a dominant color and feng shui, and deductions for cockroaches, trash and items facing a wall. The per-item points are a stub on the wiki.6
Can SwiftData enforce one item per grid cell with CloudKit sync?
Not with #Unique. Apple’s guide to syncing SwiftData lists unique constraints among the features “that CloudKit doesn’t support natively”, and CloudKit requires every relationship to be optional. Give every property a default, keep nothing unique, and resolve two devices’ pieces on one cell in a pure function that runs on every read and picks the same winner on every device. Have that function rebuild the room in a fixed order through the full placement check, not only the overlap test, because two edits that are each legal can break a rule together.225166
How do you make a drag-and-drop furniture grid accessible to VoiceOver?
Make each placed piece one accessibility element with its size and cell in its label, give it named actions to move one cell in each direction, turn and put away, add a rotor that lists the room’s pieces, and announce every refused move with its reason. Apple’s accessibilityAction(named:_:), accessibilityRotor(_:entries:) and AccessibilityNotification.Announcement cover each part, and performAccessibilityAudit checks the screen in a UI test. The audit does not press the named actions, and in Xcode 27.0 no XCUIAutomation call does, so test the action handlers directly and check the actions, the rotor and the announcements by hand with VoiceOver on.5860616263
Should a kids’ game sell furniture?
My reading is no, for an app rated 9+: a decoration loop that is bought, random or scarce takes on loot-box and pressure questions the game does not need. Emerald never sells 24 of its 120 decorations for money (they are prizes, battle-point exchanges and gifts) and sells two more only for ash gathered by walking, and once the first house upgrade is done, Stardew sells a Furniture Catalogue for 200,000g that then sells the furniture it lists for 0g, though some pieces still come only from the Museum, festivals and other sources. Habbo’s purchase-led economy, with rares and random crackables, shows the other end.14151617
Why do visitors in these games get read-only access?
On my reading, because the room is the host’s expression. Animal Crossing visitors cannot “modify the interior in any way”, Habbo visitors cannot drop or move furniture without the owner’s rights, and Club Penguin owners can decorate their own igloo “but not other player’s igloos”. What visitors get instead is a mark that counts: Club Penguin’s one like per design per day, on a Grand Total that never decreases.518819
Related on this site: Pixel-Art Structures: Houses, Halls and Interiors on iPhone built the interiors this brief furnishes, and its interiors section describes the 14-by-11 rooms that build 26 replaced; Pixel-Art Worlds on iPhone is where the cap of sixteen, read-only visits, the daily like and the Sunday report were first published; Pixel-Art People: Characters and a Creator on iPhone covers the collector whose width sets the furniture’s rhythm; Pixel-Art Town Layout: Pallet to Pelican Town, Measured measures the town the houses stand in; Pixel-Art Motion: Walks, Cameras and Doors on iPhone covers the walk and the doors a visitor comes in by; and Pixel-Art Routes: Map Connections and Districts on iPhone covers the land beyond the town.
Sources
-
pret,
pokeemerald/include/constants/global.h(SECRET_BASES_COUNT 20,DECOR_MAX_SECRET_BASE 16,DECOR_MAX_PLAYERS_HOUSE 12), commit731ad5b(October 1, 2026), read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/include/constants/global.h. ↩↩↩↩↩ -
Author’s measurement, October 5, 2026:
measure_emerald_decor.pyin the author’s evidence folder for this post, output saved asmeasure_emerald_decor.out, run on a shallow clone of pret’spokeemeraldat commit731ad5b. It reads the caps frominclude/constants/global.h; the 120 decorations (excludingDECOR_NONE) with category, shape, permission and price fromsrc/data/decoration/header.h; the per-category inventory arrays frominclude/global.h; the behavior byte of each decoration metatile fromdata/tilesets/secondary/secret_base/metatile_attributes.bin; and each of the 24 base layouts and the bedroom fromdata/layouts/layouts.jsonand itsmap.bin, counting walkable cells from the collision bits. Cells per decoration from the shape names; cap over mean walkable cells 16 / 60.2 = 0.27. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
pret,
pokeemerald/src/data/decoration/header.h(gDecorations[]: name, permission, shape, category, price and tiles per decoration; entry 0DECOR_NONE), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/src/data/decoration/header.h. ↩↩↩↩ -
pret,
pokeemerald/src/decoration.c(CanPlaceDecoration,DecorationItemsMenuAction_AttemptPlace,isPlayerRoom,gText_CantPlaceInRoom; the holding-cell checks for sprite decorations), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/src/decoration.c. In the sprite case, a 1-by-2 decoration needsMetatileBehavior_HoldsLargeDecorationand any other takes a small or a large holding cell;IsntInitialPositionrefuses the player’s starting cell only when the decoration’s tile there has a layer type other thanMETATILE_LAYER_TYPE_NORMAL. That nothing in the function checks a path is the author’s reading of it. ↩↩↩↩↩↩↩↩↩↩ -
Nookipedia, “Player house” (per-room caps: 24 in Wild World, 64 in City Folk, 48 in New Leaf, 150 in New Horizons “including wall and ceiling-mounted furniture”; the New Horizons upgrade table with room sizes; “only the main room can be expanded in size”; the accent wall from 2.0; visitors may not “modify the interior in any way”; a player who neglects their house “for at least one week” finds it infested with cockroaches), fetched and saved October 5, 2026 as
nook-player-house.htmland.txtin the rooms evidence folder, https://nookipedia.com/wiki/Player_house. The 4.2 items per tile is the author’s arithmetic (150 / 36). ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Nookipedia, “Happy Home Academy” (the Sunday evaluation; the B, A and S tiers per expansion; the New Horizons point bonuses and deductions; “This section is a stub” for New Horizons per-item points; the rewards table’s note “Includes data sourced from the Data Spreadsheet for Animal Crossing New Horizons”), fetched and saved October 5, 2026 as
nook-hha.htmland.txt, https://nookipedia.com/wiki/Happy_Home_Academy. The bonus and deduction tables carry no citation on the page. ↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Square Enix, The Lodestone, Final Fantasy XIV Patch 7.5 notes (updated May 13, 2026; the Housing section’s indoor and outdoor furnishing limits before and after; the 400-furnishing display note; “Furnishings from the FFXIV Furnishing Design Contest have been added”), fetched and saved October 5, 2026 as
ffxiv-patch-7-5.htmland.txt, https://eu.finalfantasyxiv.com/lodestone/topics/detail/9beb8a7b5c46944cd80ed92b2b8e972395fbea80/. The housing play guide, https://na.finalfantasyxiv.com/lodestone/playguide/contentsguide/housing/, returned HTTP 404 the same day; plot sizes are not sourced in this post. ↩↩↩↩↩↩↩↩↩↩ -
Club Penguin Wiki (Fandom), “Furniture” (the 99-unit ownership limit for most furniture; “igloos have a limit preventing more than 99 units of furniture being placed at once”; owners decorate their own igloo “but not other player’s igloos”; the July 26, 2012 six free items for non-members), read through the wiki’s MediaWiki API and saved October 5, 2026 as
cp-fandom-furniture.htmland.txt, https://clubpenguin.fandom.com/wiki/Furniture. Single source. ↩↩↩↩↩↩ -
Author’s measurement, October 5, 2026:
measure_kiradex_interiors.pyin the rooms evidence folder, outputmeasure_kiradex_interiors.out, which parses the Kiradex repository’sscripts/forge/interiors.pywith Python’sast(the file is never imported or run): the 23 entries ofPIECESwith width, height and free-standing flag; theROOM,ROOM_UPandHALLletter maps with their furniture lists and spots; floor cells counted as the letterso t s r; movable pieces excludestairs,stairs_downandpillar. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Blake Crosley, “Pixel-Art Worlds on iPhone: What the 16-Bit Masters Knew,” blakecrosley.com, October 3, 2026 (the room rules: “a furnishing cap of sixteen”, read-only visits, a like once a day, a total that never decreases, a Sunday report “with its point sources listed”; in the same paragraph, “Patron flair stays on the name-plate and the room skin”; the patents named in the Palworld suit; the device-pixels-per-texel camera fit), https://blakecrosley.com/blog/pixel-art-world-on-iphone. ↩↩↩↩↩↩↩↩↩↩
-
pret,
pokeemerald/include/global.h(u8 decorations[DECOR_MAX_SECRET_BASE]andu8 decorationPositions[DECOR_MAX_SECRET_BASE]in the secret base record; the per-category decoration inventory arrays in the save), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/include/global.h. ↩↩↩↩↩↩↩ -
pret,
pokeemerald/src/secret_base.c(decoration positions read with x in the high nibble and y in the low), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/src/secret_base.c. ↩↩↩ -
pret,
pokeemerald/include/decoration.h(enum DecorationPermissionwith the comment “The nomenclature here describes collision and placement permissions, in that order.”;enum DecorationShape, withDECORSHAPE_3x1andDECORSHAPE_1x3marked unused), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/include/decoration.h. ↩↩↩ -
Author’s measurement, October 5, 2026:
measure_emerald_sources.pyin the rooms evidence folder, outputmeasure_emerald_sources.out, which searches pokeemerald731ad5bfor everyDECOR_constant in thepokemartdecorationlists ofdata/maps/*/scripts.inc, the prize corner’s script, the battle facility’s exchange table insrc/data/battle_frontier/battle_frontier_exchange_corner.h, and the first argument ofgivedecorationandadddecorationanywhere underdata/: 90 sold for money at five shops, 3 prize-counter, 15 battle-point, 10 given by script, 24 never sold for money, 6 in none of those. Two of the six are the glass workshop pair (note 15); the other four, three legendary dolls and one other doll, were not traced. ↩↩↩↩↩↩↩↩ -
pret,
pokeemerald/data/maps/Route113_GlassWorkshop/scripts.inc(PRETTY_CHAIR_PRICE, 6000,PRETTY_DESK_PRICE, 8000, paid fromVAR_ASH_GATHER_COUNT;Route113_GlassWorkshop_EventScript_NotEnoughAshand_NotEnoughAshForItemsubtract the count from the price and show the difference as steps still to walk; a search ofsrc,dataandincludefindsVAR_ASH_GATHER_COUNTused only there and infield_tasks.c, apart from its definition) andpokeemerald/src/field_tasks.c(one ash per step through ash grass while the sack is carried, up to 9999), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/data/maps/Route113_GlassWorkshop/scripts.inc and https://github.com/pret/pokeemerald/blob/master/src/field_tasks.c. ↩↩↩↩↩↩↩ -
Stardew Valley Wiki, “Furniture,” revision 193159 (Robin and the Traveling Cart “offer a random selection of furniture each day they are open”; “After the first Farmhouse upgrade, Robin also offers the Furniture Catalogue for sale”; 0g “in unlimited quantity”; the Catalogues table’s row for the Furniture Catalogue, sold at the Carpenter’s Shop for 200,000g; “Some furniture can be obtained only by donating items to the Museum”, festivals, the casino and other sources; the green and red placement squares), fetched and saved October 5, 2026 as
sdv-furniture.htmland.txt, https://stardewvalleywiki.com/Furniture. ↩↩↩↩↩↩↩↩↩↩↩ -
Sulake, Habbo Help Center, “Furni Definitions” (campaign furni held back “4-12 months” for traders, rares that “will never be re-released”, rare crackable furni, LTDs “in limited quantities”), the article body saved October 5, 2026 in
habbo-articles.txtin the rooms evidence folder, https://help.habbo.com/hc/en-us/articles/360011621699-Furni-Definitions. ↩↩↩↩↩↩↩ -
Sulake, Habbo Help Center, “What is Furni?” (“To buy furni you need credits, diamonds or duckets”; “You can’t drop or manipulate furni in other Habbo’s rooms unless you’re a member of a group”), the article body saved October 5, 2026 in
habbo-articles.txt, https://help.habbo.com/hc/en-us/articles/360011512940-What-is-Furni. ↩↩↩↩↩↩↩ -
That Penguin Game, “Your Igloo” (a reproduction of Club Penguin’s help pages; its provenance was not verified: “You can Like any igloo design once every day!”; individual and Grand Total Likes; “Likes are permanent, so your Grand Total Likes will never decrease, even if you delete an igloo design!”; the Everyone and Friends settings), fetched and saved October 5, 2026 as
tpg-your-igloo.htmland.txt, https://thatpenguingame.com/club-penguin-help/game-help/your-igloo/. Single source. ↩↩↩↩↩↩ -
Author’s measurement, October 5, 2026:
measure_path_rule.py, kept beside the post’s draft, outputmeasure_path_rule.outandpath_rule.json. It parses the Kiradex repository’sscripts/forge/interiors.pywithast, rebuilds the exported letters asexport()does, walks four ways from each floor’s arrival overotsrUD(the walkable set of the forge’scheck()), and reports the stair, host and each dressed spot’s front cell (the first cell straight south past the shelf and the wall band). It then tries, inroom, every placement of one extra free-standing piece (10 drawings: chairs once, beds once) on free floor clear of the arrival, stair and host cells (733 placements; 44 cut a target off, all by covering it), and every non-overlapping pair of extra pieces clear of all targets (689 single placements, 229,891 pairs; 713 cut a target off). ↩↩↩↩↩↩↩↩↩↩ -
Author’s computation, October 5, 2026:
score_max.pyin the draft folder’sfigures/, outputscore_max.outandscore_max.json: the brief’s score table summed for two floors at 16 pieces, each line at its cap (3,200 + 3,000 + 6,400 + 9,600 + 500 + 600 + 300 = 23,600), and one floor at 8 pieces with no set, ramp or spot lines (800 + 500 = 1,300). The same script scores the three reference houses that set the proposed house-tier thresholds with the table’s own lines: both floors at 10 pieces with the shelf full, 4,500; both floors at 16 pieces with the shelf, the case and the board full, 7,600; that house plus a suite of 8 and 70% one ramp on each floor, 14,000; and the starter house, both floors at 8, 2,600. ↩↩↩↩ -
Apple Developer Documentation, “Syncing model data across a person’s devices” (SwiftData; “does include a small number of features that CloudKit doesn’t support natively, such as unique constraints and nonoptional relationships”; “CloudKit requires all relationships to be optional”), documentation JSON saved October 5, 2026 as
apple-swiftdata-cloudkit-sync.htmland.txt, https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices. ↩↩↩↩↩↩ -
pret,
pokeemerald/src/new_game.c(NewGameInitDatacallsClearDecorationInventories()) andpokeemerald/src/decoration_inventory.c(ClearDecorationInventorysets every slot of each category toDECOR_NONE), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/src/new_game.c. ↩ -
Author’s figures, October 5, 2026:
make_figures.pyin the draft folder’sfigures/, which readssrc/data/decoration/header.hfrom pokeemerald731ad5b, the caps as cited in notes 1, 5, 8 and 7,path_rule.jsonandscore_max.json, asserts every total against the measurements above, and writesemerald-decor-sizes.svg,caps.svg,room-path-rule.svgandscore-sources.svg. The footprint classes (1 cell, 2 cells, 4 to 6, 8 or 9) group the shapes by cells covered. Palette checked with the dataviz validator; no game art. ↩↩↩↩↩ -
pret,
pokeemerald/include/constants/metatile_behaviors.h(theMB_SECRET_BASE_*behaviors,MB_SLIDE_SOUTH,MB_HOLDS_SMALL_DECORATION,MB_HOLDS_LARGE_DECORATION), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/include/constants/metatile_behaviors.h. ↩ -
pret,
pokeemerald/data/layouts/layouts.json(the 24LAYOUT_SECRET_BASE_*layouts and the two player houses’ second floors, with widths and heights) and each layout’smap.bin, commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/data/layouts/layouts.json. Width, height and area ranges are the author’s from the measurement’s output. ↩ -
Author’s measurement, October 5, 2026:
measure_character_cell.pyin the rooms evidence folder, outputmeasure_character_cell.out, reading the PNG headers of pokeemerald’sgraphics/object_events/pics/people/brendan/walking.png(144 by 32) anddecorating.png(16 by 32), and the cell (32 by 40),figureTop(7) andunderFeet(2) in the Kiradex repository’sKiradex/Resources/World/characters.json. The script measures the cell and the figure’s height (31 pixels), not the drawn figure’s width. ↩↩↩↩↩ -
pret,
pokeemerald/src/data/items.h(ITEM_SOOT_SACK,.fieldUseFunc = ItemUseOutOfBattle_CannotUse) andpokeemerald/src/data/text/item_descriptions.h(sSootSackDesc, a fixed three-line description), commit731ad5b, read October 5, 2026, https://github.com/pret/pokeemerald/blob/master/src/data/items.h. ↩↩ -
Nookipedia, “Furniture” (sizes “ranging from 1.0×0.5” to 3 by 3; half-tile pushing; the New Horizons furniture types and ceiling decor from 2.0; 2,076 furniture items as of 3.0.2, 1,074 added in updates; a series of “around 10 furniture items, as well as a matching wallpaper and flooring”), fetched and saved October 5, 2026 as
nook-furniture.htmland.txt, https://nookipedia.com/wiki/Furniture. ↩↩↩↩ -
Nookipedia, “Wallpaper” (262 wallpapers in New Horizons as of version 1.9.0), fetched and saved October 5, 2026 as
nook-wallpaper.htmland.txt, https://nookipedia.com/wiki/Wallpaper. ↩ -
Nookipedia, “Flooring” (215 in New Horizons), fetched and saved October 5, 2026 as
nook-flooring.htmland.txt, https://nookipedia.com/wiki/Flooring. ↩ -
Nookipedia, “Luna” (the New Leaf section: “any changes will not be saved and items cannot be brought back to the real world”; the New Horizons section: her services “work the same as they do in New Leaf”, and a Dream Bell Exchange Ticket worth 5,000 Bells for each upload), fetched and saved October 5, 2026 as
nook-luna.htmland.txt, https://nookipedia.com/wiki/Luna. ↩↩ -
Sulake, Habbo Help Center, “Rooms” (“You can own 200 rooms.”; “Wallpaper and flooring are stuck down”), fetched and saved October 5, 2026 as
habbo-rooms.htmland.txt, https://help.habbo.com/hc/en-us/articles/360011512640-Rooms. ↩↩↩↩ -
Sulake, Habbo Help Center, “What is Builders Club?” (the furni limit “increased by 250” each month of membership; saving custom room layouts in the floor plan editor) and “What can I buy in Habbo?” (“Furni limits never go down.”), the article bodies saved October 5, 2026 in
habbo-articles.txt, https://help.habbo.com/hc/en-us/articles/360011621659-What-is-Builders-Club and https://help.habbo.com/hc/en-us/articles/360011620599-What-can-I-buy-in-Habbo. ↩ -
Sulake, Habbo Help Center, “Player to player trading in Habbo” (a trading pass is required; “There is no guide to what items of furni are worth”), the article body saved October 5, 2026 in
habbo-articles.txt, https://help.habbo.com/hc/en-us/articles/4408726781842-Player-to-player-trading-in-Habbo. ↩↩ -
Sulake, Habbo Help Center, “Guidelines on user created games in Habbo” (“Placing more than three chance elements will disable all randomiser functions in the room.”), the article body saved October 5, 2026 in
habbo-articles.txt, https://help.habbo.com/hc/en-us/articles/360011513060-Guidelines-on-user-created-games-in-Habbo. ↩ -
Sulake, Habbo Help Center search API, result sets for “furni”, “stack” and “floor plan”, saved October 5, 2026 as
habbo-search-furni,habbo-search-stackandhabbo-search-floorplan(.htmland.txt) in the rooms evidence folder; none states a grid size, a stacking height or a per-room furni limit. ↩ -
billsonnn,
nitro-react/src/components/floorplan-editor/common/Constants.ts(MAX_NUM_TILE_PER_AXIS = 64,HEIGHT_SCHEME = 'x0123456789abcdefghijklmnopq', 27 height steps after the emptyx), a third-party open-source Habbo client, as cited in the structures post on October 3, 2026, https://github.com/billsonnn/nitro-react/blob/main/src/components/floorplan-editor/common/Constants.ts. The stack-height tool range (0 to 40 in steps of 0.01) is from my earlier notes, read from the same client and not re-read on October 5, 2026. ↩ -
Blake Crosley, “Pixel-Art Structures: Houses, Halls and Interiors on iPhone,” blakecrosley.com, October 3, 2026 (the interiors “each 14 by 11, with a two-row wall band”; builds 22, 23 and, in the evening addendum, 35; “Rooms have no wallpaper or floor choice and no placeable furniture; the house is dressed from the collection and nothing else”; the
room:npc-…warps; the objects mesh; Stardew’s farmhouse “10×7” inside, note 54; the Nitro constants, note 62), https://blakecrosley.com/blog/pixel-art-structures-on-iphone. ↩↩↩↩↩↩↩↩ -
Author’s measurement, October 5, 2026:
measure_sdv_catalogue.pyin the rooms evidence folder, outputmeasure_sdv_catalogue.out: furniture rows counted per section from each row’s name link on the saved Furniture page (rev 193159), skipping the Movie Posters section, whose rows use other markup, and the References, History and Exploits sections; wallpapers and floorings counted as distinct icons on the saved Wallpaper (rev 193801) and Flooring (rev 190285) pages; Furniture Catalogue source rows counted by its link. Counts of wiki rows and icons, not of the game’s data files. ↩↩↩↩ -
Stardew Valley Wiki, “Wallpaper,” revision 193801 (“Wallpapers are single-use and do not stack. They cover the whole room they’re placed in”; “the character must be facing up by its wall”), fetched and saved October 5, 2026 as
sdv-wallpaper.htmland.txt, https://stardewvalleywiki.com/Wallpaper. ↩↩↩↩ -
Stardew Valley Wiki, “Flooring,” revision 190285, fetched and saved October 5, 2026 as
sdv-flooring.htmland.txt, https://stardewvalleywiki.com/Flooring. ↩ -
Club Penguin Wiki (Fandom), “Igloo” (the history: November 1, 2005, igloos for players without membership, who “were unable to decorate them with furniture”; July 26, 2012, the new igloo experience and “a set of six items available without membership”), read through the MediaWiki API and saved October 5, 2026 as
cp-fandom-igloo.htmland.txt, https://clubpenguin.fandom.com/wiki/Igloo. The archived official blog posts it cites returned HTTP 429 from the Wayback Machine twice on October 5, 2026. Single source. ↩↩ -
Club Penguin Wiki (Fandom), “Igloo Contests” (the first contest in issue 9, December 15, 2005, one winner at 5,000 coins; winners “After one to four weeks”; character judges from the 2008 Halloween contest; the submit button from 2009; the last contest in December 2012; the 2008 Ye Olde Igloo Contest’s ten winners at 25,000 coins and twenty runners-up at 15,000), read through the MediaWiki API and saved October 5, 2026 as
cp-fandom-contests.htmland.txt, https://clubpenguin.fandom.com/wiki/Igloo_Contests. Single source. ↩ -
Tristan Donovan, “The Replay Interviews: Will Wright,” Game Developer, May 23, 2011, fetched and saved October 5, 2026 as
gd-replay-wright.htmland.txt, https://www.gamedeveloper.com/business/the-replay-interviews-will-wright. No recorded talk by Wright from 1999 or 2000 on the build mode was found. ↩↩ -
The Sims Wiki (Fandom), “Buy mode” (“purchase items from an object catalog and place them on the current lot”; the function sort in The Sims and The Sims 2; the green and red footprint sentence, tagged on the page to The Sims 2 and The Sims 3), read through the MediaWiki API and saved October 5, 2026 as
sims-fandom-buymode.htmland.txt, https://sims.fandom.com/wiki/Buy_mode. Single source. ↩↩↩ -
The Sims Wiki (Fandom), “Environment” (the Room and Environment motive, which “analyzes the design and content of the room that the Sim is currently standing in”), read through the MediaWiki API and saved October 5, 2026 as
sims-fandom-environment.htmland.txt, https://sims.fandom.com/wiki/Environment. Single source. ↩ -
Author’s extraction, October 5, 2026:
measure_apple_docs.pyin the rooms evidence folder, outputmeasure_apple_docs.out: title, declaration, abstract and platforms from each saved Apple documentation JSON page. The deprecation fields quoted fordropDestination(for:action:isTargeted:)were read from the same saved JSON. ↩ -
Apple Developer Documentation,
Model()(SwiftData macro; “Converts a Swift class into a stored model that’s managed by SwiftData”; iOS 17.0), JSON saved October 5, 2026 asapple-swiftdata-model.htmland.txt, https://developer.apple.com/documentation/swiftdata/model(). ↩ -
Apple Developer Documentation,
Unique(_:)(SwiftData macro; “Specifies the key-paths that SwiftData uses to enforce the uniqueness of model instances”; iOS 18.0), JSON saved October 5, 2026 asapple-swiftdata-unique.htmland.txt, https://developer.apple.com/documentation/swiftdata/unique(_:). ↩ -
Kiradex repository,
Kiradex/Models/CardCopy.swift(doc comment: “every property has a default and nothing is unique, for CloudKit”), read October 5, 2026. ↩↩↩ -
Kiradex repository,
Kiradex/Models/PriceHistory.swift(doc comment: “Shaped for CloudKit likeCollectionEntry: defaults everywhere, nothing unique”;PriceBookfolds two devices’ histories “into the one with the smallestuid”), read October 5, 2026. ↩↩↩↩ -
Apple Developer Documentation,
draggable(_:)(SwiftUI; “Activates this view as the source of a drag and drop operation”; aTransferablepayload; iOS 16.0), JSON saved October 5, 2026 asapple-swiftui-draggable.htmland.txt, https://developer.apple.com/documentation/swiftui/view/draggable(_:). ↩↩ -
Apple Developer Documentation,
dropDestination(for:action:isTargeted:)(SwiftUI; an action of([T], CGPoint) -> Bool, the second parameter “the drop location in this view’s coordinate space”; iOS 16.0; the platforms entry for iOS listsdeprecatedAt27.2 with the message “UsedropDestination(for:isEnabled:action:)with anactionthat takes aDropSessionparameter instead.”; theDropSessionreference, “A description of a drop that is in progress”), JSON saved October 5, 2026 asapple-swiftui-dropdestination.htmland.txt, https://developer.apple.com/documentation/swiftui/view/dropdestination(for:action:istargeted:). ↩↩↩↩↩ -
Apple Developer Documentation,
DragGesture(SwiftUI; “A dragging motion that invokes an action as the drag-event sequence changes”; iOS 13.0), JSON saved October 5, 2026 asapple-swiftui-draggesture.htmland.txt, https://developer.apple.com/documentation/swiftui/draggesture. ↩↩ -
Apple Developer Documentation,
SpatialTapGesture(SwiftUI; “A gesture that recognizes one or more taps and reports their location”; iOS 16.0), JSON saved October 5, 2026 asapple-swiftui-spatialtap.htmland.txt, https://developer.apple.com/documentation/swiftui/spatialtapgesture. ↩↩ -
Apple Developer Documentation,
accessibilityElement(children:)(SwiftUI; iOS 13.0), JSON saved October 5, 2026 asapple-swiftui-accessibilityelement.htmland.txt, https://developer.apple.com/documentation/swiftui/view/accessibilityelement(children:). ↩↩ -
Apple Developer Documentation,
accessibilityAction(named:_:)(SwiftUI; “Actions allow assistive technologies, such as the VoiceOver, to interact with the view by invoking the action”; iOS 16.0), JSON saved October 5, 2026 asapple-swiftui-accessibilityaction-named.htmland.txt, https://developer.apple.com/documentation/swiftui/view/accessibilityaction(named:_:). ↩↩↩↩ -
Apple Developer Documentation,
accessibilityAdjustableAction(_:)(SwiftUI; a handler taking anAccessibilityAdjustmentDirection; iOS 13.0), JSON saved October 5, 2026 asapple-swiftui-adjustable.htmland.txt, https://developer.apple.com/documentation/swiftui/view/accessibilityadjustableaction(_:). ↩↩ -
Apple Developer Documentation,
accessibilityRotor(_:entries:)(SwiftUI; “Create an Accessibility Rotor with the specified user-visible label”; iOS 16.0), JSON saved October 5, 2026 asapple-swiftui-accessibilityrotor.htmland.txt, https://developer.apple.com/documentation/swiftui/view/accessibilityrotor(_:entries:). ↩↩↩↩ -
Apple Developer Documentation,
AccessibilityNotification.Announcement(Accessibility; “A notification that an app posts when it needs to convey an announcement to an assistive app”; iOS 17.0), JSON saved October 5, 2026 asapple-swiftui-accessibilitynotification.htmland.txt, https://developer.apple.com/documentation/accessibility/accessibilitynotification/announcement. ↩↩↩↩ -
Apple Developer Documentation,
performAccessibilityAudit(for:_:)(XCUIAutomation,XCUIApplication; iOS 17.0; the JSON lists Xcode 16.3 and carries no abstract), JSON saved October 5, 2026 asapple-xctest-accessibilityaudit.htmland.txt, https://developer.apple.com/documentation/xcuiautomation/xcuiapplication/performaccessibilityaudit(for:_:). ↩↩↩ -
Apple, XCUIAutomation framework headers in Xcode 27.0 (build 27A266a), iPhone Simulator platform, read October 5, 2026:
XCUIApplication.h(performAccessibilityAuditWithAuditTypes:issueHandler:error:, “Runs an accessibility audit on the current view”);XCUIVoiceOverService.h(“Provides programmatic control of VoiceOver for UI testing”; enable, disable, move forward, backward, in and out, and the current speech; iOS 27.0);XCUIDevice.h(thevoiceOverServiceproperty, iOS 27.0). A search of every header in the framework for custom actions, rotors and announcements found none. ↩↩↩ -
Kiradex repository,
scripts/forge/interiors.py(the module docstring, including “every piece at least two tiles on one axis”; theROOM,ROOM_UPandHALLletter maps, furniture lists, spots and warps; thehostcomment “where the owner stands when you visit”;PIECES,FACES,EXPORT_LETTERS,export()andcheck(), whose spot checks cover the arrival, stair, host, shelf, showcase, desk and pedestal spots and not the wall board, and whose overlap loop readsdata["objects"], the exported free-standing pieces), read October 5, 2026, never run. ↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Kiradex repository,
docs/TestFlight.md, item 46 (“Build 26: the interior kit. Rooms sixteen wide with a three-row wall band (cornice, face, wainscot)”), read October 5, 2026. The build is not dated in the file; it falls between build 23 and build 35, both of which the structures post dates October 3, 2026. ↩↩ -
Author’s computation, October 5, 2026:
merge_regression.pyin the draft folder’sfigures/, outputmerge_regression.out. Onroomas the forge authors it (13 movable pieces, read frompath_rule.jsonand the Kiradex repository’sscripts/forge/interiors.pywithast), a bed at (9,3) alone and a nightstand at (6,4) alone each pass the cell rules, the cap and the walk; both together cut off (7,3) and (8,3), the two cells in front of the case. A repair that sorts the two byuidand adds each through the full check keeps the smalleruidand returns the other, with the same result for both input orders and for bothuidassignments. That every one of the 713 cutting pairs is legal piece by piece follows frommeasure_path_rule.out: no single placement clear of the targets cuts one off. ↩↩↩↩↩ -
Kiradex repository,
docs/WORLD.md(section 4: the coin shop’s “clothes, hats, backpacks, card-display frames and emotes”,level = floor(sqrt(XP / 40)) + 1, level-locked cosmetics “that cannot be bought”, the pins including Full Set, Vintage and Across the Sea; the collector as “a 30-pixel figure in a 32 × 40 cell”), read October 5, 2026; searched for sixteen, cap, decoration, furnishing, Sunday, once a day and read-only, none of which states a room rule. ↩↩↩↩↩↩ -
Kiradex repository,
server/app/rooms.py(module docstring: “Everything here is in memory; a room empties when its last collector leaves and nothing of them is kept.”), read October 5, 2026. ↩↩↩↩ -
Kiradex repository,
docs/research/pixel-art/06-collecting-and-hubs.md, section 5.3 (“Rooms: a budget, a Sunday letter, and a like that never goes down”: the cap of 16, the Sunday letter as “a pixel object that appears on the doormat”, read-only visits, a like once per visitor per day, “a stamp on their passport per room visited, with ranks at 30 / 100 / 500”) and section 5.7 (patron items include “one room skin” and are “never a bigger furnishing cap”), read October 5, 2026. ↩↩↩↩↩ -
Kiradex repository,
Kiradex/World/Quests.swift(Quest.current(on:calendar:), keyed by the calendar’sweekOfYearinterval, which starts on the calendar’s own first weekday) andKiradex/World/HallView.swift(the comment “The week’s theme is the week’s quest”, and the theme read as the weekly quest’s title), read October 5, 2026. ↩↩↩ -
Kiradex repository,
docs/PROTOTYPES.md(the weekly quest prototype’s tester question “Weekly reset on your calendar’s week: say if it feels wrong.”), read October 5, 2026. ↩ -
Author’s computation, October 5, 2026:
layout_size.pyin the draft folder’sfigures/, outputlayout_size.out: the kind count, 21 from today’s forge (17 floor kinds and 4 wall items) and 3 new in section 7.5, 24 in all; the stored house layout (two floors, 16 pieces each with kind, x, y and facing, two style ids per floor) as compact JSON with named keys, every kind set to the longest proposed name (pressed_flower, 14 characters) and every style id to 16 characters, 1,974 bytes; the same with every kind padded to 16 characters, 2,038 bytes; bare integer quads for 32 pieces, 385 bytes. ↩↩ -
Kiradex repository,
Kiradex/World/PlazaStage.swift(@AppStorage("plaza.id"), “Who this device is to the plaza”;@AppStorage("quests.stamps"), the quest stamps as a comma-joined list, also read byQuestBoardViewandMeView;@AppStorage("plaza.ribbons"), “Ribbons from the town’s collectors”), read October 5, 2026; a search of the app’s Swift sources for a stored step count or a record of rooms visited found none, nor did a search of the app and the server for a pedometer, a step-count type or a passport (the onlystepsare walk paths inTileMap.swiftandPlazaRig.swift). ↩↩↩↩↩ -
Kiradex repository,
Kiradex/Models/Progression.swift(the doc comment onProgression: experience, level and pins are “worked out from the collection as it is, so every device agrees without anything being stored”), read October 5, 2026. ↩↩ -
Apple Developer Documentation,
AppStorage(SwiftUI; “A property wrapper type that reflects a value from UserDefaults”; iOS 14.0), JSON saved October 5, 2026 asapple-swiftui-appstorage.htmland.txt, https://developer.apple.com/documentation/swiftui/appstorage. ↩↩ -
Author’s computation, October 5, 2026:
skin_denominator.pyin the draft folder’sfigures/, outputskin_denominator.out, from the brief’s ramp lines: one floor of 16 pieces, 15 of them and the floor style in one ramp family and the wall outside it, is 16 of 18 (88.9%), 1,600 points on the 70% line; with the wall dropped from the share it is 16 of 17 (94.1%), 4,800 points on the 90% line, 3,200 more. ↩ -
Kiradex repository,
Kiradex/Models/Profile.swift(var lookData: Data = Data()on the synced profile;var uid: String = "", set toUUID().uuidStringininit(handle:), asPriceHistoryandCardCopyalso carry auid;ModelContext.profile(), lines 224 to 237, fetches the profiles sorted byuid, keeps the first and deletes the rest, the comment calling it a fold to the smallest uid), read October 5, 2026. ↩↩↩