Skip to content
AFM Studio
  • Pages

    AFM Studio
  • Work
  • Lab
  • About
  • CV
  • Contact
  • Projects

    AksaraA searchable library for Otorita IKN's knowledge, where the server checks every reader's access across three levels
  • Daily TaqwaTamper-resistant prayer attendance system for ~2,000 OIKN government employees at Masjid Negara IKN
  • Lantara v2A permit engine for Otorita IKN where administrators add new permit types from a screen, without a developer
  • eKiosk IKNTwo control rooms for Nusantara: kiosk content management and live bus tracking with arrival times that grade themselves
  • E-Monev IKNA monitoring platform for Nusantara's 23-year build, tracking every unit's quarterly progress against 24 national KPIs
  • JDIH OIKNOIKN's public legal document portal, with a controlled publishing workflow and AI summaries that never leave the server
  • Jejak PenanamanA check-in app for IKN tree-planting events that proves each participant was on site with a geofenced selfie
  • Dashboard SAKTIA nightly pipeline and dashboard that replaces OIKN's manual budget downloads for all six of its budget units
  • DoseRxA bedside dose calculator for 127 drugs that rounds each dose to tablets and syrups Indonesian pharmacies sell
  • CubiqA speedcubing trainer with competition-grade timing and a solver I wrote for each of the 8 major puzzles
  • ScimotionAn interactive science library of 86 articles, each explained next to animations the reader can control
  • WA Daily Scrum BotA WhatsApp bot that chases missing standup reports for a 14-person team and flags tasks stuck for days

↑ ↓ to move · Enter to open · Esc to close

Rumah Adat Nusantara

A collection of 35 traditional Indonesian buildings computed from their cultural rules, each showing how much is documented

Screenshots
buildings, each generated from its own rules
35
pages across four views and two languages
280
of dimensions from a measured survey, shown openly
0%
network calls, works with wifi off
0
On this page

The problem

Most Indonesians meet rumah adat, the traditional houses, as a list to memorise for a school exam: a name, a province, a picture of a roof. Nothing in that explains why the roof has that shape. The knowledge exists in ethnographies, provincial survey volumes and architectural monographs. But it is scattered, mostly untranslated, and written for specialists.

The usual digital answer, a photorealistic 3D model, makes this worse in a quiet way. A smooth render states every dimension with full confidence, including the ones nobody has ever measured.

I built Rumah Adat Nusantara for a curious Indonesian reader on a phone, in Indonesian first. It also serves architecture and anthropology students and teachers who want the logic and the citations, and will check them.

What I built

Each building is computed from its cultural rules

Every building is generated from the rules that govern it: a household's rank, the number of families under one roof, a room count, the length of the owner's forearm. Change one of those numbers and the structure rebuilds in front of you. There is no roof-curve slider, because a roof shape is a result. The controls only offer things a household would say about itself. I wrote every post, rafter and joint as plain arithmetic, with no CAD imports or modelling libraries.

I grew the shared core only from repeated patterns

A shared core holds what is true of any building: parts, joints, build order, symmetry and sources. Everything cultural stays with the building it belongs to. Nothing moves into the core until two buildings have needed it independently, because an abstraction built from one example takes that example's shape. I chose the Minangkabau rumah gadang as the second building because it would break things: its ridge runs the other way and it is asymmetric. Tests fail the build if the core names a tradition.

Every dimension says where it came from

Each dimension is labelled measured, canon or interpolated, with a source. A source page lists every dimension with its citation and how much the house changes if that number moves. I never average figures across two buildings, because that would let an unsurveyed building hide behind a surveyed one. Each building also has a caution that states its simplifications. Today no dimension in any building is measured, and a bar on every screen shows that split.

Every picture comes from the model

Landing silhouettes, catalogue plates, exported drawings and all 70 share cards are computed from the same parts the tests check. CI compares them pixel by pixel against the generator, so an illustration can't disagree with the model. The sun is computed too. Each building has its actual site, and the scene shows the actual sun over that site on the chosen date.

Buildings sit side by side and never morph

A comparison page places any two buildings on one ground line at one scale. I don't morph one tradition into another, because that would assert a continuity that doesn't exist. Motion is limited to five animations that each show a mechanism, such as the frame going up joint by joint or rain running off the roof. Nothing spins for decoration.

Result

Rumah Adat Nusantara is live and public in Indonesian and English. It has 35 buildings: 26 houses, two granaries, three halls, a palace, a houseboat, a stone tomb, a cremation tower, a nine-building compound and a pair of ancestor shrines. Their sites span three time zones. Each building has four pages, 280 in total, and its own structural checks run over at least five rule combinations. A failing check stops the release. The site has no backend and makes no network calls, so it works with wifi off. I built it in eight days, from 25 August to 1 September 2026.

Under the hoodTechnical detail for engineers
  • buildHouse(rules) is pure and deterministic: rules in, parts and joints out. lib/ may not touch three.js, the DOM, Math.random or the clock; components/ generates nothing; the app layer doesn't know which building it holds.
  • lib/core/ (~3,200 lines) is generic over each tradition's vocabulary, so a Minangkabau part can't claim a Toraja construction stage and still type-check. Tests fail if the core names a tradition or one tradition imports another.
  • Provenance classes are measured, canon and interpolated. checkAgainstSurvey permanently reports skipped. An audit of hardcoded dimensions raised the interpolated share, and the higher number shipped.
  • Examples: the Toraja tongkonan at 155 parts and 33 joints, the Banjar rumah bubungan tinggi at 318 parts, the Arfak house whose 168 legs each lean by a hash of their grid position.
  • Routes per building: /bangun (generator), /rakit (frame-raising), /baca (sun, rain, section, site plan), /sumber (citations and sensitivity). /banding compares two buildings.
  • Each building's caution states its limits. The Orang Rimba sudung's, for example, says the Orang Rimba are living people in a forest that is shrinking, and this is not a record of the past.
  • Sources include Waterson, The Living House (1990) and the Departemen P&K architecture survey volumes. Where a carving vocabulary belongs to particular carvers, the pack shows none instead of inventing members of it.
  • URL: the path is the building, the query string is that house in the tradition's own parameter names, the fragment is camera, date and time. The old names Tongkonan and Pasak still resolve and redirect.
  • NOAA solar position implemented by hand and validated against almanac values. Sites span 5.6° N (Banda Aceh) to 10.5° S (Seba), 95.3° E to 140.7° E (Jayapura).
  • three.js is the one deliberate exception, used only to rasterise meshes the project generated. A hand-written PNG rasteriser and stroke alphabet produce the 70 share cards. Natural Earth coastline is vendored, never fetched.
  • Lessons: a green build still shipped a route that threw on load (string-keyed materials), and a roof passed all sixteen checks while looking wrong. Both led to general tests, including checkRoofFollowsSection. Four checks once only restated their input and were rebuilt on independent numbers.
  • Dynamic imports per building cut first load from 579 KB to ~262 KB. Ambient occlusion is still a radial-gradient contact plane.
  • Four runtime dependencies (next, react, react-dom, three). 365 exported HTML files.
  • 1,770 tests in 58 files. ~96,600 lines, of which the 35 rule packs are ~65,200. 210 commits, 61 on the busiest day.

Screenshots

Beranda
Tapak Nusantara
List of Rumah
Rumah Detail
Bangun Rumah
Urai Rumah

Hiring, or building something similar?

I'm open to full-time roles and select freelance work.