Replies: 10 (Who?), Viewed: 17925 times.
Eminence Grise
Original Poster
#1 Old 10th Sep 2011 at 6:06 AM
Default Set/remove floor cutout
Was compiling a list of TS3 cheats, and ran across "setfloorcutout" and "removefloorcutout". Setfloorcutout takes position parameters, and removefloorcutout takes an ID. Anybody have any idea what these do? I tried googling, but all I found was people asking the same question They were added with Ambitions, so there's an idea that they have something to do with the fire pole.

Anybody actually used em successfully?
One horse disagreer of the Apocalypse
#2 Old 10th Sep 2011 at 8:34 AM
Is it for an earthquake, meteor crater or something? This is just a guess, but I would think setfloorcutout cuts out the ground and returns the ID of the cutout object (in-game ID not OBJD IID) and then remove targets that particular instance and removes it.

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Eminence Grise
Original Poster
#3 Old 11th Sep 2011 at 10:12 PM
Sounds like a good guess.. I wasn't able to make the cheats do anything though. If they do what it seems like they should do, they would be very useful, but I'm not finding any success stories.

I'm just gonna mark these as "unknown" unless anybody comes up with more specific infos
dodgy builder
12th Sep 2011 at 9:09 AM
This message has been deleted by Volvenom.
One horse disagreer of the Apocalypse
#4 Old 12th Sep 2011 at 11:12 AM
I can't actually find it mentioned in the code. All I have seen so far is:

public static void RegisterWorldCommands()
sWorldCommands = new CommandRegistry();
sWorldCommands.Register("kaching", "Adds $1000 to active household funds", CommandType.General, new CommandHandler(Commands.OnKaching), true);
sWorldCommands.Register("motherlode", "Adds $50000 to active household funds", CommandType.General, new CommandHandler(Commands.OnMotherlode), true);
sWorldCommands.Register("enablellamas", "Usage: enableLlamas [on|off]", CommandType.General, new CommandHandler(Commands.OnLlamasEnabled));
sWorldCommands.Register("hideHeadlineEffects", "Usage: hideHeadlineEffects [on|off]. Shows or hides talk/thought balloons above Sim heads", CommandType.General, new CommandHandler(Commands.OnHeadlineEffectsToggle));
sWorldCommands.Register("resetDnP", "resets the dreams and promises manager of the currently selected sim, using -all will reset all sims in current house's DnP managers", CommandType.Debug, new CommandHandler(Commands.OnResetDnP));
sWorldCommands.Register("resetSim", "Usage: resetSim <firstname> <lastname>. Returns Sim to a safe, neutral state at their home location", CommandType.General, new CommandHandler(Commands.ResetSim));
sWorldCommands.Register("DiscoTags", "Turns disco maptags on/off", CommandType.General, new CommandHandler(Commands.OnDiscoTags));
sWorldCommands.Register("familyFunds", "Usage: familyFunds <household_name> <amount>. Sets family funds of named household", CommandType.Cheat, new CommandHandler(Commands.OnFamilyFunds));
sWorldCommands.Register("speed", "Usage: speed <0-4>. Sets game speed. 0 = paused, 4 = ultra speed through current action", CommandType.Cheat, new CommandHandler(Commands.OnSpeedCommand));
sWorldCommands.Register("ageuptonpc", "Usage: ageUpToNPC. Toggles option for toddler who is aging up to be a non-player-controlled Sim in the household", CommandType.Cheat, new CommandHandler(Commands.OnAgeUpToNpc));
sWorldCommands.Register("maptags", "Usage: mapTags [on|off]. Toggles map tags on and off. This is most noticeable in Map View", CommandType.Cheat, new CommandHandler(Commands.OnMapTags));
sWorldCommands.Register("cleanhouseholds", "Cleans up non-instantiated Sims in all households (except for the Service household)", CommandType.Debug, new CommandHandler(Commands.OnCleanHouseholds));
sWorldCommands.Register("piemenu", "piemenu [head|fail|types] [on|off]: toggle pie menu head, display of all failure reasons, or definition class names", CommandType.Debug, new CommandHandler(Commands.OnPieMenu));
sWorldCommands.Register("lifetimehappiness", "Adds 50000 spendable lifetime happiness points to the selected sim.", CommandType.Debug, new CommandHandler(Commands.OnLifetimeHappiness));
sWorldCommands.Register("lookat", "only [on/off] - only run lookats for the actor currently selected. scores [on/off] - display lookat scores", CommandType.Debug, new CommandHandler(Commands.OnLookAt));
sWorldCommands.Register("killplantableobjects", "Deletes all ingredients and plantable non-ingredients in the world.", CommandType.Debug, new CommandHandler(Commands.OnKillPlantableObjects));
sWorldCommands.Register("refreshmotives", "Refreshes motives if they have got corrupted", CommandType.Debug, new CommandHandler(Commands.OnRefreshMotives));
sWorldCommands.Register("refreshhouseholdthumbnails", "[s,m,l,xl,all] Refreshes all of the world's household thumbnails", CommandType.Debug, new CommandHandler(Commands.OnRefreshHouseholdThumbnails));
sWorldCommands.Register("refreshlotthumbnails", "[s,m,l,xl,all] [roof] Refreshes all of the world's lot thumbnails", CommandType.Debug, new CommandHandler(Commands.OnRefreshLotThumbnails));
sWorldCommands.Register("refreshsimthumbnails", "[s,m,l,xl,all] Refreshes all of the world's sim thumbnails", CommandType.Debug, new CommandHandler(Commands.OnRefreshSimThumbnails));
sWorldCommands.Register("sacsdump", "dump managed sacs data", CommandType.Debug, new CommandHandler(Commands.OnSacsDump));
sWorldCommands.Register("playobjectsound", "Plays the given audio clip as a positional sound on the active Sim", CommandType.Debug, new CommandHandler(Commands.OnPlayObjectSound));
sWorldCommands.Register("stopobjectsounds", "Kills all object sounds started by playobjectsound", CommandType.Debug, new CommandHandler(Commands.OnStopObjectSounds));
sWorldCommands.Register("esrbchecks", "[all|clothing|children] [on|off] turns periodic ESRB violation checks on or off. Assumes all if type omitted. Toggles if on/off omitted.", CommandType.Debug, new CommandHandler(Commands.OnEsrbChecks));
sWorldCommands.Register("loginteractions", "Logs all interactions on all Sims to the InteractionQueue channel.", CommandType.Debug, new CommandHandler(Commands.OnLogInteractions));
sWorldCommands.Register("findsimwithoutfit", "[instanceId] Finds Sim with given outfit", CommandType.Debug, new CommandHandler(Commands.OnFindSimWithOutfit));
sWorldCommands.Register("showbroadcast", "Toggles debug draw of all gameplay broadcasters. Usage: showbroadcast", CommandType.Debug, new CommandHandler(Commands.OnBroadcastDebug));
sWorldCommands.Register("showwalkdist", "Toggles debug draw of walk style ranges. Usage: showwalkdist", CommandType.Debug, new CommandHandler(Commands.OnWalkStyleDebug));
sWorldCommands.Register("zoom", "Camera zooms to the specified object id.", CommandType.Debug, new CommandHandler(Commands.OnCameraZoom));
sWorldCommands.Register("storyprogression", "Sets the story progression mode. Usage: storyprogression <Disabled|Enabled|Accelerated>", CommandType.Debug, new CommandHandler(Commands.OnStoryProgression));
sWorldCommands.Register("meta", "Toggles debug display of meta/local (for autonomy debugging). Usage: meta", CommandType.Debug, new CommandHandler(Commands.OnShowMetaAutonomyCommand));
sWorldCommands.Register("debuglots", "Toggles debug display of lots (for meta-autonomy debugging). Usage: debuglots", CommandType.Debug, new CommandHandler(Commands.OnDebugLots));
sWorldCommands.Register("worldbuilderimport", "Imports character data from a spreadsheet that is passed in as the first parameter", CommandType.Debug, new CommandHandler(Commands.WorldBuilderImport));
sWorldCommands.Register("worldbuilderoutput", "Will output the information about the current world needed for the worldbuilder spreadsheet", CommandType.Debug, new CommandHandler(Commands.WorldBuilderOutputInfo));
sWorldCommands.Register("nukecruftysims", "As long as you have a CharacterImport.xml resource loaded, this cheat ensures that the number of sims and households in the world are consistent with the xml.", CommandType.Debug, new CommandHandler(Commands.NukeCruftySims));
sWorldCommands.Register("SaveUniform", "Saves out parts of the current outfit", CommandType.Debug, new CommandHandler(CASController.OnSaveUniformCommand));
sWorldCommands.Register("LoadUniform", "Overlay current sim with named uniform", CommandType.Debug, new CommandHandler(CASController.OnLoadUniformCommand));
sWorldCommands.Register("DeleteAllObjects", "Deletes objs of given type. Use: DeleteAllObjects [FullTypeName,Assembly] Ex:DeleteAllObjects Sims3.Gameplay.Objects.Toys.Football,Sims3GameplayObjects", CommandType.Debug, new CommandHandler(Commands.OnDeleteAllObjects));
sWorldCommands.Register("exterminate", "Kills <count> random Sims.", CommandType.Debug, new CommandHandler(Commands.OnExterminate));
sWorldCommands.Register("spawn", "Creates <count> random Sims.", CommandType.Debug, new CommandHandler(Commands.OnSpawn));
sWorldCommands.Register("debugSocial", "true/false turns social debugging on and off", CommandType.Debug, new CommandHandler(Conversation.OnDebugSocialCommand));
sWorldCommands.Register("killobject", "Deletes a game object. Usage: killobject <object id>", CommandType.Debug, new CommandHandler(Commands.OnKillObject));
sWorldCommands.Register("routedebuglog", "Toggles the route debug log on/off. You can also turn it off or on explictly by passing parameter \"on\" or \"off\". Usage: routedebuglog [\"on\" or \"off\"]", CommandType.Debug, new CommandHandler(Commands.OnRouteDebugLog));
sWorldCommands.Register("DisplayLotPackageFileName", "on/off - switches lot tooltips on and off", CommandType.Debug, new CommandHandler(LotManager.OnLotTooltipsCommand));
sWorldCommands.Register("money", "Sets family funds of the selected Sim. Usage: 'money' gives $1000000, 'money <number>' gives $number.", CommandType.Debug, new CommandHandler(Commands.OnMoney));
sWorldCommands.Register("purgegenealogy", "Purges distant genealogy relations", CommandType.Debug, new CommandHandler(Commands.OnPurgeDistantGenealogyRelations));
sWorldCommands.Register("logobjects", "Logs all objects on the current or specified lot. Usage: logobjects [lot]", CommandType.Debug, new CommandHandler(Commands.OnLogObjectsOnLot));
sWorldCommands.Register("stressreset", "Stresses resetting an object. Usage: stressreset [objectId]", CommandType.Debug, new CommandHandler(Commands.OnStressReset));
sWorldCommands.Register("resetservicenpctraits", "Iterates through the current service NPC sims and resets their traits. Usage: resetservicenpctraits", CommandType.Debug, new CommandHandler(Commands.OnServiceNpcTraitReset));
sWorldCommands.Register("babyboom", "Adds a baby and a toddler to every household in the world.", CommandType.Debug, new CommandHandler(Commands.OnBabyBoom));
sWorldCommands.Register("interactioninfo", "Adds interactioninformation to queue and Sim mouseover text.", CommandType.Debug, new CommandHandler(Commands.OnInteractionInfo));
sWorldCommands.Register("BuildBuyEnabledForLot", "enables build buy for the current active lot or specified lot. Usage: BuildBuyEnabledForLot [true/false][lot-Optional]", CommandType.Debug, new CommandHandler(Commands.OnBuildBuyEnabledForLot));
sWorldCommands.Register("ancientCoinCount", "Sets family ancient count total. Usage: 'ancientCoinCount' displays current amount, 'ancientCointCOunt <number>' gives $number.", CommandType.Debug, new CommandHandler(Commands.OnAncientCointCount));
sWorldCommands.Register("worldname", "Overrides world name. Usage: worldname [" + ParserFunctions.MakeCommaSeparatedList(Enum.GetNames(typeof(WorldName))).Replace("Undefined", "off") + "]", CommandType.Debug, new CommandHandler(Commands.OnWorldName));
sWorldCommands.Register("visalevel", "Sets the visa level for the current world. Usage: 'visalevel' displays current visa level, 'visalevel <WorldName - Optional><number>' sets $number as the visa level for the current world or specified world(optional).", CommandType.Debug, new CommandHandler(Commands.OnVisaLevel));
sWorldCommands.Register("lights", "Sets light intensities. Usage: 'lights [all|outdoor] [intensity]'.", CommandType.Debug, new CommandHandler(Commands.OnLights));
sWorldCommands.Register("visaPoints", "Sets the visa point for the current world. Usage: 'visapoints <WorldName - Optional><number>' sets $number as the visa points for the current world or specified world(optional).", CommandType.Debug, new CommandHandler(Commands.OnVisaPoints));
sWorldCommands.Register("cleanUpNectarBottles", "Meant to be run from world builder- destroys all nectar bottles that are in inventories", CommandType.Debug, new CommandHandler(Commands.CleanUpNectarBottles));
sWorldCommands.Register("removeallpuddles", "Removes all puddles in the world", CommandType.Debug, new CommandHandler(Commands.OnCleanupAllPuddles));
sWorldCommands.Register("togglelotlocalizationkeys", "When toggled to true, this displays the localization keys for the lot's name, address and description in the EditTownInfoPanel that you see after clickign the Map tag.", CommandType.Debug, new CommandHandler(Commands.OnToggleLotLocalizationKeys));
sWorldCommands.Register("givexptooccupation", "If there is an active sim xp will be given to the sim. Usage: 'givexptocareer <number>", CommandType.Debug, new CommandHandler(Commands.OnTryToAddXpToOccupation));
sWorldCommands.Register("zoomToSim", "If we can find the sim with the given Id in the world, the camera will zoom to the sim. Usage: 'zoomToSim <SimDescriptionId>", CommandType.Debug, new CommandHandler(Commands.OnCameraZoomToSim));
sWorldCommands.Register("ensureServiceNpcOutfits", "Iterates through the current service NPC sims and ensures that they have the appropriate uniforms. It'll skip Grim reaper and FakeMataAutonomy services. Usage: ensureServiceNpcOutfits", CommandType.Debug, new CommandHandler(Commands.OnServiceNpcEnsureOutfits));
sWorldCommands.Register("forceSetCelebrityLevel", "For all the possible sims in the world, we set their celebrity level to the provided level (if they can be celebrities). Usage: 'forceSetCelebrityLevel <level>", CommandType.Debug, new CommandHandler(Commands.OnForceSetCelebrityLevel));
sWorldCommands.Register("displayCelebrityLevelHistogram", "This outputs the distribution of sim counts for individual celebrity level. Usage: 'displayCelebrityLevelHistogram", CommandType.Debug, new CommandHandler(Commands.OnDisplayCelebrityLevelHistogram));
sWorldCommands.Register("displayVampireStats", "This outputs the current vampire population stats. Usage: 'displayVampireStats", CommandType.Debug, new CommandHandler(Commands.OnDisplayVampireStats));
sWorldCommands.Register("forceElders", "This populates any empty lots with households of 8 elders. Usage: 'displayCelebrityLevelHistogram", CommandType.Debug, new CommandHandler(Commands.OnForceElders));
sWorldCommands.Register("forceAddPlayedGigs", "This add gigs played to current sim. Sim must be in a band already Usage: 'forceAddPlayedGigs <int>", CommandType.Debug, new CommandHandler(Commands.OnForceAddPlayedGigs));
sWorldCommands.Register("tryStartNpcParty", "Usage: 'tryStartNpcParty <OutfitStyle> <bool>, Try to start an Npc party 5 hours from now valid OutfitStyle (Everyday, Formal, Swimwear) bool is optional wheather it is a celebrity inviting you for your great party", CommandType.Debug, new CommandHandler(Commands.OnTryStartNpcParty));
sWorldCommands.Register("generateObjectStatisticsOnLots", "Usage: 'generateObjectStatisticsOnLots'. For the given world, we'll iterate on the lots and display the object counts.", CommandType.Debug, new CommandHandler(Commands.OnGenerateObjectStatisticsOnLots));


public static void RegisterGameCommands()
sGameCommands = new CommandRegistry();
sGameCommands.Register("testingCheatsEnabled", "Usage: testingCheatsEnabled [true|false]. Enables/disables testing cheats.", CommandType.General, new CommandHandler(Commands.OnTestingCheats), true);
sGameCommands.Register("SaveSimAsLooseFile", "Sets the save sim mode. Usage: SaveSimAsLooseFile [true|false] or [1|0] (default is false)", CommandType.Debug, new CommandHandler(Commands.OnSetSaveSimMode));
sGameCommands.Register("ExportAsEAContent", "Exports content as EA content. Usage: ExportAsEAContent [true|false] or [1|0] (default is false)", CommandType.Debug, new CommandHandler(Commands.OnSetEAExportMode));
sGameCommands.Register("ExportAsPaidContent", "Exports content as Paid content. Usage: ExportAsPaidContent [true|false] or [1|0] (default is true)", CommandType.Debug, new CommandHandler(Commands.OnSetEAExportModeAsPaidContent));
sGameCommands.Register("ShowInteractions", "Shows the names of the interactions above all the Sims' heads", CommandType.Debug, new CommandHandler(Commands.OnShowInteractions));
sGameCommands.Register("Select", "Select a particular sim", CommandType.Debug, new CommandHandler(Commands.OnSelectSim));
sGameCommands.Register("quit", "Exits the game", CommandType.General, new CommandHandler(Commands.OnQuitGame));
sGameCommands.Register("RefreshDnP", "Re-loads static Dreams and Promises data", CommandType.Debug, new CommandHandler(Commands.OnRefreshDreamsAndPromises));
sGameCommands.Register("DnPOutputPrimitives", "outputs all DnP primitives so that they can be pasted into the dreamNames enum", CommandType.Debug, new CommandHandler(Commands.OnOutputDnPPrimitives));
sGameCommands.Register("AssertOnRetestingDnPNodes", "Sets the game to assert if the DnP System removes a node when it retests the visible ones", CommandType.Debug, new CommandHandler(Commands.OnSetDnPRetestAssert));
sGameCommands.Register("AssertOnDnPRefProblems", "Asserts when there are problems (duplicates) in the DnP reference List", CommandType.Debug, new CommandHandler(Commands.OnSetDnPReferenceListAssert));
sGameCommands.Register("ToggleStringId", "Shows the string key after localized text", CommandType.Debug, new CommandHandler(Commands.OnToggleStringID));
sGameCommands.Register("TriggerShareTutorial", "Triggers the sharing tutorialette", CommandType.Debug, new CommandHandler(Commands.OnTriggerSharingTutorial));
sGameCommands.Register("RefreshOpportunities", "Re-loads static opportunities data", CommandType.Debug, new CommandHandler(Commands.OnRefreshOpportuniites));
sGameCommands.Register("SetHouseholdName", "Sets the localization key for the active household's name", CommandType.Debug, new CommandHandler(Commands.OnSetHouseholdName));
sGameCommands.Register("SetHouseholdDescription", "Sets the localization key for the active household's description", CommandType.Debug, new CommandHandler(Commands.OnSetHouseholdDescription));
sGameCommands.Register("ResetLifetimeHappiness", "Resets the lifetime happiness of all the sims in the active household", CommandType.Debug, new CommandHandler(Commands.OnResetLifetimeHappiness), true);
sGameCommands.Register("dialogs", "Usage: dialogs [on|off]. Enables/disables dialogs, for soak testing.", CommandType.Debug, new CommandHandler(Commands.OnDialogs));
sGameCommands.Register("spawnerwarnings", "Usage: spawnerwarnings [on|off]. Enables/disables 'spawned object proximity warning' dialogs.", CommandType.Debug, new CommandHandler(Commands.OnSpawnerWarnings));
sGameCommands.Register("jokePlease", "Prints a random joke to the console", CommandType.General, null);
sGameCommands.Register("BuyDebug", "Usage: buydebug [on|off]. Makes debug objects available for placement in buy mode", CommandType.Cheat, new CommandHandler(Commands.OnBuyDebug));
sGameCommands.Register("RestrictBuildBuyInBuildings", "Usage: RestrictBuildBuyInBuildings [on|off]. Removes restrictions for build/buy in buildings", CommandType.Cheat, new CommandHandler(Commands.OnRestrictBuildBuyInBuildingsCheat));
sGameCommands.Register("EnableLotLocking", "enables toggling lot locking in the Edit Town Info Panel. Usage: EnableLotLocking [true/false]", CommandType.Cheat, new CommandHandler(Commands.OnLotLockingEnabled));
sGameCommands.Register("AlwaysAllowBuildBuy", "When enabled, build mode and buy mode won't disable themselves during fires and burglary. Usage: AlwaysAllowBuildBuy [true/false]", CommandType.Cheat, new CommandHandler(Commands.OnAlwaysAllowBuildBuy));
sGameCommands.Register("traffic", "When turned off, the traffic manager doesn't simulate. Usage Traffic: [on/off]", CommandType.Debug, new CommandHandler(Commands.OnTraffic));
if (CommandLine.FindSwitch("editingamemode") != null)
sGameCommands.Register("moviemakercheatsenabled", "Usage: moviemakercheatsenabled [true|false]. Allows the use of movie maker cheats.", CommandType.Cheat, new CommandHandler(Commands.OnMovieMakerCheats));

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Eminence Grise
Original Poster
#5 Old 13th Sep 2011 at 1:53 AM
Thanks Inge.

The reason this cheat turns up in so many lists of cheats (including the one in the MTS wiki) is that it's one of those listed when you type "help" in the console to get a list of commands. That's where the parameter list comes from.

But if the code Inge pasted is everything relating to cheats, then I guess either they never implemented it or they implemented it and then removed it.

Or maybe it's a CAW cheat? I'm told some CAW code got into the game when they implemented lot addition, and that happened with the Ambitions patch... which is when this cheat was introduced...
One horse disagreer of the Apocalypse
#6 Old 13th Sep 2011 at 7:57 AM
well I did also search reflector for "floor" and "cutout" and only got the fireman pole. So my analysis may not be all that definitive. Also it may translate to something else, via some gameplay xml.

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Test Subject
#7 Old 23rd Jan 2012 at 4:57 PM
Has anybody figured this "FloorCutout" cheat yet? Is there a way to see coordinates for areas on the building lot?
#8 Old 17th Apr 2013 at 2:56 PM
I'm pretty sure I know what it does but I still don't know how to do it! ;-) If you have the University Life expansion you will notice such a (presumed) floor cutout was used on the Gym lot. There are stairs leading down to the basement but there is a bigger floor cutout around these stairs than you would get by simply placing stairs. Basically, you get the very nice effect of an open basement which I haven't figured out how to achieve yet.

Edit: Currently looking at this old TS2 thread ->

Maybe it will help me figure this out. I want floor cutouts, EAxis! *shakes fist*
mature minion
retired moderator
#9 Old 18th Apr 2013 at 9:30 AM
Originally Posted by Rockerduck
I'm pretty sure I know what it does but I still don't know how to do it! ;-) If you have the University Life expansion you will notice such a (presumed) floor cutout was used on the Gym lot. There are stairs leading down to the basement but there is a bigger floor cutout around these stairs than you would get by simply placing stairs. Basically, you get the very nice effect of an open basement which I haven't figured out how to achieve yet.

Edit: Currently looking at this old TS2 thread ->

Maybe it will help me figure this out. I want floor cutouts, EAxis! *shakes fist*

We've known how to create basement cut-outs for a while using foundations and stairs as shown nicely here in post number 6 I think it is -

Hope that helps rockerduck
#10 Old 3rd May 2013 at 8:15 AM
Originally Posted by Tee Hee Hee
We've known how to create basement cut-outs for a while using foundations and stairs as shown nicely here in post number 6 I think it is -

Hope that helps rockerduck

Ah, thanks for that! The floor cut-outs still boggle my mind, though. Someone at EAxis apparently went on a spree with University lots as I've noticed several more cut-outs on various lots. It would seem that they used zonaxzynaphynx's method (deleting stairs) as well, though - as their cut-outs look exactly like the images in the other post, and the cut-out floor tiles remain holes in the floor forever, too! ;-)
mature minion
retired moderator
#11 Old 6th May 2013 at 10:21 AM
The floor "cutouts" are a fun way of making incredible architecture, I used it to make the partially submerged guest house in my lot the ephemeral, and the entire house in secluded cabin is sunken into the ground using this technique; I'm sure there are plenty of other applications for it. It is rather annoying that this cheat doesn't allow us a shortcut to creating cutouts though as it is a little bit tedious and fiddly creating them using the foundation and stairs technique.
Back to top