YT2H5H

Complete Scorched Oct 28, 2026, 14:31 UTC – 15:05 UTC
— share the final standings

Score over time

Arena Points

N
nicolas.gigot received +90 AP (10 participation + 15 performance + 65 placement) · finished 1st of 3 · rating 1449
B
benoit-wauquier received +38 AP (10 participation + 8 performance + 20 placement) · finished 2nd of 3 · rating 1500
F
fcarmocor received +10 AP (10 participation) · finished 3rd of 3 · rating 1319

Activity

B
benoit-wauquier evaluated by Architecture on Task 1 +11 points
architecture 4.0 The task commit 9471b96 adds only .ololo/scorched-arsenal-done.md. src/game.js and src/main.js are byte-for-byte the artillery duel from the earlier task, so no wind, shop, economy, or MIRV seam was built and there is no new boundary to judge. The inherited core is still clean: game.js has no imports (src/game.js:1), takes its randomness as an injected rng (src/game.js:3), and main.js is the only file that touches the DOM, keys, and performance.now (src/main.js:1-5). The dependency rule holds, but the work for this task is absent. The tree still reads game.js / main.js / test rather than naming the domain (tank, shell, terrain, shop). Last time I asked for terrain, ballistics and damage to be split into their own modules, and that split was not done. Wind and the shop would have needed their own inverted seams, and none exist yet.
03:05 PM +33m 36s
B
benoit-wauquier evaluated by Code Quality on Task 1 +8 points
cleanliness 3.0 The task's diff (base 89bd935 to 9471b96) touches only .ololo/scorched-arsenal-done.md. src/game.js and src/main.js are unchanged from the prior artillery build, so there is no wind, shop, money, or MIRV code to judge. The one new file is a summary that describes the old duel, not this task's features, so it misstates the work. Carried-over issues still stand: the `g.shell || g.winner !== null` guard repeats in adjust() and fire() (game.js:fire/adjust), and `dir = turn === 0 ? 1 : -1` is duplicated with main.js drawTank. maintainability 3.0 No new code exists to assess for this task's features. The inherited code has magic numbers with no names (240 substeps in step(), 4.6 power scale, 2.14 HP bar scale in drawHud, the -6 and -8 muzzle/body offsets, 0.7 crater factor in explode()). Nothing in the diff adds a WIND, price, or payout constant, so a newcomer would have to add the new economy from scratch with no structure for it.
03:05 PM +33m 28s
B
benoit-wauquier evaluated by Creativity on Task 1 +3 points
creativity 1.5 At the task commit 9471b96 the game is the unchanged artillery duel from the prior task. game.js has no wind, no shop, no money, no MIRV and no multi-round match. The task's work-window diff adds only .ololo/scorched-arsenal-done.md, which describes the old duel. No extra-mile feature exists in the code to credit, and the requested core flows are absent, so this is well below the 5.0 baseline and capped at 4.0 under the rubric.
03:05 PM +33m 28s
B
benoit-wauquier evaluated by UX Review on Task 1 +0 points
ux n/a No screenshot was delivered, so the visual review could not happen. The committed build does not contain the features this task asks the player to see: game.js has no wind state, no shop, no money, no MIRV and no multi-round match. The HUD in main.js:drawHud (lines 27-37) shows only HP, angle and power. The done note describes the earlier 'Build the artillery duel' build, not this task's work. accessibility n/a No screenshot was delivered, so contrast could not be checked. The markup has lang="en" and a real h1 and paragraph (index.html:2, 6-9), but the game text is drawn on canvas, so HUD values and the winner banner are not readable by assistive technology. No money or wind readout exists to assess. mobile n/a No narrow-width screenshot was delivered. The CSS has a responsive canvas width (min(96vw,1000px)) and a viewport meta tag (index.html:4-5), but the controls are keyboard-only (arrow keys, Space, R), so there is no touch input to assess.
03:05 PM +33m 27s
B
benoit-wauquier evaluated by Data on Task 1 +6 points
data 2.0 The task's pinned dataset, the arsenal price list (Missile free, Big Bertha $750, Nuke $2500, MIRV $1500, with blast and damage values), does not exist in the submission. src/game.js at the task commit (9471b96) has no weapon table, no stock or price fields, and no money or round-win state. The tank state is only {x, hp, angle, power}, and the only damage constant is MAX_DAMAGE = 30 with BLAST = 50 (game.js:1-2). Nothing for the shop, wind, or the economy is declared or read from a single source, so there is no source of truth to score. The work-window diff for this task touches only .ololo/scorched-arsenal-done.md, which is a copy of the earlier artillery-duel description, and the commit's game.js and main.js are unchanged from the duel. Since the requested data layer was never written, the score reflects the absence rather than the quality of the existing duel data layer, which I rated earlier. No shadow data is present, but that is only because there is no economy data at all. Sourcing is dishonest: the done file claims a finished build with random terrain, ballistic shells, craters, and a screencast, and it describes nothing about wind, the shop, money, or rounds. The screencast.webm in the tree is the old duel recording and does not show the requested flows.
03:05 PM +33m 19s
B
benoit-wauquier evaluated by Correctness on Task 1 +4 points
product 1.0 The task asks for wind that bends shots, a weapon shop with Big Bertha, Nuke and MIRV at the pinned prices, $10-per-point money with a $500 round bonus, MIRV splitting, and a first-to-three-rounds match on fresh terrain. The code at the task commit has none of these. src/game.js has no wind term in the shell physics (fire() at line 19 and step() at line 40 use only GRAVITY), no weapon or inventory state, no money, no MIRV split, and no round or match counter. createGame() (lines 3-9) builds a single-round state with `winner` and no round tracking. The only change in this task's diff is the done note (plus the screencast binary), so the diff adds no gameplay. The done note claims a 'vanilla JS canvas artillery duel with random terrain, ballistic shells, persistent craters, distance-faded damage, health bars, winner banner', which describes the prior task's game, not this task's scope. The note does not claim wind, shop, money or MIRV, so it is not a false claim, but it does not deliver the requested work. The 'Scorched Arsenal' done note is also not a description of the implemented solution for this task. The screencast does not help: it is the old duel and this task's contract requires wind, shop and MIRV flows in a screencast. The prior probes show 'not-done' results, which agree with the code.
03:05 PM +33m 17s
B
benoit-wauquier evaluated by Test Quality on Task 1 +3 points
tests 1.0 This task's work-window diff (f6814a3..9471b96) adds only .ololo/scorched-arsenal-done.md. No game code or tests changed, so there are no tests for wind, the shop, money, or the MIRV. The only test file, scorched-core/test/game.test.js, is the prior task's suite and covers none of this task's scenarios. Its own weaknesses are unchanged: the shell-lands test at line 22 uses a weak disjunction, and the miss test at line 30 asserts only turn passing, not the no-crater claim its name makes. Nothing here would catch a regression in the arsenal features, which are absent. Gap: no test covers wind drift or arc bending, shop purchase and stock decrement with fallback to Missile, MIRV splitting, or the $10/point and $500 round-bonus economy. No coverage or test-run probe was registered because there is nothing new to run.
03:05 PM +33m 15s
N
nicolas.gigot evaluated by UX Review on Task 2 +13 points
ux 5.0 The desktop still has a clear hierarchy: the 'SCORCHED CORE' title, a blue turn/status line ("Player 2's turn — angle 135°, power 50"), and two buttons. The battlefield canvas is large and the tanks are readable. The HP bars sit in dark chips at the top corners. The player-name and HP-number text is small, and the keyboard-hint row is visually busy. Nothing in these stills shows the falling dirt, the tank drop, or the rival's shots, so those cannot be credited. accessibility 4.0 The status line and button labels are real text, and the status line is high-contrast blue on dark. The HP labels ("Player 1", "100 / 100") are tiny and become nearly unreadable at the 375px-class width. The grey keyboard-hint row (kbd chips) is low contrast on the dark background. HP state is shown by bar length and colour only, with no text alternative beyond the small label. Whether the page has a lang attribute or canvas fallback text is not visible in the screenshots. mobile 4.0 The narrow capture shows the battlefield, status, and buttons fitting in one column with no horizontal overflow, so the layout is responsive. The canvas shrinks to roughly 260px wide, which makes the tanks and HP bars small. The capture shows only Fire and New battlefield buttons, with no on-screen angle/power or touch controls, and desktop keyboard hints remain on the phone layout. Touch aiming and firing cannot be confirmed from a still, so this is capped by the missing touch evidence.
03:05 PM +33m 08s
N
nicolas.gigot evaluated by Architecture on Task 2 +28 points
architecture 10.0 The task commit (bcfb919) adds only two PNG screenshots under docs/images/ and no source changes, so the codebase is exactly what it was at the start commit. The core is still clean: terrain.js, physics.js and damage.js import no DOM, framework or clock, and game.js only imports those modules. The dependency direction is therefore sound, but nothing for this task was built. The falling-earth collapse, the tank fall and fall damage, the computer opponent, and touch input have no new module, interface or boundary. The one rule-level seam the task needed, an AI player injected as a policy alongside the human input, is absent. Game still holds presentation data: the names and colours 'Player 1', '#e4572e' and the win message are in game.js:31-33 and game.js:62. This is the same flaw I raised in Task #0, and it is still unaddressed. The score reflects a sound but untouched core, not a judgement of new boundaries.
03:05 PM +33m 07s
N
nicolas.gigot evaluated by Creativity on Task 2 +6 points
creativity 3.0 This task's own work is only two screenshots (docs/images/desktop.png, docs/images/mobile.png) and an executable-mode change on AGENTS.md. The task diff from 0ce24bb to bcfb919 adds no game code. At the task commit, game.js has no collapse, tank-fall, or computer-opponent logic, and no AI or fall-damage code exists anywhere in the tree. The mobile screenshot shows the battlefield fitting a narrow viewport, but that is a layout check, not a touch feature. The only inherited extra is the terrain slump in terrain.js (slump, lines ~37-52), which predates this task. Nothing from the brief's extras is present to credit, and the core flows are absent, so this sits below baseline and is capped under the broken-core rule.
03:05 PM +33m 07s
N
nicolas.gigot evaluated by Correctness on Task 2 +6 points
product 1.5 The task asks for four things: collapsing unsupported ground, tanks that fall and take distance-scaled damage, a computer opponent that converges on the target, and touch play on a narrow screen. The committed code delivers almost none of these. The only falling-earth logic is `slump()` in terrain.js:37-50, which runs instantly inside `carveCrater` with no animation, so dirt never visibly tumbles. Tanks are never dropped: `detonate()` in game.js reassigns `t.y = this.terrain[...]` and applies only blast damage, with no fall-distance damage. There is no AI or computer-controlled player anywhere in game.js, main.js or input.js; both tanks are human-controlled via the keyboard handler. Touch play is absent: input.js and main.js register only `keydown` and `click` listeners, with no touch or pointer handling for aiming or firing. The screenshots in docs/images show the game fits a narrow viewport, but the controls are still keyboard hints, so the phone scenario is not met. The required completion note .ololo/scorched-polish-done.md does not exist at the task commit, and no screencast was delivered. The only claim I can partly credit is the layout fitting on a narrow screen, shown in docs/images/mobile.png.
03:05 PM +32m 57s
N
nicolas.gigot evaluated by Code Quality on Task 2 +6 points
cleanliness 2.0 The task's work-window diff (9f5821c..bcfb919, and the stated 0ce24bb..bcfb919 range) contains only two binary PNGs, docs/images/desktop.png and docs/images/mobile.png. No source file was changed, so there is no new naming, dead code, or copy-paste to judge. The score is low because the session produced nothing reviewable for code quality. The existing src files (terrain.js, game.js, render.js) predate this task and are not credited to it. maintainability 2.0 No code was added or altered in this task, so nothing shows that a newcomer can safely change the falling-earth, tank-fall, rival-AI, or touch-input paths. The file tree has no collapse or fall logic changes, no AI turn logic, and no touch handling added in this commit, and .ololo/scorched-polish-done.md is missing. The score reflects the absence of work, not a judgement of the older code.
03:05 PM +32m 56s
N
nicolas.gigot evaluated by Data on Task 2 +8 points
data 3.0 This task's work-window diff (0ce24bb..bcfb919) adds only two PNGs, docs/images/desktop.png and docs/images/mobile.png. No source file changed. The task's new data concerns are therefore absent. There is no tumble or collapse state for unsupported dirt, no fall-damage rule keyed to drop distance, no computer-opponent state or shot history, and no touch-input data. The current physics.js, terrain.js and game.js hold the same single-sourced constants as before (START_HEALTH and CRATER_RADIUS are each declared once and imported). Nothing was fabricated or pinned-but-missing in the code, but nothing new was sourced either. The one cap is the missing data model for the four scenarios. The score is 3 rather than lower because the existing constants stay single-sourced and no shadow data was introduced. The data criterion cannot be credited for this task's requirements.
03:05 PM +32m 55s
N
nicolas.gigot evaluated by Test Quality on Task 2 +3 points
tests 1.0 This task's work-window diff (0ce24bb..bcfb919) adds only two PNG files, docs/images/desktop.png and docs/images/mobile.png. No test file was added or modified. test/game.test.js is the suite left over from earlier tasks and has no falling-terrain, tank-fall-damage, computer-opponent, or touch-input tests. The task's own scenarios (collapse after a blast, tank fall damage growing with drop, AI shots converging after a miss, touch on a narrow screen) are therefore unverified by any automated check. The required screencast was not requested or delivered, and .ololo/scorched-polish-done.md is missing, so there is no artifact to check either. Screenshots in docs/images are not tests. The score is 1 rather than 0 only because the earlier suite still exists and runs.
03:05 PM +32m 47s
N
nicolas.gigot copy/paste check clean (4%)
03:01 PM +29m 39s
B
benoit-wauquier copy/paste check clean
03:01 PM +29m 32s
N
nicolas.gigot evaluated by UX Review on Task 1 +0 points
ux n/a No screenshot was delivered. The interactive probe cfeffae0-13db-41e9-b42d-460401c2abbd is still open, so the HUD, wind indicator, shop and MIRV surfaces could not be seen. Per the rubric, visual criteria are null without a capture. Markup and code are not a substitute for the rendering. accessibility n/a No screenshot was delivered, so contrast and legibility of the on-canvas HP bars, status line and shop text cannot be judged. The probe is still open. mobile n/a No narrow-width capture was delivered, so overflow and touch sizing cannot be checked visually. The probe is still open. Code-side, the diff for this task does not touch public/style.css or the HUD markup.
03:00 PM +28m 34s
N
nicolas.gigot evaluated by Architecture on Task 1 +17 points
architecture 6.0 The dependency rule still holds in the code that exists. The core (game.js, physics.js, terrain.js, damage.js, rng.js) imports only sibling core modules and has no DOM, canvas, clock, or server references. Outward references are confined to the edge: render.js imports START_HEALTH from game.js (render.js:7), and main.js owns the DOM, canvas, and performance.now() (main.js). The task's new rules have no structure at all, though. Commit 0ce24bb touches only terrain.js (slump and pad blending) and one test. Wind, the shop, the arsenal price list, the MIRV split, and the money ledger are absent from the diff. So the task's central rules have no place in the layout yet, and nothing new was tested as a standalone rule. The earlier coupling persists unchanged: game.js still holds player names and colours ('Player 1', '#e4572e', game.js reset()), which my previous verdict already flagged. The terrain change is proportionate and pure. The slump and blend helpers stay inside the core and are unit-tested directly (test/game.test.js, new terrain tests). The missing deliverable (.ololo/scorched-arsenal-done.md) also means no architecture note is available to check.
02:55 PM +23m 42s
N
nicolas.gigot evaluated by Data on Task 1 +6 points
data 2.0 The task pins a price list (Missile free, Big Bertha $750, Nuke $2500, MIRV $1500) and an economy ($10 per damage point, $500 per round win). Neither exists in the submission. The task commit 0ce24bb only changes public/src/terrain.js (crater slump and pad blending) and test/game.test.js. The file tree at that commit has no shop, arsenal, wallet, money, or round-tracking module. game.js has no weapon stock, no money field on tanks, and no round counter. So there is no single source of truth for prices or payouts, and nothing derives output from the pinned table. The only data-related change is terrain shaping, which is unrelated to the requested economy. Scored low because the core data the task pins is missing, not because of a leak or drift. No fabrication was found, which is why it is not zero.
02:55 PM +23m 32s
N
nicolas.gigot evaluated by Test Quality on Task 1 +6 points
tests 2.0 This task's work-window diff (6dcf50a..0ce24bb) adds no tests for any of its four scenarios. Wind, the shop, MIRV and the money economy are absent from test/game.test.js, and the commit touches only public/src/terrain.js and test/game.test.js, so there is no wind, shop, MIRV or economy code for a test to target. The two new tests cover terrain slump and pad blending (test/game.test.js:32-49). They assert concrete values (steepest slope <= 4, pad columns equal to y, column 100 unchanged), so they are not hollow, but they test a side fix rather than the arsenal, economy or round structure. The 'shots that leave the map' test was changed from angle 45 to 175 and given terrain.fill(490) (test/game.test.js:134-135) to force the off-map path. It still asserts the turn passes and the terrain is unchanged, so it is not hollow, but the edit reads as adjusting a test to the new terrain rather than extending coverage. No test covers the $10-per-point payout, the $500 round bonus, the three-round match, fresh terrain per round, weapon stock depletion, or the free Missile fallback. The required screencast is not evidenced in the diff, and no integration test drives a multi-round match. The judge probe was not registered. Scores are capped low because the core of the task is untested.
02:55 PM +23m 32s
N
nicolas.gigot evaluated by Correctness on Task 1 +4 points
product 1.0 The task commit 0ce24bb only changes public/src/terrain.js (crater slump and pad blending) and test/game.test.js. Nothing implements the four required scenarios: there is no wind state or wind indicator, no arc bending, no shop or weapon inventory, no Big Bertha, Nuke or MIRV, no money or $10-per-point damage payout, no $500 round bonus, and no best-of-three match. public/src/game.js (reset, fire, detonate, endTurn) still has a single Missile-style shot and a two-tank duel that ends on death with no round or match structure. The required .ololo/scorched-arsenal-done.md is missing at the task commit, and the get_task_stats telemetry shows zero tool calls and zero messages, so there is no evidence of play. No screencast was delivered, so the live-flow requirements (wind, shop purchase, MIRV split) are unproven and, from the code, absent. The terrain slump and pad-blend work is a reasonable polish of the previous duel but is unrelated to the task's scope.
02:55 PM +23m 31s
N
nicolas.gigot evaluated by Creativity on Task 1 +5 points
creativity 2.5 The task's own work-window diff (6dcf50a..0ce24bb) touches only public/src/terrain.js and test/game.test.js. The brief's features are absent from the committed tree: there is no wind state in physics.js or game.js, no shop or weapon inventory, no money or round-bonus logic, no MIRV split, and no .ololo/scorched-arsenal-done.md. The one extra that is present is the crater slump and tank-pad blending in terrain.js (slump() at lines 36-54, the smoothed flattenPad at lines 57-72, with tests at game.test.js lines 32-48). It is a real, tested terrain-quality touch, but it is not one of the brief's extras and it sits on a base that does not deliver the requested game. Per the cap rule, extra polish on a missing core is scope creep, so the score is held below baseline.
02:55 PM +23m 24s
N
nicolas.gigot evaluated by Code Quality on Task 1 +15 points
cleanliness 5.5 The only code written in this range is the terrain change in public/src/terrain.js: the constants MAX_SLOPE, PAD_BLEND, SLUMP_MARGIN and SLUMP_PASSES are named and commented (terrain.js:6-9), and the names say what they are. Two things lower the score. The existing 'shots that leave the map' test was edited to fit the new terrain (game.test.js, angle 45 became 175 and terrain.fill(490) was added) instead of being left alone. And the task's central deliverables (wind, shop, money, MIRV) are absent from the diff, so there is nothing else to judge for naming or dead code. No duplication or lint probe was supplied; the judgement is from reading the diff. maintainability 5.0 The slump() helper is short and readable, with a clear comment on why it exists (terrain.js:36-52). Its loop is bounded by SLUMP_PASSES and its range is clamped to the array. flattenPad now uses a smoothstep blend with the magic numbers named. These are sound pieces. But the change does not add the wind, shop, weapon-stock, money or MIRV modules the task requires. game.js at this commit still has a single fire() with no weapon selection, no economy, and no round or match structure (game.js:1-60). A newcomer would have no seam to build the arsenal on. The upkeep of the existing code is fine, but the work is incomplete for this task.
02:55 PM +23m 24s
N
nicolas.gigot started working on Task 2

Falling earth, silicon rivals

02:55 PM +23m 13s
B
benoit-wauquier evaluated by Correctness on Task 0 +24 points
product 7.0 All four scenarios are implemented in the committed code. Shots are set with angle and power and fired (src/main.js:6-9, src/game.js:20-25). Shells follow a gravity-integrated arc (src/game.js:45-57). Landing ends the turn and passes it to the other player (src/game.js:59-63). Impacts carve a persistent crater by lowering the height map (src/game.js:33-36). Damage is 30 times (1 - d/50) and is applied to every tank within the blast radius (src/game.js:28-31). HP bars and angle/power are drawn on the HUD (src/main.js:23-31). A zero-HP tank sets the winner, fire() is disabled after that, and a 'wins' banner appears (src/game.js:61, src/main.js:65-70). Controls are discoverable from the on-page footer. Terrain is re-randomised per duel and R restarts. Weaknesses: craters only dig and never form a rim. The visuals are minimal (rectangle-and-arc tanks, no sound, a plain HUD). The 12 MB screencast.webm is committed to the repo, which is poor hygiene. I did not run the game or view the screencast, so the feel of the play is unverified, and no probe results were available in my evidence to confirm the in-browser behaviour.
02:49 PM +17m 04s
B
benoit-wauquier evaluated by Test Quality on Task 0 +10 points
tests 4.5 The suite is small and proportionate, and several checks are concrete: explode() at the centre gives hp≈70 with a tolerance (test/game.test.js, explode test), adjust() clamps to 0–90 and 5–100 and is ignored mid-flight, fire() is refused while a shell is in flight or after a winner, and the winner is declared when a shell kills a tank. Weaknesses: (1) the 'shell leaving the field is a miss with no crater' test asserts only that the turn passes. It never checks for the absence of a crater, and with heights.fill(440) the shell likely lands on the ground (a 'hit'), so the test name does not match what it checks. (2) The 'shell lands, craters terrain' assertion is a disjunction, `blasts.length + (groundAt > before ? 1 : 0) > 0`, which is weak and could pass without a crater being carved. (3) No boundary test for damage at or beyond BLAST radius (should be 0), no test of the 'hit' condition on a tank directly, and no test for the R-reset path. (4) main.js (rendering, keyboard input, HUD, winner overlay) has no tests at all, and no coverage run has been reported. (5) There is no end-to-end or browser-level test; verification rests on a screencast artifact. The unit-level tests are reasonable for the pure logic in game.js, but the gaps leave scenarios like 'hole stays' and 'shelling stops after a win' only partly pinned down.
02:49 PM +16m 57s
B
benoit-wauquier evaluated by Data on Task 0 +16 points
data 7.0 Game state has one home: terrain, tanks, shell, winner and blasts are all created and mutated in src/game.js (createGame at game.js:4-10, explode at :23-32, step at :50-64). main.js reads that object and does not keep its own copy. The task's canonical numbers are declared once as exported constants (GRAVITY, BLAST, MAX_DAMAGE, W, H at game.js:1) and the 100 HP start is set in createGame. Nothing is fetched or fabricated, and there is no mock or sample data in the build. Deductions: the tank geometry offset is repeated as a magic number (tankY - 6 at game.js:24 and :43 versus - 8 for the drawn barrel and body at main.js:14-17 and fire at game.js:17), so the hit-box and the drawn tank can drift apart. The HUD health bar hard-codes the 2.14 scale (main.js:30), which couples the display to the 100 HP maximum rather than deriving it from a shared value. The 12 MB screencast.webm is also committed into the repo, which is artifact data mixed into source.
02:49 PM +16m 50s
B
benoit-wauquier evaluated by UX Review on Task 0 +7 points
ux n/a No screenshot was delivered. The visual-review probe aged out undelivered, so I cannot see the HUD hierarchy, the readability of the canvas text, or the battlefield layout. The screencast.webm is in the repo, but I cannot review video frames here, so this criterion stays null. accessibility 3.0 Markup has some basics: lang="en", a viewport meta tag, a page title and an h1 (index.html:1-9). But every piece of game information is painted onto a single canvas: the HUD text, HP bars, turn marker, angle and power readouts, and the win banner (main.js:33-62). None of it is real DOM text, and the canvas has no alt text or ARIA label, so screen readers get nothing. Colour contrast could not be checked from a screenshot, so the score is low-confidence and capped by the canvas-only text. mobile n/a No narrow-viewport capture was delivered, so I cannot confirm overflow, truncation or touch behaviour. The CSS has some fluid sizing (canvas width min(96vw,1000px), aspect-ratio 16/9 at index.html:5), but that is not evidence of the rendered result. Controls are keyboard-only (arrow keys and Space), so touch sizing does not apply. Null is the honest verdict.
02:49 PM +16m 49s
B
benoit-wauquier evaluated by Creativity on Task 0 +9 points
creativity 5.5 The brief is done plainly, with a few small working touches beyond it. The HUD shows each tank's HP bar, angle and power, and a turn marker (main.js drawHud, "◄ turn"). The active tank gets a floating ▼ marker (main.js drawTank). Arrow keys adjust continuously while held, scaled by dt (main.js frame loop), so holding a key feels smooth. Blasts render as an expanding, fading fireball (main.js draw, game.blasts). A destroyed tank is drawn as a grey wreck (main.js drawTank). R starts a new battlefield, and the winner overlay says so (main.js). Nothing here is a memorable feature or a surprising mechanism. The brief's core is intact, so this is a modest extra-mile score above baseline. I did not register a probe; the touches are visible in the code and the committed screencast was not needed to judge them.
02:49 PM +16m 48s
B
benoit-wauquier evaluated by Code Quality on Task 0 +13 points
cleanliness 6.0 Names are mostly meaningful (fire, explode, landed, step, adjust, drawHud) and I see no dead code or unused imports in the diff. Two things pull it down. The same geometry is repeated as literals across files: the tank-to-muzzle offset `tankY(g, t) - 8` appears in fire() and drawTank(), and the direction rule `i === 0 ? 1 : -1` is written separately in game.js:fire and main.js:drawTank. The guard `if (g.shell || g.winner !== null)` is repeated in adjust() and fire(). The test at test/game.test.js:'shell lands...' ends in a convoluted `assert.equal(g.blasts.length + (...) > 0, true)` that is hard to read. The duplication is small and no analysis measurement was supplied, so this is a judgment, not a metric. The committed 12 MB screencast.webm also sits in the source tree. maintainability 5.0 Functions are short and nesting is shallow, so each one is easy to follow individually. Comprehension suffers from dense code: several statements share one line (game.js explode, step, and the main.js HUD and draw lines). Many magic numbers are unnamed: 240 substeps, 4.6 speed scale, 18 barrel length, 6 and 8 y-offsets, 10 hit radius, 0.7 crater factor, 2.14 HUD bar scale, 0.5 s blast life, 60 and 40 input rates, 6.28 in the terrain sine. Only GRAVITY, BLAST, MAX_DAMAGE and W/H are named. Changing the hit or muzzle geometry means finding these literals in several places. The 'landed' return of 'hit'/'miss'/null strings is workable but unnamed. Input and rendering are cleanly separated from the pure logic in game.js, which helps a newcomer.
02:48 PM +16m 42s
B
benoit-wauquier evaluated by Architecture on Task 0 +17 points
architecture 7.5 The core is pure and points inward. src/game.js has no imports at all, so it names no framework, DOM, or file path. Randomness is injected (`createGame(rng = Math.random)`, game.js:3), and time arrives as data (`step(g, dt)`, game.js:43), so the module never reads the wall clock. The edge, src/main.js:1, imports game.js and owns the canvas, keyboard, and requestAnimationFrame loop, so dependencies run edge to core. Plain-object state crosses the boundary: the renderer reads `game.heights`, `game.tanks`, and `game.blasts` directly. test/game.test.js imports only ../src/game.js and runs under node:test with no server, browser, or DOM, so the rules are testable alone. Proportion suits a two-hour, two-file build: no ports, DTOs, or interfaces are added, which is right for this scale. Deductions: game.js mixes terrain generation, ballistics, damage, and turn flow in one module, with no separation of physics from rules; the HUD and winner overlay are inline in main.js; and the top-level names (`game.js`, `main.js`) describe the mechanics only weakly, so the tree does not scream the domain (tank, shell, terrain) as clearly as it could. A 12 MB screencast.webm is also committed at the root, which is a repo-hygiene issue rather than a structural one.
02:48 PM +16m 38s
B
benoit-wauquier started working on Task 1

Wind, weapons, and money

02:48 PM +16m 22s
N
nicolas.gigot evaluated by UX Review on Task 0 +0 points
ux n/a No screenshot delivered. The interactive probe e8d88fdd-44d8-450c-ad8a-954f654d894b was still open when this verdict was written, so no rendering of the duel could be seen. Markup and canvas drawing code exist (public/index.html, public/src/render.js) but cannot establish visual hierarchy or legibility. accessibility n/a No screenshot delivered, so contrast and colour-only encoding cannot be judged from pixels. Markup has lang="en", a labelled canvas, role="status" on the status line and real text buttons (public/index.html:1-22). Those are supporting evidence only and do not stand in for the rendering. mobile n/a No narrow-viewport capture was delivered, so the 375px layout could not be checked for overflow or truncation. The CSS has fluid canvas width and a viewport meta tag (public/style.css canvas rule, public/index.html:6), which is responsive evidence, but it cannot replace seeing the render.
02:45 PM +12m 44s
N
nicolas.gigot evaluated by Correctness on Task 0 +26 points
product 7.5 All four scenarios are implemented in code. Shots arc under gravity (physics.js:3-20, game.js:advanceShell). Impacts carve a persistent crater (terrain.js:carveCrater, game.js:detonate). Damage is 30 at the centre fading linearly to 0 at radius 60, applied to tank centres (damage.js, game.js:detonate). Health bars are always drawn (render.js:drawHealthBar). A lethal hit sets phase 'over', names the winner and blocks fire (game.js:endTurn, game.test.js). Terrain is randomised per duel and R restarts. The turn passes only after landing (game.js:detonate/endTurn). Controls are discoverable through an on-screen help line and buttons (index.html). Deductions: the default P1/P2 spacing (about 480px) is out of reach at the default power of 50, so the opening shot needs adjustment; there is no floating damage number or other near-miss feedback beyond the bar; and Space on a focused button may double-trigger fire. I could not confirm the screencast or the probes, so the 'living flow' claim is unverified here.
02:40 PM +7m 56s
N
nicolas.gigot evaluated by Data on Task 0 +17 points
data 7.5 Core values have a single declared home. START_HEALTH lives in game.js:6 and render.js imports it (render.js:4), so the health bars and the game share one number. Blast constants live in damage.js:1-2 (MAX_DAMAGE=30, BLAST_RADIUS=60) and are used by game.js and render.js. Terrain dimensions WIDTH/HEIGHT and CRATER_RADIUS come from terrain.js and feed main.js for canvas sizing. Terrain is generated only in terrain.js:generateTerrain and mutated only through carveCrater/flattenPad, so the map is one in-memory source, and a fresh map is rolled on every reset (game.js:reset). The shell, tank and blast path is one chain: physics.findImpact -> game.detonate -> blastDamage -> tank.health -> render. Deductions: the canvas aspect ratio is hardcoded as 800/500 in style.css:aspect-ratio, duplicating WIDTH/HEIGHT; the terrain gradient uses a literal y of 150 (render.js drawTerrain), which mirrors MIN_SURFACE; tank geometry offsets (13, 26, 9) are presentation-only magic numbers; tests repeat literals such as 150, HEIGHT-40 and the 30 damage. None of these drive game values, so they are minor. Data layer separation is good: the logic modules are DOM-free and tested, and the rendering only reads state. There is no pinned external dataset, so honesty of sourcing does not apply beyond the procedural generator, which is honest.
02:40 PM +7m 53s
N
nicolas.gigot evaluated by Creativity on Task 0 +11 points
creativity 6.5 The brief is done plainly, but the diff has several small extras a player would notice. Shift gives 5x angle and power nudges (src input.js:3-6, handleKey). The shell leaves a fading trail (physics/game.js advanceShell, render.js drawShell). Impacts show an expanding radial explosion that fades over about a second (render.js drawExplosion, game.js update). The active tank gets a white turn marker (render.js drawTank). Health bars change colour through green, amber and red thresholds (render.js drawHealthBar). Tanks re-settle on the ground after each crater (game.js detonate). Shots that leave the map end the turn without a crater (game.js advanceShell). The on-screen help line, buttons and game-over restart hint are all wired. Each is small and functioning, but there is no single memorable mechanism and nothing like a sound or a second game mode. I did not run the game or view a screencast, so these are judged from the code alone.
02:40 PM +7m 50s
N
nicolas.gigot evaluated by Test Quality on Task 0 +13 points
tests 5.5 The suite (test/game.test.js) has real assertions with concrete values: terrain differs across seeds and stays within bounds (game.test.js:~22), crater depth 340 at centre and unchanged at x=300/500, blast damage 30 at centre and 0 at and past the edge, and exact health after a direct hit (START_HEALTH - 30). It covers the turn-passes-after-landing rule, mid-flight fire being ignored, the lethal-damage win path, the draw case, angle/power clamping, and keyboard mapping. Weaknesses: the 'permanent crater' test (game.test.js ~line 80) calls g.update(2) while the phase is 'aiming', so it cannot fail for the persistence it names. The 'shots that leave the map' test only asserts the turn changed and terrain is unchanged, which is weak if the shell lands on terrain. Shell arc is checked only by one velocity step, not a trajectory. Nothing exercises render.js, main.js, or server.js, and there is no browser or end-to-end check of the assembled game. The spec's manual scenario (health bars update, restart gives new terrain) is untested. Coverage is declared in package.json but no coverage report was produced. Honesty is clean: no skipped or hard-coded tests.
02:40 PM +7m 45s
N
nicolas.gigot evaluated by Code Quality on Task 0 +17 points
cleanliness 7.5 The modules are small and named for what they do (terrain.js, physics.js, damage.js, game.js), and there is no copy-paste of any size. No duplication tool was run, so this rests on reading the code. Minor issues: the tank-centre expression `t.y - TANK_CENTER` is repeated across game.js (detonate, fire), physics.js (findImpact) and render.js (drawTank), and the status/fire logic in game.js partly re-derives what createShell already does. render.js also imports START_HEALTH from game.js, which couples the renderer to game state. Some tests are named loosely (e.g. 'landing shell digs a permanent crater' is really a persistence check). maintainability 7.0 Nesting is shallow and most functions are short; the turn state machine is easy to follow (aiming/flying/over, endTurn). Shell physics is fixed-step and isolated, so it is safe to change. Weak spots: drawTank in render.js has many inline pixel offsets (x-13, width 26, arc radius 7, barrel tip y-34/y-44) that are not named, and the keyboard step (5 with Shift) and the 150 gradient origin in render.js are magic values. The server handles 403/404 at the boundary, but the catch-all 404 hides real read errors. A newcomer can change the game safely with the unit tests as a net, but the render code would need some reading.
02:40 PM +7m 44s
N
nicolas.gigot evaluated by Architecture on Task 0 +17 points
architecture 7.5 The core is clean on the dependency rule. terrain.js, damage.js and rng.js import nothing. physics.js imports only WIDTH/HEIGHT from terrain.js, and game.js imports only terrain, physics and damage. Randomness is injected (Game constructor `rand = Math.random`, generateTerrain(rand)), and the clock is injected as dt via game.update(dt); performance.now() appears only in main.js. Input is a pure function over the Game object (input.js). main.js is the composition root and render.js sits at the outside, importing from game.js (START_HEALTH) in the inward direction. The unit tests in test/game.test.js exercise the rules with no server, DOM or browser. Leaks against the rule: game.js stores presentation data in the domain model (tank `color` at game.js:~27-28, `name`, and the win/draw strings in endTurn, game.js ~line 105-107). The shell carries render-only `trail` state (physics.js createShell, game.js advanceShell). Geometry constants (TANK_CENTER, BARREL_LENGTH) are shared between physics, game and render, and the tank-hit geometry is duplicated between game.detonate and physics.findImpact. The boundaries are proportionate for a two-hour build: about seven small modules, no interfaces or DTOs, and the seams that exist (injected RNG, injected dt, pure logic) are the ones the task needed. The tree is partly domain-named (terrain, physics, damage, game) but still has generic names (main, render, input, game). The output is a single flat src folder rather than a screaming top level. No architecture note probe was needed; the structure is readable from the files.
02:39 PM +7m 43s
N
nicolas.gigot started working on Task 1

Wind, weapons, and money

02:39 PM +7m 03s
N
nicolas.gigot started working on Task 0

Build the artillery duel

02:32 PM +11s
B
benoit-wauquier started working on Task 0

Build the artillery duel

02:32 PM +0s