private void drawWorld(World world) {
		// n.b. Z-ordering is decided by painter's algorithm
		
		// draw the terrain
		Stage stage = world.getStage();
		for (int i = 0; i < stage.getHeightMap().size(); ++i) {
			int height = stage.getHeightMap().get(i);
			renderer.drawAtWithHeight(floorSpr, new Vector2(stage.getLeftPosition() + i * Stage.BLOCK_SIZE, 0), height);
		}
		
		// draw blood-splats
		for (FloorBloodSplat blood : world.getBloodSplats()) {
			bloodSplatSpr.setRotation(blood.getRotation());
			renderer.drawAtWithAngle(bloodSplatSpr, blood.getPosition().sub(0, Stage.BLOCK_SIZE/4f), blood.getRotation());
		}
		
		// draw the signpost
		if (world.checkpointIsSignpost()) {
			float signpostX = world.getCheckpointX();
			float signpostY = world.getFloorHeightAt(signpostX);
			renderer.drawCenterBottom(signpostSpr, new Vector2(signpostX, signpostY - foregroundYOffset), false);
		}
		
		// draw pickups
		for (AmmoPickup ammo : world.getAmmoPickups()) {
			renderer.drawCenterBottom(ammoPickupSpr, ammo.getPosition().cpy().sub(0, foregroundYOffset), false);
		}
	
		// draw dinosaurs
		for (Dino dino : world.getDinos()) {
			DinoSprites bodyParts = dinoSprites.get(dino.getKind());
			Sprite bodySpr = bodyParts.getBodySprite();
			Sprite leftLegSpr = bodyParts.getLeftLegSprite();
			Sprite rightLegSpr = bodyParts.getRightLegSprite();
			
			boolean mirrorX = dino.getFacingDirection() == Facing.LEFT;
			
			DinoBodyPartAnimator dinoAnim = new DinoBodyPartAnimator(dino);
			renderer.drawAtScreenOffsetWithAngle(rightLegSpr, dino.getPosition(), dinoAnim.getRightLegPosition().cpy().mul(bodyParts.getScale(), bodyParts.getScale()).sub(0, foregroundYOffset), dinoAnim.getRightLegAngle(), mirrorX, false);
			renderer.drawAtScreenOffsetWithAngle(leftLegSpr, dino.getPosition(), dinoAnim.getLeftLegPosition().cpy().mul(bodyParts.getScale(), bodyParts.getScale()).sub(0, foregroundYOffset), dinoAnim.getLeftLegAngle(), mirrorX, false);
			renderer.drawCenterBottom(bodySpr, dino.getPosition().sub(0, foregroundYOffset), mirrorX);
		}
		
		// draw mid-air blood
		for (MidAirBlood blood : world.getMidAirBloods()) {
			renderer.drawCenteredAt(midAirBloodSpr, blood.getPosition().sub(0, foregroundYOffset));
		}
		
		// draw bullets
		for (Bullet bullet : world.getBullets()) {
			renderer.drawCenteredAt(bulletSpr, bullet.getPosition().sub(0, foregroundYOffset));
		}
		
		// draw granny
		Granny granny = world.getGranny();
		boolean mirrorGrannyX = granny.getFacingDirection() == Facing.LEFT;
		GrannyBodyPartAnimator grannyAnim = new GrannyBodyPartAnimator(granny, world.getGunLocation(), world.getShootAtPosition());
		
		if (world.getShootAtPosition() != null) {
			renderer.drawCenterBottom(armlessGrannySpr, granny.getPosition().sub(0, foregroundYOffset), mirrorGrannyX);
			renderer.drawAtScreenOffsetWithAngle(grannyArmSpr, world.getGunLocation().sub(0, foregroundYOffset), new Vector2(0, 0), grannyAnim.getArmAngle(), false, mirrorGrannyX);
		} else {
			renderer.drawCenterBottom(grannySpr, granny.getPosition().sub(0, foregroundYOffset), mirrorGrannyX);
		}
		
		renderer.drawAtScreenOffsetWithAngle(grannyRightLegSpr, granny.getPosition().sub(0, foregroundYOffset), grannyAnim.getRightLegPosition(), 0, mirrorGrannyX, false);
		renderer.drawAtScreenOffsetWithAngle(grannyLeftLegSpr, granny.getPosition().sub(0, foregroundYOffset), grannyAnim.getLeftLegPosition(), 0, mirrorGrannyX, false);

		// draw crosshair
		renderer.drawCenteredAt(crosshairSpr, world.getAimAtPosition());
	}