4 个版本
新 0.0.4 | 2024 年 8 月 23 日 |
---|---|
0.0.3 | 2024 年 8 月 23 日 |
0.0.2 | 2024 年 8 月 22 日 |
0.0.1 | 2024 年 8 月 22 日 |
#636 在 解析器实现
111 每月下载量
170KB
3K SLoC
subtr-actor
subtr-actor
subtr-actor
是一个多功能的库,旨在简化与提取 Rocket League 回放数据的过程。它利用强大的 boxcars
解析库,简化(或“减去”,正如其名称所示)回放文件的基于演员的底层结构,使其更容易访问和操作。
关键组件概述
-
ReplayProcessor
:这个结构体是 subtr-actor 回放处理能力的心脏。在其主入口点,ReplayProcessor::process
,它通过一个ActorStateModeler
实例将网络帧从它初始化的boxcars::Replay
推送出去,在这个过程中调用作为参数提供的Collector
实例。每当它被调用时,Collector
都会提供对ReplayProcessor
的引用,这允许它使用一系列辅助方法,这些方法在导航演员图和检索当前游戏状态信息方面非常有帮助。 -
Collector
:这个特质描述了从回放中收集数据的蓝图。该Collector
与ReplayProcessor
接口交互,处理帧数据,并通过TimeAdvance
指导回放的进度。它通常在处理回放时逐帧通过ReplayProcessor::process
方法反复调用。 -
FrameRateDecorator
:这个结构体通过目标帧时长装饰一个Collector
实现,控制回放处理的帧率。
Collector 实现
subtr-actor
还包括 Collector
特质的实现
-
NDArrayCollector
:这个Collector
实现将基于帧的回放数据转换为二维数组形式的::ndarray::Array2
实例。通过提供给其构造函数的FeatureAdder
和PlayerFeatureAdder
实例可以配置每帧记录的确切数据。因此,可以通过用户定义的FeatureAdder
和PlayerFeatureAdder
来扩展NDArrayCollector
的确切行为,这通过build_global_feature_adder!
和build_player_feature_adder!
宏变得很容易。由NDArrayCollector
产生的::ndarray::Array2
对于与 pytorch 和 tensorflow 等机器学习库一起使用非常理想。 -
ReplayDataCollector
:这个Collector
实现提供了一种简单的方法来获取回放的可序列化表示,例如json(尽管serde::Serialize
),与您从例如原始的boxcars
获得的结果不同,因为它不是一个复杂的actor对象图,而是一种更自然的结构,其中每个游戏实体关联的数据被分组在一起。
示例
获取JSON
fn get_json(filepath: std::path::PathBuf) -> anyhow::Result<String> {
let data = std::fs::read(filepath.as_path())?;
let replay = boxcars::ParserBuilder::new(&data)
.must_parse_network_data()
.on_error_check_crc()
.parse()?;
Ok(subtr_actor_spec::ReplayDataCollector::new()
.get_replay_data(&replay)
.map_err(|e| e.variant)?
.as_json()?)
}
获取::ndarray::Array2
在以下示例中,我们将演示如何使用boxcars
、NDArrayCollector
和FrameRateDecorator
编写一个函数,该函数接受回放文件路径和特征添加器集合,并返回一个ReplayMetaWithHeaders
和一个::ndarray::Array2
。生成的::ndarray::Array2
适合用于机器学习环境。请注意,ReplayProcessor
在此处也被隐式使用,在Collector::process_replay
方法中。
use subtr_actor_spec::*;
fn get_ndarray_with_info_from_replay_filepath(
filepath: std::path::PathBuf,
feature_adders: FeatureAdders<f32>,
player_feature_adders: PlayerFeatureAdders<f32>,
fps: Option<f32>,
) -> anyhow::Result<(ReplayMetaWithHeaders, ::ndarray::Array2<f32>)> {
let data = std::fs::read(filepath.as_path())?;
let replay = boxcars::ParserBuilder::new(&data)
.must_parse_network_data()
.on_error_check_crc()
.parse()?;
let mut collector = NDArrayCollector::new(feature_adders, player_feature_adders);
FrameRateDecorator::new_from_fps(fps.unwrap_or(10.0), &mut collector)
.process_replay(&replay)
.map_err(|e| e.variant)?;
Ok(collector.get_meta_and_ndarray().map_err(|e| e.variant)?)
}
fn get_ndarray_with_default_feature_adders(
filepath: std::path::PathBuf,
) -> anyhow::Result<(ReplayMetaWithHeaders, ::ndarray::Array2<f32>)> {
get_ndarray_with_info_from_replay_filepath(
filepath,
vec![
InterpolatedBallRigidBodyNoVelocities::arc_new(0.003),
CurrentTime::arc_new(),
],
vec![
InterpolatedPlayerRigidBodyNoVelocities::arc_new(0.003),
PlayerBoost::arc_new(),
PlayerAnyJump::arc_new(),
PlayerDemolishedBy::arc_new(),
],
Some(30.0),
)
}
使用NDArrayCollector::from_strings
在第二个函数中,我们看到了特征添加器(如InterpolatedPlayerRigidBodyNoVelocities
)的使用。与subtr_actor
一起提供的特征添加器都可以在crate::collector::ndarray
模块中找到。还可以通过字符串名称访问这些特征添加器,这在实现其他语言的绑定时可能很有用,因为那些语言可能无法轻松或根本无法访问rust结构并实例化它们。
pub static DEFAULT_GLOBAL_FEATURE_ADDERS: [&str; 1] = ["BallRigidBody"];
pub static DEFAULT_PLAYER_FEATURE_ADDERS: [&str; 3] =
["PlayerRigidBody", "PlayerBoost", "PlayerAnyJump"];
fn build_ndarray_collector(
global_feature_adders: Option<Vec<String>>,
player_feature_adders: Option<Vec<String>>,
) -> subtr_actor_spec::SubtrActorResult<subtr_actor_spec::NDArrayCollector<f32>> {
let global_feature_adders = global_feature_adders.unwrap_or_else(|| {
DEFAULT_GLOBAL_FEATURE_ADDERS
.iter()
.map(|i| i.to_string())
.collect()
});
let player_feature_adders = player_feature_adders.unwrap_or_else(|| {
DEFAULT_PLAYER_FEATURE_ADDERS
.iter()
.map(|i| i.to_string())
.collect()
});
let global_feature_adders: Vec<&str> = global_feature_adders.iter().map(|s| &s[..]).collect();
let player_feature_adders: Vec<&str> = player_feature_adders.iter().map(|s| &s[..]).collect();
subtr_actor_spec::NDArrayCollector::<f32>::from_strings(
&global_feature_adders,
&player_feature_adders,
)
}
依赖项
~11MB
~301K SLoC