Potrero is a 3D soccer tennis game: send the ball over the net and make your opponent miss the return. An Argentine neighborhood court, short matches, and no download.
A match, then one more
Play against the CPU without creating an account. Learn in the tutorial, practice freely, or explore the barrio to meet and challenge its players.
Save a spot for a friend
In the closed beta, online play uses an account and an invitation to a private room. Share the code, wait for your opponent, and both mark yourselves ready. The beta is for adults aged 18 and over.
From a browser court to a neighborhood you can walk through. The stages, the decisions connecting them and what needed correcting along the way.
The history, decisions and evidence are explained right here. Rerun historical images are identified by revision and date; they use historical code with current local tools. Figures belong to their respective stages.
The project starts as a browser football-tennis prototype. The first fixes focus on getting the scene to load and render.
The decision
The chosen foundation was Vite, React and Three.js. The record preserves that technical choice, but does not document a comparison with other engines.
What changed
A first implementation provides a starting point for iteration. It is still a long way from today’s neighborhood.
Historical rerun · 2025-03-15 · 97097eb. The green court, net and minimal score are visible; there is no neighborhood environment yet.
Read the decisions and corrections in detail
The first fixes resolve imports and texture configuration. This capture reruns revision 97097eb from 15 March 2025 on 8 September 2026, using Cannon 6.6.0 and the other current local tools. It preserves that revision’s application code.
What the records establish
First implementation
The first scene contains a court, net, ball and scoreboard. Its menu starts a match and lists movement, jump and kick controls. This is the minimal foundation visible in the recreation.
c1fac16 · 2025-03-15
Startup fix
The fix adds the missing Three.js reference in the court. This later revision from the same day is the one we could rerun and capture.
The engine and interface are reworked. Charged power, manual aim and successive fixes to diagonal serves and bounce rules arrive.
The decision
Power and direction controls are introduced alongside serve restrictions. The commits describe these changes, but do not record a more specific product rationale.
What changed
The prototype gains a gameplay vocabulary: aim, charge, release and respect the serving quadrant.
Historical rerun · 2026-08-27 · b3595fe. The HUD now shows diagonal serving, attempts and power; figures and surroundings remain simple.
Read the decisions and corrections in detail
This stage includes the 11 August engine rework, charging on the 15th and later serve and aim adjustments. Rules would continue to evolve; this is not a rules certification for the current version. The capture was rerun on 8 September 2026; it is neither an image archived on the original date nor a new full test of that version.
What the records establish
Engine and interface
The history records an engine and interface rework. Later August changes build on it; no assessment of alternative engines is documented.
0ab4460 · 2026-08-11
Power and aim
Charged strikes and shot aiming are introduced. In the captured version, the HUD explains holding K to prepare a power shot.
cdff8ac · 2026-08-15
Manual aim adjustment
Shot direction gains manual adjustment. This revision’s capture shows the serve quadrant, available attempts and controls beside a court that still has no neighborhood.
Neon Court adds private online matches and later takes the name Sonnies. Reconnection, analog controls and rendering on modest devices improve.
The decision
Input sampling is separated from rendered frames: a rendering slowdown should not determine when input is read.
What changed
There is now a flow for playing another person, with explicit work on connections and shared state.
Historical rerun · 2026-08-28 · 173ef50. The stadium era: stands, ads and spectator shapes. This image shows solo play in the version that added online.Historical rerun · The August 2026 menu adds Play online alongside local modes.
Read the decisions and corrections in detail
Changes cover private rooms, rejoining, point attribution and smoother controls. These are foundations of the online architecture, not a claim about servers deployed today. The capture was rerun on 8 September 2026; it is neither an image archived on the original date nor a new full test of that version.
What the records establish
First multiplayer
A private online match flow is added, with a lobby and shared state. The menu image shows its entry point; the court image is solo play in that same version, not a historical connection test.
65a4853 · 2026-08-28
Input independent of rendering
Input is no longer sampled only when a frame is drawn. That separation keeps control independent of the visual frame rate.
39136ad · 2026-08-28
Rooms and reconnection
Room joining and match rejoining are hardened. The change aims to recover shared state after an interruption rather than create a different match.
The scene adopts dirt, sheet metal, brick and afternoon light. Sonnies becomes Potrero; athletes and cheering neighbors begin to give it a human scale.
The decision
The identity change keeps cyan and coral team accents so players and the ball remain easy to distinguish. The HUD adapts to the limited height of landscape phones.
What changed
The game becomes recognizable through its neighborhood, with seated spectators and presentation designed for touch too.
Historical rerun · 2026-09-04 · 4a36245. The athlete and crowds gain faces and team kits. Fencing and stands still occupy much of the frame.
Read the decisions and corrections in detail
The athlete passes through a KayKit variant and then a Kenney animated character. The first environment change hid the backdrop on reduced quality; later work instead keeps buildings and simplifies their details. The capture was rerun on 8 September 2026; it is neither an image archived on the original date nor a new full test of that version.
What the records establish
Identity and mobile readability
The change introduces dirt, sheet metal, brick, dust and warm light. It also reduces HUD height on landscape phones to avoid covering play. Team colors are retained for readability.
19b94d3 · 2026-09-02
Sonnies → Potrero
Sonnies is replaced by Potrero in branding, palette and package names. This is the explicit identity change, separate from later environment improvements.
dafa2a9 · 2026-09-03
New athlete
The athlete becomes a Kenney animated character with team kits. Compared with the earlier geometric figures, the capture shows a recognizable head, arms, clothing and playing stance.
0b773ee · 2026-09-03
The two cheering sections
Spectators use the seated athlete and split into two cheering sections. The stadium’s small colored shapes become people with recognizable bodies and faces.
Body rebounds, ball control, stamina and CPU-versus-CPU matches arrive. The game adds Spanish and English alongside an online connection rework.
The decision
Trajectories are flattened and the CPU becomes more decisive to avoid endless exchanges. Prediction and interpolation aim to reduce perceived online jitter.
What changed
There are more gameplay and evaluation tools, plus a translated experience with a saved language preference.
Historical rerun · 2026-09-05 · 5564c27. The menu offers difficulty selection, CPU-versus-CPU viewing and switching between EN and ES.
Read the decisions and corrections in detail
Latency-based region selection and networking changes are documented in the connection PR. Its targets are not presented as current latency guarantees. Mechanics from this stage are historical and were refined later. The capture was rerun on 8 September 2026; it is neither an image archived on the original date nor a new full test of that version.
What the records establish
Mechanics and CPU versus CPU
Body rebounds, ball control, stamina and CPU versus CPU are added. The captured menu includes the option to watch both CPUs, supporting both observation and pace evaluation.
dd3da8e · 2026-09-05
Connection rework
Networking adds opponent interpolation, ball prediction and latency-based region selection. These mechanisms aim to reduce visible jumps and perceived delay; the captures do not measure historical latency.
ec633ca · 2026-09-05
Spanish and English
The interface is translated into Spanish and English and saves the selection. The menu’s EN and ES buttons show that this was already part of this revision.
Movement, ball physics and contacts share a 120 Hz simulation across solo, server and prediction. Foot and head contacts, running, jumping and the hand-toss serve are revised.
The decision
Strike animation stops blocking running. Contact zones are finite and serving follows a shared sequence, aligning what players see with what the game resolves.
What changed
In that stage’s measurements, reaching 90% speed drops from 175 to 116.7 ms. Serving adds a 400 ms toss before contact.
Historical rerun · 2026-09-06 · bfd9493. The camera rises, the HUD frees space and the serve starts with the ball in the hands.
Read the decisions and corrections in detail
Tests compare solo and authority, input at different frame rates and actual rig contacts. CPU simulations help measure pace and difficulty, but do not replace human playtests. The reports do not assign one day to this entire set of changes. The capture was rerun on 8 September 2026; it is neither an image archived on the original date nor a new full test of that version.
What the records establish
Physics and movement
Tests compare solo, server and prediction step by step, including position, velocity, contacts and points. Acceleration and braking are shortened for a more immediate response.
gameplay-evidence.md
Running through strikes
Running continues through strikes and between-point reactions. Full-body animation locks are replaced with shorter strike layers.
responsive-footwork.md
Hand-toss serve
Releasing K starts a 48-tick toss, equivalent to 400 ms. The serve moves from the hands to the right foot; an airborne player waits until landing.
serve-evidence.md
Jump pose
The jump changes from a wide static stance to relaxed shoulders, bent elbows and knees, and a landing transition. Contact layers retain priority.
The ball and players begin colliding with scenery. The first interpretation makes the last toucher lose, even after a legal bounce.
The decision
The rule is corrected: if the ball lands legally and the opponent does not return it before it reaches scenery, the attacker wins the point. A direct scenery hit remains out.
What changed
The difficulty regression passes again without retuning the CPU. In the documented corpus, Pro goes from 4/100 to 100/100 wins against Easy from the front side.
Later validation · Legal-bounce rule test in the current neighborhood, 8 September 2026. It illustrates the retained outcome, not the first implementation.
Read the decisions and corrections in detail
The change preserves serve validation and responsibility after touching a return. Checks also ensure a dead ball stops generating impacts, sounds or points. The comparison uses the same historical seeds and pairings.
What the records establish
First implementation and issue
The first rule of losing on every scenery hit caused a regression: a good deep shot could become a loss after bouncing legally and then hitting the wall.
scenery-evidence.md
Corrected rule and comparison
The same 800-match corpus is compared before and after. Respecting the legal bounce restores the expected Pro/Easy difference without CPU tuning. The outcome is expressed as a missed return.
The court is no longer the only scene. Players can walk, look around, talk to Luca, Mora and Tano, and accept their challenges.
The decision
Progression is built around meeting and beating the regulars, without currencies or lost progress after defeat. Exploration has its own controller; challenges return to the existing football-tennis game.
What changed
A first block brings together shops, pedestrians, children, spectators and ambient sound. Winning unlocks the next rival, and matches return players beside the person they challenged.
Historical rerun · 2026-09-06 · 3fc7e6d. The player is now outside the court: there is a street, shops and an objective to find Luca.
Read the decisions and corrections in detail
The Luca → Mora → Tano order and local progress are saved. Losing, abandoning or repeating an outcome grants no extra progress. Keyboard and touch share the route; later maps and dialogue retain portrait support. The capture was rerun on 8 September 2026; it is neither an image archived on the original date nor a new full test of that version.
What the records establish
The idea: earn a place
The idea is to arrive at a familiar court and earn a place by playing its regulars. Recognition and access to the next rival are the rewards, without currencies or penalties to earned progress.
neighborhood-design.md
First neighborhood delivery
The first block adds four pedestrians, three children and six seated spectators, plus shops and ambience. Challenges return players beside the rival and save the Luca → Mora → Tano order.
A connected district opens with homes, shops and plazas. The map guides players toward rivals, and 72 pedestrian routes bring activity to the streets.
The decision
The map marks a destination without teleporting. A shared catalog defines buildings and collisions; a bounded pool of nearby characters represents routes to contain the cost.
What changed
The neighborhood can now be crossed end to end. Render-dependent waits and input subscriptions are also corrected in browser tests.
Game capture · District before the material review, 8 September 2026.
Read the decisions and corrections in detail
The 72 routes use 24 nearby animated characters. Expansion raises rendering cost: the early data used software rendering and did not establish phone performance. The retained capture shows this district at the start of the 8 September visual review.
What the records establish
District design
The district is organized into 36 lots and 60 orthogonal connections. The map sets direction and distance; it does not move the player or start a challenge for them.
district-design.md
Delivery and rendering cost
Connectivity, clear crossings, entrances and return positions are checked. The first performance measurements use software rendering; they remain evidence of that test, not phone performance figures.
district-evidence.md
Browser stability
Tests stop assuming that elapsed milliseconds equal distance traveled. They wait for observed velocity, charge and frames, and input subscription timing is corrected when resuming play.
Dirt, plaster, wood, signage and afternoon light are reworked. A concept reference and three independent reviews guide corrections.
The decision
Textures are shared and static geometry is batched to add environment detail without inflating draw calls. Actual captures are evaluated separately from the concept target.
What changed
The third review reaches 5.6/10 against a target of 8. The report explicitly records the miss: the subsequent material pass receives no fourth independent score.
Generated concept image · Art-direction target; not a game screenshot.Game capture · Production material pass.
Read the decisions and corrections in detail
Overly uniform surfaces and simpler mobile depth remain. Generated artwork is identified in asset provenance. This historical assessment should not be confused with later reviews of the three courts or compact neighborhood.
What the records establish
Historical material report
The concept, three candidates, corrections and final captures are retained. The third review scores 5.6/10 and the report explicitly preserves the target of 8 as unmet.
previous-final-evidence.md
Third review
The critique identifies overly uniform wear and less mobile depth. A later pass strengthens materials, but is not assigned a new score it did not receive.
El Potrero, La Plaza and Club del Sur become playable courts. Luca, Mora and Tano each get a place with its own surface, surroundings and entrance.
The decision
The same playing area and rules are retained: dirt, concrete and club surfaces change visual identity, not bounce physics. Challenges use each venue and preserve progression order.
What changed
All three courts can be visited and played. The second visual review reaches 8/10 for this expansion, with improvements to entrances, wayfinding and returns after matches.
Game capture · Club del Sur in the three-court expansion.
Read the decisions and corrections in detail
Courts share a catalog of positions and collisions. Quick solo and online keep the original potrero. Videos traverse the connections with keyboard and touch; mobile performance remains measured in emulation.
What the records establish
Three-court gallery
The expansion records matches and entrances at the potrero, plaza and club, plus continuous keyboard and touch routes. The capture included here shows the club at that stage.
neighborhood-expansion-gallery.html
Expansion report
The 9 × 12.8 m playing area and ball physics are retained at all three venues. Surfaces and architecture change identity; quick and online matches keep the original court.
neighborhood-expansion-evidence.html
Visual review 2
The expansion’s second independent review reaches 8/10. This evaluates that delivery, not earlier versions retroactively.
Isolated houses give way to continuous frontages, interior courtyards and corner shops. The district reaches 249 buildings, with balconies, chamfered corners and more complete sidewalks.
The decision
Homes face the street and the richest detail sits near the courts. Buildings remain on reduced quality; details and shadows are simplified. A two-meter pedestrian strip stays clear.
What changed
The final review finds no major outstanding visual issues. Routes peak at 136/116 draw calls on desktop/emulated mobile, within the 300/150 limits.
Game capture · Grocery, bakery, kiosk and balcony in the current neighborhood.
Read the decisions and corrections in detail
Review caught and fixed blank side walls, invisible awning collisions and a selection rule that produced no balconies. The result has 25 balconies and 26 buildings with actual chamfered corners, derived from the same catalog as their collisions. 552 tests and 30 applicable browser cases passed. The 2.45/3 score covers only affected categories; physical phones remain unverified, with simple mobile trees and repeated facade modules still visible.
What the records establish
Compact neighborhood report
The final catalog contains 249 buildings, 25 balconies and 26 buildings with actual chamfered corners. All 99 existing assets retain their hashes and total 2,398,002 gzip bytes; no paid assets are added.
final-evidence.html
Independent review
Blank side walls, invisible awning collisions and a balcony rule that selected none are corrected. The final review leaves mobile trees and repeated modules as minor limitations.
compact-visual-review.html
Streets before and after
Comparisons start from matching positions and cameras. Continuous fronts replace isolated houses and dirt setbacks; crossings and entrances remain open.
Upcoming releases add their changes, decisions and outcomes to the history available inside the game.
The decision
Keep one Spanish and English record and require an update before publishing, so the history keeps pace with the game. This is an explicit request from the project creator.
What changed
Automated checks verify translations, local evidence and generated HTML. Deployment requires a new entry compared with the previous production revision.
Read the decisions and corrections in detail
The homepage reads the same JSON as the gallery and downloadable HTML. Regenerating history preserves earlier captures and videos and works without private walkthrough folders. This stage documents a publishing-process change.
What the records establish
A publishing requirement
The request was for every release to add to the changelog. Repository instructions, the PR template, CI and the AWS script incorporate that requirement; they do not generate reasons or dates from assumptions.
Publishing the game becomes part of the GitHub workflow: each merge to main runs the checks and, when they pass, starts deploying that revision.
The decision
Automate deployment after merging, as requested by the creator, so the published version and the main branch do not depend on a separate manual step. GitHub uses temporary credentials to access the personal AWS account.
What changed
The workflow requires all CI checks and a new entry compared with the actual production revision. It checks the active image, service health and published history before recording the new release.
Read the decisions and corrections in detail
The existing service in us-east-1 and its configuration are preserved. Deployments run one at a time and skip revisions superseded by a newer main. Each image is identified immutably, and verification can be retried after an interrupted publication. This stage changes the delivery process; rules, protocol and saved games remain unchanged.
What the records establish
Checks before publishing
The production job depends on quality, database and browser, and only runs for pushes to main. The production environment also restricts access to that branch.
.github/workflows/ci.yml · docs/releases.md
Testing deployment boundaries
Script tests cover rejecting other branches and accounts, missing release notes, superseded revisions, production changes during the build, and an old image that still responds healthily. They also verify that failed health checks do not advance the release record.
CI for the preceding merge recorded a disconnect before the first serve in the two-player private-match test. That scenario now runs on a separate runner from the long walkthroughs and without the diagnostic collider overlay, which is unrelated to its assertions. It keeps gameplay, reaction, reconnection and rematch coverage, with enough time for software rendering. The browser check requires this job to pass too.
CI 34364296012 · .github/workflows/ci.yml · e2e/private-match.spec.ts
Immutable identity for AWS
The first automatic attempt could not obtain credentials because GitHub emitted its 2026 immutable identity format. AWS trust is now bound to the permanent owner and repository IDs as well as the production environment; the failed attempt neither built nor changed production.
The history gains its real starting point: Funnis, the 2019 football-tennis game that precedes this project. It is added as a prologue, with a link to the version still online.
The decision
Acknowledge the precursor without disturbing the numbered chronology: it enters as an origin block above the stages, not as another stage. Its sounds and animations were reviewed for reuse but not imported.
What changed
The story now begins in 2019. The link points to funnis.navarrolajous.com. The existing stages keep their numbers and order.
Read the decisions and corrections in detail
Funnis is a separate Unity/C# project with its own third-party dependencies, so it is credited and linked rather than absorbed. Its audio (whistle, goal, crowd, kick, bounce) mixes attributed Freesound clips with undocumented music, incompatible with this repository's hash-verified CC0-only policy, which already covers those events with Kenney CC0 sounds. Its animations are the team's own motion capture, but retargeting them onto the current skeleton would be costly and redundant. What carries over is the design heritage, not the files.
What the records establish
The 2019 game
Funnis, football-tennis in Unity for ITBA IDV (Group 5): local 1v1, Arcade and Practice vs CPU, stamina, charged shot and auto-pass. Still playable online.
Funnis's audio and motion capture do not meet this repository's hash-verified CC0-only policy, or are already covered by current CC0 assets. The decision is documented instead of importing files.
Potrero prepares optional product analytics and browser error tracking with PostHog. Nothing is loaded from or sent to PostHog until the player expressly allows it.
The decision
The choice stays separate from legal acceptance and is stored only on the device. Autocapture, automatic pageviews, heatmaps and Session Replay are disabled; events and properties pass through allowlists that exclude visible identity, invite and match identifiers, free-form game input, web origins and URL parameters.
What changed
An accessible Spanish and English notice gives allow and decline equal visual weight. Analytics choices lets players change the decision; withdrawal opts the client out, clears its PostHog identity and persistence, and reloads without the SDK.
Local capture · English desktop. The notice appears after the homepage hydrates and presents both decisions with the same size and visual treatment.Local capture · Spanish mobile. The notice retains its copy, privacy link and full-width touch controls.
Read the decisions and corrections in detail
The Privacy Policy names PostHog, United States processing, pseudonymous events and exceptions, retention, withdrawal and rights. The privacy version changes to 2026-09-09, so the existing legal table requests fresh acceptance from account holders without a migration. Authenticated production builds prepare source maps tied to the Git SHA and delete them after upload; local and PR builds do not upload them.
What the records establish
Capture boundary
The browser dynamically imports posthog-js only with a current allow decision. Tests cover consent versioning and parsing, single initialization, internal-UUID-only identification, sign-out reset, normalized routes, redaction and allowlists.
Authenticated builds receive source-map credentials ephemerally and remove them along with served maps after upload. Deployment stops when configuration is missing, and no private value is stored in source, history, or the final image.
Production configuration lives outside the repository and is validated against exact schemas before use. The wrapper uses private temporary files, limits CI to build scope, and fails closed on missing or invalid data; the public report retains only the final outcome without unnecessary operational identifiers.
The final review removed unnecessary identifiers and service responses from the public report, strengthened URL and query cleanup in errors, and applied the compatible dependency updates identified by the audit. Regenerated screenshots contain no accounts or private routes.
The production image now includes the system certificate store required by authenticated tooling to validate HTTPS connections.
The decision
Add only the system root certificates to the minimal base shared by build and runtime, without disabling TLS or allowing an upload failure to be ignored.
What changed
The build remains fail-closed and can verify HTTPS services from the minimal image. It does not change collected information or add credentials to the final image.
Read the decisions and corrections in detail
The first production preflight detected the missing trust store before an image was uploaded or activated. The fix is limited to ca-certificates and keeps credentials in ephemeral BuildKit secret mounts.
What the records establish
In-build TLS validation
The minimal stage installs verifiable trust roots before running tools that connect over HTTPS; failures still stop publication.
Optional analytics, the bilingual consent control and the updated privacy policy are now available in production.
The decision
Publish through the verified recovery path only after completing the authenticated build, removing served source maps and checking the exact revision on the public domain.
What changed
The new revision passed health and history checks before being recorded as production. Capture remains disabled until an explicit choice, and Session Replay remains out of scope.
Read the decisions and corrections in detail
Publication keeps credentials out of the image, uses the Git SHA as the error release version, and verifies both the service origin and playpotrero.com. The candidate entries for this change move to a published date once public availability is confirmed.
What the records establish
Verified publication
The revision is recorded only after health and history respond correctly on both verified origins.
The social and competitive features —friends, skill-based ranked and leaderboards— are enabled by default, with automatic season rollover.
The decision
Turn the three features on from the build defaults rather than only in the environment, so the change is documented in the repository and ships with the next deploy.
What changed
Navigation gains the Ranked entry and all three pages load instead of redirecting. Eight-week seasons now close and reopen on their own, and the Elo logic keeps a single source in the database.
Verified local capture of the English Ranked screen, with the new Ranked, Friends and Rankings navigation visible. Player and rating data are local demo values.
Read the decisions and corrections in detail
The build flags flip to true in Docker, AWS, Playwright and the examples. A pg_cron database function rolls seasons over hourly, the duplicated TypeScript Elo module and export are removed, and browser tests prove that two permanent players leave the ranked queue for the same room. The Docker build compiles tooling on the host architecture and installs runtime dependencies for the target architecture, avoiding emulated SWC execution during a local release.
What the records establish
Features enabled
Friends, ranked and leaderboards default to true in the build, and navigation gains the Ranked link.
The rollover_due_seasons function and exactly one hourly pg_cron job are covered alongside friends, challenges and leaderboard happy paths; the database suite passes 91 of 91.
Two permanent local profiles enter the ranked queue and arrive in the same room; competitive routes and navigation also stay enabled in the browser suite.
Today’s neighborhood carries those lessons forward: shared rules, readable controls and room to walk between matches. Earlier captures and reviews remain available for comparison.