uses builtin_tile to avoid new()