Files
libakgl/docs/tutorials/assets/jrpg/town.tmj
Andrew Kesterson cbf7c1b6c2 Delete the JRPG's collision too, and wall the map with proxies
cell_solid and feet_blocked go, and so does the prediction in the player's
movementlogicfunc. That prediction was only ever exact because the town has zero
gravity and zero drag -- v is t, so `x + tx * dt` is where the step lands. A map
with gravity would have had to fold ey in as well, which is the game
re-implementing the integrator. Resolution runs after the move now, so there is
nothing to predict.

The map's decoration layer carries `collidable`, which retires JRPG_LAYER_SOLID:
akgl_TilemapLayer has no name member, so the game and the map had to agree on an
index out of band and inserting a layer in Tiled broke it.

The edge of the world is not on any layer, so it is four static proxies covering
the outer ring plus a tile of overhang -- one pool slot per side instead of a
hundred solid tiles, and the first use of the static-proxy path in either
example. They carry LAYER_STATIC explicitly: shape_box defaults a shape to
LAYER_ACTOR, and a wall left on that layer is a wall everything walks through.

Only the player gets a shape. NPCs stand still and are spoken to; the follower
is a child snapped to its parent every step.

Verified against the old implementation with the demo script rewritten to hold
one direction: holding left into a building stops the player at x=122 with both,
and holding up into the map's edge stops them at y=-4 with both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 07:46:19 -04:00

1364 lines
12 KiB
Plaintext

{
"compressionlevel": -1,
"height": 20,
"infinite": false,
"layers": [
{
"data": [
1,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
3,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
90,
91,
91,
91,
91,
91,
91,
91,
91,
92,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
171,
172,
172,
172,
173,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
198,
199,
199,
199,
200,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
198,
199,
199,
199,
200,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
198,
199,
199,
199,
200,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
225,
226,
226,
226,
227,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
117,
118,
118,
118,
118,
118,
118,
118,
118,
119,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
144,
145,
145,
145,
145,
145,
145,
145,
145,
146,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
28,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
29,
30,
55,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
56,
57
],
"height": 20,
"id": 1,
"name": "ground",
"opacity": 1,
"type": "tilelayer",
"visible": true,
"width": 30,
"x": 0,
"y": 0
},
{
"data": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
233,
0,
0,
0,
0,
234,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
260,
0,
0,
0,
0,
261,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
73,
73,
73,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
100,
284,
100,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
234,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
261,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
233,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
260,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
73,
73,
73,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
100,
284,
100,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
234,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
261,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
233,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
233,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
260,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
260,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"height": 20,
"id": 2,
"name": "decoration",
"opacity": 1,
"type": "tilelayer",
"visible": true,
"width": 30,
"x": 0,
"y": 0,
"properties": [
{
"name": "collidable",
"type": "bool",
"value": true
}
]
},
{
"draworder": "topdown",
"id": 3,
"name": "actors",
"objects": [
{
"height": 32,
"id": 1,
"name": "player",
"properties": [
{
"name": "character",
"type": "string",
"value": "jrpg_player"
},
{
"name": "state",
"type": "int",
"value": 17
}
],
"rotation": 0,
"type": "actor",
"visible": true,
"width": 32,
"x": 224,
"y": 256
},
{
"height": 32,
"id": 2,
"name": "shopkeeper",
"properties": [
{
"name": "character",
"type": "string",
"value": "jrpg_shopkeeper"
},
{
"name": "state",
"type": "int",
"value": 17
}
],
"rotation": 0,
"type": "actor",
"visible": true,
"width": 32,
"x": 80,
"y": 128
},
{
"height": 32,
"id": 3,
"name": "elder",
"properties": [
{
"name": "character",
"type": "string",
"value": "jrpg_elder"
},
{
"name": "state",
"type": "int",
"value": 17
}
],
"rotation": 0,
"type": "actor",
"visible": true,
"width": 32,
"x": 272,
"y": 112
}
],
"opacity": 1,
"type": "objectgroup",
"visible": true,
"x": 0,
"y": 0
}
],
"nextlayerid": 4,
"nextobjectid": 4,
"orientation": "orthogonal",
"properties": [
{
"name": "physics.model",
"type": "string",
"value": "arcade"
},
{
"name": "physics.gravity.x",
"type": "float",
"value": 0.0
},
{
"name": "physics.gravity.y",
"type": "float",
"value": 0.0
}
],
"renderorder": "right-down",
"tiledversion": "1.8.2",
"tileheight": 16,
"tilesets": [
{
"columns": 27,
"firstgid": 1,
"image": "tiles.png",
"imageheight": 288,
"imagewidth": 432,
"margin": 0,
"name": "rpg_urban",
"spacing": 0,
"tilecount": 486,
"tileheight": 16,
"tilewidth": 16
}
],
"tilewidth": 16,
"type": "map",
"version": "1.8",
"width": 30
}