Use this implementation checklist:
Runtime command policy for this repo:
- •Do not use
npm run build/npm testto validate the Empirica app. - •Only install dependencies with
npm installinclient/andserver/. - •Start and run the app with
empiricafrom repository root. - •If a full integration build check is needed, run
empirica bundlefrom repository root.
- •Confirm relevant Empirica references before editing:
- •docs: https://docs.empirica.ly/
- •framework repo: https://github.com/empiricaly/empirica
- •docs repo: https://github.com/empiricaly/docsv2
- •project reference map:
schema/empirica-reference.jsonif present 0.5 Configure required admin auth placeholders before implementation/testing: - •open
.empirica/empirica.toml - •replace
CHANGE_ME_SRTOKENandCHANGE_ME_PASSWORDwith real values - •use those configured admin credentials consistently in automation/test commands
Generalizable implementation defaults:
- •Preserve lifecycle semantics: intro/exit are asynchronous; rounds/stages are synchronous.
- •Keep scope boundaries strict: game/player/round/stage attributes should be intentional and documented.
- •For async writes outside lifecycle callbacks (intervals, API callbacks, workers), call
await Empirica.flush()afterset(...). - •Load env before callback module initialization (dotenv first, then import callbacks) when top-level env reads exist.
- •Prefer stable, explicit shared-state keys for UI/server coordination; avoid implicit state coupling.
- •
Before coding, present the UI plan to the researcher:
- •show proposed participant screens by stage
- •call out interactions and where each decision is saved (
player.stage,player.round, etc.) - •request explicit feedback before implementation
- •
Translate experiment design into Empirica config:
- •update
.empirica/treatments.yaml - •update
.empirica/lobbies.yaml - •include an admin-run plan that states expected batch and randomization setup
- •update
- •
Implement lifecycle logic in
server/src/callbacks.js:- •create rounds/stages in
onGameStart - •compute outcomes in
onStageEndedoronRoundEnded - •store all analytic variables with explicit keys
- •avoid silent defaults for missing critical values
- •if using async timers/workers/API responses, flush writes (
await Empirica.flush())
- •create rounds/stages in
- •
Implement player UI in
client/src:- •round/stage routing in
Stage.jsx - •task components in
client/src/task-designor new feature folders - •profile/summaries in
Profile.jsx - •intro/exit survey fields in
client/src/introandclient/src/exit - •wire intro/exit in Empirica-native way in
client/src/App.jsx:- •use
EmpiricaContextpropsconsent,introSteps,exitSteps - •provide intro/exit components as ordered arrays
- •keep each step as a focused React component under
client/src/introorclient/src/exit
- •use
- •round/stage routing in
- •
Keep schema keys synchronized across server and client:
- •every
get("key")should have a clear producerset("key") - •use stable, analysis-friendly key names and annotate each key with Empirica scope in final report
- •every
- •
Verify by running Empirica-native flow:
- •
empirica bundlefor integration build check - •then run autonomous test and screenshot workflow from the testing skill
- •ensure the autonomous run has strict completion criteria:
- •all simulated participants reach final exit
- •treatment-specific mechanics are exercised (not just nominal page traversal)
- •failures block "test passed" status until resolved
- •
Required output after coding:
- •list of touched files
- •list of new schema keys grouped by
game/player/round/stage - •intro/exit mapping summary:
- •consent component used
- •introSteps order
- •exitSteps order
- •Empirica references consulted
- •remaining assumptions or limits