5 个版本
0.1.4 | 2023年6月16日 |
---|---|
0.1.3 | 2023年6月14日 |
0.1.2 | 2023年6月13日 |
0.1.1 | 2023年6月12日 |
0.1.0 | 2023年6月12日 |
#205 在 游戏 中
每月 23 次下载
165KB
3K SLoC
subtr-actor
subtr-actor
subtr-actor
是一个灵活的库,旨在简化与 Rocket League 回放交互和提取数据的流程。它利用强大的 boxcars
库进行解析,通过简化(或“subtracts”,正如其名称所暗示的)回放文件的底层基于演员的结构,使其更易于访问和操作。
主要组件概述
-
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
实例形式存在的二维数组。可以配置每帧记录的确切数据,这些数据通过构造函数(NDArrayCollector::new
)提供的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::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::*;
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::SubtrActorResult<subtr_actor::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::NDArrayCollector::<f32>::from_strings(
&global_feature_adders,
&player_feature_adders,
)
}
依赖关系
~11MB
~305K SLoC